2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: vgauth.c /main/4 1996/10/04 16:56:33 drk $ */
25 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
26 * (c) Copyright 1993, 1994 International Business Machines Corp. *
27 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
28 * (c) Copyright 1993, 1994 Novell, Inc. *
30 /************************************<+>*************************************
31 ****************************************************************************
35 ** Project: HP Visual User Environment (DT)
37 ** Description: Dtgreet user authentication routines
39 ** These routines validate the user; checking name, password,
40 ** number of users on the system, password aging, etc.
43 ** (c) Copyright 1987, 1988, 1989 by Hewlett-Packard Company
46 ** Conditional compiles for HPUX:
49 ** HP-UX 7.0/7.03 restricted license counting algorithms
50 ** are used. Otherwise HP-UX 8.0 and beyond is used
52 ** AUDIT HP C2 security enhancements; checks for existence of
53 ** SECUREPASSWD file and authenticates user against
54 ** password contained in that file. Also performs
55 ** self-auditing of login actions. Incompatible with
58 ** BLS HP BLS B1 simple authentication.
60 ** __AFS AFS 3 authentication mechanism
61 ** __KERBEROS Kerberos authentication mechanism
62 ** __PASSWD_ETC Domain/OS Registry from HP-UX authentication mechanism
64 ** Platform identification:
66 ** __hpux HP-UX OS only
67 ** __apollo Domain OS only
68 ** __hp_osf HP OSF/1 OS only
71 ** SVR4 SUN OS and USL
74 ****************************************************************************
75 ************************************<+>*************************************/
78 /***************************************************************************
82 ***************************************************************************/
89 /* necessary for bzero */
91 #include <X11/Xfuncs.h>
101 * Define as generic those without platform specific code.
103 #if !(defined(__hpux) || \
104 defined(__apollo) || \
111 /***************************************************************************
113 * Start authentication routines (HPUX)
115 ***************************************************************************/
117 #include <sys/param.h> /* for MAXUID macro */
118 #include <sys/types.h>
119 #include <sys/utsname.h>
126 # include <sys/audit.h>
127 # include <sys/errno.h>
128 # include <sys/stat.h>
129 # define SECUREPASS "/.secure/etc/passwd"
133 # include <sys/security.h>
138 #include <afs/kautils.h>
143 # define KRBLIFE 255 /* max lifetime */
144 #endif /* __KERBEROS */
147 # include "rgy_base.h"
152 #define how_to_count ut_exit.e_exit
155 int num_users[] = { 2, 32767 };
156 # define MIN_VERSION 'A'
157 # define UNLIMITED 'B'
159 int num_users[] = { 2, 16, 32, 64 , 8 };
160 # define MIN_VERSION 'A'
161 # define UNLIMITED 'U'
164 /* Maximum number of users allowed with restricted license */
165 #if OSMAJORVERSION < 8
166 # define MAX_STRICT_USERS 2
168 # define MAX_STRICT_USERS 8
171 #define NUM_VERSIONS (sizeof(num_users)/sizeof(num_users[0])) - 1
175 /***************************************************************************
177 * External declarations (HPUX)
179 ***************************************************************************/
181 extern Widget focusWidget; /* login or password text field */
183 extern long groups[NGROUPS];
187 extern boolean rgy_$using_local_registry();
188 extern struct passwd * getpwnam_full();
189 extern boolean is_acct_expired();
190 extern boolean is_passwd_expired();
191 extern boolean is_passwd_invalid();
192 extern boolean rgy_$is_des();
197 /***************************************************************************
199 * Procedure declarations (HPUX)
201 ***************************************************************************/
203 static void Audit( struct passwd *p, char *msg, int errnum) ;
204 static int CheckPassword( char *name, char *passwd, struct passwd **ppwd );
205 static int CountUsers( int added_users) ;
206 static int CountUsersStrict( char *new_user) ;
207 static int PasswordAged( register struct passwd *pw) ;
208 static void WriteBtmp( char *name) ;
213 /***************************************************************************
215 * Global variables (HPUX)
217 ***************************************************************************/
220 struct s_passwd *s_pwd;
222 int secure; /* flag to denote existance of secure passwd file */
227 struct pr_passwd *b1_pwd;
231 rgy_$acct_admin_t admin_part;
232 rgy_$policy_t policy;
233 rgy_$acct_user_t user_part;
238 /***************************************************************************
242 * Construct self audit record for event and write to the audit trail.
243 * This routine assumes that the effective uid is currently 0. If auditing
244 * is not defined, this routine does nothing.
245 ***************************************************************************/
248 Audit( struct passwd *p, char *msg, int errnum )
254 struct self_audit_rec audrec;
259 * make sure program is back to super-user...
267 txtptr = (char *)audrec.aud_body.text;
268 sprintf(txtptr, "User= %s uid=%ld audid=%ld%s", p->pw_name,
269 (long)p->pw_uid, (long)p->pw_audid, msg);
270 audrec.aud_head.ah_pid = getpid();
271 audrec.aud_head.ah_error = errnum;
272 audrec.aud_head.ah_event = EN_LOGINS;
273 audrec.aud_head.ah_len = strlen (txtptr);
274 status = audwrite(&audrec);
280 LogError(ReadCatalog(
281 MC_LOG_SET,MC_LOG_NOT_SUSER,MC_DEF_LOG_NOT_SUSER));
285 LogError(ReadCatalog(
286 MC_LOG_SET,MC_LOG_INV_EVENT,MC_DEF_LOG_INV_EVENT));
290 LogError(ReadCatalog(
291 MC_LOG_SET,MC_LOG_ERR_ERRNO,MC_DEF_LOG_ERR_ERRNO),
308 /***************************************************************************
310 * CountUsers (HPUX only)
312 * see if new user has exceeded the maximum.
313 ***************************************************************************/
318 CountUsers( int added_users )
320 int count[NCOUNT], nusers, i;
323 for (i=0; i<NCOUNT; i++)
326 count[added_users]++;
328 while ( (entry = getutent()) != NULL) {
329 if (entry->ut_type == USER_PROCESS) {
330 i = entry->how_to_count;
331 if (i < 0 || i >= NCOUNT)
332 i = 1; /* if out of range, then count */
333 /* as ordinary user */
341 * [0] does not count at all
342 * [1] counts as real user
343 * [2] logins via a pty which have not gone trough login. These
344 * collectively count as 1 user IF count[3] is 0, otherwise,
345 * they are not counted. Starting with HP-UX 8.0 they are
346 * no longer counted at all.
347 * [3] logins via a pty which have been logged through login (i.e.
348 * rlogin and telnet). these count as 1 "real" user per
350 * [4-15] may be used for groups of users which collectively
355 #if OSMAJORVERSION < 8
356 for (i=2; i<NCOUNT; i++)
358 for (i=3; i<NCOUNT; i++)
369 /***************************************************************************
371 * CountUsersStrict (HPUX only)
373 * see if new user has exceeded the maximum.
374 ***************************************************************************/
377 CountUsersStrict( char *new_user )
379 char pty_users[MAX_STRICT_USERS][8];
380 int count[NCOUNT], nusers, i, cnt, pty_off = -1, uname_off;
384 * Initialize count array...
386 for (i = 0; i < NCOUNT; i++)
390 * Add in the new user (we know it's not a pty)...
394 while ( (entry = getutent()) != NULL ) {
395 if (entry->ut_type == USER_PROCESS) {
396 i = entry->how_to_count;
398 /* if out of range, then count as ordinary user logged in
400 if (i == 1 || (i < 0 || i >= NCOUNT))
402 /* See if it is a pty login granted by login program */
405 /* See if user is already logged in via login pty */
407 for (cnt = 0; cnt <= pty_off; cnt++)
408 if (strncmp(pty_users[cnt], entry->ut_user, 8) == 0)
411 if (uname_off == -1) { /* user is not logged in via pty yet */
413 if (pty_off >= MAX_STRICT_USERS) /* cannot add any
415 return(MAX_STRICT_USERS + 1);
416 /* add the user name to the array of pty users */
418 strncpy(pty_users[++pty_off], entry->ut_user, 8);
420 } /* end if (i == 3) */
423 } /* end if entry->ut_type == USER_PROCESS */
424 } /* end while (entry = getutent()) */
429 * [0] does not count at all
430 * [1] counts as "real" user
431 * [2] logins via a pty which have not gone trough login. These
432 * collectively count as 1 user IF count[3] is 0, otherwise,
433 * they are not counted. Starting with HP-UX 8.0 they are
434 * no longer counted at all.
435 * [3] logins via a pty which have been logged through login (i.e.
436 * rlogin and telnet). these count as 1 "real" user per
438 * [4-15] may be used for groups of users which collectively count
442 nusers = pty_off + 1 + count[1]; /* Current number of users is sum of
443 users logged in via tty + the
444 number of unique users logged in
445 via pty which have gone through
448 #if OSMAJORVERSION < 8
449 if ((count[3] == 0) && (count[2] != 0))
450 nusers++; /* Add 1 user for all pty logins IF
451 none of pty logins have been
452 granted by the login program */
455 * Don't count any hpterm logins (exit status of 2). We already
456 * counted all pty logins granted by the login program.
460 for (i = 4; i < NCOUNT; i++)
469 /***************************************************************************
471 * PasswordAged (HPUX)
473 * see if password has aged
474 ***************************************************************************/
475 #define SECONDS_IN_WEEK 604800L
478 PasswordAged( register struct passwd *pw )
480 long change_week; /* week password was changed (1/1/70 = Week 0) */
481 long last_week; /* week after which password must change */
482 long first_week; /* week before which password can't change */
483 long this_week; /* this week derived from time() */
485 char *passwdAge; /* password aging time */
492 passwdAge = pw->pw_age;
496 passwdAge = s_pwd->pw_age;
501 /* Account validity checks: If we were able to connect to the network
502 * registry, then we've acquired account and policy data and can perform
503 * account/password checking
506 lrgy = rgy_$using_local_registry();
509 /* Check for password expiration or invalidity */
510 if ( rgy_$is_passwd_expired(&user_part, &policy ) != 0 ) {
518 if (*passwdAge == NULL)
521 first_week = last_week = change_week = (long) a64l(passwdAge);
522 last_week &= 0x3f; /* first six bits */
523 first_week = (first_week >> 6) & 0x3f; /* next six bits */
524 change_week >>= 12; /* everything else */
526 this_week = (long) time((long *) 0) / SECONDS_IN_WEEK;
529 ** Password aging conditions:
530 ** * if the last week is less than the first week (e.g., the aging
531 ** field looks like "./"), only the superuser can change the
532 ** password. We don't request a new password.
533 ** * if the week the password was last changed is after this week,
534 ** we have a problem, and request a new password.
535 ** * if this week is after the specified aging time, we request
538 if (last_week < first_week)
541 if (change_week <= this_week && this_week <= (change_week + last_week))
551 /***************************************************************************
553 * CheckPassword (HPUX only)
555 * Check validity of user password. One of several authentication schemes
556 * can be used, including Kerberos, AFS 3, HP BLS and traditional
557 * /etc/passwd. These are selectable via a resource in Dtlogin.
559 * Domain registry authentication (PasswdEtc) can also be compiled in as
560 * the only authentication scheme used.
562 ***************************************************************************/
565 CheckPassword( char *name, char *passwd, struct passwd **ppwd )
574 char realm[REALM_SZ];
576 #endif /* __KERBEROS */
581 * validate that user has an entry in the shadow password file on an
582 * HP-UX C2 trusted system. Keep info in a global structure.
586 s_pwd = getspwnam(name);
596 * look up user's regular account information...
601 * look up entry from registry...
603 * need getpwnam_full to get policy data for passwd expiration
606 p = getpwnam_full(name, &user_part, &admin_part, &policy);
614 if ( p == NULL || strlen(name) == 0 )
621 * AFS password authentication...
624 if ( IsVerifyName(VN_AFS) ) {
626 if (focusWidget == login_text)
629 if ( ka_UserAuthenticateGeneral(
630 KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG,
631 p->pw_name, /* kerberos name */
632 (char *)0, /* instance */
633 (char *)0, /* realm */
634 passwd, /* password */
635 0, /* default lifetime */
638 &reason) == 0 ) { /* error string */
640 if (strcmp(p->pw_passwd, "*") == 0)
647 LogError(ReadCatalog(
648 MC_LOG_SET,MC_LOG_AFS_FAILATH,MC_DEF_LOG_AFS_FAILATH),reason);
657 * Kerberos password authentication...
660 if ( IsVerifyName(VN_KRB) ) {
662 if (focusWidget == login_text)
665 (void)krb_get_lrealm(realm, 1);
667 setresuid(p->pw_uid, p->pw_uid, -1);
668 kerno = krb_get_pw_in_tkt(p->pw_name,
678 if (kerno == KSUCCESS)
679 if (strcmp(p->pw_passwd, "*") == 0)
685 #endif /* __KERBEROS */
690 * traditional password verification...
693 if (strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd) == 0)
699 * If regular passwd check fails, try old-style Apollo SR
702 if (rgy_$is_des(passwd, strlen(passwd), p->pw_passwd) == TRUE)
708 * all password checks failed...
718 /***************************************************************************
724 * return codes indicate authentication results.
725 ***************************************************************************/
727 #define MAXATTEMPTS 3
729 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
732 Verify( char *name, char *passwd )
735 static int login_attempts = 0; /* # failed authentications */
737 struct passwd *p; /* password structure */
739 struct utsname utsnam;
746 * turn on self auditing...
749 if (audswitch(AUD_SUSPEND) == -1)
755 * set the secure flag if SECUREPASS exists. If so, we
756 * are using it for authentication instead of /etc/passwd...
759 secure = (stat(SECUREPASS, &s_pfile) < 0) ? 0:1;
763 * set the audit process flag unconditionally on since we want
764 * to log all logins regardless of whether the user's audit
769 setaudproc(AUD_PROC);
775 * validate password...
778 if ( CheckPassword(name, passwd, &p) == FALSE) {
779 if ( focusWidget == passwd_text ) {
783 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
785 if (p->pw_name == NULL )
788 Audit(p, " Failed login (bailout)", 1);
798 * check restricted license...
800 * Note: This only applies to local displays. Foreign displays
801 * (i.e. X-terminals) apparently do not count.
804 /* Get the version info via uname. If it doesn't look right,
805 * assume the smallest user configuration
808 if (getenv(LOCATION) != NULL) {
809 if (uname(&utsnam) < 0)
810 utsnam.version[0] = MIN_VERSION;
822 if ((!strncmp(utsnam.machine, "9000/834", UTSLEN)) ||
823 (!strncmp(utsnam.machine, "9000/844", UTSLEN)) ||
824 (!strncmp(utsnam.machine, "9000/836", UTSLEN)) ||
825 (!strncmp(utsnam.machine, "9000/846", UTSLEN)) ||
826 (!strncmp(utsnam.machine, "9000/843", UTSLEN)) ||
827 (!strncmp(utsnam.machine, "9000/853", UTSLEN))) {
829 /* strict_count = 1;*/
830 if (CountUsersStrict(name) > MAX_STRICT_USERS) {
832 " attempted to login - too many users on the system",
835 return(VF_MAX_USERS);
839 if (utsnam.version[0] != UNLIMITED) {
840 if ((utsnam.version[0]-'A' < 0) ||
841 (utsnam.version[0]-'A' > NUM_VERSIONS))
842 utsnam.version[0] = MIN_VERSION;
844 n = (int) utsnam.version[0] - 'A';
845 if (CountUsers(1) > num_users[n]) {
847 " attempted to login - too many users on the system",
850 return(VF_MAX_USERS);
858 * Check for account validity. Unfortunately, we have no graphical
859 * dialog for this at this time so the best we can do is log an
860 * error message and hope the system administrator sees it.
863 if ( !rgy_$using_local_registry() ) {
864 if (rgy_$is_acct_expired(&admin_part) != 0 ) {
865 LogError(ReadCatalog(MC_LOG_SET,MC_LOG_ACC_EXP,MC_DEF_LOG_ACC_EXP),
873 * check password aging...
876 if ( PasswordAged(p) ) return(VF_PASSWD_AGED);
880 * verify home directory exists...
883 if(chdir(p->pw_dir) < 0) {
884 Audit(p, " attempted to login - no home directory", 1);
891 * check audit flag and id...
896 if (secure && (p->pw_audflg > 1 || p->pw_audflg < 0)) {
897 Audit(p, " attempted to login - bad audit flag", 1);
898 return(VF_BAD_AFLAG);
901 if (secure && (setaudid(p->pw_audid) == -1 )) {
902 Audit(p, " attempted to login - bad audit id", 1);
909 * validate uid and gid...
912 if ((p->pw_gid < 0) ||
913 (p->pw_gid > MAXUID) ||
914 (setgid(p->pw_gid) == -1)) {
916 Audit(p, " attempted to login - bad group id", 1);
923 * ka_UserAuthenticateGeneral() sets the group access of this process
924 * to the proper PAG. Pick up these values and pass them back to
925 * Dtlogin to be put into the user's environment...
928 if ( IsVerifyName(VN_AFS) ) {
929 groups[0] = groups[1] = 0;
930 getgroups(NGROUPS, groups);
936 if ((p->pw_uid < 0) ||
937 (p->pw_uid > MAXUID) ||
938 (setresuid(p->pw_uid, p->pw_uid, 0) == -1)) {
940 Audit(p, " attempted to login - bad user id", 1);
951 Audit(p, " Successful login", 0);
958 /***************************************************************************
962 * log bad login attempts
964 ***************************************************************************/
967 WriteBtmp( char *name )
970 struct utmp utmp, *u;
974 bzero(&utmp, sizeof(struct utmp));
976 utmp.ut_pid = getppid();
977 while ((u = getutent()) != NULL) {
978 if ( (u->ut_type == INIT_PROCESS ||
979 u->ut_type == LOGIN_PROCESS ||
980 u->ut_type == USER_PROCESS) &&
981 u->ut_pid == utmp.ut_pid ) {
990 * if no utmp entry, this may be an X-terminal. Construct a utmp
995 strncpy(utmp.ut_id, "??", sizeof(utmp.ut_id));
996 strncpy(utmp.ut_line, dpyinfo.name, sizeof(utmp.ut_line));
997 utmp.ut_type = LOGIN_PROCESS;
999 strncpy(utmp.ut_host, dpyinfo.name, sizeof(utmp.ut_host));
1006 * If btmp exists, then record the bad attempt
1008 if ( (fd = open(BTMP_FILE,O_WRONLY|O_APPEND)) >= 0) {
1009 strncpy(u->ut_user, name, sizeof(u->ut_user));
1010 (void) time(&u->ut_time);
1011 write(fd, (char *)u, sizeof(utmp));
1015 endutent(); /* Close utmp file */
1018 /***************************************************************************
1020 * End authentication routines (HPUX)
1022 ***************************************************************************/
1027 /***************************************************************************
1028 ***************************************************************************
1029 ***************************************************************************
1030 ***************************************************************************
1031 ***************************************************************************
1032 ***************************************************************************
1033 ***************************************************************************
1034 ***************************************************************************/
1038 /***************************************************************************
1040 * Start authentication routines (SUN)
1042 ***************************************************************************/
1047 /***************************************************************************
1049 * External declarations (SUN)
1051 ***************************************************************************/
1056 /***************************************************************************
1058 * Procedure declarations (SUN)
1060 ***************************************************************************/
1062 static void Audit( struct passwd *p, char *msg, int errnum) ;
1063 static int PasswordAged( register struct passwd *pw) ;
1064 static void WriteBtmp( char *name) ;
1069 /***************************************************************************
1071 * Global variables (SUN)
1073 ***************************************************************************/
1078 /***************************************************************************
1082 ***************************************************************************/
1085 Audit( struct passwd *p, char *msg, int errnum )
1089 * make sure program is back to super-user...
1100 /***************************************************************************
1104 * log bad login attempts
1106 ***************************************************************************/
1109 WriteBtmp( char *name )
1117 /***************************************************************************
1119 * PasswordAged (SUN)
1121 * see if password has aged
1122 ***************************************************************************/
1123 #define SECONDS_IN_WEEK 604800L
1126 PasswordAged( register struct passwd *pw )
1128 long change_week; /* week password was changed (1/1/70 = Week 0) */
1129 long last_week; /* week after which password must change */
1130 long first_week; /* week before which password can't change */
1131 long this_week; /* this week derived from time() */
1132 char *file; /* help file name */
1133 char *command; /* the /bin/passwd command string */
1135 if (*pw->pw_age == NULL)
1138 first_week = last_week = change_week = (long) a64l(pw->pw_age);
1139 last_week &= 0x3f; /* first six bits */
1140 first_week = (first_week >> 6) & 0x3f; /* next six bits */
1141 change_week >>= 12; /* everything else */
1143 this_week = (long) time((long *) 0) / SECONDS_IN_WEEK;
1146 ** Password aging conditions:
1147 ** * if the last week is less than the first week (e.g., the aging
1148 ** field looks like "./"), only the superuser can change the
1149 ** password. We don't request a new password.
1150 ** * if the week the password was last changed is after this week,
1151 ** we have a problem, and request a new password.
1152 ** * if this week is after the specified aging time, we request
1155 if (last_week < first_week)
1158 if (change_week <= this_week && this_week <= (change_week + last_week))
1167 /***************************************************************************
1173 * return codes indicate authentication results.
1174 ***************************************************************************/
1176 #define MAXATTEMPTS 3
1178 extern Widget focusWidget; /* login or password text field */
1179 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
1182 Verify( char *name, char *passwd )
1185 static int login_attempts = 0; /* # failed authentications */
1187 struct passwd *p; /* password structure */
1188 struct spwd *sp; /* shadow info */
1194 sp = getspnam(name);
1196 if (!p || strlen(name) == 0 ||
1197 strcmp (crypt (passwd, sp->sp_pwdp), sp->sp_pwdp)) {
1199 if ( focusWidget == passwd_text ) {
1203 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
1205 if (p->pw_name == NULL )
1208 Audit(p, " Failed login (bailout)", 1);
1218 * check password aging...
1221 if ( PasswordAged(p) ) return(VF_PASSWD_AGED);
1224 * verify home directory exists...
1227 if(chdir(p->pw_dir) < 0) {
1228 Audit(p, " attempted to login - no home directory", 1);
1234 * validate uid and gid...
1238 if ((p->pw_gid < 0) ||
1239 (setgid(p->pw_gid) == -1)) {
1241 Audit(p, " attempted to login - bad group id", 1);
1245 if ((p->pw_uid < 0) ||
1246 (seteuid(p->pw_uid) == -1)) {
1248 Audit(p, " attempted to login - bad user id", 1);
1258 Audit(p, " Successful login", 0);
1264 /***************************************************************************
1266 * End authentication routines (SUN)
1268 ***************************************************************************/
1271 /***************************************************************************
1272 ***************************************************************************
1273 ***************************************************************************
1274 ***************************************************************************
1275 ***************************************************************************
1276 ***************************************************************************
1277 ***************************************************************************
1278 ***************************************************************************/
1281 /***************************************************************************
1283 * Start authentication routines (AIX)
1285 ***************************************************************************/
1288 #include <sys/types.h>
1289 #include <usersec.h>
1291 #include <userconf.h>
1293 /***************************************************************************
1295 * External declarations (AIX)
1297 ***************************************************************************/
1302 /***************************************************************************
1304 * Procedure declarations (AIX)
1306 ***************************************************************************/
1308 static void Audit( struct passwd *p, char *msg, int errnum) ;
1309 static int PasswordAged(char *name, register struct passwd *pw) ;
1310 static void WriteBtmp( char *name) ;
1315 /***************************************************************************
1317 * Global variables (AIX)
1319 ***************************************************************************/
1324 /***************************************************************************
1328 ***************************************************************************/
1331 Audit( struct passwd *p, char *msg, int errnum )
1335 * make sure program is back to super-user...
1346 /***************************************************************************
1350 * log bad login attempts
1352 ***************************************************************************/
1355 WriteBtmp( char *name )
1363 /***************************************************************************
1365 * PasswordAged (AIX)
1367 * see if password has aged
1368 ***************************************************************************/
1369 #define SECONDS_IN_WEEK 604800L
1372 PasswordAged(char *name, register struct passwd *pw )
1374 struct userpw *pupw; /* authentication information from getuserpw() */
1375 struct userpw upw; /* working authentication information */
1376 int err; /* return code from getconfattr() */
1377 ulong maxage; /* maximun age from getconfattr() */
1378 ulong now; /* time now */
1381 * Determine user password aging criteria. Note that only
1382 * the 'lastupdate' and 'flags' fields are set by this operation.
1385 if ((pupw = getuserpw(name)) != NULL)
1387 upw.upw_lastupdate = pupw->upw_lastupdate;
1388 upw.upw_flags = pupw->upw_flags;
1392 upw.upw_lastupdate = 0;
1398 * Consider password as having not expired if nocheck set.
1400 if (upw.upw_flags & PW_NOCHECK) return(FALSE);
1403 * Get system password aging criteria.
1405 err = getconfattr (SC_SYS_PASSWD, SC_MAXAGE, (void *)&maxage, SEC_INT);
1409 * Change from weeks to seconds
1411 maxage = maxage * SECONDS_IN_WEEK;
1412 now = time ((long *) 0);
1414 if ((upw.upw_lastupdate + maxage) >= now)
1417 * Password has not expired.
1425 * Could not retrieve system password aging info or maxage set to
1426 * zero. In either case, consider password has having not expired.
1432 * We haven't returned by now, so indicate password has expired.
1439 /***************************************************************************
1445 * return codes indicate authentication results.
1446 ***************************************************************************/
1448 #define MAXATTEMPTS 3
1450 extern Widget focusWidget; /* login or password text field */
1451 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
1454 Verify( char *name, char *passwd )
1457 static int login_attempts = 0; /* # failed authentications */
1459 struct passwd *p; /* password structure */
1466 if (!p || strlen(name) == 0 ||
1467 strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) {
1469 if ( focusWidget == passwd_text ) {
1473 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
1475 if (p->pw_name == NULL )
1478 Audit(p, " Failed login (bailout)", 1);
1488 * check password aging...
1491 if ( PasswordAged(name,p) ) return(VF_PASSWD_AGED);
1494 * verify home directory exists...
1497 if(chdir(p->pw_dir) < 0) {
1498 Audit(p, " attempted to login - no home directory", 1);
1504 * validate uid and gid...
1508 if ((p->pw_gid < 0) ||
1509 (setgid(p->pw_gid) == -1)) {
1511 Audit(p, " attempted to login - bad group id", 1);
1515 if ((p->pw_uid < 0)) {
1516 Audit(p, " attempted to login - bad user id", 1);
1526 Audit(p, " Successful login", 0);
1533 /***************************************************************************
1535 * End authentication routines (AIX)
1537 ***************************************************************************/
1541 /***************************************************************************
1542 ***************************************************************************
1543 ***************************************************************************
1544 ***************************************************************************
1545 ***************************************************************************
1546 ***************************************************************************
1547 ***************************************************************************
1548 ***************************************************************************/
1551 /***************************************************************************
1553 * Start authentication routines (generic)
1555 ***************************************************************************/
1558 /***************************************************************************
1560 * These are a set of routine to do simple password, home dir, uid, and gid
1561 * validation. They can be used as a first pass validation for future
1564 * When platform specific validation is developed, those routines should be
1565 * included in their own section and the use of these routines discontinued.
1567 ***************************************************************************/
1572 /***************************************************************************
1574 * External declarations (generic)
1576 ***************************************************************************/
1581 /***************************************************************************
1583 * Procedure declarations (generic)
1585 ***************************************************************************/
1587 static void Audit( struct passwd *p, char *msg, int errnum) ;
1588 static int PasswordAged( register struct passwd *pw) ;
1589 static void WriteBtmp( char *name) ;
1594 /***************************************************************************
1596 * Global variables (generic)
1598 ***************************************************************************/
1603 /***************************************************************************
1607 ***************************************************************************/
1610 Audit( struct passwd *p, char *msg, int errnum )
1614 * make sure program is back to super-user...
1625 /***************************************************************************
1627 * WriteBtmp (generic)
1629 * log bad login attempts
1631 ***************************************************************************/
1634 WriteBtmp( char *name )
1642 /***************************************************************************
1644 * PasswordAged (Generic)
1646 * see if password has aged
1647 ***************************************************************************/
1648 #define SECONDS_IN_WEEK 604800L
1651 PasswordAged( register struct passwd *pw )
1658 /***************************************************************************
1664 * return codes indicate authentication results.
1665 ***************************************************************************/
1667 #define MAXATTEMPTS 3
1669 extern Widget focusWidget; /* login or password text field */
1670 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
1673 Verify( char *name, char *passwd )
1676 static int login_attempts = 0; /* # failed authentications */
1678 struct passwd *p; /* password structure */
1685 if (!p || strlen(name) == 0 ||
1686 strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) {
1688 if ( focusWidget == passwd_text ) {
1692 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
1694 if (p->pw_name == NULL )
1697 Audit(p, " Failed login (bailout)", 1);
1707 * check password aging...
1710 if ( PasswordAged(p) ) return(VF_PASSWD_AGED);
1714 * verify home directory exists...
1717 if(chdir(p->pw_dir) < 0) {
1718 Audit(p, " attempted to login - no home directory", 1);
1724 * validate uid and gid...
1728 if ((p->pw_gid < 0) ||
1729 (setgid(p->pw_gid) == -1)) {
1731 Audit(p, " attempted to login - bad group id", 1);
1735 if ((p->pw_uid < 0) ||
1736 (seteuid(p->pw_uid) == -1)) {
1738 Audit(p, " attempted to login - bad user id", 1);
1748 Audit(p, " Successful login", 0);
1755 /***************************************************************************
1757 * End authentication routines (generic)
1759 ***************************************************************************/
1760 #endif /* generic */
1764 /***************************************************************************
1765 ***************************************************************************
1766 ***************************************************************************
1767 ***************************************************************************
1768 ***************************************************************************
1769 ***************************************************************************
1770 ***************************************************************************
1771 ***************************************************************************/