/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* * * (c) Copyright 1993, 1994 Hewlett-Packard Company * * (c) Copyright 1993, 1994 International Business Machines Corp. * * (c) Copyright 1993, 1994 Sun Microsystems, Inc. * * (c) Copyright 1993, 1994 Novell, Inc. * */ /* * xdm - display manager daemon * * $TOG: verify.c /main/7 1998/11/02 15:25:40 mgreess $ * * Copyright 1988 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * Author: Keith Packard, MIT X Consortium */ /* * verify.c * * typical unix verification routine. */ # include "dm.h" # include "vgmsg.h" # include "vgproto.h" #include #ifdef _AIX # include #endif # include # ifdef NGROUPS # include # endif #ifdef sun # include #endif struct passwd nobody = { "Nobody", "***************" }; static char *Pndefault = "/etc/default/login"; extern char *_ExpandLang( char *string, char *lang ); int Verify( struct display *d, struct greet_info *greet, struct verify_info *verify ) { struct passwd *p; char *shell, *home; char **argv; FILE *lastsession; char last_sess[MAXPATHLEN]; int notify_dt; int i; Debug ("Verify(): %s\n", greet->name); /* * The user has already been verified by the Greeter. This is * really just to look up the rest of his environment. Better * performance would be realized by having the Greeter look this up * and pass it back in the pipe (saving an additional getpwnam). */ p = getpwnam (greet->name); if (!p || strlen (greet->name) == 0) { Debug ("Can't get user information for %s\n", greet->name); return 0; } #ifdef BYPASSLOGIN Debug ("BypassLogin = %d\n",d->bypassLogin); if ( d->bypassLogin ) { char *s = NULL; if ( !strcmp (p->pw_name, "Nobody" )) s = "Greetless login failed; user invalid\n"; else if ( access ( p->pw_dir, F_OK )) s = "Greetless login failed; bad user home dir access\n"; else if ( p->pw_uid == 0 ) s = "Greetless login failed; root bypass disallowed\n"; if (s) { Debug(s); LogError((unsigned char *) s); bzero(greet->password, strlen(greet->password)); return 0; } } #endif /* BYPASSLOGIN */ #ifdef AthenaWidgets #ifdef BYPASSLOGIN if (strcmp(crypt(greet->password,p->pw_passwd),p->pw_passwd) && !d->bypassLogin) { #else if (strcmp(crypt(greet->password,p->pw_passwd),p->pw_passwd)) { #endif /* BYPASSLOGIN */ Debug ("verify failed\n"); bzero(greet->password, strlen(greet->password)); return 0; } Debug ("verify succeeded\n"); bzero(greet->password, strlen(greet->password)); #endif Debug ("User information for %s acquired\n", greet->name); verify->uid = p->pw_uid; #ifdef __AFS if ( IsVerifyName(VN_AFS) ) { (void)setgid(p->pw_gid); verify->groups[2] = p->pw_gid; } #else # ifdef NGROUPS getGroups (greet->name, verify, p->pw_gid); # else verify->gid = p->pw_gid; # endif #endif /* __AFS */ #ifdef AUDIT verify->audid = p->pw_audid; verify->audflg = p->pw_audflg; #endif home = p->pw_dir; shell = p->pw_shell; argv = 0; if(d->sessionType > NOTIFY_ALT_DTS) notify_dt = NOTIFY_ALT_DTS; else notify_dt = d->sessionType; switch (notify_dt) { case NOTIFY_DT: case NOTIFY_OK: if(d->session) argv = parseArgs (argv,d->session); break; case NOTIFY_ALT_DTS: if((argv = setDt(d,argv,notify_dt)) == NULL) /*if no startup file, startup the regular desktop*/ if(d->session) { argv = parseArgs (argv,d->session); Debug ("No Startup file \n"); } break; case NOTIFY_LAST_DT: snprintf(last_sess, sizeof(last_sess), "%s%s", home, LAST_SESSION_FILE); if((lastsession = fopen(last_sess,"r")) == NULL) { /* * if no lastsession file, execute the logically * first alternate desktop */ if((argv = setDt(d,argv,notify_dt)) == NULL) if(d->session) { argv = parseArgs (argv,d->session); /* No altdts, set the Default Regular session */ Debug ("No AltDestops in the resources file \n"); } } else{ strcpy(last_sess,"\0"); fgets(last_sess,MAXPATHLEN,lastsession); if(access(last_sess, X_OK) != 0) { if((argv = setDt(d,argv,notify_dt)) == NULL) if(d->session){ argv = parseArgs (argv,d->session); /* No altdts, set the Default Regular session */ Debug ("No AltDestops in the resources file setting to %s \n",argv[0]); } } else { argv = parseArgs (argv, last_sess); } fclose(lastsession); } break; default: break; } if (greet->string) argv = parseArgs (argv, greet->string); if (!argv) argv = parseArgs (argv, "xsession"); verify->argv = argv; verify->userEnviron = userEnv (d, greet->name, home, shell,p); Debug ("User environment:\n"); printEnv (verify->userEnviron); verify->systemEnviron = systemEnv (d, greet->name, home); Debug ("System environment:\n"); printEnv (verify->systemEnviron); Debug ("End of environments\n"); return 1; } char ** setDt( struct display *d, char **argv, int dt_type) { int i; char *resources = NULL; char altdts[MAXPATHLEN]; char altdtsclass[MAXPATHLEN]; char altdtstart[MAXPATHLEN]; char altdtstartclass[MAXPATHLEN]; int adts; XrmValue value_dts; char *rmtype; XrmValue rmvalue; int altdtrequested; if(!XresourceDB) { Debug ("Verify - No resources \n"); return 0; } if(dt_type == NOTIFY_LAST_DT) { sprintf(altdts,"%s","Dtlogin*altDts"); sprintf(altdtsclass,"%s","Dtlogin*AltDts"); if(XrmGetResource(XresourceDB, altdts, altdtsclass, &rmtype, &value_dts) == True){ adts = atoi(value_dts.addr); for(i = 0; i < adts; i++) { sprintf(altdtstart,"%s%d","Dtlogin*altDtStart",i+1); sprintf(altdtstartclass,"%s%d","Dtlogin*AltDtStart",i+1); if(XrmGetResource(XresourceDB, altdtstart, altdtstartclass, &rmtype, &rmvalue) == True){ Debug ("Start up file is %s\n",rmvalue.addr); argv = parseArgs (argv, rmvalue.addr); return argv; } } } } else { altdtrequested = d->sessionType - NOTIFY_ALT_DTS; sprintf(altdtstart,"%s%d", "Dtlogin*altDtStart",altdtrequested); sprintf(altdtstartclass,"%s%d", "Dtlogin*AltDtStart",altdtrequested); if(XrmGetResource(XresourceDB, altdtstart, altdtstartclass, &rmtype, &rmvalue) == True){ Debug ("Start up file is %s\n",rmvalue.addr); argv = parseArgs (argv, rmvalue.addr); return argv; } } return 0; } char ** userEnv( struct display *d, char *user, char *home, char *shell, struct passwd *p) { char **env; char *value; char **exp; char *Def_path; char *langlist = NULL; #ifdef _AIX /* * For AIX, we must delimit protected variables. This is done by * adding special tags to the environment list. The setpenv() * routine serched the environent for these special tags. * * NOTE: If you change the location of PENV_SYSSTR or PENV_USRSTR * in this environment list, you MUST change the index * in session.c prior to the call to setpenv(). */ env = 0; env = setEnv(env,PENV_SYSSTR,""); /* protected vars */ env = setEnv(env,"LOGNAME",user); env = setEnv(env,"LOGIN",user); env = setEnv(env,PENV_USRSTR,""); /* regular vars */ #else env = 0; env = setEnv (env,"LOGNAME", user); #endif for (exp = exportList; exp && *exp; ++exp) { value = getenv (*exp); if (value) env = setEnv (env, *exp, value); } env = setEnv (env, "DISPLAY", d->name); env = setEnv (env, "HOME", home); env = setEnv (env, "USER", user); #ifdef sun if ((Def_path = login_defaults(p,d)) != NULL) { env = setEnv (env, "PATH", Def_path); free(Def_path); } #else if (d->userPath && strlen(d->userPath) > 0) env = setEnv (env, "PATH", d->userPath); #endif env = setEnv (env, "SHELL", shell); if (timeZone && strlen(timeZone) > 0 ) env = setEnv(env, "TZ", timeZone); if ( d->langList && strlen(d->langList) > 0 ) langlist = d->langList; #if defined (ENABLE_DYNAMIC_LANGLIST) if (d->language && strlen(d->language) > 0) langlist = d->language; #else else if ( strlen(languageList) > 0 ) langlist = languageList; #endif /* ENABLE_DYNAMIC_LANGLIST */ if (env && d->language && strlen(d->language) > 0) env = setLang(d, env, langlist); #if 0 /* setting LC_ALL can cause undesirable side effects -- bf@hp */ /* * Don't set LC_MESSAGES to LANG since: * 1) if LC_MESSAGES is unset, it will by default take on the value of LANG * 2) if set, we don't want to override the user's setting */ env = setEnv (env, "LC_ALL", d->language); env = setEnv (env, "LC_MESSAGES", d->language); #endif #if 0 /* setting XAUTHORITY here is a bug, needs further study... */ if (d->authFile) env = setEnv (env, "XAUTHORITY", d->authFile); #endif if (d->displayType.location != Local) env = setEnv (env, XFORCEINTERNET, "True"); if (d->environStr && strlen(d->environStr) > 0) env = parseEnv(env, d->environStr); /* * set SESSIONTYPE environment variable if requested by user, or * if the "dtlite" resource is set... * * Note: the dtlite resource takes precedence over xdmMode. */ if (d->dtlite == True) d->sessionType = NOTIFY_DTLITE; else if (d->xdmMode == True) d->sessionType = NOTIFY_XDM; switch (d->sessionType) { case NOTIFY_DTLITE: Debug("Setting SESSIONTYPE to 'dtlite'.\n"); env = setEnv(env, SESSIONTYPE, "dtlite"); break; case NOTIFY_XDM: Debug("Setting SESSIONTYPE to 'xdm'.\n"); env = setEnv(env, SESSIONTYPE, "xdm"); break; case NOTIFY_DT: Debug("Setting SESSIONTYPE to 'dt'.\n"); env = setEnv(env, SESSIONTYPE, "dt"); break; default: Debug("SESSIONTYPE NOT set.\n"); break; } return env; } /* * read login defaults */ #ifdef sun char * login_defaults( struct passwd *p, struct display *d ) { extern int defcntl(); int flags; char *ptr; char *Def_path; char *final_path = malloc(MAXPATHLEN); char *element; if (defopen(Pndefault) == 0) { /* * ignore case * code taken from login.c */ flags = defcntl(DC_GETFLAGS, 0); TURNOFF(flags, DC_CASE); defcntl(DC_SETFLAGS, flags); if ( p->pw_uid == 0 ) { if ((Def_path = defread("SUPATH=")) != NULL) Def_path = strdup(Def_path); else Def_path = strdup(DEF_SUPATH); } else { if ((Def_path = defread("PATH=")) != NULL) Def_path = strdup(Def_path); else Def_path = strdup(DEF_PATH); } } /* * close the file..(/etc/default/login) */ (void) defopen((char *)NULL); Debug ("login_defaults(): \n"); if (d->userPath && strlen(d->userPath) > 0) { if(Def_path && strlen(Def_path) > 0) element = strtok(Def_path,":"); else return d->userPath; strcpy(final_path,d->userPath); while(element) { if((strstr(d->userPath,element)) == NULL) { strcat (final_path,":"); strcat (final_path,element); } element = strtok(NULL,":"); } return final_path; } else { if(Def_path && strlen(Def_path) > 0) return Def_path; else return 0; } } #endif char ** systemEnv( struct display *d, char *user, char *home ) { char **env; char *value; char **exp; char *langlist = NULL; env = 0; for (exp = exportList; exp && *exp; ++exp) { value = getenv (*exp); if (value) env = setEnv (env, *exp, value); } value = getenv("TZ"); if (value) env = setEnv (env, "TZ", value); else if (timeZone && strlen(timeZone) > 0 ) env = setEnv(env, "TZ", timeZone); env = setEnv (env, "DISPLAY", d->name); if (home) env = setEnv (env, "HOME", home); if (user) env = setEnv (env, "USER", user); env = setEnv (env, "PATH", d->systemPath); env = setEnv (env, "SHELL", d->systemShell); if ( d->langList && strlen(d->langList) > 0 ) langlist = d->langList; #if defined (ENABLE_DYNAMIC_LANGLIST) else if (d->language && strlen(d->language) > 0 ) langlist = d->language; #else else if ( strlen(languageList) > 0 ) langlist = languageList; #endif /* ENABLE_DYNAMIC_LANGLIST */ if (d->language && strlen(d->language) > 0) env = setLang(d, env, langlist); if (d->displayType.location != Local) env = setEnv (env, XFORCEINTERNET, "True"); #if defined (sun) if (getEnv (env, "OPENWINHOME") == NULL) env = setEnv(env, "OPENWINHOME", "/usr/openwin"); #endif return env; } #ifdef NGROUPS #ifndef __hpux /* * groupMember() not used in HP-UX */ int groupMember( char *name, char **members ) { while (*members) { if (!strcmp (name, *members)) return 1; ++members; } return 0; } #endif /* ! __hpux */ void getGroups( char *name, struct verify_info *verify, int gid ) { int ngroups; struct group *g; int i; ngroups = 0; verify->groups[ngroups++] = gid; setgrent (); /* * if your system does not support "initgroups(3C)", activate * this code... */ #if !(defined(__hpux)) while ( (g = getgrent()) != NULL ) { /* * make the list unique */ for (i = 0; i < ngroups; i++) if (verify->groups[i] == g->gr_gid) break; if (i != ngroups) continue; if (groupMember (name, g->gr_mem)) { if (ngroups >= NGROUPS) LogError(ReadCatalog(MC_LOG_SET, MC_LOG_MORE_GRP,MC_DEF_LOG_MORE_GRP), name, NGROUPS, g->gr_name); else verify->groups[ngroups++] = g->gr_gid; } } #endif verify->ngroups = ngroups; endgrent (); } #endif