[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdebase/workspace/kdm
From: Oswald Buddenhagen <ossi () kde ! org>
Date: 2010-02-28 20:39:28
Message-ID: 1267389568.267487.31895.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 1097269 by ossi:
make it possible to run greeter as non-root
genkdmconf will try to set it up, but currently it knows how to do
it only on debian-alikes (which have the adduser command).
CCMAIL: kde-packager@kde.org
M +2 -1 ChangeLog
M +0 -2 TODO
M +30 -17 backend/auth.c
M +2 -1 backend/dm.h
M +1 -0 backend/dm_auth.h
M +4 -0 backend/dpylist.c
M +21 -18 backend/process.c
M +1 -1 backend/resource.c
M +16 -3 backend/session.c
M +12 -1 config.def
M +82 -1 kfrontend/genkdmconf.c
M +13 -11 kfrontend/kgreeter.cpp
--- trunk/KDE/kdebase/workspace/kdm/ChangeLog #1097268:1097269
@@ -4,7 +4,8 @@
2010-02-28 Oswald Buddenhagen <ossi@kde.org>
- * Made it possible to run X server as non-root. Option ServerUID.
+ * Made it possible to run X server and greeter as non-root.
+ Options ServerUID and GreeterUID.
2009-10-17 Oswald Buddenhagen <ossi@kde.org>
--- trunk/KDE/kdebase/workspace/kdm/TODO #1097268:1097269
@@ -192,8 +192,6 @@
- the process reaping from gClose should be in sync with the main loop.
- kill warning on AIX - see bug #13628 (really present?)
- xdmcp.c: make networkAddressToName use networkAddressToHostname?
-- options for running the greeter and the core unprivileged. problem: xauth.
-- make the openbsd _x11-user hack in auth.c sane
- rethink the coupling of the kdm components, particularily the config reader.
options:
- keep things basically as-is, make the Xaccess interface even more flexible,
--- trunk/KDE/kdebase/workspace/kdm/backend/auth.c #1097268:1097269
@@ -335,7 +335,7 @@
#define NAMELEN 255
static FILE *
-makeServerAuthFile( struct display *d )
+makeServerAuthFile( struct display *d, char **authFile )
{
FILE *f;
int i;
@@ -352,34 +352,32 @@
cleanUpFileName( d->name, cleanname, NAMELEN - 8 );
i = sprintf( nambuf, "%s/A%s-", authDir, cleanname );
if ((f = mkTempFile( nambuf, i ))) {
- strDup( &d->authFile, nambuf );
+ strDup( authFile, nambuf );
return f;
}
return 0;
}
-int
-saveServerAuthorizations( struct display *d, Xauth **auths, int count )
+static int
+saveAuthorizations( struct display *d, char **authFile, Xauth **auths, int count )
{
FILE *auth_file;
int i;
- if (!d->authFile && d->clientAuthFile && *d->clientAuthFile)
- strDup( &d->authFile, d->clientAuthFile );
- if (d->authFile) {
- if (!(auth_file = fdOpenW( creat( d->authFile, 0600 ) ))) {
- logError( "Cannot open X server authorization file %s\n", d->authFile );
- free( d->authFile );
- d->authFile = 0;
+ if (*authFile) {
+ if (!(auth_file = fdOpenW( creat( *authFile, 0600 ) ))) {
+ logError( "Cannot open X server authorization file %s\n", *authFile );
+ free( *authFile );
+ *authFile = 0;
return False;
}
} else {
- if (!(auth_file = makeServerAuthFile( d ))) {
+ if (!(auth_file = makeServerAuthFile( d, authFile ))) {
logError( "Cannot create X server authorization file\n" );
return False;
}
}
- debug( "file: %s auth: %p\n", d->authFile, auths );
+ debug( "file: %s auth: %p\n", *authFile, auths );
for (i = 0; i < count; i++) {
/*
* User-based auths may not have data until
@@ -395,15 +393,30 @@
if (fclose( auth_file ) == EOF) {
whoops:
logError( "Cannot write X server authorization file %s: %m\n",
- d->authFile );
- unlink( d->authFile );
- free( d->authFile );
- d->authFile = 0;
+ *authFile );
+ unlink( *authFile );
+ free( *authFile );
+ *authFile = 0;
return False;
}
return True;
}
+int
+saveGreeterAuthorizations( struct display *d )
+{
+ return saveAuthorizations( d, &d->greeterAuthFile,
+ d->authorizations, d->authNum );
+}
+
+int
+saveServerAuthorizations( struct display *d, Xauth **auths, int count )
+{
+ if (!d->authFile && d->clientAuthFile && *d->clientAuthFile)
+ strDup( &d->authFile, d->clientAuthFile );
+ return saveAuthorizations( d, &d->authFile, auths, count );
+}
+
void
setLocalAuthorization( struct display *d )
{
--- trunk/KDE/kdebase/workspace/kdm/backend/dm.h #1097268:1097269
@@ -288,6 +288,7 @@
Xauth **authorizations; /* authorization data */
int authNum; /* number of authorizations */
char *authFile; /* file to store authorization in */
+ char *greeterAuthFile; /* file to store authorization for greeter in */
};
#define d_location 1
@@ -475,7 +476,7 @@
void gClosen( GPipe *pajp );
int gOpen( GProc *proc,
char **argv, const char *what, char **env, char *cname,
- GPipe *igp );
+ const char *user, const char *authfile, GPipe *igp );
int gClose( GProc *proc, GPipe *gp, int force );
void gSendInt( int val );
--- trunk/KDE/kdebase/workspace/kdm/backend/dm_auth.h #1097268:1097269
@@ -83,6 +83,7 @@
#endif /* XDMCP */
+int saveGreeterAuthorizations( struct display *d );
int saveServerAuthorizations( struct display *d, Xauth **auths, int count );
void cleanUpFileName( const char *src, char *dst, int len );
void removeUserAuthorization( struct display *d );
--- trunk/KDE/kdebase/workspace/kdm/backend/dpylist.c #1097268:1097269
@@ -218,6 +218,10 @@
(void)unlink( d->authFile );
free( d->authFile );
}
+ if (d->greeterAuthFile) {
+ (void)unlink( d->greeterAuthFile );
+ free( d->greeterAuthFile );
+ }
#ifdef XDMCP
XdmcpDisposeARRAY8( &d->peer );
XdmcpDisposeARRAY8( &d->from );
--- trunk/KDE/kdebase/workspace/kdm/backend/process.c #1097268:1097269
@@ -471,7 +471,7 @@
int
gOpen( GProc *proc, char **argv, const char *what, char **env, char *cname,
- GPipe *gp )
+ const char *user, const char *authfile, GPipe *gp )
{
char **margv;
int pip[2];
@@ -516,23 +516,26 @@
(void)Signal( SIGPIPE, SIG_IGN );
close( pip[0] );
fcntl( pip[1], F_SETFD, FD_CLOEXEC );
- if (gp)
- sprintf( coninfo, "CONINFO=%d %d %d %d",
- proc->pipe.fd.r, proc->pipe.fd.w, gp->fd.r, gp->fd.w );
- else
- sprintf( coninfo, "CONINFO=%d %d",
- proc->pipe.fd.r, proc->pipe.fd.w );
- env = putEnv( coninfo, env );
- if (debugLevel & DEBUG_VALGRIND) {
- char **nmargv = xCopyStrArr( 1, margv );
- nmargv[0] = locate( "valgrind" );
- execute( nmargv, env );
- } else if (debugLevel & DEBUG_STRACE) {
- char **nmargv = xCopyStrArr( 1, margv );
- nmargv[0] = locate( "strace" );
- execute( nmargv, env );
- } else
- execute( margv, env );
+ if (changeUser( user, authfile )) {
+ if (gp)
+ sprintf( coninfo, "CONINFO=%d %d %d %d",
+ proc->pipe.fd.r, proc->pipe.fd.w, gp->fd.r, gp->fd.w );
+ else
+ sprintf( coninfo, "CONINFO=%d %d",
+ proc->pipe.fd.r, proc->pipe.fd.w );
+ env = putEnv( coninfo, env );
+ if (debugLevel & DEBUG_VALGRIND) {
+ char **nmargv = xCopyStrArr( 1, margv );
+ nmargv[0] = locate( "valgrind" );
+ execute( nmargv, env );
+ } else if (debugLevel & DEBUG_STRACE) {
+ char **nmargv = xCopyStrArr( 1, margv );
+ nmargv[0] = locate( "strace" );
+ execute( nmargv, env );
+ } else {
+ execute( margv, env );
+ }
+ }
write( pip[1], "", 1 );
exit( 1 );
default:
--- trunk/KDE/kdebase/workspace/kdm/backend/resource.c #1097268:1097269
@@ -54,7 +54,7 @@
if (!getter.pid) {
if (gOpen( &getter,
originalArgv, "_config", 0, strdup( "config reader" ),
- 0 ))
+ "", 0, 0 ))
logPanic( "Cannot run config reader\n" );
debug( "getter now ready\n" );
}
--- trunk/KDE/kdebase/workspace/kdm/backend/session.c #1097268:1097269
@@ -35,6 +35,7 @@
*/
#include "dm.h"
+#include "dm_auth.h"
#include "dm_error.h"
#include <X11/Xlib.h>
@@ -433,9 +434,13 @@
/* Load system default Resources (if any) */
loadXloginResources();
+ if (*greeterUID && !saveGreeterAuthorizations( td ))
+ sessionExit( EX_UNMANAGE_DPY );
+
grttalk.pipe = &grtproc.pipe;
env = systemEnv( dupEnv(), 0 );
- if (gOpen( &grtproc, (char **)0, "_greet", env, name, &td->gpipe ))
+ if (gOpen( &grtproc, (char **)0, "_greet", env, name,
+ greeterUID, td->greeterAuthFile, &td->gpipe ))
sessionExit( EX_UNMANAGE_DPY );
freeStrArr( env );
if ((cmd = ctrlGreeterWait( True ))) {
@@ -462,6 +467,12 @@
sessionExit( wcCode( ret ) );
}
+ if (td->greeterAuthFile) {
+ (void)unlink( td->greeterAuthFile );
+ free( td->greeterAuthFile );
+ td->greeterAuthFile = 0;
+ }
+
deleteXloginResources();
return ret;
@@ -825,9 +836,11 @@
char **
systemEnv( char **env, const char *user )
{
+ const char *authFile;
+
env = baseEnv( env, user );
- if (td->authFile)
- env = setEnv( env, "XAUTHORITY", td->authFile );
+ if ((authFile = td->greeterAuthFile) || (authFile = td->authFile))
+ env = setEnv( env, "XAUTHORITY", authFile );
env = setEnv( env, "PATH", td->systemPath );
env = setEnv( env, "SHELL", td->systemShell );
return env;
--- trunk/KDE/kdebase/workspace/kdm/config.def #1097268:1097269
@@ -1029,12 +1029,23 @@
The group to which the global command socket should belong;
can be either a name or a numerical ID.
+Key: GreeterUID
+Type: string
+Default: ""
+User: core
+Instance: "kdm"
+Update: upd_greeteruid
+Comment: &
+Description:
+ The user the greeter should run as. Empty results in <systemitem class="username">root</systemitem>.
+ Consider the impact on <option>LogSource</option> when setting it.
+
Key: DataDir
Type: path
Default: *"/var/lib/kdm"
User: greeter
Instance: #""
-Update: upd_datadir
+Update: upd_datadir/1
Comment:
The directory in which &kdm; should store persistent working data.
Description:
--- trunk/KDE/kdebase/workspace/kdm/kfrontend/genkdmconf.c #1097268:1097269
@@ -43,6 +43,7 @@
#include <time.h>
#include <limits.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <sys/param.h>
#define WANT_CONF_GEN
@@ -399,7 +400,29 @@
return 0;
}
+static int
+runAndWait( char **args )
+{
+ int pid, ret;
+ switch ((pid = fork())) {
+ case 0:
+ execv( args[0], args );
+ fprintf( stderr, "Cannot execute %s: %s\n",
+ args[0], strerror( errno ) );
+ _exit( 127 );
+ case -1:
+ fprintf( stderr, "Cannot fork to execute %s: %s\n",
+ args[0], strerror( errno ) );
+ return -1;
+ }
+ while (waitpid( pid, &ret, 0 ) < 0)
+ if (errno != EINTR)
+ return -1;
+ return ret;
+}
+
+
/*
* target data to be written to kdmrc
*/
@@ -2042,20 +2065,78 @@
chmod( dir, st.st_mode | 0755 );
}
+static gid_t greeter_gid;
+static uid_t greeter_uid;
+
static void
+upd_greeteruid( Entry *ce, Section *cs ATTR_UNUSED )
+{
+ struct passwd *pw;
+ char *ok, *adduser;
+ int uid;
+
+ if (use_destdir || !ce->active)
+ return;
+ if (!(pw = getpwnam( ce->value ))) {
+ uid = strtol( ce->value, &ok, 10 );
+ if (*ok || !(pw = getpwuid( uid ))) {
+ if ((adduser = locate( "adduser" ))) { /* Debian-style */
+ const char *args[] = {
+ adduser, "--system", "--group",
+ "--home", "/var", "--no-create-home",
+ ce->value, 0
+ };
+ if (runAndWait( (char **)args )) {
+ fprintf( stderr, "Warning: Creation of missing GreeterUID"
+ " user %s failed\n", ce->value );
+ ce->active = False;
+ return;
+ }
+ } else {
+ fprintf( stderr, "Warning: Do not know how to create missing"
+ " GreeterUID user %s\n", ce->value );
+ ce->active = False;
+ return;
+ }
+ if (!(pw = getpwnam( ce->value ))) {
+ fprintf( stderr, "Warning: Newly created GreeterUID user %s"
+ " still missing!?\n", ce->value );
+ ce->active = False;
+ return;
+ }
+ }
+ }
+ greeter_uid = pw->pw_uid;
+ greeter_gid = pw->pw_gid;
+}
+
+static void
upd_datadir( Entry *ce, Section *cs ATTR_UNUSED )
{
char *oldsts, *newsts;
const char *dir;
+ struct stat st;
if (use_destdir)
return;
dir = ce->active ? ce->value : def_DataDir;
+ ASPrintf( &newsts, "%s/kdmsts", dir );
if (mkdirp( dir, 0755, "data", 0 ) && oldkde) {
ASPrintf( &oldsts, "%s/kdm/kdmsts", oldkde );
- ASPrintf( &newsts, "%s/kdmsts", dir );
rename( oldsts, newsts );
}
+ if (stat( dir, &st ))
+ return;
+ if ((st.st_uid != greeter_uid || st.st_gid != greeter_gid) &&
+ chown( dir, greeter_uid, greeter_gid ))
+ fprintf( stderr, "Warning: Cannot assign ownership of data directory"
+ " %s: %s\n", dir, strerror( errno ) );
+ if (stat( newsts, &st ))
+ return;
+ if ((st.st_uid != greeter_uid || st.st_gid != greeter_gid) &&
+ chown( newsts, greeter_uid, greeter_gid ))
+ fprintf( stderr, "Warning: Cannot assign ownership of status file"
+ " %s: %s\n", newsts, strerror( errno ) );
}
static void
--- trunk/KDE/kdebase/workspace/kdm/kfrontend/kgreeter.cpp #1097268:1097269
@@ -366,14 +366,15 @@
{
struct passwd *ps;
- // XXX remove seteuid-voodoo when we run as nobody
- if (!(ps = getpwnam( "nobody" )))
- return;
- if (setegid( ps->pw_gid ))
- return;
- if (seteuid( ps->pw_uid )) {
- setegid( 0 );
- return;
+ if (!getuid()) {
+ if (!(ps = getpwnam( "nobody" )))
+ return;
+ if (setegid( ps->pw_gid ))
+ return;
+ if (seteuid( ps->pw_uid )) {
+ setegid( 0 );
+ return;
+ }
}
QImage default_pix;
@@ -436,9 +437,10 @@
userList->sort();
}
- // XXX remove seteuid-voodoo when we run as nobody
- seteuid( 0 );
- setegid( 0 );
+ if (!getuid()) {
+ seteuid( 0 );
+ setegid( 0 );
+ }
}
void
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic