verify.c revision 629baa8c
1145b7b3cSmrg/* 2145b7b3cSmrg 3145b7b3cSmrgCopyright 1988, 1998 The Open Group 4145b7b3cSmrg 5145b7b3cSmrgPermission to use, copy, modify, distribute, and sell this software and its 6145b7b3cSmrgdocumentation for any purpose is hereby granted without fee, provided that 7145b7b3cSmrgthe above copyright notice appear in all copies and that both that 8145b7b3cSmrgcopyright notice and this permission notice appear in supporting 9145b7b3cSmrgdocumentation. 10145b7b3cSmrg 11145b7b3cSmrgThe above copyright notice and this permission notice shall be included 12145b7b3cSmrgin all copies or substantial portions of the Software. 13145b7b3cSmrg 14145b7b3cSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15145b7b3cSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16145b7b3cSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17145b7b3cSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18145b7b3cSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19145b7b3cSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20145b7b3cSmrgOTHER DEALINGS IN THE SOFTWARE. 21145b7b3cSmrg 22145b7b3cSmrgExcept as contained in this notice, the name of The Open Group shall 23145b7b3cSmrgnot be used in advertising or otherwise to promote the sale, use or 24145b7b3cSmrgother dealings in this Software without prior written authorization 25145b7b3cSmrgfrom The Open Group. 26145b7b3cSmrg 27145b7b3cSmrg*/ 28145b7b3cSmrg 29145b7b3cSmrg/* 30145b7b3cSmrg * xdm - display manager daemon 31145b7b3cSmrg * Author: Keith Packard, MIT X Consortium 32145b7b3cSmrg * 33145b7b3cSmrg * verify.c 34145b7b3cSmrg * 35145b7b3cSmrg * typical unix verification routine. 36145b7b3cSmrg */ 37145b7b3cSmrg 38145b7b3cSmrg#include "dm.h" 39145b7b3cSmrg#include "dm_error.h" 40145b7b3cSmrg 41145b7b3cSmrg#include <pwd.h> 42145b7b3cSmrg 43145b7b3cSmrg#if defined(USE_PAM) 44145b7b3cSmrg# include <security/pam_appl.h> 45145b7b3cSmrg# include <stdlib.h> 46629baa8cSmrg#elif defined(HAVE_GETSPNAM) 47145b7b3cSmrg# include <shadow.h> 48145b7b3cSmrg# include <errno.h> 49145b7b3cSmrg#elif defined(USE_BSDAUTH) 50145b7b3cSmrg# include <login_cap.h> 51145b7b3cSmrg# include <varargs.h> 52145b7b3cSmrg# include <bsd_auth.h> 53145b7b3cSmrg#elif defined(USESECUREWARE) 54145b7b3cSmrg# include <sys/types.h> 55145b7b3cSmrg# include <prot.h> 56145b7b3cSmrg#endif 57145b7b3cSmrg 58578741aaSmrg#include "greet.h" 59145b7b3cSmrg 60145b7b3cSmrg#ifdef QNX4 61145b7b3cSmrgextern char *crypt(const char *, const char *); 62145b7b3cSmrg#endif 63145b7b3cSmrg 64145b7b3cSmrgstatic char *envvars[] = { 65145b7b3cSmrg "TZ", /* SYSV and SVR4, but never hurts */ 66145b7b3cSmrg#if defined(sony) && !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV) 67145b7b3cSmrg "bootdev", 68145b7b3cSmrg "boothowto", 69145b7b3cSmrg "cputype", 70145b7b3cSmrg "ioptype", 71145b7b3cSmrg "machine", 72145b7b3cSmrg "model", 73145b7b3cSmrg "CONSDEVTYPE", 74145b7b3cSmrg "SYS_LANGUAGE", 75145b7b3cSmrg "SYS_CODE", 76145b7b3cSmrg#endif 77145b7b3cSmrg#if (defined(SVR4) || defined(SYSV)) && defined(i386) && !defined(sun) 78145b7b3cSmrg "XLOCAL", 79145b7b3cSmrg#endif 80145b7b3cSmrg NULL 81145b7b3cSmrg}; 82145b7b3cSmrg 83145b7b3cSmrg#ifdef KERBEROS 84578741aaSmrg# include <sys/param.h> 85578741aaSmrg# include <kerberosIV/krb.h> 86145b7b3cSmrg/* OpenBSD 2.8 needs this. */ 87578741aaSmrg# if defined(OpenBSD) && (OpenBSD <= 200012) 88578741aaSmrg# include <kerberosIV/kafs.h> 89578741aaSmrg# endif 90145b7b3cSmrgstatic char krbtkfile[MAXPATHLEN]; 91145b7b3cSmrg#endif 92145b7b3cSmrg 93145b7b3cSmrgstatic char ** 94145b7b3cSmrguserEnv (struct display *d, int useSystemPath, char *user, char *home, char *shell) 95145b7b3cSmrg{ 96145b7b3cSmrg char **env; 97145b7b3cSmrg char **envvar; 98145b7b3cSmrg char *str; 99145b7b3cSmrg 100145b7b3cSmrg env = defaultEnv (); 101145b7b3cSmrg env = setEnv (env, "DISPLAY", d->name); 102145b7b3cSmrg env = setEnv (env, "HOME", home); 103145b7b3cSmrg env = setEnv (env, "LOGNAME", user); /* POSIX, System V */ 104145b7b3cSmrg env = setEnv (env, "USER", user); /* BSD */ 105145b7b3cSmrg env = setEnv (env, "PATH", useSystemPath ? d->systemPath : d->userPath); 106145b7b3cSmrg env = setEnv (env, "SHELL", shell); 107145b7b3cSmrg#ifdef KERBEROS 108145b7b3cSmrg if (krbtkfile[0] != '\0') 109145b7b3cSmrg env = setEnv (env, "KRBTKFILE", krbtkfile); 110145b7b3cSmrg#endif 111145b7b3cSmrg for (envvar = envvars; *envvar; envvar++) 112145b7b3cSmrg { 113145b7b3cSmrg str = getenv(*envvar); 114145b7b3cSmrg if (str) 115145b7b3cSmrg env = setEnv (env, *envvar, str); 116145b7b3cSmrg } 117145b7b3cSmrg return env; 118145b7b3cSmrg} 119145b7b3cSmrg 120145b7b3cSmrg#ifdef USE_BSDAUTH 121145b7b3cSmrg_X_INTERNAL 122145b7b3cSmrgint 123145b7b3cSmrgVerify (struct display *d, struct greet_info *greet, struct verify_info *verify) 124145b7b3cSmrg{ 125145b7b3cSmrg struct passwd *p; 126145b7b3cSmrg login_cap_t *lc; 127145b7b3cSmrg auth_session_t *as; 128145b7b3cSmrg char *style, *shell, *home, *s, **argv; 129145b7b3cSmrg char path[MAXPATHLEN]; 130145b7b3cSmrg int authok; 131145b7b3cSmrg 132145b7b3cSmrg /* User may have specified an authentication style. */ 133145b7b3cSmrg if ((style = strchr(greet->name, ':')) != NULL) 134145b7b3cSmrg *style++ = '\0'; 135145b7b3cSmrg 136145b7b3cSmrg Debug ("Verify %s, style %s ...\n", greet->name, 137145b7b3cSmrg style ? style : "default"); 138145b7b3cSmrg 139145b7b3cSmrg p = getpwnam (greet->name); 140145b7b3cSmrg endpwent(); 141145b7b3cSmrg 142145b7b3cSmrg if (!p || strlen (greet->name) == 0) { 143145b7b3cSmrg Debug("getpwnam() failed.\n"); 144145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 145145b7b3cSmrg return 0; 146145b7b3cSmrg } 147145b7b3cSmrg 148145b7b3cSmrg if ((lc = login_getclass(p->pw_class)) == NULL) { 149145b7b3cSmrg Debug("login_getclass() failed.\n"); 150145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 151145b7b3cSmrg return 0; 152145b7b3cSmrg } 153145b7b3cSmrg if ((style = login_getstyle(lc, style, "xdm")) == NULL) { 154145b7b3cSmrg Debug("login_getstyle() failed.\n"); 155145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 156145b7b3cSmrg return 0; 157145b7b3cSmrg } 158145b7b3cSmrg if ((as = auth_open()) == NULL) { 159145b7b3cSmrg Debug("auth_open() failed.\n"); 160145b7b3cSmrg login_close(lc); 161145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 162145b7b3cSmrg return 0; 163145b7b3cSmrg } 164145b7b3cSmrg if (auth_setoption(as, "login", "yes") == -1) { 165145b7b3cSmrg Debug("auth_setoption() failed.\n"); 166145b7b3cSmrg login_close(lc); 167145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 168145b7b3cSmrg return 0; 169145b7b3cSmrg } 170145b7b3cSmrg 171145b7b3cSmrg /* Set up state for no challenge, just check a response. */ 172145b7b3cSmrg auth_setstate(as, 0); 173145b7b3cSmrg auth_setdata(as, "", 1); 174145b7b3cSmrg auth_setdata(as, greet->password, strlen(greet->password) + 1); 175145b7b3cSmrg 176145b7b3cSmrg /* Build path of the auth script and call it */ 177145b7b3cSmrg snprintf(path, sizeof(path), _PATH_AUTHPROG "%s", style); 178578741aaSmrg auth_call(as, path, style, "-s", "response", greet->name, 179145b7b3cSmrg lc->lc_class, (void *)NULL); 180145b7b3cSmrg authok = auth_getstate(as); 181145b7b3cSmrg 182145b7b3cSmrg if ((authok & AUTH_ALLOW) == 0) { 183145b7b3cSmrg Debug("password verify failed\n"); 184145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 185145b7b3cSmrg auth_close(as); 186145b7b3cSmrg login_close(lc); 187145b7b3cSmrg return 0; 188145b7b3cSmrg } 189145b7b3cSmrg /* Run the approval script */ 190145b7b3cSmrg if (!auth_approval(as, lc, greet->name, "auth-xdm")) { 191145b7b3cSmrg Debug("login not approved\n"); 192145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 193145b7b3cSmrg auth_close(as); 194145b7b3cSmrg login_close(lc); 195145b7b3cSmrg return 0; 196145b7b3cSmrg } 197145b7b3cSmrg auth_close(as); 198145b7b3cSmrg login_close(lc); 199145b7b3cSmrg /* Check empty passwords against allowNullPasswd */ 200145b7b3cSmrg if (!greet->allow_null_passwd && strlen(greet->password) == 0) { 201145b7b3cSmrg Debug("empty password not allowed\n"); 202145b7b3cSmrg return 0; 203145b7b3cSmrg } 204145b7b3cSmrg /* Only accept root logins if allowRootLogin resource is set */ 205145b7b3cSmrg if (p->pw_uid == 0 && !greet->allow_root_login) { 206145b7b3cSmrg Debug("root logins not allowed\n"); 207145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 208145b7b3cSmrg return 0; 209145b7b3cSmrg } 210145b7b3cSmrg 211145b7b3cSmrg /* 212578741aaSmrg * Shell must be in /etc/shells 213145b7b3cSmrg */ 214145b7b3cSmrg for (;;) { 215145b7b3cSmrg s = getusershell(); 216145b7b3cSmrg if (s == NULL) { 217578741aaSmrg /* did not found the shell in /etc/shells 218145b7b3cSmrg -> failure */ 219145b7b3cSmrg Debug("shell not in /etc/shells\n"); 220145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 221145b7b3cSmrg endusershell(); 222145b7b3cSmrg return 0; 223145b7b3cSmrg } 224145b7b3cSmrg if (strcmp(s, p->pw_shell) == 0) { 225145b7b3cSmrg /* found the shell in /etc/shells */ 226145b7b3cSmrg endusershell(); 227145b7b3cSmrg break; 228145b7b3cSmrg } 229578741aaSmrg } 230145b7b3cSmrg#elif defined(USESECUREWARE) /* !USE_BSDAUTH */ 231145b7b3cSmrg/* 232145b7b3cSmrg * This is a global variable and will be referenced in at least session.c 233145b7b3cSmrg */ 234145b7b3cSmrgstruct smp_user_info *userp = 0; 235145b7b3cSmrg 236145b7b3cSmrg_X_INTERNAL 237145b7b3cSmrgint 238145b7b3cSmrgVerify (struct display *d, struct greet_info *greet, struct verify_info *verify) 239145b7b3cSmrg{ 240145b7b3cSmrg int ret, pwtries = 0, nis, delay; 241145b7b3cSmrg char *reason = 0; 242145b7b3cSmrg struct passwd *p; 243145b7b3cSmrg char *shell, *home, **argv; 244145b7b3cSmrg 245145b7b3cSmrg Debug ("Verify %s ...\n", greet->name); 246145b7b3cSmrg 247145b7b3cSmrg p = getpwnam (greet->name); 248145b7b3cSmrg endpwent(); 249145b7b3cSmrg 250145b7b3cSmrg if (!p || strlen (greet->name) == 0) { 251145b7b3cSmrg LogError ("getpwnam() failed.\n"); 252145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 253145b7b3cSmrg return 0; 254145b7b3cSmrg } 255145b7b3cSmrg 256145b7b3cSmrg ret = smp_check_user (SMP_LOGIN, greet->name, 0, 0, &userp, &pwtries, 257145b7b3cSmrg &reason, &nis, &delay); 258145b7b3cSmrg if (ret != SMP_RETIRED && userp->retired) 259145b7b3cSmrg ret = userp->result = SMP_RETIRED; 260145b7b3cSmrg Debug ("smp_check_user returns %d\n", ret); 261145b7b3cSmrg 262145b7b3cSmrg switch (ret) { 263145b7b3cSmrg case SMP_FAIL: 264145b7b3cSmrg Debug ("Out of memory in smp_check_user\n"); 265145b7b3cSmrg goto smp_fail; 266145b7b3cSmrg case SMP_EXTFAIL: 267145b7b3cSmrg Debug ("SMP_EXTFAIL: %s", reason); 268145b7b3cSmrg goto smp_fail; 269145b7b3cSmrg case SMP_NOTAUTH: 270145b7b3cSmrg Debug ("Not authorized\n"); 271145b7b3cSmrg goto smp_fail; 272145b7b3cSmrg case SMP_TERMLOCK: 273145b7b3cSmrg Debug ("Terminal is locked!\n"); 274145b7b3cSmrg goto smp_fail; 275145b7b3cSmrg case SMP_ACCTLOCK: 276145b7b3cSmrg Debug ("Account is locked\n"); 277145b7b3cSmrg goto smp_fail; 278145b7b3cSmrg case SMP_RETIRED: 279145b7b3cSmrg Debug ("Account is retired\n"); 280145b7b3cSmrg goto smp_fail; 281145b7b3cSmrg case SMP_OVERRIDE: 282145b7b3cSmrg Debug ("On override device ... proceeding\n"); 283145b7b3cSmrg break; 284145b7b3cSmrg case SMP_NULLPW: 285145b7b3cSmrg Debug ("NULL password entry\n"); 286145b7b3cSmrg if (!greet->allow_null_passwd) { 287145b7b3cSmrg goto smp_fail; 288145b7b3cSmrg } 289145b7b3cSmrg break; 290145b7b3cSmrg case SMP_BADUSER: 291145b7b3cSmrg Debug ("User not found in protected password database\n"); 292145b7b3cSmrg goto smp_fail; 293145b7b3cSmrg case SMP_PWREQ: 294145b7b3cSmrg Debug ("Password change required\n"); 295145b7b3cSmrg goto smp_fail; 296145b7b3cSmrg case SMP_HASPW: 297145b7b3cSmrg break; 298145b7b3cSmrg default: 299145b7b3cSmrg Debug ("Unhandled smp_check_user return %d\n", ret); 300145b7b3cSmrgsmp_fail: 301145b7b3cSmrg sleep(delay); 302145b7b3cSmrg smp_audit_fail (userp, 0); 303145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 304145b7b3cSmrg return 0; 305145b7b3cSmrg break; 306145b7b3cSmrg } 307145b7b3cSmrg 308145b7b3cSmrg if (ret != SMP_NULLPW) { 309145b7b3cSmrg /* 310145b7b3cSmrg * If we require a password, check it. 311145b7b3cSmrg */ 312145b7b3cSmrg ret = smp_check_pw (greet->password, userp, &reason); 313145b7b3cSmrg switch (ret) { 314145b7b3cSmrg case SMP_CANCHANGE: 315145b7b3cSmrg case SMP_CANTCHANGE: 316145b7b3cSmrg case SMP_OVERRIDE: 317145b7b3cSmrg break; 318145b7b3cSmrg default: 319145b7b3cSmrg goto smp_fail; 320145b7b3cSmrg } 321145b7b3cSmrg } 322145b7b3cSmrg#else /* !USE_BSDAUTH && !USESECUREWARE */ 323145b7b3cSmrg_X_INTERNAL 324145b7b3cSmrgint 325145b7b3cSmrgVerify (struct display *d, struct greet_info *greet, struct verify_info *verify) 326145b7b3cSmrg{ 327145b7b3cSmrg struct passwd *p; 328578741aaSmrg# ifndef USE_PAM 329629baa8cSmrg# ifdef HAVE_GETSPNAM 330145b7b3cSmrg struct spwd *sp; 331578741aaSmrg# endif 332145b7b3cSmrg char *user_pass = NULL; 333578741aaSmrg# endif 334578741aaSmrg# ifdef __OpenBSD__ 335145b7b3cSmrg char *s; 336145b7b3cSmrg struct timeval tp; 337578741aaSmrg# endif 338145b7b3cSmrg char *shell, *home; 339145b7b3cSmrg char **argv; 340145b7b3cSmrg 341145b7b3cSmrg Debug ("Verify %s ...\n", greet->name); 342145b7b3cSmrg 343145b7b3cSmrg p = getpwnam (greet->name); 344145b7b3cSmrg endpwent(); 345145b7b3cSmrg 346145b7b3cSmrg if (!p || strlen (greet->name) == 0) { 347145b7b3cSmrg Debug ("getpwnam() failed.\n"); 348145b7b3cSmrg if (greet->password != NULL) 349145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 350145b7b3cSmrg return 0; 351145b7b3cSmrg } 352145b7b3cSmrg 353629baa8cSmrg /* 354629baa8cSmrg * Only accept root logins if allowRootLogin resource is not false 355629baa8cSmrg */ 356629baa8cSmrg if ((p->pw_uid == 0) && !greet->allow_root_login) { 357629baa8cSmrg Debug("root logins not allowed\n"); 358629baa8cSmrg if (greet->password != NULL) 359629baa8cSmrg bzero(greet->password, strlen(greet->password)); 360629baa8cSmrg return 0; 361629baa8cSmrg } 362629baa8cSmrg 363578741aaSmrg# if defined(sun) && defined(SVR4) 364578741aaSmrg /* Solaris: If CONSOLE is set to /dev/console in /etc/default/login, 365145b7b3cSmrg then root can only login on system console */ 366145b7b3cSmrg 367578741aaSmrg# define SOLARIS_LOGIN_DEFAULTS "/etc/default/login" 368145b7b3cSmrg 369145b7b3cSmrg if (p->pw_uid == 0) { 370145b7b3cSmrg char *console = NULL, *tmp = NULL; 371145b7b3cSmrg FILE *fs; 372145b7b3cSmrg 373145b7b3cSmrg if ((fs= fopen(SOLARIS_LOGIN_DEFAULTS, "r")) != NULL) 374578741aaSmrg { 375145b7b3cSmrg char str[120]; 376145b7b3cSmrg while (!feof(fs)) 377145b7b3cSmrg { 378145b7b3cSmrg fgets(str, 120, fs); 379145b7b3cSmrg if(str[0] == '#' || strlen(str) < 8) 380145b7b3cSmrg continue; 381145b7b3cSmrg if((tmp = strstr(str, "CONSOLE=")) != NULL) 382145b7b3cSmrg console = strdup((tmp+8)); 383145b7b3cSmrg } 384145b7b3cSmrg fclose(fs); 385578741aaSmrg if ( console != NULL && 386578741aaSmrg (strncmp(console, "/dev/console", 12) == 0) && 387145b7b3cSmrg (strncmp(d->name,":0",2) != 0) ) 388145b7b3cSmrg { 389145b7b3cSmrg Debug("Not on system console\n"); 390145b7b3cSmrg if (greet->password != NULL) 391145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 392629baa8cSmrg free(console); 393145b7b3cSmrg return 0; 394145b7b3cSmrg } 395145b7b3cSmrg free(console); 396145b7b3cSmrg } 397145b7b3cSmrg else 398145b7b3cSmrg { 399145b7b3cSmrg Debug("Could not open %s\n", SOLARIS_LOGIN_DEFAULTS); 400578741aaSmrg } 401145b7b3cSmrg } 402578741aaSmrg# endif 403145b7b3cSmrg 404578741aaSmrg# ifndef USE_PAM /* PAM authentication happened in GreetUser already */ 405578741aaSmrg# ifdef linux 406145b7b3cSmrg if (!strcmp(p->pw_passwd, "!") || !strcmp(p->pw_passwd, "*")) { 407145b7b3cSmrg Debug ("The account is locked, no login allowed.\n"); 408145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 409145b7b3cSmrg return 0; 410145b7b3cSmrg } 411578741aaSmrg# endif 412145b7b3cSmrg user_pass = p->pw_passwd; 413578741aaSmrg# ifdef KERBEROS 414145b7b3cSmrg if(strcmp(greet->name, "root") != 0){ 415145b7b3cSmrg char name[ANAME_SZ]; 416145b7b3cSmrg char realm[REALM_SZ]; 417145b7b3cSmrg char *q; 418145b7b3cSmrg int ret; 419578741aaSmrg 420145b7b3cSmrg if(krb_get_lrealm(realm, 1)){ 421145b7b3cSmrg Debug ("Can't get Kerberos realm.\n"); 422145b7b3cSmrg } else { 423145b7b3cSmrg 424578741aaSmrg snprintf(krbtkfile, sizeof(krbktfile), "%s.%s", 425578741aaSmrg TKT_ROOT, d->name); 426145b7b3cSmrg krb_set_tkt_string(krbtkfile); 427145b7b3cSmrg unlink(krbtkfile); 428578741aaSmrg 429578741aaSmrg ret = krb_verify_user(greet->name, "", realm, 430145b7b3cSmrg greet->password, 1, "rcmd"); 431578741aaSmrg 432145b7b3cSmrg if(ret == KSUCCESS){ 433145b7b3cSmrg chown(krbtkfile, p->pw_uid, p->pw_gid); 434145b7b3cSmrg Debug("kerberos verify succeeded\n"); 435145b7b3cSmrg if (k_hasafs()) { 436145b7b3cSmrg if (k_setpag() == -1) 437145b7b3cSmrg LogError ("setpag() failed for %s\n", 438145b7b3cSmrg greet->name); 439578741aaSmrg 440145b7b3cSmrg if((ret = k_afsklog(NULL, NULL)) != KSUCCESS) 441578741aaSmrg LogError("Warning %s\n", 442145b7b3cSmrg krb_get_err_text(ret)); 443145b7b3cSmrg } 444145b7b3cSmrg goto done; 445145b7b3cSmrg } else if(ret != KDC_PR_UNKNOWN && ret != SKDC_CANT){ 446145b7b3cSmrg /* failure */ 447145b7b3cSmrg Debug("kerberos verify failure %d\n", ret); 448145b7b3cSmrg krbtkfile[0] = '\0'; 449145b7b3cSmrg } 450145b7b3cSmrg } 451145b7b3cSmrg } 452578741aaSmrg# endif 453629baa8cSmrg# ifdef HAVE_GETSPNAM 454145b7b3cSmrg errno = 0; 455145b7b3cSmrg sp = getspnam(greet->name); 456145b7b3cSmrg if (sp == NULL) { 457578741aaSmrg Debug ("getspnam() failed: %s\n", _SysErrorMsg (errno)); 458145b7b3cSmrg } else { 459145b7b3cSmrg user_pass = sp->sp_pwdp; 460145b7b3cSmrg } 461578741aaSmrg# ifndef QNX4 462145b7b3cSmrg endspent(); 463578741aaSmrg# endif /* QNX4 doesn't need endspent() to end shadow passwd ops */ 464629baa8cSmrg# endif /* HAVE_GETSPNAM */ 465578741aaSmrg# if defined(ultrix) || defined(__ultrix__) 466145b7b3cSmrg if (authenticate_user(p, greet->password, NULL) < 0) 467578741aaSmrg# else 468145b7b3cSmrg if (strcmp (crypt (greet->password, user_pass), user_pass)) 469578741aaSmrg# endif 470145b7b3cSmrg { 471145b7b3cSmrg if(!greet->allow_null_passwd || strlen(p->pw_passwd) > 0) { 472145b7b3cSmrg Debug ("password verify failed\n"); 473145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 474145b7b3cSmrg return 0; 475145b7b3cSmrg } /* else: null passwd okay */ 476145b7b3cSmrg } 477578741aaSmrg# ifdef KERBEROS 478145b7b3cSmrgdone: 479578741aaSmrg# endif 480145b7b3cSmrg /* 481145b7b3cSmrg * Only accept root logins if allowRootLogin resource is set 482145b7b3cSmrg */ 483145b7b3cSmrg if ((p->pw_uid == 0) && !greet->allow_root_login) { 484145b7b3cSmrg Debug("root logins not allowed\n"); 485145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 486145b7b3cSmrg return 0; 487145b7b3cSmrg } 488629baa8cSmrg# ifdef __OpenBSD__ 489145b7b3cSmrg /* 490578741aaSmrg * Shell must be in /etc/shells 491145b7b3cSmrg */ 492145b7b3cSmrg for (;;) { 493145b7b3cSmrg s = getusershell(); 494145b7b3cSmrg if (s == NULL) { 495578741aaSmrg /* did not found the shell in /etc/shells 496145b7b3cSmrg -> failure */ 497145b7b3cSmrg Debug("shell not in /etc/shells\n"); 498145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 499145b7b3cSmrg endusershell(); 500145b7b3cSmrg return 0; 501145b7b3cSmrg } 502145b7b3cSmrg if (strcmp(s, p->pw_shell) == 0) { 503145b7b3cSmrg /* found the shell in /etc/shells */ 504145b7b3cSmrg endusershell(); 505145b7b3cSmrg break; 506145b7b3cSmrg } 507578741aaSmrg } 508145b7b3cSmrg /* 509145b7b3cSmrg * Test for expired password 510145b7b3cSmrg */ 511145b7b3cSmrg if (p->pw_change || p->pw_expire) 512145b7b3cSmrg (void)gettimeofday(&tp, (struct timezone *)NULL); 513145b7b3cSmrg if (p->pw_change) { 514145b7b3cSmrg if (tp.tv_sec >= p->pw_change) { 515145b7b3cSmrg Debug("Password has expired.\n"); 516145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 517145b7b3cSmrg return 0; 518145b7b3cSmrg } 519145b7b3cSmrg } 520145b7b3cSmrg if (p->pw_expire) { 521145b7b3cSmrg if (tp.tv_sec >= p->pw_expire) { 522145b7b3cSmrg Debug("account has expired.\n"); 523145b7b3cSmrg bzero(greet->password, strlen(greet->password)); 524145b7b3cSmrg return 0; 525578741aaSmrg } 526145b7b3cSmrg } 527578741aaSmrg# endif /* __OpenBSD__ */ 528145b7b3cSmrg bzero(user_pass, strlen(user_pass)); /* in case shadow password */ 529145b7b3cSmrg 530578741aaSmrg# endif /* USE_PAM */ 531145b7b3cSmrg#endif /* USE_BSDAUTH */ 532145b7b3cSmrg 533145b7b3cSmrg Debug ("verify succeeded\n"); 534145b7b3cSmrg /* The password is passed to StartClient() for use by user-based 535145b7b3cSmrg authorization schemes. It is zeroed there. */ 536145b7b3cSmrg verify->uid = p->pw_uid; 537145b7b3cSmrg verify->gid = p->pw_gid; 538145b7b3cSmrg home = p->pw_dir; 539145b7b3cSmrg shell = p->pw_shell; 540145b7b3cSmrg argv = NULL; 541145b7b3cSmrg if (d->session) 542145b7b3cSmrg argv = parseArgs (argv, d->session); 543145b7b3cSmrg if (greet->string) 544145b7b3cSmrg argv = parseArgs (argv, greet->string); 545145b7b3cSmrg if (!argv) 546145b7b3cSmrg argv = parseArgs (argv, "xsession"); 547145b7b3cSmrg verify->argv = argv; 548145b7b3cSmrg verify->userEnviron = userEnv (d, p->pw_uid == 0, 549145b7b3cSmrg greet->name, home, shell); 550145b7b3cSmrg Debug ("user environment:\n"); 551145b7b3cSmrg printEnv (verify->userEnviron); 552145b7b3cSmrg verify->systemEnviron = systemEnv (d, greet->name, home); 553145b7b3cSmrg Debug ("system environment:\n"); 554145b7b3cSmrg printEnv (verify->systemEnviron); 555145b7b3cSmrg Debug ("end of environments\n"); 556145b7b3cSmrg return 1; 557145b7b3cSmrg} 558