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 libraries 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: sysauth.c /main/7 1996/10/30 11:12:45 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 ****************************************************************************
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
72 ** _POWER AIX version 4 only
74 ****************************************************************************
75 ************************************<+>*************************************/
78 /***************************************************************************
82 ***************************************************************************/
90 #include <security/pam_appl.h>
96 #include <sys/access.h>
100 #include <sys/audit.h>
103 /* necessary for bzero */
105 #include <X11/Xfuncs.h>
117 * Define as generic those without platform specific code.
119 #if !(defined(__hpux) || \
120 defined(__apollo) || \
127 #include <sys/sysinfo.h>
135 /***************************************************************************
137 * Start authentication routines (HPUX)
139 ***************************************************************************/
141 #include <sys/param.h> /* for MAXUID macro */
142 #include <sys/types.h>
143 #include <sys/utsname.h>
150 # include <sys/audit.h>
151 # include <sys/errno.h>
152 # include <sys/stat.h>
153 # define SECUREPASS "/.secure/etc/passwd"
157 # include <sys/security.h>
162 #include <afs/kautils.h>
167 # define KRBLIFE 255 /* max lifetime */
168 #endif /* __KERBEROS */
171 # include "rgy_base.h"
176 #define how_to_count ut_exit.e_exit
179 int num_users[] = { 2, 32767 };
180 # define MIN_VERSION 'A'
181 # define UNLIMITED 'B'
183 int num_users[] = { 2, 16, 32, 64 , 8 };
184 # define MIN_VERSION 'A'
185 # define UNLIMITED 'U'
188 /* Maximum number of users allowed with restricted license */
189 #if OSMAJORVERSION < 8
190 # define MAX_STRICT_USERS 2
192 # define MAX_STRICT_USERS 8
195 #define NUM_VERSIONS (sizeof(num_users)/sizeof(num_users[0])) - 1
197 extern char *globalDisplayName;
199 /***************************************************************************
201 * External declarations (HPUX)
203 ***************************************************************************/
205 extern long groups[NGROUPS];
209 extern boolean rgy_$using_local_registry();
210 extern struct passwd * getpwnam_full();
211 extern boolean is_acct_expired();
212 extern boolean is_passwd_expired();
213 extern boolean is_passwd_invalid();
214 extern boolean rgy_$is_des();
219 /***************************************************************************
221 * Procedure declarations (HPUX)
223 ***************************************************************************/
225 static void Audit( struct passwd *p, char *msg, int errnum) ;
226 static int CheckPassword( char *name, char *passwd, struct passwd **ppwd );
227 static int CountUsers( int added_users) ;
228 static int CountUsersStrict( char *new_user) ;
229 static int PasswordAged( register struct passwd *pw) ;
230 static void WriteBtmp( char *name) ;
235 /***************************************************************************
237 * Global variables (HPUX)
239 ***************************************************************************/
242 struct s_passwd *s_pwd;
244 int secure; /* flag to denote existence of secure passwd file */
249 struct pr_passwd *b1_pwd;
253 rgy_$acct_admin_t admin_part;
254 rgy_$policy_t policy;
255 rgy_$acct_user_t user_part;
260 /***************************************************************************
264 * Construct self audit record for event and write to the audit trail.
265 * This routine assumes that the effective uid is currently 0. If auditing
266 * is not defined, this routine does nothing.
267 ***************************************************************************/
270 Audit( struct passwd *p, char *msg, int errnum )
276 struct self_audit_rec audrec;
281 * make sure program is back to super-user...
289 txtptr = (char *)audrec.aud_body.text;
290 sprintf(txtptr, "User= %s uid=%ld audid=%ld%s", p->pw_name,
291 (long)p->pw_uid, (long)p->pw_audid, msg);
292 audrec.aud_head.ah_pid = getpid();
293 audrec.aud_head.ah_error = errnum;
294 audrec.aud_head.ah_event = EN_LOGINS;
295 audrec.aud_head.ah_len = strlen (txtptr);
296 status = audwrite(&audrec);
302 LogError(ReadCatalog(
303 MC_LOG_SET,MC_LOG_NOT_SUSER,MC_DEF_LOG_NOT_SUSER));
307 LogError(ReadCatalog(
308 MC_LOG_SET,MC_LOG_INV_EVENT,MC_DEF_LOG_INV_EVENT));
312 LogError(ReadCatalog(
313 MC_LOG_SET,MC_LOG_ERR_ERRNO,MC_DEF_LOG_ERR_ERRNO),
330 /***************************************************************************
332 * CountUsers (HPUX only)
334 * see if new user has exceeded the maximum.
335 ***************************************************************************/
340 CountUsers( int added_users )
342 int count[NCOUNT], nusers, i;
345 for (i=0; i<NCOUNT; i++)
348 count[added_users]++;
350 while ( (entry = getutent()) != NULL) {
351 if (entry->ut_type == USER_PROCESS) {
352 i = entry->how_to_count;
353 if (i < 0 || i >= NCOUNT)
354 i = 1; /* if out of range, then count */
355 /* as ordinary user */
363 * [0] does not count at all
364 * [1] counts as real user
365 * [2] logins via a pty which have not gone trough login. These
366 * collectively count as 1 user IF count[3] is 0, otherwise,
367 * they are not counted. Starting with HP-UX 8.0 they are
368 * no longer counted at all.
369 * [3] logins via a pty which have been logged through login (i.e.
370 * rlogin and telnet). these count as 1 "real" user per
372 * [4-15] may be used for groups of users which collectively
377 #if OSMAJORVERSION < 8
378 for (i=2; i<NCOUNT; i++)
380 for (i=3; i<NCOUNT; i++)
391 /***************************************************************************
393 * CountUsersStrict (HPUX only)
395 * see if new user has exceeded the maximum.
396 ***************************************************************************/
399 CountUsersStrict( char *new_user )
401 char pty_users[MAX_STRICT_USERS][8];
402 int count[NCOUNT], nusers, i, cnt, pty_off = -1, uname_off;
406 * Initialize count array...
408 for (i = 0; i < NCOUNT; i++)
412 * Add in the new user (we know it's not a pty)...
416 while ( (entry = getutent()) != NULL ) {
417 if (entry->ut_type == USER_PROCESS) {
418 i = entry->how_to_count;
420 /* if out of range, then count as ordinary user logged in
422 if (i == 1 || (i < 0 || i >= NCOUNT))
424 /* See if it is a pty login granted by login program */
427 /* See if user is already logged in via login pty */
429 for (cnt = 0; cnt <= pty_off; cnt++)
430 if (strncmp(pty_users[cnt], entry->ut_user, 8) == 0)
433 if (uname_off == -1) { /* user is not logged in via pty yet */
435 if (pty_off >= MAX_STRICT_USERS) /* cannot add any
437 return(MAX_STRICT_USERS + 1);
438 /* add the user name to the array of pty users */
440 strncpy(pty_users[++pty_off], entry->ut_user, 8);
442 } /* end if (i == 3) */
445 } /* end if entry->ut_type == USER_PROCESS */
446 } /* end while (entry = getutent()) */
451 * [0] does not count at all
452 * [1] counts as "real" user
453 * [2] logins via a pty which have not gone trough login. These
454 * collectively count as 1 user IF count[3] is 0, otherwise,
455 * they are not counted. Starting with HP-UX 8.0 they are
456 * no longer counted at all.
457 * [3] logins via a pty which have been logged through login (i.e.
458 * rlogin and telnet). these count as 1 "real" user per
460 * [4-15] may be used for groups of users which collectively count
464 nusers = pty_off + 1 + count[1]; /* Current number of users is sum of
465 users logged in via tty + the
466 number of unique users logged in
467 via pty which have gone through
470 #if OSMAJORVERSION < 8
471 if ((count[3] == 0) && (count[2] != 0))
472 nusers++; /* Add 1 user for all pty logins IF
473 none of pty logins have been
474 granted by the login program */
477 * Don't count any hpterm logins (exit status of 2). We already
478 * counted all pty logins granted by the login program.
482 for (i = 4; i < NCOUNT; i++)
491 /***************************************************************************
493 * PasswordAged (HPUX)
495 * see if password has aged
496 ***************************************************************************/
497 #define SECONDS_IN_WEEK 604800L
500 PasswordAged( register struct passwd *pw )
502 long change_week; /* week password was changed (1/1/70 = Week 0) */
503 long last_week; /* week after which password must change */
504 long first_week; /* week before which password can't change */
505 long this_week; /* this week derived from time() */
507 char *passwdAge; /* password aging time */
514 passwdAge = pw->pw_age;
518 passwdAge = s_pwd->pw_age;
523 /* Account validity checks: If we were able to connect to the network
524 * registry, then we've acquired account and policy data and can perform
525 * account/password checking
528 lrgy = rgy_$using_local_registry();
531 /* Check for password expiration or invalidity */
532 if ( rgy_$is_passwd_expired(&user_part, &policy ) != 0 ) {
540 if (*passwdAge == NULL)
543 first_week = last_week = change_week = (long) a64l(passwdAge);
544 last_week &= 0x3f; /* first six bits */
545 first_week = (first_week >> 6) & 0x3f; /* next six bits */
546 change_week >>= 12; /* everything else */
548 this_week = (long) time((long *) 0) / SECONDS_IN_WEEK;
551 ** Password aging conditions:
552 ** * if the last week is less than the first week (e.g., the aging
553 ** field looks like "./"), only the superuser can change the
554 ** password. We don't request a new password.
555 ** * if the week the password was last changed is after this week,
556 ** we have a problem, and request a new password.
557 ** * if this week is after the specified aging time, we request
560 if (last_week < first_week)
563 if (change_week <= this_week && this_week <= (change_week + last_week))
573 /***************************************************************************
575 * CheckPassword (HPUX only)
577 * Check validity of user password. One of several authentication schemes
578 * can be used, including Kerberos, AFS 3, HP BLS and traditional
579 * /etc/passwd. These are selectable via a resource in Dtlogin.
581 * Domain registry authentication (PasswdEtc) can also be compiled in as
582 * the only authentication scheme used.
584 ***************************************************************************/
587 CheckPassword( char *name, char *passwd, struct passwd **ppwd )
596 char realm[REALM_SZ];
598 #endif /* __KERBEROS */
603 * validate that user has an entry in the shadow password file on an
604 * HP-UX C2 trusted system. Keep info in a global structure.
608 s_pwd = getspwnam(name);
618 * look up user's regular account information...
623 * look up entry from registry...
625 * need getpwnam_full to get policy data for passwd expiration
628 p = getpwnam_full(name, &user_part, &admin_part, &policy);
636 if ( p == NULL || strlen(name) == 0 )
643 * AFS password authentication...
646 if ( vg_IsVerifyName(VN_AFS) ) {
648 if ( ka_UserAuthenticateGeneral(
649 KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG,
650 p->pw_name, /* kerberos name */
651 (char *)0, /* instance */
652 (char *)0, /* realm */
653 passwd, /* password */
654 0, /* default lifetime */
657 &reason) == 0 ) { /* error string */
659 if (strcmp(p->pw_passwd, "*") == 0)
666 LogError(ReadCatalog(
667 MC_LOG_SET,MC_LOG_AFS_FAILATH,MC_DEF_LOG_AFS_FAILATH),reason);
676 * Kerberos password authentication...
679 if ( vg_IsVerifyName(VN_KRB) ) {
681 (void)krb_get_lrealm(realm, 1);
683 setresuid(p->pw_uid, p->pw_uid, -1);
684 kerno = krb_get_pw_in_tkt(p->pw_name,
694 if (kerno == KSUCCESS)
695 if (strcmp(p->pw_passwd, "*") == 0)
701 #endif /* __KERBEROS */
706 * traditional password verification...
709 if (strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd) == 0)
715 * If regular passwd check fails, try old-style Apollo SR
718 if (rgy_$is_des(passwd, strlen(passwd), p->pw_passwd) == TRUE)
724 * all password checks failed...
734 /***************************************************************************
736 * Authenticate (HPUX)
740 * return codes indicate authentication results.
741 ***************************************************************************/
743 #define MAXATTEMPTS 3
745 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
748 Authenticate( struct display *d, char *name, char *passwd, char **msg )
751 static int login_attempts = 0; /* # failed authentications */
753 struct passwd *p = NULL; /* password structure */
755 struct utsname utsnam;
761 * Nothing to do if no name provided.
768 if (strlen(name) == 0)
772 return(VF_CHALLENGE);
779 * Save provided password.
782 if (!passwd) passwd = "";
786 * turn on self auditing...
789 if (audswitch(AUD_SUSPEND) == -1)
795 * set the secure flag if SECUREPASS exists. If so, we
796 * are using it for authentication instead of /etc/passwd...
799 secure = (stat(SECUREPASS, &s_pfile) < 0) ? 0:1;
803 * set the audit process flag unconditionally on since we want
804 * to log all logins regardless of whether the user's audit
809 setaudproc(AUD_PROC);
815 * validate password...
818 if ( CheckPassword(name, passwd, &p) == FALSE) {
822 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
827 Audit(p, " Failed login (bailout)", 1);
831 return(origpw ? VF_INVALID : VF_CHALLENGE);
836 * check restricted license...
838 * Note: This only applies to local displays. Foreign displays
839 * (i.e. X-terminals) apparently do not count.
842 /* Get the version info via uname. If it doesn't look right,
843 * assume the smallest user configuration
846 if (uname(&utsnam) < 0)
847 utsnam.version[0] = MIN_VERSION;
859 if ((!strncmp(utsnam.machine, "9000/834", UTSLEN)) ||
860 (!strncmp(utsnam.machine, "9000/844", UTSLEN)) ||
861 (!strncmp(utsnam.machine, "9000/836", UTSLEN)) ||
862 (!strncmp(utsnam.machine, "9000/846", UTSLEN)) ||
863 (!strncmp(utsnam.machine, "9000/843", UTSLEN)) ||
864 (!strncmp(utsnam.machine, "9000/853", UTSLEN))) {
866 /* strict_count = 1;*/
867 if (CountUsersStrict(name) > MAX_STRICT_USERS) {
869 " attempted to login - too many users on the system",
872 return(VF_MAX_USERS);
876 if (utsnam.version[0] != UNLIMITED) {
877 if ((utsnam.version[0]-'A' < 0) ||
878 (utsnam.version[0]-'A' > NUM_VERSIONS))
879 utsnam.version[0] = MIN_VERSION;
881 n = (int) utsnam.version[0] - 'A';
882 if (CountUsers(1) > num_users[n]) {
884 " attempted to login - too many users on the system",
887 return(VF_MAX_USERS);
895 * Check for account validity. Unfortunately, we have no graphical
896 * dialog for this at this time so the best we can do is log an
897 * error message and hope the system administrator sees it.
900 if ( !rgy_$using_local_registry() ) {
901 if (rgy_$is_acct_expired(&admin_part) != 0 ) {
902 LogError(ReadCatalog(MC_LOG_SET,MC_LOG_ACC_EXP,MC_DEF_LOG_ACC_EXP),
910 * check password aging...
913 if ( PasswordAged(p) ) return(VF_PASSWD_AGED);
917 * verify home directory exists...
920 if(chdir(p->pw_dir) < 0) {
921 Audit(p, " attempted to login - no home directory", 1);
928 * check audit flag and id...
933 if (secure && (p->pw_audflg > 1 || p->pw_audflg < 0)) {
934 Audit(p, " attempted to login - bad audit flag", 1);
935 return(VF_BAD_AFLAG);
938 if (secure && (setaudid(p->pw_audid) == -1 )) {
939 Audit(p, " attempted to login - bad audit id", 1);
946 * validate uid and gid...
949 if ((p->pw_gid < 0) ||
950 (p->pw_gid > MAXUID) ||
951 (setgid(p->pw_gid) == -1)) {
953 Audit(p, " attempted to login - bad group id", 1);
960 * ka_UserAuthenticateGeneral() sets the group access of this process
961 * to the proper PAG. Pick up these values and pass them back to
962 * Dtlogin to be put into the user's environment...
965 if ( vg_IsVerifyName(VN_AFS) ) {
966 groups[0] = groups[1] = 0;
967 getgroups(NGROUPS, groups);
973 if ((p->pw_uid < 0) ||
974 (p->pw_uid > MAXUID) ||
975 (setresuid(p->pw_uid, p->pw_uid, 0) == -1)) {
977 Audit(p, " attempted to login - bad user id", 1);
988 Audit(p, " Successful login", 0);
995 /***************************************************************************
999 * log bad login attempts
1001 ***************************************************************************/
1004 WriteBtmp( char *name )
1007 struct utmp utmp, *u;
1011 bzero(&utmp, sizeof(struct utmp));
1013 utmp.ut_pid = getppid();
1014 while ((u = getutent()) != NULL) {
1015 if ( (u->ut_type == INIT_PROCESS ||
1016 u->ut_type == LOGIN_PROCESS ||
1017 u->ut_type == USER_PROCESS) &&
1018 u->ut_pid == utmp.ut_pid ) {
1027 * if no utmp entry, this may be an X-terminal. Construct a utmp
1032 strncpy(utmp.ut_id, "??", sizeof(utmp.ut_id));
1033 strncpy(utmp.ut_line, globalDisplayName, sizeof(utmp.ut_line));
1034 utmp.ut_type = LOGIN_PROCESS;
1036 strncpy(utmp.ut_host, globalDisplayName, sizeof(utmp.ut_host));
1043 * If btmp exists, then record the bad attempt
1045 if ( (fd = open(BTMP_FILE,O_WRONLY|O_APPEND)) >= 0) {
1046 strncpy(u->ut_user, name, sizeof(u->ut_user));
1047 (void) time(&u->ut_time);
1048 write(fd, (char *)u, sizeof(utmp));
1052 endutent(); /* Close utmp file */
1055 /***************************************************************************
1057 * End authentication routines (HPUX)
1059 ***************************************************************************/
1063 /***************************************************************************
1064 ***************************************************************************
1065 ***************************************************************************
1066 ***************************************************************************
1067 ***************************************************************************
1068 ***************************************************************************
1069 ***************************************************************************
1070 ***************************************************************************/
1074 /***************************************************************************
1076 * Start authentication routines (SUN)
1078 ***************************************************************************/
1080 #include "solaris.h"
1082 #include <security/ia_appl.h>
1086 /***************************************************************************
1088 * Procedure declarations (SUN)
1090 ***************************************************************************/
1092 static void Audit( struct passwd *p, char *msg, int errnum) ;
1096 /***************************************************************************
1100 ***************************************************************************/
1103 Audit( struct passwd *p, char *msg, int errnum )
1107 * make sure program is back to super-user...
1112 Debug("Audit: %s\n", msg);
1118 /***************************************************************************
1120 * Authenticate (SUN)
1124 * return codes indicate authentication results.
1125 ***************************************************************************/
1128 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1131 char* ttyLine = d->gettyLine;
1134 * Nothing to do if no name provided.
1141 * Construct device line
1143 #ifdef DEF_NETWORK_DEV
1145 * If location is not local (remote XDMCP dtlogin) and
1146 * remote accouting is enabled (networkDev start with /dev/...)
1147 * Set tty line name to match network device for accouting.
1148 * Unless the resource was specifically set, default is value
1149 * of DEF_NETWORK_DEV define (/dev/dtremote)
1152 if ( d->displayType.location != Local &&
1153 networkDev && !strncmp(networkDev,"/dev/",5)) {
1154 ttyLine = networkDev+5;
1159 * Authenticate user and return status
1163 status = PamAuthenticate("dtlogin", d->name, passwd, name, ttyLine);
1169 case PAM_NEW_AUTHTOK_REQD:
1170 return(VF_PASSWD_AGED);
1173 return(passwd ? VF_INVALID : VF_CHALLENGE);
1176 status = solaris_authenticate("dtlogin", d->name, passwd, name, ttyLine);
1182 case IA_NEWTOK_REQD:
1183 return(VF_PASSWD_AGED);
1186 return(passwd ? VF_INVALID : VF_CHALLENGE);
1193 /***************************************************************************
1195 * End authentication routines (SUN)
1197 ***************************************************************************/
1200 /***************************************************************************
1201 ***************************************************************************
1202 ***************************************************************************
1203 ***************************************************************************
1204 ***************************************************************************/
1206 /***************************************************************************
1210 * get the information from the display about local/remote login and
1211 * create a dummy tty name for loginrestrictions.
1213 ***************************************************************************/
1215 GetLoginInfo(struct display *d, int *loginType, char *ttyName, char **hostname)
1219 CleanUpName(d->name, workarea, 128);
1220 sprintf(ttyName, "/dev/dtlogin/%s", workarea);
1222 if (d->displayType.location == Foreign) {
1223 *loginType = S_RLOGIN;
1224 *hostname = d->name;
1225 Debug("Login Info - Remote user on tty=%s.\n", ttyName);
1227 *loginType = S_LOGIN;
1229 Debug("Login Info - Local user on tty=%s.\n", ttyName);
1233 /***************************************************************************
1235 * Authenticate (AIX version 4.1)
1239 * return codes indicate authentication results.
1240 ***************************************************************************/
1241 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1247 static char *msgpending;
1252 GetLoginInfo(d, &loginType, tty, &hostname);
1262 * No more challenges. User failed login.
1265 loginfailed(name, hostname, tty);
1270 * Authenticate with response to last challenge.
1272 rc = authenticate(name, passwd, &reenter, msg);
1277 * System has presented user with new challenge.
1279 return(VF_CHALLENGE);
1282 if (rc && errno == ENOENT)
1285 * User is unknown to the system. Simulate a password
1286 * challenge, but save message for display for next call.
1289 return(VF_CHALLENGE);
1295 * No more challenges. User failed login.
1297 loginfailed(name, hostname, tty);
1302 * User authenticated. Check login restrictions.
1304 rc = loginrestrictions(name, loginType, tty, msg);
1309 * Login restrictions disallow login.
1311 loginfailed(name, hostname, tty);
1316 * Check password expiration.
1318 rc = passwdexpired(name, msg);
1323 * Login succeeded, but password expired.
1325 return(VF_PASSWD_AGED);
1331 loginsuccess(name, hostname, tty, msg);
1338 /***************************************************************************
1340 * Start authentication routines (AIX)
1342 ***************************************************************************/
1345 #include <sys/types.h>
1346 #include <sys/errno.h>
1347 #include <usersec.h>
1349 #include <userconf.h>
1353 /***************************************************************************
1355 * External declarations (AIX)
1357 ***************************************************************************/
1362 /***************************************************************************
1364 * Procedure declarations (AIX)
1366 ***************************************************************************/
1368 static void Audit( struct passwd *p, char *msg, int errnum) ;
1369 static int PasswordAged(char *name, register struct passwd *pw) ;
1370 static void WriteBtmp( char *name) ;
1375 /***************************************************************************
1377 * Global variables (AIX)
1379 ***************************************************************************/
1384 /***************************************************************************
1388 ***************************************************************************/
1391 Audit( struct passwd *p, char *msg, int errnum )
1395 * make sure program is back to super-user...
1399 if ( (auditwrite ("USER_Login", AUDIT_OK,
1400 p->pw_name, strlen (p->pw_name) + 1,
1401 msg, strlen (msg) + 1, NULL)) == -1 )
1402 Debug(" Could not do Auditing\n");
1409 /***************************************************************************
1413 * log bad login attempts to /etc/security/failedlogin file
1416 ***************************************************************************/
1419 WriteBtmp( char *name )
1424 if( (fd = open("/etc/security/failedlogin",O_CREAT|O_RDWR,0644)) != -1) {
1425 bzero(&ut,sizeof(struct utmp));
1427 strncpy(ut.ut_user, name, sizeof ut.ut_user);
1428 ut.ut_type = USER_PROCESS;
1429 ut.ut_pid = getpid();
1430 ut.ut_time = time((time_t *)0);
1431 write(fd, (char *)&ut, sizeof(struct utmp));
1439 /***************************************************************************
1441 * PasswordAged (AIX)
1443 * see if password has aged
1444 ***************************************************************************/
1445 #define SECONDS_IN_WEEK 604800L
1448 PasswordAged(char *name, register struct passwd *pw )
1450 struct userpw *pupw; /* authentication information from getuserpw() */
1451 struct userpw upw; /* working authentication information */
1452 int err; /* return code from getconfattr() */
1453 ulong maxage; /* maximun age from getconfattr() */
1454 ulong now; /* time now */
1460 * Determine user password aging criteria. Note that only
1461 * the 'lastupdate' and 'flags' fields are set by this operation.
1464 if ((pupw = getuserpw(name)) != NULL)
1466 upw.upw_lastupdate = pupw->upw_lastupdate;
1467 upw.upw_flags = pupw->upw_flags;
1471 upw.upw_lastupdate = 0;
1477 * Consider password as having not expired if nocheck set.
1479 if (upw.upw_flags & PW_NOCHECK) return(FALSE);
1482 * Get system password aging criteria.
1484 err = getconfattr (SC_SYS_PASSWD, SC_MAXAGE, (void *)&maxage, SEC_INT);
1488 * Change from weeks to seconds
1490 maxage = maxage * SECONDS_IN_WEEK;
1491 now = time ((long *) 0);
1493 if ((upw.upw_lastupdate + maxage) >= now)
1496 * Password has not expired.
1504 * Could not retrieve system password aging info or maxage set to
1505 * zero. In either case, consider password has having not expired.
1511 * We haven't returned by now, so indicate password has expired.
1517 /***************************************************************************
1518 * dt_failedlogin (AIX)
1520 * log failed login in /etc/security/lastlog
1521 ***************************************************************************/
1533 dt_lastlogin ( char * user, struct lastlogin * llogin);
1536 dt_failedlogin(char *name, char *ttyName, char *hostName)
1538 struct lastlogin last_login;
1540 last_login.stime = 0;
1542 time(&last_login.ftime);
1544 last_login.ftty = ttyName;
1546 last_login.fhost = (char *) malloc (MAXHOSTNAMELEN);
1547 if (hostName == NULL) {
1548 gethostname (last_login.fhost , MAXHOSTNAMELEN);
1550 strncpy(last_login.fhost, hostName, MAXHOSTNAMELEN);
1551 last_login.fhost[MAXHOSTNAMELEN -1] = '\0';
1554 Debug("logging failed lastlogin entry (user=%s)\n",name);
1555 dt_lastlogin(name, &last_login);
1556 free(last_login.fhost);
1561 /***************************************************************************
1563 * Authenticate (AIX)
1567 * return codes indicate authentication results.
1568 ***************************************************************************/
1570 #define MAXATTEMPTS 3
1572 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
1575 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1578 static int login_attempts = 0; /* # failed authentications */
1579 struct passwd *p; /* password structure */
1587 * Nothing to do if no name provided.
1593 * Save provided password.
1596 if (!passwd) passwd = "";
1598 if(strlen(name) > S_NAMELEN)
1601 GetLoginInfo(d, &loginType, tty, &hostname);
1605 if (!p || strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) {
1609 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
1614 Audit(p, " Failed login (bailout)", 1);
1618 dt_failedlogin(name, tty, hostname);
1619 return (VF_INVALID);
1621 return(VF_CHALLENGE);
1624 /* Note: The password should be checked if it is the first time
1625 the user is logging in or whether the sysadm has changed
1626 the password for the user. Code should be added here if
1627 this functionality should be supported. The "upw_flags"
1628 of the password structure gets set to PW_ADMCHG in this
1633 * check password aging...
1636 if ( PasswordAged(name,p) ) return(VF_PASSWD_AGED);
1639 /* Validate for User Account RK 09.13.93 */
1640 if(ckuseracct(name, loginType, tty) == -1) {
1641 dt_failedlogin(name, tty, hostname);
1647 * validate uid and gid...
1651 if ((p->pw_gid < 0) ||
1652 (setgid(p->pw_gid) == -1)) {
1654 Audit(p, " attempted to login - bad group id", 1);
1658 if ((p->pw_uid < 0)) {
1659 Audit(p, " attempted to login - bad user id", 1);
1663 /* Check for max number of logins RK 09.13.93 */
1664 if (tsm_check_login(p->pw_uid) == -1) {
1665 dt_failedlogin(name, tty, hostname);
1669 /* Check for /etc/nologin file RK 09.13.93 */
1670 if ( (access("/etc/nologin",R_OK) == 0) && (p->pw_uid != 0) ) {
1671 dt_failedlogin(name, tty, hostname);
1676 * verify home directory exists...
1679 if(chdir(p->pw_dir) < 0) {
1680 Audit(p, " attempted to login - no home directory", 1);
1688 Audit(p, " Successful login", 0);
1692 /**************************************************************************
1696 * Checks for max number of logins on the system. If the new user trying to
1697 * login exceeds the max limit then the user is not allowed to login.
1700 **************************************************************************/
1702 /**************************************************************************
1706 * Checks for max number of logins on the system. If the new user trying to
1707 * login exceeds the max limit then the user is not allowed to login.
1710 **************************************************************************/
1713 tsm_check_login(uid_t uid)
1720 struct stat stat_buf;
1721 static struct sembuf sop = { 0, -1, (SEM_UNDO|IPC_NOWAIT) };
1722 static struct sembuf initsop = { 0, 0, (IPC_NOWAIT) };
1725 * The login counter semaphore may not be set yet. See if it exists
1726 * and try creating it with the correct count if it doesn't. An
1727 * attempt is made to create the semaphore. Only if that attempt fails
1728 * is the semaphore set to maxlogins from login.cfg.
1733 * Don't Check if the user is already logged. ie running login
1737 * Generate the semaphore key from the init program.
1739 Debug("Start of maxlogin check\n");
1740 if ((key = ftok (CDE_INSTALLATION_TOP "/bin/dtlogin", 1)) != (key_t) -1) {
1741 Debug("key created\n");
1742 if ((semid = semget (key, 1, IPC_CREAT|IPC_EXCL|0600)) != -1) {
1744 Debug("Completed IPCkey\n");
1745 if (! getconfattr ("usw", "maxlogins", &i, SEC_INT)) {
1746 Debug("Max logins from login.cfg is :%d\n",i);
1748 i = 10000; /* a very large number */
1751 if (semop (semid, &initsop, 1))
1753 Debug("failed while decrementing\n");
1757 semctl (semid, 1, IPC_RMID, 0);
1762 * Only 'n' login sessions are allowed on the system.
1763 * This code block decrements a semaphore.
1764 * The semundo value will be set to adjust the
1765 * semaphore when tsm exits.
1767 * This code will be ignored if the appropriate
1768 * semaphore set does not exist.
1771 if ((semid = semget (key, 1, 0)) != -1) {
1772 Debug("getting key for maxlogins\n");
1774 * If the semaphore is zero and we are not
1775 * root, then we fail as there are already the
1776 * allotted number of login sessions on the
1779 if ((semop (semid, &sop, 1) == -1) && uid) {
1780 Debug("reached MAXLOGINS limit\n");
1788 #endif /* !_POWER */
1790 /***************************************************************************
1792 * End authentication routines (AIX)
1794 ***************************************************************************/
1796 /***************************************************************************
1797 ***************************************************************************
1798 ***************************************************************************
1799 ***************************************************************************
1800 ***************************************************************************
1801 ***************************************************************************
1802 ***************************************************************************
1803 ***************************************************************************/
1807 /***************************************************************************
1809 * Start authentication routines (generic)
1811 ***************************************************************************/
1814 /***************************************************************************
1816 * These are a set of routine to do simple password, home dir, uid, and gid
1817 * validation. They can be used as a first pass validation for future
1820 * When platform specific validation is developed, those routines should be
1821 * included in their own section and the use of these routines discontinued.
1823 ***************************************************************************/
1828 /***************************************************************************
1830 * External declarations (generic)
1832 ***************************************************************************/
1837 /***************************************************************************
1839 * Procedure declarations (generic)
1841 ***************************************************************************/
1843 static void Audit( struct passwd *p, char *msg, int errnum) ;
1844 static int PasswordAged( register struct passwd *pw) ;
1845 static void WriteBtmp( char *name) ;
1850 /***************************************************************************
1852 * Global variables (generic)
1854 ***************************************************************************/
1859 /***************************************************************************
1863 ***************************************************************************/
1866 Audit( struct passwd *p, char *msg, int errnum )
1870 * make sure program is back to super-user...
1872 if(-1 == seteuid(0)) {
1873 perror(strerror(errno));
1882 /***************************************************************************
1884 * WriteBtmp (generic)
1886 * log bad login attempts
1888 ***************************************************************************/
1891 WriteBtmp( char *name )
1899 /***************************************************************************
1901 * PasswordAged (Generic)
1903 * see if password has aged
1904 ***************************************************************************/
1905 #define SECONDS_IN_WEEK 604800L
1908 PasswordAged( register struct passwd *pw )
1915 /***************************************************************************
1917 * Authenticate (generic)
1921 * return codes indicate authentication results.
1922 ***************************************************************************/
1924 #define MAXATTEMPTS 3
1926 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
1929 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1932 static int login_attempts = 0; /* # failed authentications */
1934 struct passwd *p; /* password structure */
1942 * Nothing to do if no name provided.
1948 * Save provided password.
1951 if (!passwd) passwd = "";
1957 * Use the Linux Shadow Password system to get the crypt()ed password
1960 struct spwd *s = getspnam(name);
1962 p->pw_passwd = s->sp_pwdp;
1967 if (!p || strlen(name) == 0 ||
1968 strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) {
1972 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
1977 Audit(p, " Failed login (bailout)", 1);
1981 return(origpw ? VF_INVALID : VF_CHALLENGE);
1986 * check password aging...
1989 if ( PasswordAged(p) ) return(VF_PASSWD_AGED);
1993 * verify home directory exists...
1996 if(chdir(p->pw_dir) < 0) {
1997 Audit(p, " attempted to login - no home directory", 1);
2003 * validate uid and gid...
2007 if (setgid(p->pw_gid) == -1) {
2009 Audit(p, " attempted to login - bad group id", 1);
2013 if (seteuid(p->pw_uid) == -1) {
2015 Audit(p, " attempted to login - bad user id", 1);
2025 Audit(p, " Successful login", 0);
2032 /***************************************************************************
2034 * End authentication routines (generic)
2036 ***************************************************************************/
2037 #endif /* generic */
2041 /***************************************************************************
2042 ***************************************************************************
2043 ***************************************************************************
2044 ***************************************************************************
2045 ***************************************************************************
2046 ***************************************************************************
2047 ***************************************************************************
2048 ***************************************************************************/