SVN commit 1097267 by ossi: add ServerUID option M +4 -0 ChangeLog M +38 -0 backend/client.c M +1 -0 backend/dm.h M +4 -0 backend/server.c M +9 -0 config.def M +45 -21 kfrontend/genkdmconf.c --- trunk/KDE/kdebase/workspace/kdm/ChangeLog #1097266:1097267 @@ -2,6 +2,10 @@ startup and packaging. Bug fixes are not listed, and feature changes only if they affect the configuration. +2010-02-28 Oswald Buddenhagen + + * Made it possible to run X server as non-root. Option ServerUID. + 2009-10-17 Oswald Buddenhagen * Made input grabbing optional. Option GrabInput. --- trunk/KDE/kdebase/workspace/kdm/backend/client.c #1097266:1097267 @@ -1115,6 +1115,44 @@ return False; } +int +changeUser( const char *user, const char *authfile ) +{ + struct passwd *pw; + char *ok; + int uid; + + if (!*user) + return True; + + if (!(pw = getpwnam( user ))) { + uid = strtol( user, &ok, 10 ); + if (*ok || !(pw = getpwuid( uid ))) { + logError( "no user like %'s\n", user ); + return False; + } + } + + if (authfile && chown( authfile, pw->pw_uid, pw->pw_gid )) + logWarn( "chmod for %s failed: %m\n", authfile ); + +#ifdef AIXV3 + if (setpcred( user, NULL )) { + logError( "setusercontext for %s failed: %m\n", user ); + return False; + } + return True; +#elif defined(HAS_SETUSERCONTEXT) + if (setusercontext( NULL, pw, pw->pw_uid, LOGIN_SETALL )) { + logError( "setpcred for %s failed: %m\n", user ); + return False; + } + return True; +#else + return setUser( user, pw->pw_uid, pw->pw_gid ); +#endif +} + #if defined(SECURE_RPC) || defined(K5AUTH) static void nukeAuth( int len, const char *name ) --- trunk/KDE/kdebase/workspace/kdm/backend/dm.h #1097266:1097267 @@ -507,6 +507,7 @@ void clientExited( void ); void sessionExit( int status ) ATTR_NORETURN; int readDmrc( void ); +int changeUser( const char *user, const char *authfile ); extern char **userEnviron, **systemEnviron; extern char *curuser, *curpass, *curtype, *newpass, *dmrcuser, *curdmrc, *newdmrc; --- trunk/KDE/kdebase/workspace/kdm/backend/server.c #1097266:1097267 @@ -65,6 +65,10 @@ sprintf( vtstr, "vt%d", d->serverVT ) ))) exit( 47 ); #endif + + if (!changeUser( d->serverUID, d->authFile )) + exit( 49 ); + return argv; } --- trunk/KDE/kdebase/workspace/kdm/config.def #1097266:1097267 @@ -1412,6 +1412,15 @@ /dev/) for activity. If the line is not used for some time, &kdm; switches back to the X login. +Key: ServerUID +Type: string +Default: "" +User: core +Instance: #:*/"_x11" +Comment: & +Description: + The user the &X-Server; should run as. Empty results in root. + Key: PingInterval Type: int Default: 5 --- trunk/KDE/kdebase/workspace/kdm/kfrontend/genkdmconf.c #1097266:1097267 @@ -1109,8 +1109,6 @@ #endif -/* TODO: handle solaris' local_uid specs */ - static char * readWord( File *file, int EOFatEOL ) { @@ -1301,15 +1299,19 @@ return rs; } +typedef enum { InvalidDpy, LocalDpy, LocalUidDpy, ForeignDpy } DisplayMatchType; + static struct displayMatch { const char *name; - int len, local; + int len; + DisplayMatchType type; } displayTypes[] = { - { "local", 5, True }, - { "foreign", 7, False }, + { "local", 5, LocalDpy }, + { "local_uid", 9, LocalUidDpy }, + { "foreign", 7, ForeignDpy }, }; -static int +static DisplayMatchType parseDisplayType( const char *string, const char **atPos ) { struct displayMatch *d; @@ -1321,19 +1323,32 @@ { if (string[d->len] == '@' && string[d->len + 1]) *atPos = string + d->len + 1; - return d->local; + return d->type; } } - return -1; + return InvalidDpy; } typedef struct serverEntry { struct serverEntry *next; - const char *name, *class2, *console, *argvs, *arglvs; + const char *name, *class2, *console, *owner, *argvs, *arglvs; StrList *argv, *arglv; - int local, reserve, vt; + DisplayMatchType type; + int reserve, vt; } ServerEntry; +static int +mstrcmp( const char *s1, const char *s2 ) +{ + if (s1 == s2) + return 0; + if (!s1) + return -1; + if (!s2) + return 1; + return strcmp( s1, s2 ); +} + static void absorbXservers( const char *sect ATTR_UNUSED, char **value ) { @@ -1343,7 +1358,7 @@ StrList **argp, **arglp, *ap, *ap2; File file; int nldpys = 0, nrdpys = 0, dpymask = 0; - int cpcmd, cpcmdl; + int cpuid, cpcmd, cpcmdl; #ifdef HAVE_VTS int dn, cpvt, mtty; #endif @@ -1367,23 +1382,26 @@ se->name = word; if (!(word = readWord( &file, 1 ))) continue; - se->local = parseDisplayType( word, &se->console ); - if (se->local < 0) { + se->type = parseDisplayType( word, &se->console ); + if (se->type == InvalidDpy) { se->class2 = word; if (!(word = readWord( &file, 1 ))) continue; - se->local = parseDisplayType( word, &se->console ); - if (se->local < 0) { + se->type = parseDisplayType( word, &se->console ); + if (se->type == InvalidDpy) { while (readWord( &file, 1 )); continue; } } + if (se->type == LocalUidDpy) + if (!(se->owner = readWord( &file, 1 ))) + continue; word = readWord( &file, 1 ); if (word && !strcmp( word, "reserve" )) { se->reserve = True; word = readWord( &file, 1 ); } - if (se->local != (word != 0)) + if ((se->type != ForeignDpy) != (word != 0)) continue; argp = &se->argv; arglp = &se->arglv; @@ -1422,7 +1440,7 @@ word = readWord( &file, 1 ); } *argp = *arglp = 0; - if (se->local) { + if (se->type != ForeignDpy) { nldpys++; dpymask |= 1 << atoi( se->name + 1 ); if (se->reserve) @@ -1438,7 +1456,7 @@ cpvt = False; getInitTab(); for (se = serverList, mtty = maxTTY; se; se = se->next) - if (se->local) { + if (se->type != ForeignDpy) { mtty++; if (se->vt != mtty) { cpvt = True; @@ -1452,9 +1470,9 @@ se->arglvs = joinArgs( se->arglv ); } - se1 = 0, cpcmd = cpcmdl = False; + se1 = 0, cpuid = cpcmd = cpcmdl = False; for (se = serverList; se; se = se->next) - if (se->local) { + if (se->type != ForeignDpy) { if (!se1) se1 = se; else { @@ -1462,13 +1480,17 @@ cpcmd = True; if (strcmp( se1->arglvs, se->arglvs )) cpcmdl = True; + if (mstrcmp( se1->owner, se->owner )) + cpuid = True; } } if (se1) { putFqVal( "X-:*-Core", "ServerCmd", se1->argvs ); + if (se1->owner) + putFqVal( "X-:*-Core", "ServerUID", se1->owner ); putFqVal( "X-:*-Core", "ServerArgsLocal", se1->arglvs ); for (se = serverList; se; se = se->next) - if (se->local) { + if (se->type != ForeignDpy) { char sec[32]; sprintf( sec, "X-%s-Core", se->name ); if (cpcmd) @@ -1485,6 +1507,8 @@ if (se->console) putFqVal( sec, "ServerTTY", se->console ); #endif + if (cpuid && se->owner) + putFqVal( sec, "ServerUID", se->owner ); } }