(kcm_send_request): add support for doing a door call to kcm

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@15256 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2005-05-29 14:27:09 +00:00
parent 8e78ed6e48
commit a50f5cbbd4

View File

@@ -54,6 +54,68 @@ typedef struct krb5_kcmcache {
#define CACHENAME(X) (KCMCACHE(X)->name)
#define KCMCURSOR(C) (*(u_int32_t *)(C))
static krb5_error_code
try_door(krb5_context context, const krb5_kcmcache *k,
krb5_data *request_data,
krb5_data *response_data)
{
#ifdef HAVE_DOOR_CREATE
door_arg_t arg;
int fd;
int ret;
memset(&arg, 0, sizeof(arg));
fd = open(_PATH_KCM_DOOR, O_RDWR);
if (fd < 0)
return KRB5_CC_IO;
arg.data_ptr = request_data->data;
arg.data_size = request_data->length;
arg.desc_ptr = NULL;
arg.desc_num = 0;
arg.rbuf = NULL;
arg.rsize = 0;
ret = door_call(fd, &arg);
close(fd);
if (ret != 0)
return KRB5_CC_IO;
ret = krb5_data_copy(response_data, arg.rbuf, arg.rsize);
munmap(arg.rbuf, arg.rsize);
if (ret)
return ret;
return 0;
#else
return KRB5_CC_IO;
#endif
}
static krb5_error_code
try_unix_socket(krb5_context context, const krb5_kcmcache *k,
krb5_data *request_data,
krb5_data *response_data)
{
krb5_error_code ret;
int fd;
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
return KRB5_CC_IO;
if (connect(fd, (struct sockaddr *)&k->path, sizeof(k->path)) != 0) {
close(fd);
return KRB5_CC_IO;
}
ret = _krb5_send_and_recv_tcp(fd, context->kdc_timeout,
request_data, response_data);
close(fd);
return ret;
}
static krb5_error_code
kcm_send_request(krb5_context context,
krb5_kcmcache *k,
@@ -69,35 +131,27 @@ kcm_send_request(krb5_context context,
ret = krb5_storage_to_data(request, &request_data);
if (ret) {
krb5_clear_error_string(context);
return KRB5_CC_NOMEM;
}
ret = KRB5_CC_IO;
for (i = 0; i < context->max_retries; i++) {
int fd;
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
continue;
if (connect(fd, (struct sockaddr *)&k->path, sizeof(k->path)) != 0) {
close(fd);
continue;
}
ret = _krb5_send_and_recv_tcp(fd, context->kdc_timeout,
&request_data, response_data);
close(fd);
if (ret == 0 && response_data->length != 0) {
ret = try_door(context, k, &request_data, response_data);
if (ret == 0 && response_data->length != 0)
break;
ret = try_unix_socket(context, k, &request_data, response_data);
if (ret == 0 && response_data->length != 0)
break;
}
}
krb5_data_free(&request_data);
if (ret)
if (ret) {
krb5_clear_error_string(context);
ret = KRB5_CC_IO;
}
return ret;
}