aboutsummaryrefslogtreecommitdiff
path: root/nx-X11
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
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')
-rw-r--r--nx-X11/programs/Xserver/include/os.h18
-rw-r--r--nx-X11/programs/Xserver/os/Imakefile4
-rw-r--r--nx-X11/programs/Xserver/os/access.c161
-rw-r--r--nx-X11/programs/Xserver/os/connection.c46
4 files changed, 160 insertions, 69 deletions
diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h
index 99003922f..af84f54c0 100644
--- a/nx-X11/programs/Xserver/include/os.h
+++ b/nx-X11/programs/Xserver/include/os.h
@@ -321,6 +321,24 @@ extern int LocalClient(ClientPtr /* client */);
extern int LocalClientCred(ClientPtr, int *, int *);
+#define LCC_UID_SET (1 << 0)
+#define LCC_GID_SET (1 << 1)
+#define LCC_PID_SET (1 << 2)
+#define LCC_ZID_SET (1 << 3)
+
+typedef struct {
+ int fieldsSet; /* Bit mask of fields set */
+ int euid; /* Effective uid */
+ int egid; /* Primary effective group id */
+ int nSuppGids; /* Number of supplementary group ids */
+ int *pSuppGids; /* Array of supplementary group ids */
+ int pid; /* Process id */
+ int zoneid; /* Only set on Solaris 10 & later */
+} LocalClientCredRec;
+
+extern int GetLocalClientCreds(ClientPtr, LocalClientCredRec **);
+extern void FreeLocalClientCreds(LocalClientCredRec *);
+
extern int ChangeAccessControl(ClientPtr /*client*/, int /*fEnabled*/);
extern int GetAccessControl(void);
diff --git a/nx-X11/programs/Xserver/os/Imakefile b/nx-X11/programs/Xserver/os/Imakefile
index c2e1e8699..144cb5a55 100644
--- a/nx-X11/programs/Xserver/os/Imakefile
+++ b/nx-X11/programs/Xserver/os/Imakefile
@@ -31,6 +31,8 @@ NULL =
* If you have any extra files to be put into the library, define them here.
*/
+ZONEID_DEFINES = -UHAVE_GETZONEID
+
#if NXLibraries
NX_INCLUDES = -I../../../../nxcomp
@@ -235,7 +237,7 @@ alloca.o: $(PWLIB)
ar x $(PWLIB) alloca.o
#endif /* NEED_ALLOCA_FROM_LIBPW */
-SpecialCObjectRule(access,$(ICONFIGFILES),$(XDMCP_DEFINES) $(SOCK_DEFINES) $(IFADDRS_DEFINES))
+SpecialCObjectRule(access,$(ICONFIGFILES),$(XDMCP_DEFINES) $(SOCK_DEFINES) $(IFADDRS_DEFINES) $(ZONEID_DEFINES))
SpecialCObjectRule(auth,$(ICONFIGFILES),$(XDMCP_DEFINES))
SpecialCObjectRule(xdmauth,$(ICONFIGFILES),$(XDMCP_DEFINES))
SpecialCObjectRule(xdmcp,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES))
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;
}
diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c
index 151605cfb..538996198 100644
--- a/nx-X11/programs/Xserver/os/connection.c
+++ b/nx-X11/programs/Xserver/os/connection.c
@@ -534,8 +534,8 @@ AuthAudit (ClientPtr client, Bool letin,
char addr[128];
char *out = addr;
- int client_uid;
- char client_uid_string[32];
+ char client_uid_string[64];
+ LocalClientCredRec *lcc;
if (!len)
strcpy(out, "local host");
@@ -567,10 +567,44 @@ AuthAudit (ClientPtr client, Bool letin,
strcpy(out, "unknown address");
}
- if (LocalClientCred(client, &client_uid, NULL) != -1) {
- snprintf(client_uid_string, sizeof(client_uid_string),
- " (uid %d)", client_uid);
- } else {
+ if (GetLocalClientCreds(client, &lcc) != -1) {
+ int slen; /* length written to client_uid_string */
+
+ strcpy(client_uid_string, " ( ");
+ slen = 3;
+
+ if (lcc->fieldsSet & LCC_UID_SET) {
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "uid=%ld ", (long) lcc->euid);
+ slen = strlen(client_uid_string);
+ }
+
+ if (lcc->fieldsSet & LCC_GID_SET) {
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "gid=%ld ", (long) lcc->egid);
+ slen = strlen(client_uid_string);
+ }
+
+ if (lcc->fieldsSet & LCC_PID_SET) {
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "pid=%ld ", (long) lcc->pid);
+ slen = strlen(client_uid_string);
+ }
+
+ if (lcc->fieldsSet & LCC_ZID_SET) {
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "zoneid=%ld ", (long) lcc->zoneid);
+ slen = strlen(client_uid_string);
+ }
+
+ snprintf(client_uid_string + slen, sizeof(client_uid_string) - slen, ")");
+ FreeLocalClientCreds(lcc);
+ }
+ else {
client_uid_string[0] = '\0';
}