diff --git a/kcm/config.c b/kcm/config.c index 42f896f3f..58d39ef47 100644 --- a/kcm/config.c +++ b/kcm/config.c @@ -40,7 +40,6 @@ static const char *config_file; /* location of kcm config file */ size_t max_request = 0; /* maximal size of a request */ char *socket_path = NULL; -char *door_path = NULL; static char *max_request_str; /* `max_request' as a string */ @@ -123,12 +122,6 @@ static struct getargs args[] = { "socket-path", 's', arg_string, &socket_path, "path to kcm domain socket", "path" }, -#ifdef HAVE_DOOR_CREATE - { - "door-path", 's', arg_string, &door_path, - "path to kcm door", "path" - }, -#endif { "server", 'S', arg_string, &system_server, "server to get system ticket for", "principal" diff --git a/kcm/kcm.8 b/kcm/kcm.8 index 978f4dfdb..744ab0f1d 100644 --- a/kcm/kcm.8 +++ b/kcm/kcm.8 @@ -73,10 +73,6 @@ .Fl Fl socket-path= Ns Ar path .Xc .Oc -.Oo Xo -.Fl Fl door-path= Ns Ar path -.Xc -.Oc .Oo Fl S Ar principal \*(Ba Xo .Fl Fl server= Ns Ar principal .Xc @@ -153,8 +149,6 @@ disable credentials cache name constraints renewable lifetime of system tickets .It Fl s Ar path , Fl Fl socket-path= Ns Ar path path to kcm domain socket -.It Fl Fl door-path= Ns Ar path -path to kcm door socket .It Fl S Ar principal , Fl Fl server= Ns Ar principal server to get system ticket for .It Fl t Ar keytab , Fl Fl keytab= Ns Ar keytab diff --git a/kcm/kcm_locl.h b/kcm/kcm_locl.h index a70e8b839..c33738497 100644 --- a/kcm/kcm_locl.h +++ b/kcm/kcm_locl.h @@ -164,8 +164,6 @@ struct kcm_op { #define _PATH_KCM_CONF SYSCONFDIR "/kcm.conf" extern krb5_context kcm_context; -extern char *socket_path; -extern char *door_path; extern size_t max_request; extern sig_atomic_t exit_flag; extern int name_constraints; diff --git a/kcm/main.c b/kcm/main.c index ee691d5f2..ec992d8bb 100644 --- a/kcm/main.c +++ b/kcm/main.c @@ -97,6 +97,12 @@ main(int argc, char **argv) heim_sipc un; heim_sipc_service_unix(service_name, kcm_service, NULL, &un); } +#ifdef HAVE_DOOR_CREATE + { + heim_sipc door; + heim_sipc_service_door(service_name, kcm_service, NULL, &door); + } +#endif roken_detach_finish(NULL, daemon_child); diff --git a/kdc/digest-service.c b/kdc/digest-service.c index 011586650..9f0880bb3 100644 --- a/kdc/digest-service.c +++ b/kdc/digest-service.c @@ -273,6 +273,12 @@ main(int argc, char **argv) ntlm_service, context, &mach); heim_sipc_timeout(60); } +#endif +#ifdef HAVE_DOOR_CREATE + { + heim_sipc door; + heim_sipc_service_door("org.h5l.ntlm-service", ntlm_service, NULL, &door); + } #endif { heim_sipc un; diff --git a/lib/ipc/client.c b/lib/ipc/client.c index a51e91c99..82ef2bfc2 100644 --- a/lib/ipc/client.c +++ b/lib/ipc/client.c @@ -428,28 +428,51 @@ common_release(void *ctx) return 0; } -#ifdef HAVE_DOOR +#ifdef HAVE_DOOR_CREATE + +#include + +#ifdef HAVE_SYS_MMAN_H +#include +#endif static int door_init(const char *service, void **ctx) { - ret = common_path_init(context, service, "door", ctx); + int ret; + struct path_ctx *d; + + ret = common_path_init(service, "door", ctx); if (ret) return ret; - ret = connect_door(*ctx); - if (ret) + + d = (struct path_ctx *)*ctx; + d->fd = open(d->path, O_RDWR); + if (d->fd < 0) { + ret = errno; common_release(*ctx); - return ret; + return ret; + } + + return 0; } +struct door_reply { + int returnvalue; + size_t length; + unsigned char data[1]; +}; + static int door_ipc(void *ctx, const heim_idata *request, heim_idata *response, heim_icred *cred) { + struct path_ctx *d = (struct path_ctx *)ctx; door_arg_t arg; int ret; + struct door_reply *r; arg.data_ptr = request->data; arg.data_size = request->length; @@ -458,24 +481,34 @@ door_ipc(void *ctx, arg.rbuf = NULL; arg.rsize = 0; - ret = door_call(fd, &arg); - close(fd); + ret = door_call(d->fd, &arg); if (ret != 0) return errno; - response->data = malloc(arg.rsize); + if (arg.rsize < offsetof(struct door_reply, data)) + return EINVAL; + + r = (struct door_reply *)arg.rbuf; + if (r->returnvalue != 0) + return r->returnvalue; + + if (arg.rsize < offsetof(struct door_reply, data) + r->length) + return ERANGE; + + response->data = malloc(r->length); if (response->data == NULL) { munmap(arg.rbuf, arg.rsize); return ENOMEM; } - memcpy(response->data, arg.rbuf, arg.rsize); - response->length = arg.rsize; + + memcpy(response->data, r->data, r->length); + response->length = r->length; munmap(arg.rbuf, arg.rsize); - return ret; + return 0; } -#endif +#endif /* HAVE_DOOR_CREATE */ struct hipc_ops { const char *prefix; @@ -490,8 +523,8 @@ struct hipc_ops ipcs[] = { #if defined(__APPLE__) && defined(HAVE_GCD) { "MACH", mach_init, mach_release, mach_ipc, mach_async }, #endif -#ifdef HAVE_DOOR - { "DOOR", door_init, common_release, door_ipc, NULL } +#ifdef HAVE_DOOR_CREATE + { "DOOR", door_init, common_release, door_ipc, NULL }, #endif { "UNIX", unix_socket_init, common_release, unix_socket_ipc, NULL } }; diff --git a/lib/ipc/heim-ipc.h b/lib/ipc/heim-ipc.h index b5b919b64..0f4a3ad64 100644 --- a/lib/ipc/heim-ipc.h +++ b/lib/ipc/heim-ipc.h @@ -119,6 +119,9 @@ int heim_sipc_service_unix(const char *, heim_ipc_callback, void *, heim_sipc *); +int +heim_sipc_service_door(const char *, heim_ipc_callback, + void *, heim_sipc *); void heim_sipc_timeout(time_t); diff --git a/lib/ipc/server.c b/lib/ipc/server.c index 126910be8..87031d2a8 100644 --- a/lib/ipc/server.c +++ b/lib/ipc/server.c @@ -457,6 +457,7 @@ struct client { #define WAITING_CLOSE 8 #define HTTP_REPLY 16 +#define DOOR_FD 32 #define INHERIT_MASK 0xffff0000 #define INCLUDE_ERROR_CODE (1 << 16) @@ -612,7 +613,6 @@ update_client_creds(struct client *c) return 0; } - static struct client * add_new_socket(int fd, int flags, @@ -628,6 +628,8 @@ add_new_socket(int fd, if (flags & LISTEN_SOCKET) { c->fd = fd; + } else if (flags & DOOR_FD) { + c->fd = -1; /* cannot poll a door descriptor */ } else { c->fd = accept(fd, NULL, NULL); if(c->fd < 0) { @@ -870,6 +872,8 @@ handle_read(struct client *c) ssize_t len; uint32_t dlen; + assert((c->flags & DOOR_FD) == 0); + if (c->flags & LISTEN_SOCKET) { add_new_socket(c->fd, WAITING_READ | (c->flags & INHERIT_MASK), @@ -930,6 +934,7 @@ handle_read(struct client *c) cs->in.data = emalloc(dlen); memcpy(cs->in.data, c->inmsg + sizeof(dlen), dlen); cs->in.length = dlen; + cs->cred = NULL; c->ptr -= sizeof(dlen) + dlen; memmove(c->inmsg, @@ -1131,6 +1136,144 @@ heim_sipc_service_unix(const char *service, return ret; } +#ifdef HAVE_DOOR_CREATE +#include +#include + +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +struct door_call { + heim_idata in; + door_desc_t *dp; + heim_icred cred; +}; + +struct door_reply { + int returnvalue; + size_t length; + unsigned char data[1]; +}; + +static int +door_release(heim_sipc ctx) +{ + struct client *c = ctx->mech; + return 0; +} + +static void +door_complete(heim_sipc_call ctx, int returnvalue, heim_idata *reply) +{ + struct door_call *cs = (struct door_call *)ctx; + size_t rlen = offsetof(struct door_reply, data); + struct door_reply *r; + + if (returnvalue == 0) + rlen += reply->length; + + r = alloca(rlen); + r->returnvalue = returnvalue; + + if (returnvalue == 0) { + r->length = reply->length; + memcpy(r->data, reply->data, reply->length); + } + + /* door_return() doesn't return; don't leak cred */ + heim_ipc_free_cred(cs->cred); + + door_return((char *)r, rlen, NULL, 0); +} + +static void +door_callback(void *cookie, + char *argp, + size_t arg_size, + door_desc_t *dp, + uint_t n_desc) +{ + heim_sipc c = (heim_sipc)cookie; + struct door_call cs = { 0 }; + ucred_t *peercred = NULL; + + if (door_ucred(&peercred) < 0) + return; + + _heim_ipc_create_cred(ucred_geteuid(peercred), + ucred_getegid(peercred), + ucred_getpid(peercred), + -1, + &cs.cred); + ucred_free(peercred); + + cs.dp = dp; + cs.in.data = argp; + cs.in.length = arg_size; + + c->callback(c->userctx, &cs.in, cs.cred, door_complete, (heim_sipc_call)&cs); +} + +int +heim_sipc_service_door(const char *service, + heim_ipc_callback callback, + void *user, heim_sipc *ctx) +{ + char path[PATH_MAX]; + int fd = -1, dfd = -1, ret; + heim_sipc ct = NULL; + struct client *c = NULL; + + ct = calloc(1, sizeof(*ct)); + if (ct == NULL) { + ret = ENOMEM; + goto cleanup; + } + ct->release = door_release; + ct->userctx = user; + ct->callback = callback; + + snprintf(path, sizeof(path), "/var/run/.heim_%s-door", service); + fd = door_create(door_callback, ct, DOOR_REFUSE_DESC | DOOR_NO_CANCEL); + if (fd < 0) { + ret = errno; + goto cleanup; + } + + fdetach(path); + dfd = open(path, O_RDWR | O_CREAT, 0666); + if (dfd < 0) { + ret = errno; + goto cleanup; + } + fchmod(dfd, 0666); /* XXX */ + + if (fattach(fd, path) < 0) { + ret = errno; + goto cleanup; + } + + c = add_new_socket(fd, DOOR_FD, callback, user); + ct->mech = c; + + *ctx = ct; + ret = 0; + +cleanup: + if (ret != 0) { + free(ct); + free(c); + if (fd != -1) + close(fd); + } + if (dfd != -1) + close(dfd); + + return ret; +} +#endif /* HAVE_DOOR_CREATE */ + /** * Set the idle timeout value diff --git a/lib/ipc/tc.c b/lib/ipc/tc.c index fb799bba9..29d3affda 100644 --- a/lib/ipc/tc.c +++ b/lib/ipc/tc.c @@ -33,6 +33,7 @@ * SUCH DAMAGE. */ +#include "config.h" #include #include #include @@ -62,7 +63,7 @@ usage(int ret) static void reply(void *ctx, int errorcode, heim_idata *rep, heim_icred cred) { - printf("got reply\n"); + printf("got reply errorcode %d, rep %.*s\n", errorcode, rep->length, rep->data); heim_ipc_semaphore_signal((heim_isemaphore)ctx); /* tell caller we are done */ } @@ -73,13 +74,18 @@ test_ipc(const char *service) heim_idata req, rep; heim_ipc ipc; int ret; + char buf[128]; + + snprintf(buf, sizeof(buf), "testing heim IPC via %s", service); + + printf("%s\n", buf); ret = heim_ipc_init_context(service, &ipc); if (ret) errx(1, "heim_ipc_init_context: %d", ret); - req.length = 0; - req.data = NULL; + req.length = strlen(buf); + req.data = buf; ret = heim_ipc_call(ipc, &req, &rep, NULL); if (ret) @@ -122,6 +128,9 @@ main(int argc, char **argv) #endif test_ipc("ANY:org.h5l.test-ipc"); test_ipc("UNIX:org.h5l.test-ipc"); +#ifdef HAVE_DOOR_CREATE + test_ipc("DOOR:org.h5l.test-ipc"); +#endif return 0; } diff --git a/lib/ipc/ts.c b/lib/ipc/ts.c index e0f846eee..9d7693bf4 100644 --- a/lib/ipc/ts.c +++ b/lib/ipc/ts.c @@ -33,6 +33,7 @@ * SUCH DAMAGE. */ +#include "config.h" #include #include #include @@ -64,9 +65,12 @@ test_service(void *ctx, const heim_idata *req, heim_sipc_call cctx) { heim_idata rep; - printf("got request\n"); - rep.length = 0; - rep.data = NULL; + char buf[128]; + + printf("got request via %s\n", (const char *)ctx); + snprintf(buf, sizeof(buf), "Hello back via %s\n", (const char *)ctx); + rep.data = buf; + rep.length = strlen(buf); (*complete)(cctx, 0, &rep); } @@ -94,11 +98,18 @@ main(int argc, char **argv) { heim_sipc mach; heim_sipc_launchd_mach_init("org.h5l.test-ipc", - test_service, NULL, &mach); + test_service, "MACH", &mach); } #endif heim_sipc_service_unix("org.h5l.test-ipc", - test_service, NULL, &u); + test_service, "UNIX", &u); +#ifdef HAVE_DOOR_CREATE + { + heim_sipc door; + heim_sipc_service_door("org.h5l.test-ipc", + test_service, "DOOR", &door); + } +#endif heim_ipc_main(); return 0; diff --git a/lib/krb5/kcm.h b/lib/krb5/kcm.h index 27197fec3..ba484b9ca 100644 --- a/lib/krb5/kcm.h +++ b/lib/krb5/kcm.h @@ -78,9 +78,6 @@ typedef enum kcm_operation { KCM_OP_MAX } kcm_operation; -#define _PATH_KCM_SOCKET "/var/run/.kcm_socket" -#define _PATH_KCM_DOOR "/var/run/.kcm_door" - #define KCM_NTLM_FLAG_SESSIONKEY 1 #define KCM_NTLM_FLAG_NTLM2_SESSION 2 #define KCM_NTLM_FLAG_KEYEX 4