Commit 8996f80a authored by Alan Coopersmith's avatar Alan Coopersmith Committed by Mike Gabriel

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: 's avatarMike 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
parent 6bc37b98
...@@ -321,6 +321,24 @@ extern int LocalClient(ClientPtr /* client */); ...@@ -321,6 +321,24 @@ extern int LocalClient(ClientPtr /* client */);
extern int LocalClientCred(ClientPtr, int *, int *); 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 ChangeAccessControl(ClientPtr /*client*/, int /*fEnabled*/);
extern int GetAccessControl(void); extern int GetAccessControl(void);
......
...@@ -31,6 +31,8 @@ NULL = ...@@ -31,6 +31,8 @@ NULL =
* If you have any extra files to be put into the library, define them here. * If you have any extra files to be put into the library, define them here.
*/ */
ZONEID_DEFINES = -UHAVE_GETZONEID
#if NXLibraries #if NXLibraries
NX_INCLUDES = -I../../../../nxcomp NX_INCLUDES = -I../../../../nxcomp
...@@ -235,7 +237,7 @@ alloca.o: $(PWLIB) ...@@ -235,7 +237,7 @@ alloca.o: $(PWLIB)
ar x $(PWLIB) alloca.o ar x $(PWLIB) alloca.o
#endif /* NEED_ALLOCA_FROM_LIBPW */ #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(auth,$(ICONFIGFILES),$(XDMCP_DEFINES))
SpecialCObjectRule(xdmauth,$(ICONFIGFILES),$(XDMCP_DEFINES)) SpecialCObjectRule(xdmauth,$(ICONFIGFILES),$(XDMCP_DEFINES))
SpecialCObjectRule(xdmcp,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES)) SpecialCObjectRule(xdmcp,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES))
......
...@@ -204,10 +204,6 @@ static Bool NewHost(int /*family*/, ...@@ -204,10 +204,6 @@ static Bool NewHost(int /*family*/,
int /*len*/, int /*len*/,
int /* addingLocalHosts */); 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 /* 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, /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 and a LocalHostRequested variable. These default to FALSE, but are set
...@@ -1264,38 +1260,51 @@ Bool LocalClient(ClientPtr client) ...@@ -1264,38 +1260,51 @@ Bool LocalClient(ClientPtr client)
/* /*
* Return the uid and gid of a connected local 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 * Used by XShm to test access rights to shared memory segments
*/ */
int int
LocalClientCred(ClientPtr client, int *pUid, int *pGid) 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 * 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 localuser & localgroup ServerInterpreted access control forms below
* Used by AuthAudit to log where local connections came from
*/ */
int int
LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, GetLocalClientCreds(ClientPtr client, LocalClientCredRec **lccp)
int **pSuppGids, int *nSuppGids)
{ {
#if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED) #if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED)
int fd; int fd;
XtransConnInfo ci; XtransConnInfo ci;
LocalClientCredRec *lcc;
#ifdef HAS_GETPEEREID #ifdef HAS_GETPEEREID
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
#elif defined(HAS_GETPEERUCRED) #elif defined(HAS_GETPEERUCRED)
ucred_t *peercred = NULL; ucred_t *peercred = NULL;
const gid_t *gids;
#elif defined(SO_PEERCRED) #elif defined(SO_PEERCRED)
struct ucred peercred; struct ucred peercred;
socklen_t so_len = sizeof(peercred); socklen_t so_len = sizeof(peercred);
...@@ -1314,57 +1323,64 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, ...@@ -1314,57 +1323,64 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
} }
#endif #endif
if (pSuppGids != NULL) *lccp = calloc(1, sizeof(LocalClientCredRec));
*pSuppGids = NULL; if (*lccp == NULL)
if (nSuppGids != NULL) return -1;
*nSuppGids = 0; lcc = *lccp;
fd = _XSERVTransGetConnectionNumber(ci); fd = _XSERVTransGetConnectionNumber(ci);
#ifdef HAS_GETPEEREID #ifdef HAS_GETPEEREID
if (getpeereid(fd, &uid, &gid) == -1) if (getpeereid(fd, &uid, &gid) == -1) {
FreeLocalClientCreds(lcc);
return -1; return -1;
if (pUid != NULL) }
*pUid = uid; lcc->euid = uid;
if (pGid != NULL) lcc->egid = gid;
*pGid = gid; lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET;
return 0; return 0;
#elif defined(HAS_GETPEERUCRED) #elif defined(HAS_GETPEERUCRED)
if (getpeerucred(fd, &peercred) < 0) if (getpeerucred(fd, &peercred) < 0) {
FreeLocalClientCreds(lcc);
return -1; return -1;
#ifdef sun /* Ensure process is in the same zone */ lcc->euid = ucred_geteuid(peercred);
if (getzoneid() != ucred_getzoneid(peercred)) { if (lcc->euid != -1)
ucred_free(peercred); lcc->fieldsSet |= LCC_UID_SET;
return -1; lcc->egid = ucred_getegid(peercred);
} if (lcc->egid != -1)
#endif lcc->fieldsSet |= LCC_GID_SET;
if (pUid != NULL) lcc->pid = ucred_getpid(peercred);
*pUid = ucred_geteuid(peercred); if (lcc->pid != -1)
if (pGid != NULL) lcc->fieldsSet |= LCC_PID_SET;
*pGid = ucred_getegid(peercred); #ifdef HAVE_GETZONEID
if (pSuppGids != NULL && nSuppGids != NULL) { lcc->zoneid = ucred_getzoneid(peercred);
const gid_t *gids; if (lcc->zoneid != -1)
*nSuppGids = ucred_getgroups(peercred, &gids); lcc->fieldsSet |= LCC_ZID_SET;
if (*nSuppGids > 0) { #endif
*pSuppGids = malloc(sizeof(int) * (*nSuppGids)); lcc->nSuppGids = ucred_getgroups(peercred, &gids);
if (*pSuppGids == NULL) { if (lcc->nSuppGids > 0) {
*nSuppGids = 0; lcc->pSuppGids = calloc((lcc->nSuppGids), sizeof(int));
if (lcc->pSuppGids == NULL) {
lcc->nSuppGids = 0;
} else { } else {
int i; int i;
for (i = 0 ; i < *nSuppGids; i++) { for (i = 0 ; i < lcc->nSuppGids; i++) {
(*pSuppGids)[i] = (int) gids[i]; (lcc->pSuppGids)[i] = (int) gids[i];
}
} }
} }
} else {
lcc->nSuppGids = 0;
} }
ucred_free(peercred); ucred_free(peercred);
return 0; return 0;
#elif defined(SO_PEERCRED) #elif defined(SO_PEERCRED)
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) {
FreeLocalClientCreds(lcc);
return -1; return -1;
if (pUid != NULL) }
*pUid = peercred.uid; lcc->euid = peercred.uid;
if (pGid != NULL) lcc->egid = peercred.gid;
*pGid = peercred.gid; lcc->pid = peercred.pid;
lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET;
return 0; return 0;
#endif #endif
#else #else
...@@ -1374,6 +1390,17 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, ...@@ -1374,6 +1390,17 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
#endif #endif
} }
void
FreeLocalClientCreds(LocalClientCredRec *lcc)
{
if (lcc != NULL) {
if (lcc->nSuppGids > 0) {
free(lcc->pSuppGids);
}
free(lcc);
}
}
static Bool static Bool
AuthorizedClient(ClientPtr client) AuthorizedClient(ClientPtr client)
{ {
...@@ -2177,38 +2204,48 @@ static Bool ...@@ -2177,38 +2204,48 @@ static Bool
siLocalCredAddrMatch(int family, void * addr, int len, siLocalCredAddrMatch(int family, void * addr, int len,
const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv) const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
{ {
int connUid, connGid, *connSuppGids, connNumSuppGids, siAddrId; int siAddrId;
LocalClientCredRec *lcc;
siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv; siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
if (LocalClientCredAndGroups(client, &connUid, &connGid, if (GetLocalClientCreds(client, &lcc) == -1) {
&connSuppGids, &connNumSuppGids) == -1) {
return FALSE; 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) { if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) {
FreeLocalClientCreds(lcc);
return FALSE; return FALSE;
} }
if (lcPriv->credType == LOCAL_USER) { if (lcPriv->credType == LOCAL_USER) {
if (connUid == siAddrId) { if ((lcc->fieldsSet & LCC_UID_SET) && (lcc->euid == siAddrId)) {
FreeLocalClientCreds(lcc);
return TRUE; return TRUE;
} }
} else { } else {
if (connGid == siAddrId) { if ((lcc->fieldsSet & LCC_GID_SET) && (lcc->egid == siAddrId)) {
FreeLocalClientCreds(lcc);
return TRUE; return TRUE;
} }
if (connSuppGids != NULL) { if (lcc->pSuppGids != NULL) {
int i; int i;
for (i = 0 ; i < connNumSuppGids; i++) { for (i = 0 ; i < lcc->nSuppGids; i++) {
if (connSuppGids[i] == siAddrId) { if (lcc->pSuppGids[i] == siAddrId) {
free(connSuppGids); FreeLocalClientCreds(lcc);
return TRUE; return TRUE;
} }
} }
free(connSuppGids);
} }
} }
FreeLocalClientCreds(lcc);
return FALSE; return FALSE;
} }
......
...@@ -534,8 +534,8 @@ AuthAudit (ClientPtr client, Bool letin, ...@@ -534,8 +534,8 @@ AuthAudit (ClientPtr client, Bool letin,
char addr[128]; char addr[128];
char *out = addr; char *out = addr;
int client_uid; char client_uid_string[64];
char client_uid_string[32]; LocalClientCredRec *lcc;
if (!len) if (!len)
strcpy(out, "local host"); strcpy(out, "local host");
...@@ -567,10 +567,44 @@ AuthAudit (ClientPtr client, Bool letin, ...@@ -567,10 +567,44 @@ AuthAudit (ClientPtr client, Bool letin,
strcpy(out, "unknown address"); strcpy(out, "unknown address");
} }
if (LocalClientCred(client, &client_uid, NULL) != -1) { if (GetLocalClientCreds(client, &lcc) != -1) {
snprintf(client_uid_string, sizeof(client_uid_string), int slen; /* length written to client_uid_string */
" (uid %d)", client_uid);
} else { 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'; client_uid_string[0] = '\0';
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment