aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver/os/access.c
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@sun.com>2017-02-15 14:42:48 +0000
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2017-03-21 10:33:30 +0100
commit8996f80a5e3b205cb580aba34aa21d165ef78cfb (patch)
tree63247f1c738a59600e2a437054d18826db4dc2d2 /nx-X11/programs/Xserver/os/access.c
parent6bc37b980515995b0944632e5a062246683f1d97 (diff)
downloadnx-libs-8996f80a5e3b205cb580aba34aa21d165ef78cfb.tar.gz
nx-libs-8996f80a5e3b205cb580aba34aa21d165ef78cfb.tar.bz2
nx-libs-8996f80a5e3b205cb580aba34aa21d165ef78cfb.zip
Rework local client id finding code to be more uniform
Backport of X.org commit: commit 2d93e69690d2c5d4a89a795ede6423796528e5df Author: Alan Coopersmith <alan.coopersmith@sun.com> Date: Thu Sep 27 16:47:06 2007 -0700 Rework local client id finding code to be more uniform Backported-to-NX-by: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Note: This commit also switches client_uid_string's size from 32 to 64 chars, as found in this X.org commit (spotted by Mihai Moldovan during code review): commit a7b944f0d96c3e0e15e75378a04def1ac96089fb Author: Alan Coopersmith <alan.coopersmith@sun.com> Date: Wed Nov 1 16:17:49 2006 -0800 If getpeerucred() is available, include pid & zoneid in audit messages too
Diffstat (limited to 'nx-X11/programs/Xserver/os/access.c')
-rw-r--r--nx-X11/programs/Xserver/os/access.c161
1 files changed, 99 insertions, 62 deletions
diff --git a/nx-X11/programs/Xserver/os/access.c b/nx-X11/programs/Xserver/os/access.c
index 34e193bbd..152287889 100644
--- a/nx-X11/programs/Xserver/os/access.c
+++ b/nx-X11/programs/Xserver/os/access.c
@@ -204,10 +204,6 @@ static Bool NewHost(int /*family*/,
int /*len*/,
int /* addingLocalHosts */);
-int LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
- int **pSuppGids, int *nSuppGids);
-
-
/* XFree86 bug #156: To keep track of which hosts were explicitly requested in
/etc/X<display>.hosts, we've added a requested field to the HOST struct,
and a LocalHostRequested variable. These default to FALSE, but are set
@@ -1264,38 +1260,51 @@ Bool LocalClient(ClientPtr client)
/*
* Return the uid and gid of a connected local client
- * or the uid/gid for nobody those ids cannot be determined
*
* Used by XShm to test access rights to shared memory segments
*/
int
LocalClientCred(ClientPtr client, int *pUid, int *pGid)
{
- return LocalClientCredAndGroups(client, pUid, pGid, NULL, NULL);
+ LocalClientCredRec *lcc;
+ int ret = GetLocalClientCreds(client, &lcc);
+
+ if (ret == 0) {
+#ifdef HAVE_GETZONEID /* only local if in the same zone */
+ if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
+ FreeLocalClientCreds(lcc);
+ return -1;
+ }
+#endif
+ if ((lcc->fieldsSet & LCC_UID_SET) && (pUid != NULL))
+ *pUid = lcc->euid;
+ if ((lcc->fieldsSet & LCC_GID_SET) && (pGid != NULL))
+ *pGid = lcc->egid;
+ FreeLocalClientCreds(lcc);
+ }
+ return ret;
}
/*
* Return the uid and all gids of a connected local client
- * or the uid/gid for nobody those ids cannot be determined
+ * Allocates a LocalClientCredRec - caller must call FreeLocalClientCreds
*
- * If the caller passes non-NULL values for pSuppGids & nSuppGids,
- * they are responsible for calling XFree(*pSuppGids) to release the
- * memory allocated for the supplemental group ids list.
- *
* Used by localuser & localgroup ServerInterpreted access control forms below
+ * Used by AuthAudit to log where local connections came from
*/
int
-LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
- int **pSuppGids, int *nSuppGids)
+GetLocalClientCreds(ClientPtr client, LocalClientCredRec **lccp)
{
#if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED)
int fd;
XtransConnInfo ci;
+ LocalClientCredRec *lcc;
#ifdef HAS_GETPEEREID
uid_t uid;
gid_t gid;
#elif defined(HAS_GETPEERUCRED)
ucred_t *peercred = NULL;
+ const gid_t *gids;
#elif defined(SO_PEERCRED)
struct ucred peercred;
socklen_t so_len = sizeof(peercred);
@@ -1314,57 +1323,64 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
}
#endif
- if (pSuppGids != NULL)
- *pSuppGids = NULL;
- if (nSuppGids != NULL)
- *nSuppGids = 0;
+ *lccp = calloc(1, sizeof(LocalClientCredRec));
+ if (*lccp == NULL)
+ return -1;
+ lcc = *lccp;
fd = _XSERVTransGetConnectionNumber(ci);
#ifdef HAS_GETPEEREID
- if (getpeereid(fd, &uid, &gid) == -1)
- return -1;
- if (pUid != NULL)
- *pUid = uid;
- if (pGid != NULL)
- *pGid = gid;
+ if (getpeereid(fd, &uid, &gid) == -1) {
+ FreeLocalClientCreds(lcc);
+ return -1;
+ }
+ lcc->euid = uid;
+ lcc->egid = gid;
+ lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET;
return 0;
#elif defined(HAS_GETPEERUCRED)
- if (getpeerucred(fd, &peercred) < 0)
- return -1;
-#ifdef sun /* Ensure process is in the same zone */
- if (getzoneid() != ucred_getzoneid(peercred)) {
- ucred_free(peercred);
+ if (getpeerucred(fd, &peercred) < 0) {
+ FreeLocalClientCreds(lcc);
return -1;
- }
-#endif
- if (pUid != NULL)
- *pUid = ucred_geteuid(peercred);
- if (pGid != NULL)
- *pGid = ucred_getegid(peercred);
- if (pSuppGids != NULL && nSuppGids != NULL) {
- const gid_t *gids;
- *nSuppGids = ucred_getgroups(peercred, &gids);
- if (*nSuppGids > 0) {
- *pSuppGids = malloc(sizeof(int) * (*nSuppGids));
- if (*pSuppGids == NULL) {
- *nSuppGids = 0;
- } else {
- int i;
- for (i = 0 ; i < *nSuppGids; i++) {
- (*pSuppGids)[i] = (int) gids[i];
- }
+ lcc->euid = ucred_geteuid(peercred);
+ if (lcc->euid != -1)
+ lcc->fieldsSet |= LCC_UID_SET;
+ lcc->egid = ucred_getegid(peercred);
+ if (lcc->egid != -1)
+ lcc->fieldsSet |= LCC_GID_SET;
+ lcc->pid = ucred_getpid(peercred);
+ if (lcc->pid != -1)
+ lcc->fieldsSet |= LCC_PID_SET;
+#ifdef HAVE_GETZONEID
+ lcc->zoneid = ucred_getzoneid(peercred);
+ if (lcc->zoneid != -1)
+ lcc->fieldsSet |= LCC_ZID_SET;
+#endif
+ lcc->nSuppGids = ucred_getgroups(peercred, &gids);
+ if (lcc->nSuppGids > 0) {
+ lcc->pSuppGids = calloc((lcc->nSuppGids), sizeof(int));
+ if (lcc->pSuppGids == NULL) {
+ lcc->nSuppGids = 0;
+ } else {
+ int i;
+ for (i = 0 ; i < lcc->nSuppGids; i++) {
+ (lcc->pSuppGids)[i] = (int) gids[i];
}
}
+ } else {
+ lcc->nSuppGids = 0;
}
ucred_free(peercred);
return 0;
#elif defined(SO_PEERCRED)
- if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1)
- return -1;
- if (pUid != NULL)
- *pUid = peercred.uid;
- if (pGid != NULL)
- *pGid = peercred.gid;
+ if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) {
+ FreeLocalClientCreds(lcc);
+ return -1;
+ }
+ lcc->euid = peercred.uid;
+ lcc->egid = peercred.gid;
+ lcc->pid = peercred.pid;
+ lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET;
return 0;
#endif
#else
@@ -1374,6 +1390,17 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
#endif
}
+void
+FreeLocalClientCreds(LocalClientCredRec *lcc)
+{
+ if (lcc != NULL) {
+ if (lcc->nSuppGids > 0) {
+ free(lcc->pSuppGids);
+ }
+ free(lcc);
+ }
+}
+
static Bool
AuthorizedClient(ClientPtr client)
{
@@ -2177,38 +2204,48 @@ static Bool
siLocalCredAddrMatch(int family, void * addr, int len,
const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
{
- int connUid, connGid, *connSuppGids, connNumSuppGids, siAddrId;
+ int siAddrId;
+ LocalClientCredRec *lcc;
siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
- if (LocalClientCredAndGroups(client, &connUid, &connGid,
- &connSuppGids, &connNumSuppGids) == -1) {
+ if (GetLocalClientCreds(client, &lcc) == -1) {
return FALSE;
}
+#ifdef HAVE_GETZONEID /* Ensure process is in the same zone */
+ if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
+ FreeLocalClientCreds(lcc);
+ return FALSE;
+ }
+#endif
+
if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) {
+ FreeLocalClientCreds(lcc);
return FALSE;
}
if (lcPriv->credType == LOCAL_USER) {
- if (connUid == siAddrId) {
+ if ((lcc->fieldsSet & LCC_UID_SET) && (lcc->euid == siAddrId)) {
+ FreeLocalClientCreds(lcc);
return TRUE;
}
} else {
- if (connGid == siAddrId) {
+ if ((lcc->fieldsSet & LCC_GID_SET) && (lcc->egid == siAddrId)) {
+ FreeLocalClientCreds(lcc);
return TRUE;
}
- if (connSuppGids != NULL) {
+ if (lcc->pSuppGids != NULL) {
int i;
- for (i = 0 ; i < connNumSuppGids; i++) {
- if (connSuppGids[i] == siAddrId) {
- free(connSuppGids);
+ for (i = 0 ; i < lcc->nSuppGids; i++) {
+ if (lcc->pSuppGids[i] == siAddrId) {
+ FreeLocalClientCreds(lcc);
return TRUE;
}
}
- free(connSuppGids);
}
}
+ FreeLocalClientCreds(lcc);
return FALSE;
}