/* * 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 */ /* $XConsortium: vgauth.c /main/4 1996/10/04 16:56:33 drk $ */ /* * * (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. * */ /************************************<+>************************************* **************************************************************************** ** ** File: vgauth.h ** ** Project: HP Visual User Environment (DT) ** ** Description: Dtgreet user authentication routines ** ** These routines validate the user; checking name, password, ** number of users on the system, password aging, etc. ** ** ** (c) Copyright 1987, 1988, 1989 by Hewlett-Packard Company ** ** ** Conditional compiles for HPUX: ** ** OSMAJORVERSION < 8 ** HP-UX 7.0/7.03 restricted license counting algorithms ** are used. Otherwise HP-UX 8.0 and beyond is used ** ** AUDIT HP C2 security enhancements; checks for existence of ** SECUREPASSWD file and authenticates user against ** password contained in that file. Also performs ** self-auditing of login actions. Incompatible with ** #ifdef SecureWare ** ** BLS HP BLS B1 simple authentication. ** ** __AFS AFS 3 authentication mechanism ** __KERBEROS Kerberos authentication mechanism ** __PASSWD_ETC Domain/OS Registry from HP-UX authentication mechanism ** ** Platform identification: ** ** __hpux HP-UX OS only ** sun SUN OS only ** SVR4 SUN OS et al. ** _AIX AIX only ** **************************************************************************** ************************************<+>*************************************/ /*************************************************************************** * * Includes & Defines * ***************************************************************************/ #include #include #include #include /* necessary for bzero */ #ifdef SVR4 #include #ifdef sun #include #endif #endif #include "vg.h" #include "vgmsg.h" /* * Define as generic those without platform specific code. */ #if !(defined(__hpux) || defined(_AIX) || defined(sun)) #define generic #endif #ifdef __hpux /*************************************************************************** * * Start authentication routines (HPUX) * ***************************************************************************/ #include /* for MAXUID macro */ #include #include #include #include #include #ifdef AUDIT # include # include # include # define SECUREPASS "/.secure/etc/passwd" #endif #ifdef BLS # include # include #endif #ifdef __AFS #include #endif /* __AFS */ #ifdef __KERBEROS # include # define KRBLIFE 255 /* max lifetime */ #endif /* __KERBEROS */ #ifdef __PASSWD_ETC # include "rgy_base.h" #endif #define how_to_count ut_exit.e_exit #ifdef __hp9000s300 int num_users[] = { 2, 32767 }; # define MIN_VERSION 'A' # define UNLIMITED 'B' #else int num_users[] = { 2, 16, 32, 64 , 8 }; # define MIN_VERSION 'A' # define UNLIMITED 'U' #endif /* Maximum number of users allowed with restricted license */ #if OSMAJORVERSION < 8 # define MAX_STRICT_USERS 2 #else # define MAX_STRICT_USERS 8 #endif #define NUM_VERSIONS (sizeof(num_users)/sizeof(num_users[0])) - 1 /*************************************************************************** * * External declarations (HPUX) * ***************************************************************************/ extern Widget focusWidget; /* login or password text field */ extern long groups[NGROUPS]; #ifdef __PASSWD_ETC extern boolean rgy_$using_local_registry(); extern struct passwd * getpwnam_full(); extern boolean is_acct_expired(); extern boolean is_passwd_expired(); extern boolean is_passwd_invalid(); extern boolean rgy_$is_des(); #endif /*************************************************************************** * * Procedure declarations (HPUX) * ***************************************************************************/ static void Audit( struct passwd *p, char *msg, int errnum) ; static int CheckPassword( char *name, char *passwd, struct passwd **ppwd ); static int CountUsers( int added_users) ; static int CountUsersStrict( char *new_user) ; static int PasswordAged( struct passwd *pw) ; static void WriteBtmp( char *name) ; /*************************************************************************** * * Global variables (HPUX) * ***************************************************************************/ #ifdef AUDIT struct s_passwd *s_pwd; struct stat s_pfile; int secure; /* flag to denote existence of secure passwd file */ Boolean selfAuditOn; #endif #ifdef BLS struct pr_passwd *b1_pwd; #endif #ifdef __PASSWD_ETC rgy_$acct_admin_t admin_part; rgy_$policy_t policy; rgy_$acct_user_t user_part; #endif /*************************************************************************** * * Audit (HPUX) * * Construct self audit record for event and write to the audit trail. * This routine assumes that the effective uid is currently 0. If auditing * is not defined, this routine does nothing. ***************************************************************************/ static void Audit( struct passwd *p, char *msg, int errnum ) { #ifdef AUDIT char *txtptr; struct self_audit_rec audrec; int status; #endif /* * make sure program is back to super-user... */ setresuid(0,0,0); #ifdef AUDIT if (selfAuditOn) { txtptr = (char *)audrec.aud_body.text; sprintf(txtptr, "User= %s uid=%ld audid=%ld%s", p->pw_name, (long)p->pw_uid, (long)p->pw_audid, msg); audrec.aud_head.ah_pid = getpid(); audrec.aud_head.ah_error = errnum; audrec.aud_head.ah_event = EN_LOGINS; audrec.aud_head.ah_len = strlen (txtptr); status = audwrite(&audrec); if ( status != 0 ) { switch (errno) { case EPERM: LogError(ReadCatalog( MC_LOG_SET,MC_LOG_NOT_SUSER,MC_DEF_LOG_NOT_SUSER)); break; case EINVAL: LogError(ReadCatalog( MC_LOG_SET,MC_LOG_INV_EVENT,MC_DEF_LOG_INV_EVENT)); break; default: LogError(ReadCatalog( MC_LOG_SET,MC_LOG_ERR_ERRNO,MC_DEF_LOG_ERR_ERRNO), errno); break; } } } #else return; #endif } /*************************************************************************** * * CountUsers (HPUX only) * * see if new user has exceeded the maximum. ***************************************************************************/ #define NCOUNT 16 static int CountUsers( int added_users ) { int count[NCOUNT], nusers, i; struct utmp *entry; for (i=0; iut_type == USER_PROCESS) { i = entry->how_to_count; if (i < 0 || i >= NCOUNT) i = 1; /* if out of range, then count */ /* as ordinary user */ count[i]++; } } endutent(); /* * KEY: * [0] does not count at all * [1] counts as real user * [2] logins via a pty which have not gone trough login. These * collectively count as 1 user IF count[3] is 0, otherwise, * they are not counted. Starting with HP-UX 8.0 they are * no longer counted at all. * [3] logins via a pty which have been logged through login (i.e. * rlogin and telnet). these count as 1 "real" user per * unique user name. * [4-15] may be used for groups of users which collectively * count as 1 */ nusers = count[1]; #if OSMAJORVERSION < 8 for (i=2; i 0) nusers++; return(nusers); } /*************************************************************************** * * CountUsersStrict (HPUX only) * * see if new user has exceeded the maximum. ***************************************************************************/ static int CountUsersStrict( char *new_user ) { char pty_users[MAX_STRICT_USERS][8]; int count[NCOUNT], nusers, i, cnt, pty_off = -1, uname_off; struct utmp *entry; /* * Initialize count array... */ for (i = 0; i < NCOUNT; i++) count[i] = 0; /* * Add in the new user (we know it's not a pty)... */ count[1]++; while ( (entry = getutent()) != NULL ) { if (entry->ut_type == USER_PROCESS) { i = entry->how_to_count; /* if out of range, then count as ordinary user logged in via a tty */ if (i == 1 || (i < 0 || i >= NCOUNT)) count[1]++; /* See if it is a pty login granted by login program */ else if (i == 3) { count[3]++; /* See if user is already logged in via login pty */ uname_off = -1; for (cnt = 0; cnt <= pty_off; cnt++) if (strncmp(pty_users[cnt], entry->ut_user, 8) == 0) uname_off = cnt; if (uname_off == -1) { /* user is not logged in via pty yet */ if (pty_off >= MAX_STRICT_USERS) /* cannot add any more users */ return(MAX_STRICT_USERS + 1); /* add the user name to the array of pty users */ else strncpy(pty_users[++pty_off], entry->ut_user, 8); } } /* end if (i == 3) */ else count[i]++; } /* end if entry->ut_type == USER_PROCESS */ } /* end while (entry = getutent()) */ endutent(); /* * KEY: * [0] does not count at all * [1] counts as "real" user * [2] logins via a pty which have not gone trough login. These * collectively count as 1 user IF count[3] is 0, otherwise, * they are not counted. Starting with HP-UX 8.0 they are * no longer counted at all. * [3] logins via a pty which have been logged through login (i.e. * rlogin and telnet). these count as 1 "real" user per * unique user name. * [4-15] may be used for groups of users which collectively count * as 1 */ nusers = pty_off + 1 + count[1]; /* Current number of users is sum of users logged in via tty + the number of unique users logged in via pty which have gone through login */ #if OSMAJORVERSION < 8 if ((count[3] == 0) && (count[2] != 0)) nusers++; /* Add 1 user for all pty logins IF none of pty logins have been granted by the login program */ #else /* * Don't count any hpterm logins (exit status of 2). We already * counted all pty logins granted by the login program. */ #endif for (i = 4; i < NCOUNT; i++) if (count[i] > 0) nusers++; return(nusers); } /*************************************************************************** * * PasswordAged (HPUX) * * see if password has aged ***************************************************************************/ #define SECONDS_IN_WEEK 604800L static int PasswordAged( struct passwd *pw ) { long change_week; /* week password was changed (1/1/70 = Week 0) */ long last_week; /* week after which password must change */ long first_week; /* week before which password can't change */ long this_week; /* this week derived from time() */ char *passwdAge; /* password aging time */ #ifdef __PASSWD_ETC boolean lrgy; #endif passwdAge = pw->pw_age; #ifdef AUDIT if (secure) passwdAge = s_pwd->pw_age; #endif #ifdef __PASSWD_ETC /* Account validity checks: If we were able to connect to the network * registry, then we've acquired account and policy data and can perform * account/password checking */ lrgy = rgy_$using_local_registry(); if ( !lrgy ) { /* Check for password expiration or invalidity */ if ( rgy_$is_passwd_expired(&user_part, &policy ) != 0 ) { return TRUE; } } return FALSE; #else if (*passwdAge == NULL) return(0); first_week = last_week = change_week = (long) a64l(passwdAge); last_week &= 0x3f; /* first six bits */ first_week = (first_week >> 6) & 0x3f; /* next six bits */ change_week >>= 12; /* everything else */ this_week = (long) time((long *) 0) / SECONDS_IN_WEEK; /* ** Password aging conditions: ** * if the last week is less than the first week (e.g., the aging ** field looks like "./"), only the superuser can change the ** password. We don't request a new password. ** * if the week the password was last changed is after this week, ** we have a problem, and request a new password. ** * if this week is after the specified aging time, we request ** a new password. */ if (last_week < first_week) return(0); if (change_week <= this_week && this_week <= (change_week + last_week)) return(0); return(1); #endif } /*************************************************************************** * * CheckPassword (HPUX only) * * Check validity of user password. One of several authentication schemes * can be used, including Kerberos, AFS 3, HP BLS and traditional * /etc/passwd. These are selectable via a resource in Dtlogin. * * Domain registry authentication (PasswdEtc) can also be compiled in as * the only authentication scheme used. * ***************************************************************************/ static int CheckPassword( char *name, char *passwd, struct passwd **ppwd ) { char *crypt(); struct passwd *p; char *reason; #ifdef __KERBEROS char realm[REALM_SZ]; int kerno; #endif /* __KERBEROS */ #ifdef AUDIT /* * validate that user has an entry in the shadow password file on an * HP-UX C2 trusted system. Keep info in a global structure. */ if (secure) { setspwent(); s_pwd = getspwnam(name); endspwent(); if (s_pwd == NULL) return(FALSE); } #endif /* * look up user's regular account information... */ #ifdef __PASSWD_ETC /* * look up entry from registry... * * need getpwnam_full to get policy data for passwd expiration * or invalidity... */ p = getpwnam_full(name, &user_part, &admin_part, &policy); #else p = getpwnam(name); #endif endpwent(); *ppwd = p; if ( p == NULL || strlen(name) == 0 ) return(FALSE); #ifdef __AFS /* * AFS password authentication... */ if ( IsVerifyName(VN_AFS) ) { if (focusWidget == login_text) return(FALSE); if ( ka_UserAuthenticateGeneral( KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG, p->pw_name, /* kerberos name */ (char *)0, /* instance */ (char *)0, /* realm */ passwd, /* password */ 0, /* default lifetime */ 0, /* spare 1 */ 0, /* spare 2 */ &reason) == 0 ) { /* error string */ if (strcmp(p->pw_passwd, "*") == 0) return(FALSE); else return(TRUE); } else { LogError(ReadCatalog( MC_LOG_SET,MC_LOG_AFS_FAILATH,MC_DEF_LOG_AFS_FAILATH),reason); } } #endif /* __AFS */ #ifdef __KERBEROS /* * Kerberos password authentication... */ if ( IsVerifyName(VN_KRB) ) { if (focusWidget == login_text) return(FALSE); (void)krb_get_lrealm(realm, 1); setresuid(p->pw_uid, p->pw_uid, -1); kerno = krb_get_pw_in_tkt(p->pw_name, "", realm, "krbtgt", realm, KRBLIFE, passwd); setresuid(0, 0, -1); if (kerno == KSUCCESS) if (strcmp(p->pw_passwd, "*") == 0) return(FALSE); else return(TRUE); } #endif /* __KERBEROS */ /* * traditional password verification... */ if (strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd) == 0) return(TRUE); #ifdef __PASSWD_ETC /* * If regular passwd check fails, try old-style SR */ if (rgy_$is_des(passwd, strlen(passwd), p->pw_passwd) == TRUE) return (TRUE); #endif /* * all password checks failed... */ return (FALSE); } /*************************************************************************** * * Verify (HPUX) * * verify the user * * return codes indicate authentication results. ***************************************************************************/ #define MAXATTEMPTS 3 struct passwd nouser = {"", "nope"}; /* invalid user password struct */ int Verify( char *name, char *passwd ) { static int login_attempts = 0; /* # failed authentications */ struct passwd *p; /* password structure */ struct utsname utsnam; int n; #ifdef AUDIT /* * turn on self auditing... */ if (audswitch(AUD_SUSPEND) == -1) selfAuditOn = FALSE; else selfAuditOn = TRUE; /* * set the secure flag if SECUREPASS exists. If so, we * are using it for authentication instead of /etc/passwd... */ secure = (stat(SECUREPASS, &s_pfile) < 0) ? 0:1; /* * set the audit process flag unconditionally on since we want * to log all logins regardless of whether the user's audit * flag is set... */ if (secure) setaudproc(AUD_PROC); #endif /* AUDIT */ /* * validate password... */ if ( CheckPassword(name, passwd, &p) == FALSE) { if ( focusWidget == passwd_text ) { WriteBtmp(name); if ((++login_attempts % MAXATTEMPTS) == 0 ) { if (p->pw_name == NULL ) p = &nouser; Audit(p, " Failed login (bailout)", 1); } } return(VF_INVALID); } /* * check restricted license... * * Note: This only applies to local displays. Foreign displays * (i.e. X-terminals) apparently do not count. */ /* Get the version info via uname. If it doesn't look right, * assume the smallest user configuration */ if (getenv(LOCATION) != NULL) { if (uname(&utsnam) < 0) utsnam.version[0] = MIN_VERSION; /* * Mappings: * 834 -> 834 * 844 -> 844 * 836 -> 635 * 846 -> 645 * 843 -> 642 * 853 -> 652 */ if ((!strncmp(utsnam.machine, "9000/834", UTSLEN)) || (!strncmp(utsnam.machine, "9000/844", UTSLEN)) || (!strncmp(utsnam.machine, "9000/836", UTSLEN)) || (!strncmp(utsnam.machine, "9000/846", UTSLEN)) || (!strncmp(utsnam.machine, "9000/843", UTSLEN)) || (!strncmp(utsnam.machine, "9000/853", UTSLEN))) { /* strict_count = 1;*/ if (CountUsersStrict(name) > MAX_STRICT_USERS) { Audit(p, " attempted to login - too many users on the system", 20); return(VF_MAX_USERS); } } else { if (utsnam.version[0] != UNLIMITED) { if ((utsnam.version[0]-'A' < 0) || (utsnam.version[0]-'A' > NUM_VERSIONS)) utsnam.version[0] = MIN_VERSION; n = (int) utsnam.version[0] - 'A'; if (CountUsers(1) > num_users[n]) { Audit(p, " attempted to login - too many users on the system", 20); return(VF_MAX_USERS); } } } } #ifdef __PASSWD_ETC /* * Check for account validity. Unfortunately, we have no graphical * dialog for this at this time so the best we can do is log an * error message and hope the system administrator sees it. */ if ( !rgy_$using_local_registry() ) { if (rgy_$is_acct_expired(&admin_part) != 0 ) { LogError(ReadCatalog(MC_LOG_SET,MC_LOG_ACC_EXP,MC_DEF_LOG_ACC_EXP), name); return(VF_INVALID); } } #endif /* * check password aging... */ if ( PasswordAged(p) ) return(VF_PASSWD_AGED); /* * verify home directory exists... */ if(chdir(p->pw_dir) < 0) { Audit(p, " attempted to login - no home directory", 1); return(VF_HOME); } #ifdef AUDIT /* * check audit flag and id... */ setresuid(0,0,0); if (secure && (p->pw_audflg > 1 || p->pw_audflg < 0)) { Audit(p, " attempted to login - bad audit flag", 1); return(VF_BAD_AFLAG); } if (secure && (setaudid(p->pw_audid) == -1 )) { Audit(p, " attempted to login - bad audit id", 1); return(VF_BAD_AID); } #endif /* AUDIT */ /* * validate uid and gid... */ if ((p->pw_gid < 0) || (p->pw_gid > MAXUID) || (setgid(p->pw_gid) == -1)) { Audit(p, " attempted to login - bad group id", 1); return(VF_BAD_GID); } #ifdef __AFS /* * ka_UserAuthenticateGeneral() sets the group access of this process * to the proper PAG. Pick up these values and pass them back to * Dtlogin to be put into the user's environment... */ if ( IsVerifyName(VN_AFS) ) { groups[0] = groups[1] = 0; getgroups(NGROUPS, groups); } #endif /* __AFS */ if ((p->pw_uid < 0) || (p->pw_uid > MAXUID) || (setresuid(p->pw_uid, p->pw_uid, 0) == -1)) { Audit(p, " attempted to login - bad user id", 1); return(VF_BAD_UID); } /* * verify ok... */ Audit(p, " Successful login", 0); return(VF_OK); } /*************************************************************************** * * WriteBtmp (HPUX) * * log bad login attempts * ***************************************************************************/ static void WriteBtmp( char *name ) { int fd; struct utmp utmp, *u; Boolean found=FALSE; bzero(&utmp, sizeof(struct utmp)); utmp.ut_pid = getppid(); while ((u = getutent()) != NULL) { if ( (u->ut_type == INIT_PROCESS || u->ut_type == LOGIN_PROCESS || u->ut_type == USER_PROCESS) && u->ut_pid == utmp.ut_pid ) { found = TRUE; break; } } /* * if no utmp entry, this may be an X-terminal. Construct a utmp * entry for it... */ if ( ! found ) { strncpy(utmp.ut_id, "??", sizeof(utmp.ut_id)); strncpy(utmp.ut_line, dpyinfo.name, sizeof(utmp.ut_line)); utmp.ut_type = LOGIN_PROCESS; #ifndef SVR4 strncpy(utmp.ut_host, dpyinfo.name, sizeof(utmp.ut_host)); #endif u = &utmp; } /* * If btmp exists, then record the bad attempt */ if ( (fd = open(BTMP_FILE,O_WRONLY|O_APPEND)) >= 0) { strncpy(u->ut_user, name, sizeof(u->ut_user)); (void) time(&u->ut_time); write(fd, (char *)u, sizeof(utmp)); (void) close(fd); } endutent(); /* Close utmp file */ } /*************************************************************************** * * End authentication routines (HPUX) * ***************************************************************************/ #endif /* __hpux */ /*************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** ***************************************************************************/ #ifdef sun /*************************************************************************** * * Start authentication routines (SUN) * ***************************************************************************/ /*************************************************************************** * * External declarations (SUN) * ***************************************************************************/ /*************************************************************************** * * Procedure declarations (SUN) * ***************************************************************************/ static void Audit( struct passwd *p, char *msg, int errnum) ; static int PasswordAged( struct passwd *pw) ; static void WriteBtmp( char *name) ; /*************************************************************************** * * Global variables (SUN) * ***************************************************************************/ /*************************************************************************** * * Audit (SUN) * ***************************************************************************/ static void Audit( struct passwd *p, char *msg, int errnum ) { /* * make sure program is back to super-user... */ seteuid(0); return; } /*************************************************************************** * * WriteBtmp (SUN) * * log bad login attempts * ***************************************************************************/ static void WriteBtmp( char *name ) { return; } /*************************************************************************** * * PasswordAged (SUN) * * see if password has aged ***************************************************************************/ #define SECONDS_IN_WEEK 604800L static int PasswordAged( struct passwd *pw ) { long change_week; /* week password was changed (1/1/70 = Week 0) */ long last_week; /* week after which password must change */ long first_week; /* week before which password can't change */ long this_week; /* this week derived from time() */ char *file; /* help file name */ char *command; /* the /bin/passwd command string */ if (*pw->pw_age == NULL) return(0); first_week = last_week = change_week = (long) a64l(pw->pw_age); last_week &= 0x3f; /* first six bits */ first_week = (first_week >> 6) & 0x3f; /* next six bits */ change_week >>= 12; /* everything else */ this_week = (long) time((long *) 0) / SECONDS_IN_WEEK; /* ** Password aging conditions: ** * if the last week is less than the first week (e.g., the aging ** field looks like "./"), only the superuser can change the ** password. We don't request a new password. ** * if the week the password was last changed is after this week, ** we have a problem, and request a new password. ** * if this week is after the specified aging time, we request ** a new password. */ if (last_week < first_week) return(0); if (change_week <= this_week && this_week <= (change_week + last_week)) return(0); return(1); } /*************************************************************************** * * Verify (SUN) * * verify the user * * return codes indicate authentication results. ***************************************************************************/ #define MAXATTEMPTS 3 extern Widget focusWidget; /* login or password text field */ struct passwd nouser = {"", "nope"}; /* invalid user password struct */ int Verify( char *name, char *passwd ) { static int login_attempts = 0; /* # failed authentications */ struct passwd *p; /* password structure */ struct spwd *sp; /* shadow info */ char *crypt(); int n; p = getpwnam(name); sp = getspnam(name); if (!p || strlen(name) == 0 || strcmp (crypt (passwd, sp->sp_pwdp), sp->sp_pwdp)) { if ( focusWidget == passwd_text ) { WriteBtmp(name); if ((++login_attempts % MAXATTEMPTS) == 0 ) { if (p->pw_name == NULL ) p = &nouser; Audit(p, " Failed login (bailout)", 1); } } return(VF_INVALID); } /* * check password aging... */ if ( PasswordAged(p) ) return(VF_PASSWD_AGED); /* * verify home directory exists... */ if(chdir(p->pw_dir) < 0) { Audit(p, " attempted to login - no home directory", 1); return(VF_HOME); } /* * validate uid and gid... */ if ((p->pw_gid < 0) || (setgid(p->pw_gid) == -1)) { Audit(p, " attempted to login - bad group id", 1); return(VF_BAD_GID); } if ((p->pw_uid < 0) || (seteuid(p->pw_uid) == -1)) { Audit(p, " attempted to login - bad user id", 1); return(VF_BAD_UID); } /* * verify ok... */ Audit(p, " Successful login", 0); return(VF_OK); } /*************************************************************************** * * End authentication routines (SUN) * ***************************************************************************/ #endif /* sun */ /*************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** ***************************************************************************/ #ifdef _AIX /*************************************************************************** * * Start authentication routines (AIX) * ***************************************************************************/ #include #include #include #include #include /*************************************************************************** * * External declarations (AIX) * ***************************************************************************/ /*************************************************************************** * * Procedure declarations (AIX) * ***************************************************************************/ static void Audit( struct passwd *p, char *msg, int errnum) ; static int PasswordAged(char *name, struct passwd *pw) ; static void WriteBtmp( char *name) ; /*************************************************************************** * * Global variables (AIX) * ***************************************************************************/ /*************************************************************************** * * Audit (AIX) * ***************************************************************************/ static void Audit( struct passwd *p, char *msg, int errnum ) { /* * make sure program is back to super-user... */ seteuid(0); return; } /*************************************************************************** * * WriteBtmp (AIX) * * log bad login attempts * ***************************************************************************/ static void WriteBtmp( char *name ) { return; } /*************************************************************************** * * PasswordAged (AIX) * * see if password has aged ***************************************************************************/ #define SECONDS_IN_WEEK 604800L static int PasswordAged(char *name, struct passwd *pw ) { struct userpw *pupw; /* authentication information from getuserpw() */ struct userpw upw; /* working authentication information */ int err; /* return code from getconfattr() */ ulong maxage; /* maximun age from getconfattr() */ ulong now; /* time now */ /* * Determine user password aging criteria. Note that only * the 'lastupdate' and 'flags' fields are set by this operation. */ setpwdb(S_READ); if ((pupw = getuserpw(name)) != NULL) { upw.upw_lastupdate = pupw->upw_lastupdate; upw.upw_flags = pupw->upw_flags; } else { upw.upw_lastupdate = 0; upw.upw_flags = 0; } endpwdb(); /* * Consider password as having not expired if nocheck set. */ if (upw.upw_flags & PW_NOCHECK) return(FALSE); /* * Get system password aging criteria. */ err = getconfattr (SC_SYS_PASSWD, SC_MAXAGE, (void *)&maxage, SEC_INT); if (!err && maxage) { /* * Change from weeks to seconds */ maxage = maxage * SECONDS_IN_WEEK; now = time ((long *) 0); if ((upw.upw_lastupdate + maxage) >= now) { /* * Password has not expired. */ return(FALSE); } } else { /* * Could not retrieve system password aging info or maxage set to * zero. In either case, consider password has having not expired. */ return(FALSE); } /* * We haven't returned by now, so indicate password has expired. */ return(TRUE); } /*************************************************************************** * * Verify (AIX) * * verify the user * * return codes indicate authentication results. ***************************************************************************/ #define MAXATTEMPTS 3 extern Widget focusWidget; /* login or password text field */ struct passwd nouser = {"", "nope"}; /* invalid user password struct */ int Verify( char *name, char *passwd ) { static int login_attempts = 0; /* # failed authentications */ struct passwd *p; /* password structure */ char *crypt(); int n; p = getpwnam(name); if (!p || strlen(name) == 0 || strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) { if ( focusWidget == passwd_text ) { WriteBtmp(name); if ((++login_attempts % MAXATTEMPTS) == 0 ) { if (p->pw_name == NULL ) p = &nouser; Audit(p, " Failed login (bailout)", 1); } } return(VF_INVALID); } /* * check password aging... */ if ( PasswordAged(name,p) ) return(VF_PASSWD_AGED); /* * verify home directory exists... */ if(chdir(p->pw_dir) < 0) { Audit(p, " attempted to login - no home directory", 1); return(VF_HOME); } /* * validate uid and gid... */ if ((p->pw_gid < 0) || (setgid(p->pw_gid) == -1)) { Audit(p, " attempted to login - bad group id", 1); return(VF_BAD_GID); } if ((p->pw_uid < 0)) { Audit(p, " attempted to login - bad user id", 1); return(VF_BAD_UID); } /* * verify ok... */ Audit(p, " Successful login", 0); return(VF_OK); } /*************************************************************************** * * End authentication routines (AIX) * ***************************************************************************/ #endif /* _AIX */ /*************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** ***************************************************************************/ #ifdef generic /*************************************************************************** * * Start authentication routines (generic) * ***************************************************************************/ /*************************************************************************** * * These are a set of routine to do simple password, home dir, uid, and gid * validation. They can be used as a first pass validation for future * porting efforts. * * When platform specific validation is developed, those routines should be * included in their own section and the use of these routines discontinued. * ***************************************************************************/ /*************************************************************************** * * External declarations (generic) * ***************************************************************************/ /*************************************************************************** * * Procedure declarations (generic) * ***************************************************************************/ static void Audit( struct passwd *p, char *msg, int errnum) ; static int PasswordAged( struct passwd *pw) ; static void WriteBtmp( char *name) ; /*************************************************************************** * * Global variables (generic) * ***************************************************************************/ /*************************************************************************** * * Audit (generic) * ***************************************************************************/ static void Audit( struct passwd *p, char *msg, int errnum ) { /* * make sure program is back to super-user... */ seteuid(0); return; } /*************************************************************************** * * WriteBtmp (generic) * * log bad login attempts * ***************************************************************************/ static void WriteBtmp( char *name ) { return; } /*************************************************************************** * * PasswordAged (Generic) * * see if password has aged ***************************************************************************/ #define SECONDS_IN_WEEK 604800L static int PasswordAged( struct passwd *pw ) { return(FALSE); } /*************************************************************************** * * Verify (generic) * * verify the user * * return codes indicate authentication results. ***************************************************************************/ #define MAXATTEMPTS 3 extern Widget focusWidget; /* login or password text field */ struct passwd nouser = {"", "nope"}; /* invalid user password struct */ int Verify( char *name, char *passwd ) { static int login_attempts = 0; /* # failed authentications */ struct passwd *p; /* password structure */ char *crypt(); int n; p = getpwnam(name); if (!p || strlen(name) == 0 || strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) { if ( focusWidget == passwd_text ) { WriteBtmp(name); if ((++login_attempts % MAXATTEMPTS) == 0 ) { if (p->pw_name == NULL ) p = &nouser; Audit(p, " Failed login (bailout)", 1); } } return(VF_INVALID); } /* * check password aging... */ if ( PasswordAged(p) ) return(VF_PASSWD_AGED); /* * verify home directory exists... */ if(chdir(p->pw_dir) < 0) { Audit(p, " attempted to login - no home directory", 1); return(VF_HOME); } /* * validate uid and gid... */ if ((p->pw_gid < 0) || (setgid(p->pw_gid) == -1)) { Audit(p, " attempted to login - bad group id", 1); return(VF_BAD_GID); } if ((p->pw_uid < 0) || (seteuid(p->pw_uid) == -1)) { Audit(p, " attempted to login - bad user id", 1); return(VF_BAD_UID); } /* * verify ok... */ Audit(p, " Successful login", 0); return(VF_OK); } /*************************************************************************** * * End authentication routines (generic) * ***************************************************************************/ #endif /* generic */ /*************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** *************************************************************************** ***************************************************************************/