summaryrefslogtreecommitdiff
path: root/os
diff options
context:
space:
mode:
Diffstat (limited to 'os')
-rw-r--r--os/access.c203
-rw-r--r--os/log.c14
-rw-r--r--os/utils.c78
-rw-r--r--os/xalloc.c1
-rw-r--r--os/xdmcp.c2
5 files changed, 280 insertions, 18 deletions
diff --git a/os/access.c b/os/access.c
index 4519b56eb..2cc050860 100644
--- a/os/access.c
+++ b/os/access.c
@@ -1,5 +1,5 @@
/* $Xorg: access.c,v 1.5 2001/02/09 02:05:23 xorgcvs Exp $ */
-/* $XdotOrg$ */
+/* $XdotOrg: xc/programs/Xserver/os/access.c,v 1.5 2004/07/17 01:13:31 alanc Exp $ */
/***********************************************************
Copyright 1987, 1998 The Open Group
@@ -88,6 +88,12 @@ SOFTWARE.
#include <netdnet/dnetdb.h>
#endif
+#ifdef HAS_GETPEERUCRED
+# include <ucred.h>
+# ifdef sun
+# include <zone.h>
+# endif
+#endif
#if defined(DGUX)
#include <sys/ioctl.h>
@@ -224,6 +230,10 @@ 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
@@ -302,7 +312,7 @@ AccessUsingXdmcp (void)
}
-#if ((defined(SVR4) && !defined(DGUX) && !defined(SCO325) && !defined(sun) && !defined(NCR)) || defined(ISC)) && defined(SIOCGIFCONF) && !defined(USE_SIOCGLIFCONF)
+#if ((defined(SVR4) && !defined(DGUX) && !defined(SCO325) && !defined(sun) && !defined(NCR)) || defined(ISC)) && !defined(__sgi) && defined(SIOCGIFCONF) && !defined(USE_SIOCGLIFCONF)
/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
@@ -1393,19 +1403,38 @@ Bool LocalClient(ClientPtr client)
/*
* Return the uid and gid of a connected local client
- * or the uid/gid for nobody those ids cannot be determinded
+ * 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)
{
-#if defined(HAS_GETPEEREID) || defined(SO_PEERCRED)
+ return LocalClientCredAndGroups(client, pUid, pGid, NULL, NULL);
+}
+
+/*
+ * Return the uid and all gids of a connected local client
+ * or the uid/gid for nobody those ids cannot be determined
+ *
+ * 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
+ */
+int
+LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
+ int **pSuppGids, int *nSuppGids)
+{
+#if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED)
int fd;
XtransConnInfo ci;
#ifdef HAS_GETPEEREID
uid_t uid;
gid_t gid;
+#elif defined(HAS_GETPEERUCRED)
+ ucred_t *peercred = NULL;
#elif defined(SO_PEERCRED)
struct ucred peercred;
socklen_t so_len = sizeof(peercred);
@@ -1414,10 +1443,21 @@ LocalClientCred(ClientPtr client, int *pUid, int *pGid)
if (client == NULL)
return -1;
ci = ((OsCommPtr)client->osPrivate)->trans_conn;
- /* We can only determine peer credentials for Unix domain sockets */
+#if !(defined(sun) && defined(HAS_GETPEERUCRED))
+ /* Most implementations can only determine peer credentials for Unix
+ * domain sockets - Solaris getpeerucred can work with a bit more, so
+ * we just let it tell us if the connection type is supported or not
+ */
if (!_XSERVTransIsLocal(ci)) {
return -1;
}
+#endif
+
+ if (pSuppGids != NULL)
+ *pSuppGids = NULL;
+ if (nSuppGids != NULL)
+ *nSuppGids = 0;
+
fd = _XSERVTransGetConnectionNumber(ci);
#ifdef HAS_GETPEEREID
if (getpeereid(fd, &uid, &gid) == -1)
@@ -1427,6 +1467,36 @@ LocalClientCred(ClientPtr client, int *pUid, int *pGid)
if (pGid != NULL)
*pGid = gid;
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);
+ 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 = xalloc(sizeof(int) * (*nSuppGids));
+ if (*pSuppGids == NULL) {
+ *nSuppGids = 0;
+ } else {
+ int i;
+ for (i = 0 ; i < *nSuppGids; i++) {
+ (*pSuppGids)[i] = (int) gids[i];
+ }
+ }
+ }
+ }
+ ucred_free(peercred);
+ return 0;
#elif defined(SO_PEERCRED)
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1)
return -1;
@@ -1438,6 +1508,7 @@ LocalClientCred(ClientPtr client, int *pUid, int *pGid)
#endif
#else
/* No system call available to get the credentials of the peer */
+#define NO_LOCAL_CLIENT_CRED
return -1;
#endif
}
@@ -1743,7 +1814,6 @@ InvalidHost (
return 0;
}
}
- return 1;
} else
return 0;
}
@@ -2206,6 +2276,121 @@ siIPv6CheckAddr(const char *addrString, int length, void *typePriv)
}
#endif /* IPv6 */
+#if !defined(NO_LOCAL_CLIENT_CRED)
+/***
+ * "localuser" & "localgroup" server interpreted types
+ *
+ * Allows local connections from a given local user or group
+ */
+
+#include <pwd.h>
+#include <grp.h>
+
+#define LOCAL_USER 1
+#define LOCAL_GROUP 2
+
+typedef struct {
+ int credType;
+} siLocalCredPrivRec, *siLocalCredPrivPtr;
+
+static siLocalCredPrivRec siLocalUserPriv = { LOCAL_USER };
+static siLocalCredPrivRec siLocalGroupPriv = { LOCAL_GROUP };
+
+static Bool
+siLocalCredGetId(const char *addr, int len, siLocalCredPrivPtr lcPriv, int *id)
+{
+ Bool parsedOK = FALSE;
+ char *addrbuf = xalloc(len + 1);
+
+ if (addrbuf == NULL) {
+ return FALSE;
+ }
+
+ memcpy(addrbuf, addr, len);
+ addrbuf[len] = '\0';
+
+ if (addr[0] == '#') { /* numeric id */
+ char *cp;
+ errno = 0;
+ *id = strtol(addrbuf + 1, &cp, 0);
+ if ((errno == 0) && (cp != (addrbuf+1))) {
+ parsedOK = TRUE;
+ }
+ } else { /* non-numeric name */
+ if (lcPriv->credType == LOCAL_USER) {
+ struct passwd *pw = getpwnam(addrbuf);
+
+ if (pw != NULL) {
+ *id = (int) pw->pw_uid;
+ parsedOK = TRUE;
+ }
+ } else { /* group */
+ struct group *gr = getgrnam(addrbuf);
+
+ if (gr != NULL) {
+ *id = (int) gr->gr_gid;
+ parsedOK = TRUE;
+ }
+ }
+ }
+
+ xfree(addrbuf);
+ return parsedOK;
+}
+
+static Bool
+siLocalCredAddrMatch(int family, pointer addr, int len,
+ const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
+{
+ int connUid, connGid, *connSuppGids, connNumSuppGids, siAddrId;
+ siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
+
+ if (LocalClientCredAndGroups(client, &connUid, &connGid,
+ &connSuppGids, &connNumSuppGids) == -1) {
+ return FALSE;
+ }
+
+ if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) {
+ return FALSE;
+ }
+
+ if (lcPriv->credType == LOCAL_USER) {
+ if (connUid == siAddrId) {
+ return TRUE;
+ }
+ } else {
+ if (connGid == siAddrId) {
+ return TRUE;
+ }
+ if (connSuppGids != NULL) {
+ int i;
+
+ for (i = 0 ; i < connNumSuppGids; i++) {
+ if (connSuppGids[i] == siAddrId) {
+ xfree(connSuppGids);
+ return TRUE;
+ }
+ }
+ xfree(connSuppGids);
+ }
+ }
+ return FALSE;
+}
+
+static int
+siLocalCredCheckAddr(const char *addrString, int length, void *typePriv)
+{
+ int len = length;
+ int id;
+
+ if (siLocalCredGetId(addrString, length,
+ (siLocalCredPrivPtr)typePriv, &id) == FALSE) {
+ len = -1;
+ }
+ return len;
+}
+#endif /* localuser */
+
static void
siTypesInitialize(void)
{
@@ -2213,4 +2398,10 @@ siTypesInitialize(void)
#if defined(IPv6) && defined(AF_INET6)
siTypeAdd("ipv6", siIPv6AddrMatch, siIPv6CheckAddr, NULL);
#endif
+#if !defined(NO_LOCAL_CLIENT_CRED)
+ siTypeAdd("localuser", siLocalCredAddrMatch, siLocalCredCheckAddr,
+ &siLocalUserPriv);
+ siTypeAdd("localgroup", siLocalCredAddrMatch, siLocalCredCheckAddr,
+ &siLocalGroupPriv);
+#endif
}
diff --git a/os/log.c b/os/log.c
index e537f8c41..1794919a1 100644
--- a/os/log.c
+++ b/os/log.c
@@ -385,10 +385,10 @@ LogMessage(MessageType type, const char *format, ...)
}
#ifdef __GNUC__
-static void AbortServer(void) __attribute__((noreturn));
+void AbortServer(void) __attribute__((noreturn));
#endif
-static void
+void
AbortServer(void)
{
OsCleanup(TRUE);
@@ -487,6 +487,15 @@ VAuditF(const char *f, va_list args)
prefix = AuditPrefix();
len = vsnprintf(buf, sizeof(buf), f, args);
+#if 1
+ /* XXX Compressing duplicated messages is temporarily disabled to
+ * work around bugzilla 964:
+ * https://freedesktop.org/bugzilla/show_bug.cgi?id=964
+ */
+ ErrorF("%s%s", prefix != NULL ? prefix : "", buf);
+ oldlen = -1;
+ nrepeat = 0;
+#else
if (len == oldlen && strcmp(buf, oldbuf) == 0) {
/* Message already seen */
nrepeat++;
@@ -500,6 +509,7 @@ VAuditF(const char *f, va_list args)
nrepeat = 0;
auditTimer = TimerSet(auditTimer, 0, AUDIT_TIMEOUT, AuditFlush, NULL);
}
+#endif
if (prefix != NULL)
free(prefix);
}
diff --git a/os/utils.c b/os/utils.c
index 5b9ca5436..522530a7b 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1,4 +1,4 @@
-/* $XdotOrg: xc/programs/Xserver/os/utils.c,v 1.1.4.6.2.4 2004/03/04 17:48:31 eich Exp $ */
+/* $XdotOrg: xc/programs/Xserver/os/utils.c,v 1.6 2004/08/11 22:27:50 kem Exp $ */
/* $Xorg: utils.c,v 1.5 2001/02/09 02:05:24 xorgcvs Exp $ */
/*
@@ -119,6 +119,7 @@ OR PERFORMANCE OF THIS SOFTWARE.
#ifdef RENDER
#include "picture.h"
+Bool noRenderExtension = FALSE;
#endif
#define X_INCLUDE_NETDB_H
@@ -137,6 +138,14 @@ Bool PanoramiXWindowExposureSent = FALSE;
Bool PanoramiXOneExposeRequest = FALSE;
#endif
+#ifdef XEVIE
+Bool noXevieExtension = TRUE;
+#endif
+
+#ifdef COMPOSITE
+Bool noCompositeExtension = TRUE;
+#endif
+
int auditTrailLevel = 1;
Bool Must_have_memory = FALSE;
@@ -170,6 +179,10 @@ char *dev_tty_from_init = NULL; /* since we need to parse it anyway */
extern char dispatchExceptionAtReset;
+/* Extension enable/disable in miinitext.c */
+extern Bool EnableDisableExtension(char *name, Bool enable);
+extern void EnableDisableExtensionError(char *name, Bool enable);
+
OsSigHandlerPtr
OsSignal(sig, handler)
int sig;
@@ -516,6 +529,8 @@ void UseMsg(void)
ErrorF("nologo disable logo in screen saver\n");
#endif
ErrorF("-nolisten string don't listen on protocol\n");
+ ErrorF("-noreset don't reset after last client exists\n");
+ ErrorF("-reset reset after last client exists\n");
ErrorF("-p # screen-saver pattern duration (minutes)\n");
ErrorF("-pn accept failure to listen on all ports\n");
ErrorF("-nopn reject failure to listen on all ports\n");
@@ -547,6 +562,8 @@ void UseMsg(void)
ErrorF("-dumbSched Disable smart scheduling, enable old behavior\n");
ErrorF("-schedInterval int Set scheduler interval in msec\n");
#endif
+ ErrorF("+extension name Enable extension\n");
+ ErrorF("-extension name Disable extension\n");
#ifdef XDMCP
XdmcpUseMsg();
#endif
@@ -576,6 +593,17 @@ VerifyDisplayName(const char *d)
}
/*
+ * This function is responsible for doing initalisation of any global
+ * variables at an very early point of server startup (even before
+ * |ProcessCommandLine()|.
+ */
+void InitGlobals(void)
+{
+ ddxInitGlobals();
+}
+
+
+/*
* This function parses the command line. Handles device-independent fields
* and allows ddx to handle additional fields. It is not allowed to modify
* argc or any of the strings pointed to by argv.
@@ -812,6 +840,10 @@ ProcessCommandLine(int argc, char *argv[])
{
dispatchExceptionAtReset = 0;
}
+ else if ( strcmp( argv[i], "-reset") == 0)
+ {
+ dispatchExceptionAtReset = DE_RESET;
+ }
else if ( strcmp( argv[i], "-p") == 0)
{
if(++i < argc)
@@ -982,6 +1014,26 @@ ProcessCommandLine(int argc, char *argv[])
UseMsg ();
}
#endif
+ else if ( strcmp( argv[i], "+extension") == 0)
+ {
+ if (++i < argc)
+ {
+ if (!EnableDisableExtension(argv[i], TRUE))
+ EnableDisableExtensionError(argv[i], TRUE);
+ }
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-extension") == 0)
+ {
+ if (++i < argc)
+ {
+ if (!EnableDisableExtension(argv[i], FALSE))
+ EnableDisableExtensionError(argv[i], FALSE);
+ }
+ else
+ UseMsg();
+ }
else
{
ErrorF("Unrecognized option: %s\n", argv[i]);
@@ -1846,16 +1898,24 @@ enum BadCode {
InternalError
};
+#if defined(VENDORSUPPORT)
+#define BUGADDRESS VENDORSUPPORT
+#elif defined(BUILDERADDR)
+#define BUGADDRESS BUILDERADDR
+#else
+#define BUGADDRESS "xorg@freedesktop.org"
+#endif
+
#define ARGMSG \
"\nIf the arguments used are valid, and have been rejected incorrectly\n" \
"please send details of the arguments and why they are valid to\n" \
- "&&&&&@X.org. In the meantime, you can start the Xserver as\n" \
+ "%s. In the meantime, you can start the Xserver as\n" \
"the \"super user\" (root).\n"
#define ENVMSG \
"\nIf the environment is valid, and have been rejected incorrectly\n" \
"please send details of the environment and why it is valid to\n" \
- "&&&&&@X.org. In the meantime, you can start the Xserver as\n" \
+ "%s. In the meantime, you can start the Xserver as\n" \
"the \"super user\" (root).\n"
void
@@ -1963,20 +2023,20 @@ CheckUserParameters(int argc, char **argv, char **envp)
return;
case UnsafeArg:
ErrorF("Command line argument number %d is unsafe\n", i);
- ErrorF(ARGMSG);
+ ErrorF(ARGMSG, BUGADDRESS);
break;
case ArgTooLong:
ErrorF("Command line argument number %d is too long\n", i);
- ErrorF(ARGMSG);
+ ErrorF(ARGMSG, BUGADDRESS);
break;
case UnprintableArg:
ErrorF("Command line argument number %d contains unprintable"
" characters\n", i);
- ErrorF(ARGMSG);
+ ErrorF(ARGMSG, BUGADDRESS);
break;
case EnvTooLong:
ErrorF("Environment variable `%s' is too long\n", e);
- ErrorF(ENVMSG);
+ ErrorF(ENVMSG, BUGADDRESS);
break;
case OutputIsPipe:
ErrorF("Stdout and/or stderr is a pipe\n");
@@ -1986,8 +2046,8 @@ CheckUserParameters(int argc, char **argv, char **envp)
break;
default:
ErrorF("Unknown error\n");
- ErrorF(ARGMSG);
- ErrorF(ENVMSG);
+ ErrorF(ARGMSG, BUGADDRESS);
+ ErrorF(ENVMSG, BUGADDRESS);
break;
}
FatalError("X server aborted because of unsafe environment\n");
diff --git a/os/xalloc.c b/os/xalloc.c
index 5677896dc..6740e89cb 100644
--- a/os/xalloc.c
+++ b/os/xalloc.c
@@ -185,6 +185,7 @@ extern Bool Must_have_memory;
defined(__sparc64__) || \
defined(__s390x__) || \
defined(__amd64__) || defined(amd64) || \
+ defined(__powerpc64__) || \
(defined(sgi) && _MIPS_SZLONG == 64))
#define MAGIC 0x1404196414071968
#define MAGIC_FREE 0x1506196615061966
diff --git a/os/xdmcp.c b/os/xdmcp.c
index 87e207382..96478d7bb 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -1,4 +1,4 @@
-/* $XdotOrg: xc/programs/Xserver/os/xdmcp.c,v 1.1.4.3.2.4 2004/07/19 18:59:05 ago Exp $ */
+/* $XdotOrg: xc/programs/Xserver/os/xdmcp.c,v 1.3 2004/07/20 15:15:13 ago Exp $ */
/* $Xorg: xdmcp.c,v 1.4 2001/01/31 13:37:19 pookie Exp $ */
/*
* Copyright 1989 Network Computing Devices, Inc., Mountain View, California.