From: Jon Trulson Date: Thu, 12 Jul 2012 20:22:59 +0000 (-0600) Subject: dtsession: implement screen lock/unlock for linux X-Git-Tag: 2.2.0a~20 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=1c733e5b16b65a4e8ee6ae9f1f46fb77c6bbfa2b;p=oweals%2Fcde.git dtsession: implement screen lock/unlock for linux In order for this to work, dtsession must be setuid root. If dtsession is not setuid root, then locking will be disabled, and a message will be written to ~/.dt/errorlog with the message: "Unable to lock display due to security restrictions". --- diff --git a/cde/programs/dtsession/SmLock.c b/cde/programs/dtsession/SmLock.c index 7b0d5d6e..41b4abd7 100644 --- a/cde/programs/dtsession/SmLock.c +++ b/cde/programs/dtsession/SmLock.c @@ -82,6 +82,15 @@ # include #endif #endif + +#if defined(linux) +# include +#endif +#if defined(CSRG_BASED) +#include +#include +#endif + #include "Sm.h" #include "SmUI.h" #include "SmError.h" @@ -140,6 +149,93 @@ static void RequirePassword( XtPointer, XtIntervalId *) ; static void CycleSaver( XtPointer, XtIntervalId *) ; static void BlinkCaret( XtPointer, XtIntervalId *) ; +#if defined(linux) +/* #define JET_AUTHDEBUG */ + +/* Test for re-auth ability - see if we can re-authenticate via pwd, + * shadow, or NIS + */ +static Boolean CanReAuthenticate(char *name, uid_t uid, char *passwd, + struct passwd **pwent, struct spwd **spent) +{ + Boolean fail = False; + + *pwent = (name == NULL) ? getpwuid(uid) : getpwnam(name); + *spent = getspnam((*pwent)->pw_name); + +#ifdef JET_AUTHDEBUG + fprintf(stderr, "CanReAuthenticate(): %s %s %s\n", + (*pwent) ? "PWENT" : "NULL", + (*spent) ? "SPENT" : "NULL", + (name) ? name : "NULL"); +#endif + + /* some checking for aging stuff on RedPhat */ + + if (*pwent && (*pwent)->pw_passwd) + { + char *loc; + + if ((loc = strchr((*pwent)->pw_passwd, ',')) != NULL) + *loc = '\0'; +#ifdef JET_AUTHDEBUG + fprintf(stderr, "CanReAuthenticate(): pw: '%s'\n", + (*pwent)->pw_passwd); +#endif + + } + + if (*spent && (*spent)->sp_pwdp) + { + char *loc; + + if ((loc = strchr((*spent)->sp_pwdp, ',')) != NULL) + *loc = '\0'; + } + + if (*pwent == NULL) + { /* if we can't get this, we're screwed. */ +#ifdef JET_AUTHDEBUG + fprintf(stderr, "CanReAuthenticate(): PWENT == NULL - FALSE\n"); +#endif + return False; + } + + if ((*pwent)->pw_passwd == NULL) + { +#ifdef JET_AUTHDEBUG + fprintf(stderr, "CanReAuthenticate(): (*pwent)->pw_passwd == NULL - FALSE\n"); +#endif + + return False; + } + + /* ok, now we have the prequisite data, look first to see if the + * passwd field is larger than 1 char - implying NIS, or a shadowed + * system. if not look for *spent being non-NULL + */ + if (*spent == NULL) + { /* if it's null, lets check for the NIS case */ + if (strlen((*pwent)->pw_passwd) <= 1) + { +#ifdef JET_AUTHDEBUG + fprintf(stderr, "strlen((*pwent)->pw_passwd) <= 1\n"); +#endif + + return False; /* not NIS */ + } + } + + /* supposedly we have valid data */ +#ifdef JET_AUTHDEBUG + fprintf(stderr, "CanReAuthenticate(): TRUE\n"); +#endif + + return True; +} + +#endif /* linux */ + @@ -185,21 +281,6 @@ LockDisplay( timerId = lockTimeId = lockDelayId = cycleId = flash_id = (XtIntervalId)0; - #if defined (SMGETTIMEOUTS) -/*D*/ getTimeouts(&lockNow, NULL, NULL, NULL, NULL); - - { - FILE *fp = fopen("/tmp/session", "a"); - if (fp) fprintf(fp, "lockNow=%d saverTimeout=%d " - "lockTimeout=%d cycleTimeout=%d" - "saverList='%s'\n", - lockNow, smSaverRes.saverTimeout, - smSaverRes.lockTimeout, smSaverRes.cycleTimeout, - smGD.saverList); - if (fp) fclose(fp); - } - #endif - /* * coverScreen * 0 - screen will not be covered, nor will external screen saver run @@ -1589,6 +1670,97 @@ localAuthenticate( return FALSE; } +#elif defined(linux) + +{ + struct passwd *pwent = NULL; + char *p, *q; + char *crypt(); + Boolean rc = True; + Boolean done = False; + struct spwd *sp = NULL; + + if(smGD.secureSystem) + { + SM_SETEUID(smGD.unLockUID); + } + + /* + * Get password entry for 'name' or 'uid'. + */ + if (CanReAuthenticate(name, uid, passwd, &pwent, &sp) == False) + { + /* + * Can't get entry. + */ + rc = False; + done = True; + } + + if(smGD.secureSystem) + { + SM_SETEUID(smGD.runningUID); + } + + if (done == False) + { + + if (pwent->pw_passwd == NULL || pwent->pw_passwd[0] == '*') + { + /* check sp */ + if (sp == NULL || sp->sp_pwdp == NULL) + { + /* + * Could not read password. + */ + rc = False; + done = True; + } + } + } + + if (done == False) + { + if (passwd == NULL) + { + /* + * Caller just checking if it is possible to access + * password file (ie is dtsession suid bit set properly). + */ + rc = True; + done = True; + } + } + + if (done == False) + { + /* + * Check password. + */ + + if (sp != NULL && !strcmp(sp->sp_pwdp, crypt(passwd,sp->sp_pwdp))) + { /* a shadow match */ + rc = True; + done = True; + } + else if (pwent != NULL && + !strcmp(pwent->pw_passwd, crypt(passwd, pwent->pw_passwd))) + { /* passwd match */ + rc = True; + done = True; + } + else + { /* failure dude! */ + rc = False; + done = True; + } + } + + endpwent(); + endspent(); + + return(rc); +} #else diff --git a/cde/programs/dtsession/SmMain.c b/cde/programs/dtsession/SmMain.c index 52a8ca9a..9a864d61 100644 --- a/cde/programs/dtsession/SmMain.c +++ b/cde/programs/dtsession/SmMain.c @@ -82,7 +82,6 @@ /* * Internal Functions */ -void main(int, char **); static void StopAll(int i); static int RegisterX11ScreenSaver(Display *display, int *ssEventType); @@ -125,9 +124,8 @@ static int RegisterX11ScreenSaver(Display *display, int *ssEventType); * -------- * *************************************<->***********************************/ -void -main (int argc, - char **argv) +int +main (int argc, char **argv) { int n, tmp; Arg args[10]; @@ -205,21 +203,22 @@ main (int argc, */ smGD.runningUID = getuid(); -#ifdef SECURE_SYS_PATH - status = stat(SECURE_SYS_PATH, &buf); -#else - status = -1; -#endif +#ifdef linux /* linux always needs to be setup as secure */ /* - * Initialize LANG if it isn't defined. + * Save the root priviledge to be restored when trying to unlock */ - if ((lang = getenv ("LANG")) == NULL) - { - lang = XtMalloc (7); - (void) strcpy (lang, "LANG=C"); - (void) putenv (lang); - } + smGD.unLockUID = geteuid(); + smGD.secureSystem = True; + SM_SETEUID(smGD.runningUID); + +#else + +# ifdef SECURE_SYS_PATH + status = stat(SECURE_SYS_PATH, &buf); +# else + status = -1; +# endif if(status == -1) { @@ -240,6 +239,18 @@ main (int argc, SM_SETEUID(smGD.runningUID); } +#endif /* linux */ + + /* + * Initialize LANG if it isn't defined. + */ + if ((lang = getenv ("LANG")) == NULL) + { + lang = XtMalloc (7); + (void) strcpy (lang, "LANG=C"); + (void) putenv (lang); + } + #ifdef __hpux setresgid(-1, smGD.runningGID, -1); #else /* _AIX or any other system */ @@ -445,7 +456,7 @@ main (int argc, /* * Restore resources for lang/resolution independence */ - if((smGD.resourcePath[0] != NULL) || (smGD.compatMode == False)) + if((smGD.resourcePath[0] != 0) || (smGD.compatMode == False)) { RestoreIndependentResources(); } @@ -453,7 +464,7 @@ main (int argc, /* * Now restore the rest of the clients and the settings */ - if((smGD.clientPath[0] != NULL) && (smGD.compatMode == False)) + if((smGD.clientPath[0] != 0) && (smGD.compatMode == False)) { if(RestoreState() == -1) {