From 570beed06bb70120e1a9f3aceb1224bc1d047de5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20R=C4=99korajski?= Date: Tue, 19 Oct 2010 21:20:16 +0000 Subject: [PATCH] - rel 9 - pull "make kcm work on *nix" fixes from upstream Changed files: heimdal-kcm.patch -> 1.4 heimdal.spec -> 1.221 --- heimdal-kcm.patch | 285 ++++++++++++++++++++++++++++++++++++++++++++++ heimdal.spec | 4 +- 2 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 heimdal-kcm.patch diff --git a/heimdal-kcm.patch b/heimdal-kcm.patch new file mode 100644 index 0000000..0e10e5c --- /dev/null +++ b/heimdal-kcm.patch @@ -0,0 +1,285 @@ +diff --git a/kcm/cache.c b/kcm/cache.c +index 8a27ba0..d0a5b6f 100644 +--- a/kcm/cache.c ++++ b/kcm/cache.c +@@ -428,6 +428,8 @@ kcm_release_ccache(krb5_context context, kcm_ccache c) + + HEIMDAL_MUTEX_lock(&c->mutex); + if (c->refcnt == 1) { ++ kcm_free_ccache_data_internal(context, c); ++ free(c); + } else { + c->refcnt--; + HEIMDAL_MUTEX_unlock(&c->mutex); +diff --git a/kcm/protocol.c b/kcm/protocol.c +index de65599..a019edd 100644 +--- a/kcm/protocol.c ++++ b/kcm/protocol.c +@@ -948,6 +948,13 @@ kcm_op_move_cache(krb5_context context, + return ret; + } + ++ /* move to ourself is simple, done! */ ++ if (strcmp(oldname, newname) == 0) { ++ free(oldname); ++ free(newname); ++ return 0; ++ } ++ + ret = kcm_ccache_resolve_client(context, client, opcode, oldname, &oldid); + if (ret) { + free(oldname); +diff --git a/lib/ipc/hi_locl.h b/lib/ipc/hi_locl.h +index b9a094f..1cbab32 100644 +--- a/lib/ipc/hi_locl.h ++++ b/lib/ipc/hi_locl.h +@@ -49,6 +49,10 @@ + #include + #include + ++#ifdef HAVE_SYS_UN_H ++#include ++#endif ++ + #include + + #include +diff --git a/lib/ipc/server.c b/lib/ipc/server.c +index e2f771c..81127b7 100644 +--- a/lib/ipc/server.c ++++ b/lib/ipc/server.c +@@ -456,6 +456,7 @@ struct client { + #define INHERIT_MASK 0xffff0000 + #define INCLUDE_ERROR_CODE (1 << 16) + #define ALLOW_HTTP (1<<17) ++#define UNIX_SOCKET (1<<18) + unsigned calls; + size_t ptr, len; + uint8_t *inmsg; +@@ -465,6 +466,11 @@ struct client { + dispatch_source_t in; + dispatch_source_t out; + #endif ++ struct { ++ uid_t uid; ++ gid_t gid; ++ pid_t pid; ++ } unixrights; + }; + + #ifndef HAVE_GCD +@@ -476,6 +482,132 @@ static void handle_read(struct client *); + static void handle_write(struct client *); + static int maybe_close(struct client *); + ++/* ++ * Update peer credentials from socket. ++ * ++ * SCM_CREDS can only be updated the first time there is read data to ++ * read from the filedescriptor, so if we read do it before this ++ * point, the cred data might not be is not there yet. ++ */ ++ ++static int ++update_client_creds(struct client *c) ++{ ++#ifdef HAVE_GETPEERUCRED ++ /* Solaris 10 */ ++ { ++ ucred_t *peercred; ++ ++ if (getpeerucred(c->fd, &peercred) != 0) { ++ c->unixrights.uid = ucred_geteuid(peercred); ++ c->unixrights.gid = ucred_getegid(peercred); ++ c->unixrights.pid = 0; ++ ucred_free(peercred); ++ return 1; ++ } ++ } ++#endif ++#ifdef HAVE_GETPEEREID ++ /* FreeBSD, OpenBSD */ ++ { ++ uid_t uid; ++ gid_t gid; ++ ++ if (getpeereid(c->fd, &uid, &gid) == 0) { ++ c->unixrights.uid = uid; ++ c->unixrights.gid = gid; ++ c->unixrights.pid = 0; ++ return 1; ++ } ++ } ++#endif ++#ifdef SO_PEERCRED ++ /* Linux */ ++ { ++ struct ucred pc; ++ socklen_t pclen = sizeof(pc); ++ ++ if (getsockopt(c->fd, SOL_SOCKET, SO_PEERCRED, (void *)&pc, &pclen) == 0) { ++ c->unixrights.uid = pc.uid; ++ c->unixrights.gid = pc.gid; ++ c->unixrights.pid = pc.pid; ++ return 1; ++ } ++ } ++#endif ++#if defined(LOCAL_PEERCRED) && defined(XUCRED_VERSION) ++ { ++ struct xucred peercred; ++ socklen_t peercredlen = sizeof(peercred); ++ ++ if (getsockopt(c->fd, LOCAL_PEERCRED, 1, ++ (void *)&peercred, &peercredlen) == 0 ++ && peercred.cr_version == XUCRED_VERSION) ++ { ++ c->unixrights.uid = peercred.cr_uid; ++ c->unixrights.gid = peercred.cr_gid; ++ c->unixrights.pid = 0; ++ return 1; ++ } ++ } ++#endif ++#if defined(SOCKCREDSIZE) && defined(SCM_CREDS) ++ /* NetBSD */ ++ if (c->unixrights.uid == -1) { ++ struct msghdr msg; ++ socklen_t crmsgsize; ++ void *crmsg; ++ struct cmsghdr *cmp; ++ struct sockcred *sc; ++ ++ memset(&msg, 0, sizeof(msg)); ++ crmsgsize = CMSG_SPACE(SOCKCREDSIZE(NGROUPS)); ++ if (crmsgsize == 0) ++ return 1 ; ++ ++ crmsg = malloc(crmsgsize); ++ if (crmsg == NULL) ++ goto failed_scm_creds; ++ ++ memset(crmsg, 0, crmsgsize); ++ ++ msg.msg_control = crmsg; ++ msg.msg_controllen = crmsgsize; ++ ++ if (recvmsg(c->fd, &msg, 0) < 0) { ++ free(crmsg); ++ goto failed_scm_creds; ++ } ++ ++ if (msg.msg_controllen == 0 || (msg.msg_flags & MSG_CTRUNC) != 0) { ++ free(crmsg); ++ goto failed_scm_creds; ++ } ++ ++ cmp = CMSG_FIRSTHDR(&msg); ++ if (cmp->cmsg_level != SOL_SOCKET || cmp->cmsg_type != SCM_CREDS) { ++ free(crmsg); ++ goto failed_scm_creds; ++ } ++ ++ sc = (struct sockcred *)(void *)CMSG_DATA(cmp); ++ ++ c->unixrights.uid = sc->sc_euid; ++ c->unixrights.gid = sc->sc_egid; ++ c->unixrights.pid = 0; ++ ++ free(crmsg); ++ return 1; ++ } else { ++ /* we already got the cred, just return it */ ++ return 1; ++ } ++ failed_scm_creds: ++#endif ++ return 0; ++} ++ ++ + static struct client * + add_new_socket(int fd, + int flags, +@@ -569,6 +701,7 @@ maybe_close(struct client *c) + struct socket_call { + heim_idata in; + struct client *c; ++ heim_icred cred; + }; + + static void +@@ -616,7 +749,8 @@ socket_complete(heim_sipc_call ctx, int returnvalue, heim_idata *reply) + } + + c->calls--; +- ++ if (sc->cred) ++ heim_ipc_free_cred(sc->cred); + free(sc->in.data); + sc->c = NULL; /* so we can catch double complete */ + free(sc); +@@ -782,7 +916,7 @@ handle_read(struct client *c) + c->flags &= ~WAITING_READ; + return; + } +- if (dlen < c->ptr - sizeof(dlen)) { ++ if (dlen > c->ptr - sizeof(dlen)) { + break; + } + +@@ -799,8 +933,15 @@ handle_read(struct client *c) + } + + c->calls++; ++ ++ if ((c->flags & UNIX_SOCKET) != 0) { ++ if (update_client_creds(c)) ++ _heim_ipc_create_cred(c->unixrights.uid, c->unixrights.gid, ++ c->unixrights.pid, -1, &cs->cred); ++ } ++ + c->callback(c->userctx, &cs->in, +- NULL, socket_complete, ++ cs->cred, socket_complete, + (heim_sipc_call)cs); + } + } +@@ -924,6 +1065,11 @@ heim_sipc_stream_listener(int fd, int type, + + ct->mech = c; + ct->release = socket_release; ++ ++ c->unixrights.uid = (uid_t) -1; ++ c->unixrights.gid = (gid_t) -1; ++ c->unixrights.pid = (pid_t) 0; ++ + *ctx = ct; + return 0; + } +@@ -934,7 +1080,7 @@ heim_sipc_service_unix(const char *service, + void *user, heim_sipc *ctx) + { + struct sockaddr_un un; +- int fd; ++ int fd, ret; + + un.sun_family = AF_UNIX; + +@@ -966,8 +1112,14 @@ heim_sipc_service_unix(const char *service, + + chmod(un.sun_path, 0666); + +- return heim_sipc_stream_listener(fd, HEIM_SIPC_TYPE_IPC, +- callback, user, ctx); ++ ret = heim_sipc_stream_listener(fd, HEIM_SIPC_TYPE_IPC, ++ callback, user, ctx); ++ if (ret == 0) { ++ struct client *c = (*ctx)->mech; ++ c->flags |= UNIX_SOCKET; ++ } ++ ++ return ret; + } + + /** diff --git a/heimdal.spec b/heimdal.spec index 12bcd1f..75ce9a8 100644 --- a/heimdal.spec +++ b/heimdal.spec @@ -8,7 +8,7 @@ Summary: Heimdal implementation of Kerberos V5 system Summary(pl.UTF-8): Implementacja Heimdal systemu Kerberos V5 Name: heimdal Version: 1.4 -Release: 8 +Release: 9 License: Free Group: Networking Source0: http://www.h5l.org/dist/src/%{name}-%{version}.tar.gz @@ -37,6 +37,7 @@ Patch9: %{name}-shared-libcom_err.patch Patch10: %{name}-sbindir.patch Patch11: %{name}-ntlm-digest.patch Patch12: %{name}-krb5config-nosysdirs.patch +Patch13: %{name}-kcm.patch URL: http://www.h5l.org/ BuildRequires: autoconf >= 2.62 BuildRequires: automake >= 1:1.10.3 @@ -366,6 +367,7 @@ Demony korzystające z systemu Kerberos do autoryzacji dostępu. %patch10 -p1 %patch11 -p1 %patch12 -p1 +%patch13 -p1 %build %{__rm} acinclude.m4 cf/{libtool,lt*}.m4 -- 2.44.0