diff options
Diffstat (limited to 'os')
-rw-r--r-- | os/access.c | 203 | ||||
-rw-r--r-- | os/log.c | 14 | ||||
-rw-r--r-- | os/utils.c | 78 | ||||
-rw-r--r-- | os/xalloc.c | 1 | ||||
-rw-r--r-- | os/xdmcp.c | 2 |
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 } @@ -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. |