(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:
@@ -54,6 +54,68 @@ typedef struct krb5_kcmcache {
|
|||||||
#define CACHENAME(X) (KCMCACHE(X)->name)
|
#define CACHENAME(X) (KCMCACHE(X)->name)
|
||||||
#define KCMCURSOR(C) (*(u_int32_t *)(C))
|
#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
|
static krb5_error_code
|
||||||
kcm_send_request(krb5_context context,
|
kcm_send_request(krb5_context context,
|
||||||
krb5_kcmcache *k,
|
krb5_kcmcache *k,
|
||||||
@@ -69,35 +131,27 @@ kcm_send_request(krb5_context context,
|
|||||||
|
|
||||||
ret = krb5_storage_to_data(request, &request_data);
|
ret = krb5_storage_to_data(request, &request_data);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
krb5_clear_error_string(context);
|
||||||
return KRB5_CC_NOMEM;
|
return KRB5_CC_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = KRB5_CC_IO;
|
ret = KRB5_CC_IO;
|
||||||
|
|
||||||
for (i = 0; i < context->max_retries; i++) {
|
for (i = 0; i < context->max_retries; i++) {
|
||||||
int fd;
|
ret = try_door(context, k, &request_data, response_data);
|
||||||
|
if (ret == 0 && response_data->length != 0)
|
||||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
break;
|
||||||
if (fd < 0)
|
ret = try_unix_socket(context, k, &request_data, response_data);
|
||||||
continue;
|
if (ret == 0 && response_data->length != 0)
|
||||||
|
|
||||||
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) {
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
krb5_data_free(&request_data);
|
krb5_data_free(&request_data);
|
||||||
|
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_clear_error_string(context);
|
||||||
ret = KRB5_CC_IO;
|
ret = KRB5_CC_IO;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user