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
71 ** _POWER AIX version 4 only
73 ****************************************************************************
74 ************************************<+>*************************************/
77 /***************************************************************************
81 ***************************************************************************/
89 #include <security/pam_appl.h>
95 #include <sys/access.h>
99 #include <sys/audit.h>
102 /* necessary for bzero */
104 #include <X11/Xfuncs.h>
116 * Define as generic those without platform specific code.
118 #if !(defined(__hpux) || defined(__apollo) || defined(_AIX) || defined(sun))
122 #if defined(__linux__)
127 /***************************************************************************
129 * Start authentication routines (HPUX)
131 ***************************************************************************/
133 #include <sys/param.h> /* for MAXUID macro */
134 #include <sys/types.h>
135 #include <sys/utsname.h>
142 # include <sys/audit.h>
143 # include <sys/errno.h>
144 # include <sys/stat.h>
145 # define SECUREPASS "/.secure/etc/passwd"
149 # include <sys/security.h>
154 #include <afs/kautils.h>
159 # define KRBLIFE 255 /* max lifetime */
160 #endif /* __KERBEROS */
163 # include "rgy_base.h"
168 #define how_to_count ut_exit.e_exit
171 int num_users[] = { 2, 32767 };
172 # define MIN_VERSION 'A'
173 # define UNLIMITED 'B'
175 int num_users[] = { 2, 16, 32, 64 , 8 };
176 # define MIN_VERSION 'A'
177 # define UNLIMITED 'U'
180 /* Maximum number of users allowed with restricted license */
181 #if OSMAJORVERSION < 8
182 # define MAX_STRICT_USERS 2
184 # define MAX_STRICT_USERS 8
187 #define NUM_VERSIONS (sizeof(num_users)/sizeof(num_users[0])) - 1
189 extern char *globalDisplayName;
191 /***************************************************************************
193 * External declarations (HPUX)
195 ***************************************************************************/
197 extern long groups[NGROUPS];
201 extern boolean rgy_$using_local_registry();
202 extern struct passwd * getpwnam_full();
203 extern boolean is_acct_expired();
204 extern boolean is_passwd_expired();
205 extern boolean is_passwd_invalid();
206 extern boolean rgy_$is_des();
211 /***************************************************************************
213 * Procedure declarations (HPUX)
215 ***************************************************************************/
217 static void Audit( struct passwd *p, char *msg, int errnum) ;
218 static int CheckPassword( char *name, char *passwd, struct passwd **ppwd );
219 static int CountUsers( int added_users) ;
220 static int CountUsersStrict( char *new_user) ;
221 static int PasswordAged( register struct passwd *pw) ;
222 static void WriteBtmp( char *name) ;
227 /***************************************************************************
229 * Global variables (HPUX)
231 ***************************************************************************/
234 struct s_passwd *s_pwd;
236 int secure; /* flag to denote existence of secure passwd file */
241 struct pr_passwd *b1_pwd;
245 rgy_$acct_admin_t admin_part;
246 rgy_$policy_t policy;
247 rgy_$acct_user_t user_part;
252 /***************************************************************************
256 * Construct self audit record for event and write to the audit trail.
257 * This routine assumes that the effective uid is currently 0. If auditing
258 * is not defined, this routine does nothing.
259 ***************************************************************************/
262 Audit( struct passwd *p, char *msg, int errnum )
268 struct self_audit_rec audrec;
273 * make sure program is back to super-user...
281 txtptr = (char *)audrec.aud_body.text;
282 sprintf(txtptr, "User= %s uid=%ld audid=%ld%s", p->pw_name,
283 (long)p->pw_uid, (long)p->pw_audid, msg);
284 audrec.aud_head.ah_pid = getpid();
285 audrec.aud_head.ah_error = errnum;
286 audrec.aud_head.ah_event = EN_LOGINS;
287 audrec.aud_head.ah_len = strlen (txtptr);
288 status = audwrite(&audrec);
294 LogError(ReadCatalog(
295 MC_LOG_SET,MC_LOG_NOT_SUSER,MC_DEF_LOG_NOT_SUSER));
299 LogError(ReadCatalog(
300 MC_LOG_SET,MC_LOG_INV_EVENT,MC_DEF_LOG_INV_EVENT));
304 LogError(ReadCatalog(
305 MC_LOG_SET,MC_LOG_ERR_ERRNO,MC_DEF_LOG_ERR_ERRNO),
322 /***************************************************************************
324 * CountUsers (HPUX only)
326 * see if new user has exceeded the maximum.
327 ***************************************************************************/
332 CountUsers( int added_users )
334 int count[NCOUNT], nusers, i;
337 for (i=0; i<NCOUNT; i++)
340 count[added_users]++;
342 while ( (entry = getutent()) != NULL) {
343 if (entry->ut_type == USER_PROCESS) {
344 i = entry->how_to_count;
345 if (i < 0 || i >= NCOUNT)
346 i = 1; /* if out of range, then count */
347 /* as ordinary user */
355 * [0] does not count at all
356 * [1] counts as real user
357 * [2] logins via a pty which have not gone trough login. These
358 * collectively count as 1 user IF count[3] is 0, otherwise,
359 * they are not counted. Starting with HP-UX 8.0 they are
360 * no longer counted at all.
361 * [3] logins via a pty which have been logged through login (i.e.
362 * rlogin and telnet). these count as 1 "real" user per
364 * [4-15] may be used for groups of users which collectively
369 #if OSMAJORVERSION < 8
370 for (i=2; i<NCOUNT; i++)
372 for (i=3; i<NCOUNT; i++)
383 /***************************************************************************
385 * CountUsersStrict (HPUX only)
387 * see if new user has exceeded the maximum.
388 ***************************************************************************/
391 CountUsersStrict( char *new_user )
393 char pty_users[MAX_STRICT_USERS][8];
394 int count[NCOUNT], nusers, i, cnt, pty_off = -1, uname_off;
398 * Initialize count array...
400 for (i = 0; i < NCOUNT; i++)
404 * Add in the new user (we know it's not a pty)...
408 while ( (entry = getutent()) != NULL ) {
409 if (entry->ut_type == USER_PROCESS) {
410 i = entry->how_to_count;
412 /* if out of range, then count as ordinary user logged in
414 if (i == 1 || (i < 0 || i >= NCOUNT))
416 /* See if it is a pty login granted by login program */
419 /* See if user is already logged in via login pty */
421 for (cnt = 0; cnt <= pty_off; cnt++)
422 if (strncmp(pty_users[cnt], entry->ut_user, 8) == 0)
425 if (uname_off == -1) { /* user is not logged in via pty yet */
427 if (pty_off >= MAX_STRICT_USERS) /* cannot add any
429 return(MAX_STRICT_USERS + 1);
430 /* add the user name to the array of pty users */
432 strncpy(pty_users[++pty_off], entry->ut_user, 8);
434 } /* end if (i == 3) */
437 } /* end if entry->ut_type == USER_PROCESS */
438 } /* end while (entry = getutent()) */
443 * [0] does not count at all
444 * [1] counts as "real" user
445 * [2] logins via a pty which have not gone trough login. These
446 * collectively count as 1 user IF count[3] is 0, otherwise,
447 * they are not counted. Starting with HP-UX 8.0 they are
448 * no longer counted at all.
449 * [3] logins via a pty which have been logged through login (i.e.
450 * rlogin and telnet). these count as 1 "real" user per
452 * [4-15] may be used for groups of users which collectively count
456 nusers = pty_off + 1 + count[1]; /* Current number of users is sum of
457 users logged in via tty + the
458 number of unique users logged in
459 via pty which have gone through
462 #if OSMAJORVERSION < 8
463 if ((count[3] == 0) && (count[2] != 0))
464 nusers++; /* Add 1 user for all pty logins IF
465 none of pty logins have been
466 granted by the login program */
469 * Don't count any hpterm logins (exit status of 2). We already
470 * counted all pty logins granted by the login program.
474 for (i = 4; i < NCOUNT; i++)
483 /***************************************************************************
485 * PasswordAged (HPUX)
487 * see if password has aged
488 ***************************************************************************/
489 #define SECONDS_IN_WEEK 604800L
492 PasswordAged( register struct passwd *pw )
494 long change_week; /* week password was changed (1/1/70 = Week 0) */
495 long last_week; /* week after which password must change */
496 long first_week; /* week before which password can't change */
497 long this_week; /* this week derived from time() */
499 char *passwdAge; /* password aging time */
506 passwdAge = pw->pw_age;
510 passwdAge = s_pwd->pw_age;
515 /* Account validity checks: If we were able to connect to the network
516 * registry, then we've acquired account and policy data and can perform
517 * account/password checking
520 lrgy = rgy_$using_local_registry();
523 /* Check for password expiration or invalidity */
524 if ( rgy_$is_passwd_expired(&user_part, &policy ) != 0 ) {
532 if (*passwdAge == NULL)
535 first_week = last_week = change_week = (long) a64l(passwdAge);
536 last_week &= 0x3f; /* first six bits */
537 first_week = (first_week >> 6) & 0x3f; /* next six bits */
538 change_week >>= 12; /* everything else */
540 this_week = (long) time((long *) 0) / SECONDS_IN_WEEK;
543 ** Password aging conditions:
544 ** * if the last week is less than the first week (e.g., the aging
545 ** field looks like "./"), only the superuser can change the
546 ** password. We don't request a new password.
547 ** * if the week the password was last changed is after this week,
548 ** we have a problem, and request a new password.
549 ** * if this week is after the specified aging time, we request
552 if (last_week < first_week)
555 if (change_week <= this_week && this_week <= (change_week + last_week))
565 /***************************************************************************
567 * CheckPassword (HPUX only)
569 * Check validity of user password. One of several authentication schemes
570 * can be used, including Kerberos, AFS 3, HP BLS and traditional
571 * /etc/passwd. These are selectable via a resource in Dtlogin.
573 * Domain registry authentication (PasswdEtc) can also be compiled in as
574 * the only authentication scheme used.
576 ***************************************************************************/
579 CheckPassword( char *name, char *passwd, struct passwd **ppwd )
588 char realm[REALM_SZ];
590 #endif /* __KERBEROS */
595 * validate that user has an entry in the shadow password file on an
596 * HP-UX C2 trusted system. Keep info in a global structure.
600 s_pwd = getspwnam(name);
610 * look up user's regular account information...
615 * look up entry from registry...
617 * need getpwnam_full to get policy data for passwd expiration
620 p = getpwnam_full(name, &user_part, &admin_part, &policy);
628 if ( p == NULL || strlen(name) == 0 )
635 * AFS password authentication...
638 if ( vg_IsVerifyName(VN_AFS) ) {
640 if ( ka_UserAuthenticateGeneral(
641 KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG,
642 p->pw_name, /* kerberos name */
643 (char *)0, /* instance */
644 (char *)0, /* realm */
645 passwd, /* password */
646 0, /* default lifetime */
649 &reason) == 0 ) { /* error string */
651 if (strcmp(p->pw_passwd, "*") == 0)
658 LogError(ReadCatalog(
659 MC_LOG_SET,MC_LOG_AFS_FAILATH,MC_DEF_LOG_AFS_FAILATH),reason);
668 * Kerberos password authentication...
671 if ( vg_IsVerifyName(VN_KRB) ) {
673 (void)krb_get_lrealm(realm, 1);
675 setresuid(p->pw_uid, p->pw_uid, -1);
676 kerno = krb_get_pw_in_tkt(p->pw_name,
686 if (kerno == KSUCCESS)
687 if (strcmp(p->pw_passwd, "*") == 0)
693 #endif /* __KERBEROS */
698 * traditional password verification...
701 if (strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd) == 0)
707 * If regular passwd check fails, try old-style Apollo SR
710 if (rgy_$is_des(passwd, strlen(passwd), p->pw_passwd) == TRUE)
716 * all password checks failed...
726 /***************************************************************************
728 * Authenticate (HPUX)
732 * return codes indicate authentication results.
733 ***************************************************************************/
735 #define MAXATTEMPTS 3
737 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
740 Authenticate( struct display *d, char *name, char *passwd, char **msg )
743 static int login_attempts = 0; /* # failed authentications */
745 struct passwd *p = NULL; /* password structure */
747 struct utsname utsnam;
753 * Nothing to do if no name provided.
760 if (strlen(name) == 0)
764 return(VF_CHALLENGE);
771 * Save provided password.
774 if (!passwd) passwd = "";
778 * turn on self auditing...
781 if (audswitch(AUD_SUSPEND) == -1)
787 * set the secure flag if SECUREPASS exists. If so, we
788 * are using it for authentication instead of /etc/passwd...
791 secure = (stat(SECUREPASS, &s_pfile) < 0) ? 0:1;
795 * set the audit process flag unconditionally on since we want
796 * to log all logins regardless of whether the user's audit
801 setaudproc(AUD_PROC);
807 * validate password...
810 if ( CheckPassword(name, passwd, &p) == FALSE) {
814 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
819 Audit(p, " Failed login (bailout)", 1);
823 return(origpw ? VF_INVALID : VF_CHALLENGE);
828 * check restricted license...
830 * Note: This only applies to local displays. Foreign displays
831 * (i.e. X-terminals) apparently do not count.
834 /* Get the version info via uname. If it doesn't look right,
835 * assume the smallest user configuration
838 if (uname(&utsnam) < 0)
839 utsnam.version[0] = MIN_VERSION;
851 if ((!strncmp(utsnam.machine, "9000/834", UTSLEN)) ||
852 (!strncmp(utsnam.machine, "9000/844", UTSLEN)) ||
853 (!strncmp(utsnam.machine, "9000/836", UTSLEN)) ||
854 (!strncmp(utsnam.machine, "9000/846", UTSLEN)) ||
855 (!strncmp(utsnam.machine, "9000/843", UTSLEN)) ||
856 (!strncmp(utsnam.machine, "9000/853", UTSLEN))) {
858 /* strict_count = 1;*/
859 if (CountUsersStrict(name) > MAX_STRICT_USERS) {
861 " attempted to login - too many users on the system",
864 return(VF_MAX_USERS);
868 if (utsnam.version[0] != UNLIMITED) {
869 if ((utsnam.version[0]-'A' < 0) ||
870 (utsnam.version[0]-'A' > NUM_VERSIONS))
871 utsnam.version[0] = MIN_VERSION;
873 n = (int) utsnam.version[0] - 'A';
874 if (CountUsers(1) > num_users[n]) {
876 " attempted to login - too many users on the system",
879 return(VF_MAX_USERS);
887 * Check for account validity. Unfortunately, we have no graphical
888 * dialog for this at this time so the best we can do is log an
889 * error message and hope the system administrator sees it.
892 if ( !rgy_$using_local_registry() ) {
893 if (rgy_$is_acct_expired(&admin_part) != 0 ) {
894 LogError(ReadCatalog(MC_LOG_SET,MC_LOG_ACC_EXP,MC_DEF_LOG_ACC_EXP),
902 * check password aging...
905 if ( PasswordAged(p) ) return(VF_PASSWD_AGED);
909 * verify home directory exists...
912 if(chdir(p->pw_dir) < 0) {
913 Audit(p, " attempted to login - no home directory", 1);
920 * check audit flag and id...
925 if (secure && (p->pw_audflg > 1 || p->pw_audflg < 0)) {
926 Audit(p, " attempted to login - bad audit flag", 1);
927 return(VF_BAD_AFLAG);
930 if (secure && (setaudid(p->pw_audid) == -1 )) {
931 Audit(p, " attempted to login - bad audit id", 1);
938 * validate uid and gid...
941 if ((p->pw_gid < 0) ||
942 (p->pw_gid > MAXUID) ||
943 (setgid(p->pw_gid) == -1)) {
945 Audit(p, " attempted to login - bad group id", 1);
952 * ka_UserAuthenticateGeneral() sets the group access of this process
953 * to the proper PAG. Pick up these values and pass them back to
954 * Dtlogin to be put into the user's environment...
957 if ( vg_IsVerifyName(VN_AFS) ) {
958 groups[0] = groups[1] = 0;
959 getgroups(NGROUPS, groups);
965 if ((p->pw_uid < 0) ||
966 (p->pw_uid > MAXUID) ||
967 (setresuid(p->pw_uid, p->pw_uid, 0) == -1)) {
969 Audit(p, " attempted to login - bad user id", 1);
980 Audit(p, " Successful login", 0);
987 /***************************************************************************
991 * log bad login attempts
993 ***************************************************************************/
996 WriteBtmp( char *name )
999 struct utmp utmp, *u;
1003 bzero(&utmp, sizeof(struct utmp));
1005 utmp.ut_pid = getppid();
1006 while ((u = getutent()) != NULL) {
1007 if ( (u->ut_type == INIT_PROCESS ||
1008 u->ut_type == LOGIN_PROCESS ||
1009 u->ut_type == USER_PROCESS) &&
1010 u->ut_pid == utmp.ut_pid ) {
1019 * if no utmp entry, this may be an X-terminal. Construct a utmp
1024 strncpy(utmp.ut_id, "??", sizeof(utmp.ut_id));
1025 strncpy(utmp.ut_line, globalDisplayName, sizeof(utmp.ut_line));
1026 utmp.ut_type = LOGIN_PROCESS;
1028 strncpy(utmp.ut_host, globalDisplayName, sizeof(utmp.ut_host));
1035 * If btmp exists, then record the bad attempt
1037 if ( (fd = open(BTMP_FILE,O_WRONLY|O_APPEND)) >= 0) {
1038 strncpy(u->ut_user, name, sizeof(u->ut_user));
1039 (void) time(&u->ut_time);
1040 write(fd, (char *)u, sizeof(utmp));
1044 endutent(); /* Close utmp file */
1047 /***************************************************************************
1049 * End authentication routines (HPUX)
1051 ***************************************************************************/
1055 /***************************************************************************
1056 ***************************************************************************
1057 ***************************************************************************
1058 ***************************************************************************
1059 ***************************************************************************
1060 ***************************************************************************
1061 ***************************************************************************
1062 ***************************************************************************/
1066 /***************************************************************************
1068 * Start authentication routines (SUN)
1070 ***************************************************************************/
1072 #include "solaris.h"
1074 #include <security/ia_appl.h>
1078 /***************************************************************************
1080 * Procedure declarations (SUN)
1082 ***************************************************************************/
1084 static void Audit( struct passwd *p, char *msg, int errnum) ;
1088 /***************************************************************************
1092 ***************************************************************************/
1095 Audit( struct passwd *p, char *msg, int errnum )
1099 * make sure program is back to super-user...
1104 Debug("Audit: %s\n", msg);
1110 /***************************************************************************
1112 * Authenticate (SUN)
1116 * return codes indicate authentication results.
1117 ***************************************************************************/
1120 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1123 char* ttyLine = d->gettyLine;
1126 * Nothing to do if no name provided.
1133 * Construct device line
1135 #ifdef DEF_NETWORK_DEV
1137 * If location is not local (remote XDMCP dtlogin) and
1138 * remote accouting is enabled (networkDev start with /dev/...)
1139 * Set tty line name to match network device for accouting.
1140 * Unless the resource was specifically set, default is value
1141 * of DEF_NETWORK_DEV define (/dev/dtremote)
1144 if ( d->displayType.location != Local &&
1145 networkDev && !strncmp(networkDev,"/dev/",5)) {
1146 ttyLine = networkDev+5;
1151 * Authenticate user and return status
1155 status = PamAuthenticate("dtlogin", d->name, passwd, name, ttyLine);
1161 case PAM_NEW_AUTHTOK_REQD:
1162 return(VF_PASSWD_AGED);
1165 return(passwd ? VF_INVALID : VF_CHALLENGE);
1168 status = solaris_authenticate("dtlogin", d->name, passwd, name, ttyLine);
1174 case IA_NEWTOK_REQD:
1175 return(VF_PASSWD_AGED);
1178 return(passwd ? VF_INVALID : VF_CHALLENGE);
1185 /***************************************************************************
1187 * End authentication routines (SUN)
1189 ***************************************************************************/
1192 /***************************************************************************
1193 ***************************************************************************
1194 ***************************************************************************
1195 ***************************************************************************
1196 ***************************************************************************/
1198 /***************************************************************************
1202 * get the information from the display about local/remote login and
1203 * create a dummy tty name for loginrestrictions.
1205 ***************************************************************************/
1207 GetLoginInfo(struct display *d, int *loginType, char *ttyName, char **hostname)
1211 CleanUpName(d->name, workarea, 128);
1212 sprintf(ttyName, "/dev/dtlogin/%s", workarea);
1214 if (d->displayType.location == Foreign) {
1215 *loginType = S_RLOGIN;
1216 *hostname = d->name;
1217 Debug("Login Info - Remote user on tty=%s.\n", ttyName);
1219 *loginType = S_LOGIN;
1221 Debug("Login Info - Local user on tty=%s.\n", ttyName);
1225 /***************************************************************************
1227 * Authenticate (AIX version 4.1)
1231 * return codes indicate authentication results.
1232 ***************************************************************************/
1233 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1239 static char *msgpending;
1244 GetLoginInfo(d, &loginType, tty, &hostname);
1254 * No more challenges. User failed login.
1257 loginfailed(name, hostname, tty);
1262 * Authenticate with response to last challenge.
1264 rc = authenticate(name, passwd, &reenter, msg);
1269 * System has presented user with new challenge.
1271 return(VF_CHALLENGE);
1274 if (rc && errno == ENOENT)
1277 * User is unknown to the system. Simulate a password
1278 * challenge, but save message for display for next call.
1281 return(VF_CHALLENGE);
1287 * No more challenges. User failed login.
1289 loginfailed(name, hostname, tty);
1294 * User authenticated. Check login restrictions.
1296 rc = loginrestrictions(name, loginType, tty, msg);
1301 * Login restrictions disallow login.
1303 loginfailed(name, hostname, tty);
1308 * Check password expiration.
1310 rc = passwdexpired(name, msg);
1315 * Login succeeded, but password expired.
1317 return(VF_PASSWD_AGED);
1323 loginsuccess(name, hostname, tty, msg);
1330 /***************************************************************************
1332 * Start authentication routines (AIX)
1334 ***************************************************************************/
1337 #include <sys/types.h>
1338 #include <sys/errno.h>
1339 #include <usersec.h>
1341 #include <userconf.h>
1345 /***************************************************************************
1347 * External declarations (AIX)
1349 ***************************************************************************/
1354 /***************************************************************************
1356 * Procedure declarations (AIX)
1358 ***************************************************************************/
1360 static void Audit( struct passwd *p, char *msg, int errnum) ;
1361 static int PasswordAged(char *name, register struct passwd *pw) ;
1362 static void WriteBtmp( char *name) ;
1367 /***************************************************************************
1369 * Global variables (AIX)
1371 ***************************************************************************/
1376 /***************************************************************************
1380 ***************************************************************************/
1383 Audit( struct passwd *p, char *msg, int errnum )
1387 * make sure program is back to super-user...
1391 if ( (auditwrite ("USER_Login", AUDIT_OK,
1392 p->pw_name, strlen (p->pw_name) + 1,
1393 msg, strlen (msg) + 1, NULL)) == -1 )
1394 Debug(" Could not do Auditing\n");
1401 /***************************************************************************
1405 * log bad login attempts to /etc/security/failedlogin file
1408 ***************************************************************************/
1411 WriteBtmp( char *name )
1416 if( (fd = open("/etc/security/failedlogin",O_CREAT|O_RDWR,0644)) != -1) {
1417 bzero(&ut,sizeof(struct utmp));
1419 strncpy(ut.ut_user, name, sizeof ut.ut_user);
1420 ut.ut_type = USER_PROCESS;
1421 ut.ut_pid = getpid();
1422 ut.ut_time = time((time_t *)0);
1423 write(fd, (char *)&ut, sizeof(struct utmp));
1431 /***************************************************************************
1433 * PasswordAged (AIX)
1435 * see if password has aged
1436 ***************************************************************************/
1437 #define SECONDS_IN_WEEK 604800L
1440 PasswordAged(char *name, register struct passwd *pw )
1442 struct userpw *pupw; /* authentication information from getuserpw() */
1443 struct userpw upw; /* working authentication information */
1444 int err; /* return code from getconfattr() */
1445 ulong maxage; /* maximun age from getconfattr() */
1446 ulong now; /* time now */
1452 * Determine user password aging criteria. Note that only
1453 * the 'lastupdate' and 'flags' fields are set by this operation.
1456 if ((pupw = getuserpw(name)) != NULL)
1458 upw.upw_lastupdate = pupw->upw_lastupdate;
1459 upw.upw_flags = pupw->upw_flags;
1463 upw.upw_lastupdate = 0;
1469 * Consider password as having not expired if nocheck set.
1471 if (upw.upw_flags & PW_NOCHECK) return(FALSE);
1474 * Get system password aging criteria.
1476 err = getconfattr (SC_SYS_PASSWD, SC_MAXAGE, (void *)&maxage, SEC_INT);
1480 * Change from weeks to seconds
1482 maxage = maxage * SECONDS_IN_WEEK;
1483 now = time ((long *) 0);
1485 if ((upw.upw_lastupdate + maxage) >= now)
1488 * Password has not expired.
1496 * Could not retrieve system password aging info or maxage set to
1497 * zero. In either case, consider password has having not expired.
1503 * We haven't returned by now, so indicate password has expired.
1509 /***************************************************************************
1510 * dt_failedlogin (AIX)
1512 * log failed login in /etc/security/lastlog
1513 ***************************************************************************/
1525 dt_lastlogin ( char * user, struct lastlogin * llogin);
1528 dt_failedlogin(char *name, char *ttyName, char *hostName)
1530 struct lastlogin last_login;
1532 last_login.stime = 0;
1534 time(&last_login.ftime);
1536 last_login.ftty = ttyName;
1538 last_login.fhost = (char *) malloc (MAXHOSTNAMELEN);
1539 if (hostName == NULL) {
1540 gethostname (last_login.fhost , MAXHOSTNAMELEN);
1542 strncpy(last_login.fhost, hostName, MAXHOSTNAMELEN);
1543 last_login.fhost[MAXHOSTNAMELEN -1] = '\0';
1546 Debug("logging failed lastlogin entry (user=%s)\n",name);
1547 dt_lastlogin(name, &last_login);
1548 free(last_login.fhost);
1553 /***************************************************************************
1555 * Authenticate (AIX)
1559 * return codes indicate authentication results.
1560 ***************************************************************************/
1562 #define MAXATTEMPTS 3
1564 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
1567 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1570 static int login_attempts = 0; /* # failed authentications */
1571 struct passwd *p; /* password structure */
1579 * Nothing to do if no name provided.
1585 * Save provided password.
1588 if (!passwd) passwd = "";
1590 if(strlen(name) > S_NAMELEN)
1593 GetLoginInfo(d, &loginType, tty, &hostname);
1597 if (!p || strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) {
1601 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
1606 Audit(p, " Failed login (bailout)", 1);
1610 dt_failedlogin(name, tty, hostname);
1611 return (VF_INVALID);
1613 return(VF_CHALLENGE);
1616 /* Note: The password should be checked if it is the first time
1617 the user is logging in or whether the sysadm has changed
1618 the password for the user. Code should be added here if
1619 this functionality should be supported. The "upw_flags"
1620 of the password structure gets set to PW_ADMCHG in this
1625 * check password aging...
1628 if ( PasswordAged(name,p) ) return(VF_PASSWD_AGED);
1631 /* Validate for User Account RK 09.13.93 */
1632 if(ckuseracct(name, loginType, tty) == -1) {
1633 dt_failedlogin(name, tty, hostname);
1639 * validate uid and gid...
1643 if ((p->pw_gid < 0) ||
1644 (setgid(p->pw_gid) == -1)) {
1646 Audit(p, " attempted to login - bad group id", 1);
1650 if ((p->pw_uid < 0)) {
1651 Audit(p, " attempted to login - bad user id", 1);
1655 /* Check for max number of logins RK 09.13.93 */
1656 if (tsm_check_login(p->pw_uid) == -1) {
1657 dt_failedlogin(name, tty, hostname);
1661 /* Check for /etc/nologin file RK 09.13.93 */
1662 if ( (access("/etc/nologin",R_OK) == 0) && (p->pw_uid != 0) ) {
1663 dt_failedlogin(name, tty, hostname);
1668 * verify home directory exists...
1671 if(chdir(p->pw_dir) < 0) {
1672 Audit(p, " attempted to login - no home directory", 1);
1680 Audit(p, " Successful login", 0);
1684 /**************************************************************************
1688 * Checks for max number of logins on the system. If the new user trying to
1689 * login exceeds the max limit then the user is not allowed to login.
1692 **************************************************************************/
1694 /**************************************************************************
1698 * Checks for max number of logins on the system. If the new user trying to
1699 * login exceeds the max limit then the user is not allowed to login.
1702 **************************************************************************/
1705 tsm_check_login(uid_t uid)
1712 struct stat stat_buf;
1713 static struct sembuf sop = { 0, -1, (SEM_UNDO|IPC_NOWAIT) };
1714 static struct sembuf initsop = { 0, 0, (IPC_NOWAIT) };
1717 * The login counter semaphore may not be set yet. See if it exists
1718 * and try creating it with the correct count if it doesn't. An
1719 * attempt is made to create the semaphore. Only if that attempt fails
1720 * is the semaphore set to maxlogins from login.cfg.
1725 * Don't Check if the user is already logged. ie running login
1729 * Generate the semaphore key from the init program.
1731 Debug("Start of maxlogin check\n");
1732 if ((key = ftok (CDE_INSTALLATION_TOP "/bin/dtlogin", 1)) != (key_t) -1) {
1733 Debug("key created\n");
1734 if ((semid = semget (key, 1, IPC_CREAT|IPC_EXCL|0600)) != -1) {
1736 Debug("Completed IPCkey\n");
1737 if (! getconfattr ("usw", "maxlogins", &i, SEC_INT)) {
1738 Debug("Max logins from login.cfg is :%d\n",i);
1740 i = 10000; /* a very large number */
1743 if (semop (semid, &initsop, 1))
1745 Debug("failed while decrementing\n");
1749 semctl (semid, 1, IPC_RMID, 0);
1754 * Only 'n' login sessions are allowed on the system.
1755 * This code block decrements a semaphore.
1756 * The semundo value will be set to adjust the
1757 * semaphore when tsm exits.
1759 * This code will be ignored if the appropriate
1760 * semaphore set does not exist.
1763 if ((semid = semget (key, 1, 0)) != -1) {
1764 Debug("getting key for maxlogins\n");
1766 * If the semaphore is zero and we are not
1767 * root, then we fail as there are already the
1768 * allotted number of login sessions on the
1771 if ((semop (semid, &sop, 1) == -1) && uid) {
1772 Debug("reached MAXLOGINS limit\n");
1780 #endif /* !_POWER */
1782 /***************************************************************************
1784 * End authentication routines (AIX)
1786 ***************************************************************************/
1788 /***************************************************************************
1789 ***************************************************************************
1790 ***************************************************************************
1791 ***************************************************************************
1792 ***************************************************************************
1793 ***************************************************************************
1794 ***************************************************************************
1795 ***************************************************************************/
1799 /***************************************************************************
1801 * Start authentication routines (generic)
1803 ***************************************************************************/
1806 /***************************************************************************
1808 * These are a set of routine to do simple password, home dir, uid, and gid
1809 * validation. They can be used as a first pass validation for future
1812 * When platform specific validation is developed, those routines should be
1813 * included in their own section and the use of these routines discontinued.
1815 ***************************************************************************/
1820 /***************************************************************************
1822 * External declarations (generic)
1824 ***************************************************************************/
1829 /***************************************************************************
1831 * Procedure declarations (generic)
1833 ***************************************************************************/
1835 static void Audit( struct passwd *p, char *msg, int errnum) ;
1836 static int PasswordAged( register struct passwd *pw) ;
1837 static void WriteBtmp( char *name) ;
1842 /***************************************************************************
1844 * Global variables (generic)
1846 ***************************************************************************/
1851 /***************************************************************************
1855 ***************************************************************************/
1858 Audit( struct passwd *p, char *msg, int errnum )
1862 * make sure program is back to super-user...
1864 if(-1 == seteuid(0)) {
1865 perror(strerror(errno));
1874 /***************************************************************************
1876 * WriteBtmp (generic)
1878 * log bad login attempts
1880 ***************************************************************************/
1883 WriteBtmp( char *name )
1891 /***************************************************************************
1893 * PasswordAged (Generic)
1895 * see if password has aged
1896 ***************************************************************************/
1897 #define SECONDS_IN_WEEK 604800L
1900 PasswordAged( register struct passwd *pw )
1907 /***************************************************************************
1909 * Authenticate (generic)
1913 * return codes indicate authentication results.
1914 ***************************************************************************/
1916 #define MAXATTEMPTS 3
1918 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
1921 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1924 static int login_attempts = 0; /* # failed authentications */
1926 struct passwd *p; /* password structure */
1934 * Nothing to do if no name provided.
1940 * Save provided password.
1943 if (!passwd) passwd = "";
1947 #if defined(__linux__)
1949 * Use the Linux Shadow Password system to get the crypt()ed password
1952 struct spwd *s = getspnam(name);
1954 p->pw_passwd = s->sp_pwdp;
1959 if (!p || strlen(name) == 0 ||
1960 strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) {
1964 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
1969 Audit(p, " Failed login (bailout)", 1);
1973 return(origpw ? VF_INVALID : VF_CHALLENGE);
1978 * check password aging...
1981 if ( PasswordAged(p) ) return(VF_PASSWD_AGED);
1985 * verify home directory exists...
1988 if(chdir(p->pw_dir) < 0) {
1989 Audit(p, " attempted to login - no home directory", 1);
1995 * validate uid and gid...
1999 if (setgid(p->pw_gid) == -1) {
2001 Audit(p, " attempted to login - bad group id", 1);
2005 if (seteuid(p->pw_uid) == -1) {
2007 Audit(p, " attempted to login - bad user id", 1);
2017 Audit(p, " Successful login", 0);
2024 /***************************************************************************
2026 * End authentication routines (generic)
2028 ***************************************************************************/
2029 #endif /* generic */
2033 /***************************************************************************
2034 ***************************************************************************
2035 ***************************************************************************
2036 ***************************************************************************
2037 ***************************************************************************
2038 ***************************************************************************
2039 ***************************************************************************
2040 ***************************************************************************/