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
71 ** SVR4 SUN OS and USL
73 ** _POWER AIX version 4 only
75 ****************************************************************************
76 ************************************<+>*************************************/
79 /***************************************************************************
83 ***************************************************************************/
91 #include <security/pam_appl.h>
97 #include <sys/access.h>
101 #include <sys/audit.h>
104 /* necessary for bzero */
106 #include <X11/Xfuncs.h>
122 * Define as generic those without platform specific code.
124 #if !(defined(__hpux) || \
125 defined(__apollo) || \
133 #include <sys/sysinfo.h>
141 /***************************************************************************
143 * Start authentication routines (HPUX)
145 ***************************************************************************/
147 #include <sys/param.h> /* for MAXUID macro */
148 #include <sys/types.h>
149 #include <sys/utsname.h>
156 # include <sys/audit.h>
157 # include <sys/errno.h>
158 # include <sys/stat.h>
159 # define SECUREPASS "/.secure/etc/passwd"
163 # include <sys/security.h>
168 #include <afs/kautils.h>
173 # define KRBLIFE 255 /* max lifetime */
174 #endif /* __KERBEROS */
177 # include "rgy_base.h"
182 #define how_to_count ut_exit.e_exit
185 int num_users[] = { 2, 32767 };
186 # define MIN_VERSION 'A'
187 # define UNLIMITED 'B'
189 int num_users[] = { 2, 16, 32, 64 , 8 };
190 # define MIN_VERSION 'A'
191 # define UNLIMITED 'U'
194 /* Maximum number of users allowed with restricted license */
195 #if OSMAJORVERSION < 8
196 # define MAX_STRICT_USERS 2
198 # define MAX_STRICT_USERS 8
201 #define NUM_VERSIONS (sizeof(num_users)/sizeof(num_users[0])) - 1
203 extern char *globalDisplayName;
205 /***************************************************************************
207 * External declarations (HPUX)
209 ***************************************************************************/
211 extern long groups[NGROUPS];
215 extern boolean rgy_$using_local_registry();
216 extern struct passwd * getpwnam_full();
217 extern boolean is_acct_expired();
218 extern boolean is_passwd_expired();
219 extern boolean is_passwd_invalid();
220 extern boolean rgy_$is_des();
225 /***************************************************************************
227 * Procedure declarations (HPUX)
229 ***************************************************************************/
231 static void Audit( struct passwd *p, char *msg, int errnum) ;
232 static int CheckPassword( char *name, char *passwd, struct passwd **ppwd );
233 static int CountUsers( int added_users) ;
234 static int CountUsersStrict( char *new_user) ;
235 static int PasswordAged( register struct passwd *pw) ;
236 static void WriteBtmp( char *name) ;
241 /***************************************************************************
243 * Global variables (HPUX)
245 ***************************************************************************/
248 struct s_passwd *s_pwd;
250 int secure; /* flag to denote existence of secure passwd file */
255 struct pr_passwd *b1_pwd;
259 rgy_$acct_admin_t admin_part;
260 rgy_$policy_t policy;
261 rgy_$acct_user_t user_part;
266 /***************************************************************************
270 * Construct self audit record for event and write to the audit trail.
271 * This routine assumes that the effective uid is currently 0. If auditing
272 * is not defined, this routine does nothing.
273 ***************************************************************************/
276 Audit( struct passwd *p, char *msg, int errnum )
282 struct self_audit_rec audrec;
287 * make sure program is back to super-user...
295 txtptr = (char *)audrec.aud_body.text;
296 sprintf(txtptr, "User= %s uid=%ld audid=%ld%s", p->pw_name,
297 (long)p->pw_uid, (long)p->pw_audid, msg);
298 audrec.aud_head.ah_pid = getpid();
299 audrec.aud_head.ah_error = errnum;
300 audrec.aud_head.ah_event = EN_LOGINS;
301 audrec.aud_head.ah_len = strlen (txtptr);
302 status = audwrite(&audrec);
308 LogError(ReadCatalog(
309 MC_LOG_SET,MC_LOG_NOT_SUSER,MC_DEF_LOG_NOT_SUSER));
313 LogError(ReadCatalog(
314 MC_LOG_SET,MC_LOG_INV_EVENT,MC_DEF_LOG_INV_EVENT));
318 LogError(ReadCatalog(
319 MC_LOG_SET,MC_LOG_ERR_ERRNO,MC_DEF_LOG_ERR_ERRNO),
336 /***************************************************************************
338 * CountUsers (HPUX only)
340 * see if new user has exceeded the maximum.
341 ***************************************************************************/
346 CountUsers( int added_users )
348 int count[NCOUNT], nusers, i;
351 for (i=0; i<NCOUNT; i++)
354 count[added_users]++;
356 while ( (entry = getutent()) != NULL) {
357 if (entry->ut_type == USER_PROCESS) {
358 i = entry->how_to_count;
359 if (i < 0 || i >= NCOUNT)
360 i = 1; /* if out of range, then count */
361 /* as ordinary user */
369 * [0] does not count at all
370 * [1] counts as real user
371 * [2] logins via a pty which have not gone trough login. These
372 * collectively count as 1 user IF count[3] is 0, otherwise,
373 * they are not counted. Starting with HP-UX 8.0 they are
374 * no longer counted at all.
375 * [3] logins via a pty which have been logged through login (i.e.
376 * rlogin and telnet). these count as 1 "real" user per
378 * [4-15] may be used for groups of users which collectively
383 #if OSMAJORVERSION < 8
384 for (i=2; i<NCOUNT; i++)
386 for (i=3; i<NCOUNT; i++)
397 /***************************************************************************
399 * CountUsersStrict (HPUX only)
401 * see if new user has exceeded the maximum.
402 ***************************************************************************/
405 CountUsersStrict( char *new_user )
407 char pty_users[MAX_STRICT_USERS][8];
408 int count[NCOUNT], nusers, i, cnt, pty_off = -1, uname_off;
412 * Initialize count array...
414 for (i = 0; i < NCOUNT; i++)
418 * Add in the new user (we know it's not a pty)...
422 while ( (entry = getutent()) != NULL ) {
423 if (entry->ut_type == USER_PROCESS) {
424 i = entry->how_to_count;
426 /* if out of range, then count as ordinary user logged in
428 if (i == 1 || (i < 0 || i >= NCOUNT))
430 /* See if it is a pty login granted by login program */
433 /* See if user is already logged in via login pty */
435 for (cnt = 0; cnt <= pty_off; cnt++)
436 if (strncmp(pty_users[cnt], entry->ut_user, 8) == 0)
439 if (uname_off == -1) { /* user is not logged in via pty yet */
441 if (pty_off >= MAX_STRICT_USERS) /* cannot add any
443 return(MAX_STRICT_USERS + 1);
444 /* add the user name to the array of pty users */
446 strncpy(pty_users[++pty_off], entry->ut_user, 8);
448 } /* end if (i == 3) */
451 } /* end if entry->ut_type == USER_PROCESS */
452 } /* end while (entry = getutent()) */
457 * [0] does not count at all
458 * [1] counts as "real" user
459 * [2] logins via a pty which have not gone trough login. These
460 * collectively count as 1 user IF count[3] is 0, otherwise,
461 * they are not counted. Starting with HP-UX 8.0 they are
462 * no longer counted at all.
463 * [3] logins via a pty which have been logged through login (i.e.
464 * rlogin and telnet). these count as 1 "real" user per
466 * [4-15] may be used for groups of users which collectively count
470 nusers = pty_off + 1 + count[1]; /* Current number of users is sum of
471 users logged in via tty + the
472 number of unique users logged in
473 via pty which have gone through
476 #if OSMAJORVERSION < 8
477 if ((count[3] == 0) && (count[2] != 0))
478 nusers++; /* Add 1 user for all pty logins IF
479 none of pty logins have been
480 granted by the login program */
483 * Don't count any hpterm logins (exit status of 2). We already
484 * counted all pty logins granted by the login program.
488 for (i = 4; i < NCOUNT; i++)
497 /***************************************************************************
499 * PasswordAged (HPUX)
501 * see if password has aged
502 ***************************************************************************/
503 #define SECONDS_IN_WEEK 604800L
506 PasswordAged( register struct passwd *pw )
508 long change_week; /* week password was changed (1/1/70 = Week 0) */
509 long last_week; /* week after which password must change */
510 long first_week; /* week before which password can't change */
511 long this_week; /* this week derived from time() */
513 char *passwdAge; /* password aging time */
520 passwdAge = pw->pw_age;
524 passwdAge = s_pwd->pw_age;
529 /* Account validity checks: If we were able to connect to the network
530 * registry, then we've acquired account and policy data and can perform
531 * account/password checking
534 lrgy = rgy_$using_local_registry();
537 /* Check for password expiration or invalidity */
538 if ( rgy_$is_passwd_expired(&user_part, &policy ) != 0 ) {
546 if (*passwdAge == NULL)
549 first_week = last_week = change_week = (long) a64l(passwdAge);
550 last_week &= 0x3f; /* first six bits */
551 first_week = (first_week >> 6) & 0x3f; /* next six bits */
552 change_week >>= 12; /* everything else */
554 this_week = (long) time((long *) 0) / SECONDS_IN_WEEK;
557 ** Password aging conditions:
558 ** * if the last week is less than the first week (e.g., the aging
559 ** field looks like "./"), only the superuser can change the
560 ** password. We don't request a new password.
561 ** * if the week the password was last changed is after this week,
562 ** we have a problem, and request a new password.
563 ** * if this week is after the specified aging time, we request
566 if (last_week < first_week)
569 if (change_week <= this_week && this_week <= (change_week + last_week))
579 /***************************************************************************
581 * CheckPassword (HPUX only)
583 * Check validity of user password. One of several authentication schemes
584 * can be used, including Kerberos, AFS 3, HP BLS and traditional
585 * /etc/passwd. These are selectable via a resource in Dtlogin.
587 * Domain registry authentication (PasswdEtc) can also be compiled in as
588 * the only authentication scheme used.
590 ***************************************************************************/
593 CheckPassword( char *name, char *passwd, struct passwd **ppwd )
602 char realm[REALM_SZ];
604 #endif /* __KERBEROS */
609 * validate that user has an entry in the shadow password file on an
610 * HP-UX C2 trusted system. Keep info in a global structure.
614 s_pwd = getspwnam(name);
624 * look up user's regular account information...
629 * look up entry from registry...
631 * need getpwnam_full to get policy data for passwd expiration
634 p = getpwnam_full(name, &user_part, &admin_part, &policy);
642 if ( p == NULL || strlen(name) == 0 )
649 * AFS password authentication...
652 if ( vg_IsVerifyName(VN_AFS) ) {
654 if ( ka_UserAuthenticateGeneral(
655 KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG,
656 p->pw_name, /* kerberos name */
657 (char *)0, /* instance */
658 (char *)0, /* realm */
659 passwd, /* password */
660 0, /* default lifetime */
663 &reason) == 0 ) { /* error string */
665 if (strcmp(p->pw_passwd, "*") == 0)
672 LogError(ReadCatalog(
673 MC_LOG_SET,MC_LOG_AFS_FAILATH,MC_DEF_LOG_AFS_FAILATH),reason);
682 * Kerberos password authentication...
685 if ( vg_IsVerifyName(VN_KRB) ) {
687 (void)krb_get_lrealm(realm, 1);
689 setresuid(p->pw_uid, p->pw_uid, -1);
690 kerno = krb_get_pw_in_tkt(p->pw_name,
700 if (kerno == KSUCCESS)
701 if (strcmp(p->pw_passwd, "*") == 0)
707 #endif /* __KERBEROS */
712 * traditional password verification...
715 if (strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd) == 0)
721 * If regular passwd check fails, try old-style Apollo SR
724 if (rgy_$is_des(passwd, strlen(passwd), p->pw_passwd) == TRUE)
730 * all password checks failed...
740 /***************************************************************************
742 * Authenticate (HPUX)
746 * return codes indicate authentication results.
747 ***************************************************************************/
749 #define MAXATTEMPTS 3
751 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
754 Authenticate( struct display *d, char *name, char *passwd, char **msg )
757 static int login_attempts = 0; /* # failed authentications */
759 struct passwd *p = NULL; /* password structure */
761 struct utsname utsnam;
767 * Nothing to do if no name provided.
774 if (strlen(name) == 0)
778 return(VF_CHALLENGE);
785 * Save provided password.
788 if (!passwd) passwd = "";
792 * turn on self auditing...
795 if (audswitch(AUD_SUSPEND) == -1)
801 * set the secure flag if SECUREPASS exists. If so, we
802 * are using it for authentication instead of /etc/passwd...
805 secure = (stat(SECUREPASS, &s_pfile) < 0) ? 0:1;
809 * set the audit process flag unconditionally on since we want
810 * to log all logins regardless of whether the user's audit
815 setaudproc(AUD_PROC);
821 * validate password...
824 if ( CheckPassword(name, passwd, &p) == FALSE) {
828 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
833 Audit(p, " Failed login (bailout)", 1);
837 return(origpw ? VF_INVALID : VF_CHALLENGE);
842 * check restricted license...
844 * Note: This only applies to local displays. Foreign displays
845 * (i.e. X-terminals) apparently do not count.
848 /* Get the version info via uname. If it doesn't look right,
849 * assume the smallest user configuration
852 if (uname(&utsnam) < 0)
853 utsnam.version[0] = MIN_VERSION;
865 if ((!strncmp(utsnam.machine, "9000/834", UTSLEN)) ||
866 (!strncmp(utsnam.machine, "9000/844", UTSLEN)) ||
867 (!strncmp(utsnam.machine, "9000/836", UTSLEN)) ||
868 (!strncmp(utsnam.machine, "9000/846", UTSLEN)) ||
869 (!strncmp(utsnam.machine, "9000/843", UTSLEN)) ||
870 (!strncmp(utsnam.machine, "9000/853", UTSLEN))) {
872 /* strict_count = 1;*/
873 if (CountUsersStrict(name) > MAX_STRICT_USERS) {
875 " attempted to login - too many users on the system",
878 return(VF_MAX_USERS);
882 if (utsnam.version[0] != UNLIMITED) {
883 if ((utsnam.version[0]-'A' < 0) ||
884 (utsnam.version[0]-'A' > NUM_VERSIONS))
885 utsnam.version[0] = MIN_VERSION;
887 n = (int) utsnam.version[0] - 'A';
888 if (CountUsers(1) > num_users[n]) {
890 " attempted to login - too many users on the system",
893 return(VF_MAX_USERS);
901 * Check for account validity. Unfortunately, we have no graphical
902 * dialog for this at this time so the best we can do is log an
903 * error message and hope the system administrator sees it.
906 if ( !rgy_$using_local_registry() ) {
907 if (rgy_$is_acct_expired(&admin_part) != 0 ) {
908 LogError(ReadCatalog(MC_LOG_SET,MC_LOG_ACC_EXP,MC_DEF_LOG_ACC_EXP),
916 * check password aging...
919 if ( PasswordAged(p) ) return(VF_PASSWD_AGED);
923 * verify home directory exists...
926 if(chdir(p->pw_dir) < 0) {
927 Audit(p, " attempted to login - no home directory", 1);
934 * check audit flag and id...
939 if (secure && (p->pw_audflg > 1 || p->pw_audflg < 0)) {
940 Audit(p, " attempted to login - bad audit flag", 1);
941 return(VF_BAD_AFLAG);
944 if (secure && (setaudid(p->pw_audid) == -1 )) {
945 Audit(p, " attempted to login - bad audit id", 1);
952 * validate uid and gid...
955 if ((p->pw_gid < 0) ||
956 (p->pw_gid > MAXUID) ||
957 (setgid(p->pw_gid) == -1)) {
959 Audit(p, " attempted to login - bad group id", 1);
966 * ka_UserAuthenticateGeneral() sets the group access of this process
967 * to the proper PAG. Pick up these values and pass them back to
968 * Dtlogin to be put into the user's environment...
971 if ( vg_IsVerifyName(VN_AFS) ) {
972 groups[0] = groups[1] = 0;
973 getgroups(NGROUPS, groups);
979 if ((p->pw_uid < 0) ||
980 (p->pw_uid > MAXUID) ||
981 (setresuid(p->pw_uid, p->pw_uid, 0) == -1)) {
983 Audit(p, " attempted to login - bad user id", 1);
994 Audit(p, " Successful login", 0);
1001 /***************************************************************************
1005 * log bad login attempts
1007 ***************************************************************************/
1010 WriteBtmp( char *name )
1013 struct utmp utmp, *u;
1017 bzero(&utmp, sizeof(struct utmp));
1019 utmp.ut_pid = getppid();
1020 while ((u = getutent()) != NULL) {
1021 if ( (u->ut_type == INIT_PROCESS ||
1022 u->ut_type == LOGIN_PROCESS ||
1023 u->ut_type == USER_PROCESS) &&
1024 u->ut_pid == utmp.ut_pid ) {
1033 * if no utmp entry, this may be an X-terminal. Construct a utmp
1038 strncpy(utmp.ut_id, "??", sizeof(utmp.ut_id));
1039 strncpy(utmp.ut_line, globalDisplayName, sizeof(utmp.ut_line));
1040 utmp.ut_type = LOGIN_PROCESS;
1042 strncpy(utmp.ut_host, globalDisplayName, sizeof(utmp.ut_host));
1049 * If btmp exists, then record the bad attempt
1051 if ( (fd = open(BTMP_FILE,O_WRONLY|O_APPEND)) >= 0) {
1052 strncpy(u->ut_user, name, sizeof(u->ut_user));
1053 (void) time(&u->ut_time);
1054 write(fd, (char *)u, sizeof(utmp));
1058 endutent(); /* Close utmp file */
1061 /***************************************************************************
1063 * End authentication routines (HPUX)
1065 ***************************************************************************/
1069 /***************************************************************************
1070 ***************************************************************************
1071 ***************************************************************************
1072 ***************************************************************************
1073 ***************************************************************************
1074 ***************************************************************************
1075 ***************************************************************************
1076 ***************************************************************************/
1080 /***************************************************************************
1082 * Start authentication routines (SUN)
1084 ***************************************************************************/
1086 #include "solaris.h"
1088 #include <security/ia_appl.h>
1092 /***************************************************************************
1094 * Procedure declarations (SUN)
1096 ***************************************************************************/
1098 static void Audit( struct passwd *p, char *msg, int errnum) ;
1102 /***************************************************************************
1106 ***************************************************************************/
1109 Audit( struct passwd *p, char *msg, int errnum )
1113 * make sure program is back to super-user...
1118 Debug("Audit: %s\n", msg);
1124 /***************************************************************************
1126 * Authenticate (SUN)
1130 * return codes indicate authentication results.
1131 ***************************************************************************/
1134 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1137 char* ttyLine = d->gettyLine;
1140 * Nothing to do if no name provided.
1147 * Construct device line
1149 #ifdef DEF_NETWORK_DEV
1151 * If location is not local (remote XDMCP dtlogin) and
1152 * remote accouting is enabled (networkDev start with /dev/...)
1153 * Set tty line name to match network device for accouting.
1154 * Unless the resource was specifically set, default is value
1155 * of DEF_NETWORK_DEV define (/dev/dtremote)
1158 if ( d->displayType.location != Local &&
1159 networkDev && !strncmp(networkDev,"/dev/",5)) {
1160 ttyLine = networkDev+5;
1165 * Authenticate user and return status
1169 status = PamAuthenticate("dtlogin", d->name, passwd, name, ttyLine);
1175 case PAM_NEW_AUTHTOK_REQD:
1176 return(VF_PASSWD_AGED);
1179 return(passwd ? VF_INVALID : VF_CHALLENGE);
1182 status = solaris_authenticate("dtlogin", d->name, passwd, name, ttyLine);
1188 case IA_NEWTOK_REQD:
1189 return(VF_PASSWD_AGED);
1192 return(passwd ? VF_INVALID : VF_CHALLENGE);
1199 /***************************************************************************
1201 * End authentication routines (SUN)
1203 ***************************************************************************/
1206 /***************************************************************************
1207 ***************************************************************************
1208 ***************************************************************************
1209 ***************************************************************************
1210 ***************************************************************************/
1212 /***************************************************************************
1216 * get the information from the display about local/remote login and
1217 * create a dummy tty name for loginrestrictions.
1219 ***************************************************************************/
1221 GetLoginInfo(struct display *d, int *loginType, char *ttyName, char **hostname)
1225 CleanUpName(d->name, workarea, 128);
1226 sprintf(ttyName, "/dev/dtlogin/%s", workarea);
1228 if (d->displayType.location == Foreign) {
1229 *loginType = S_RLOGIN;
1230 *hostname = d->name;
1231 Debug("Login Info - Remote user on tty=%s.\n", ttyName);
1233 *loginType = S_LOGIN;
1235 Debug("Login Info - Local user on tty=%s.\n", ttyName);
1239 /***************************************************************************
1241 * Authenticate (AIX version 4.1)
1245 * return codes indicate authentication results.
1246 ***************************************************************************/
1247 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1253 static char *msgpending;
1258 GetLoginInfo(d, &loginType, tty, &hostname);
1268 * No more challenges. User failed login.
1271 loginfailed(name, hostname, tty);
1276 * Authenticate with response to last challenge.
1278 rc = authenticate(name, passwd, &reenter, msg);
1283 * System has presented user with new challenge.
1285 return(VF_CHALLENGE);
1288 if (rc && errno == ENOENT)
1291 * User is unknown to the system. Simulate a password
1292 * challenge, but save message for display for next call.
1295 return(VF_CHALLENGE);
1301 * No more challenges. User failed login.
1303 loginfailed(name, hostname, tty);
1308 * User authenticated. Check login restrictions.
1310 rc = loginrestrictions(name, loginType, tty, msg);
1315 * Login restrictions disallow login.
1317 loginfailed(name, hostname, tty);
1322 * Check password expiration.
1324 rc = passwdexpired(name, msg);
1329 * Login succeeded, but password expired.
1331 return(VF_PASSWD_AGED);
1337 loginsuccess(name, hostname, tty, msg);
1344 /***************************************************************************
1346 * Start authentication routines (AIX)
1348 ***************************************************************************/
1351 #include <sys/types.h>
1352 #include <sys/errno.h>
1353 #include <usersec.h>
1355 #include <userconf.h>
1359 /***************************************************************************
1361 * External declarations (AIX)
1363 ***************************************************************************/
1368 /***************************************************************************
1370 * Procedure declarations (AIX)
1372 ***************************************************************************/
1374 static void Audit( struct passwd *p, char *msg, int errnum) ;
1375 static int PasswordAged(char *name, register struct passwd *pw) ;
1376 static void WriteBtmp( char *name) ;
1381 /***************************************************************************
1383 * Global variables (AIX)
1385 ***************************************************************************/
1390 /***************************************************************************
1394 ***************************************************************************/
1397 Audit( struct passwd *p, char *msg, int errnum )
1401 * make sure program is back to super-user...
1405 if ( (auditwrite ("USER_Login", AUDIT_OK,
1406 p->pw_name, strlen (p->pw_name) + 1,
1407 msg, strlen (msg) + 1, NULL)) == -1 )
1408 Debug(" Could not do Auditing\n");
1415 /***************************************************************************
1419 * log bad login attempts to /etc/security/failedlogin file
1422 ***************************************************************************/
1425 WriteBtmp( char *name )
1430 if( (fd = open("/etc/security/failedlogin",O_CREAT|O_RDWR,0644)) != -1) {
1431 bzero(&ut,sizeof(struct utmp));
1433 strncpy(ut.ut_user, name, sizeof ut.ut_user);
1434 ut.ut_type = USER_PROCESS;
1435 ut.ut_pid = getpid();
1436 ut.ut_time = time((time_t *)0);
1437 write(fd, (char *)&ut, sizeof(struct utmp));
1445 /***************************************************************************
1447 * PasswordAged (AIX)
1449 * see if password has aged
1450 ***************************************************************************/
1451 #define SECONDS_IN_WEEK 604800L
1454 PasswordAged(char *name, register struct passwd *pw )
1456 struct userpw *pupw; /* authentication information from getuserpw() */
1457 struct userpw upw; /* working authentication information */
1458 int err; /* return code from getconfattr() */
1459 ulong maxage; /* maximun age from getconfattr() */
1460 ulong now; /* time now */
1466 * Determine user password aging criteria. Note that only
1467 * the 'lastupdate' and 'flags' fields are set by this operation.
1470 if ((pupw = getuserpw(name)) != NULL)
1472 upw.upw_lastupdate = pupw->upw_lastupdate;
1473 upw.upw_flags = pupw->upw_flags;
1477 upw.upw_lastupdate = 0;
1483 * Consider password as having not expired if nocheck set.
1485 if (upw.upw_flags & PW_NOCHECK) return(FALSE);
1488 * Get system password aging criteria.
1490 err = getconfattr (SC_SYS_PASSWD, SC_MAXAGE, (void *)&maxage, SEC_INT);
1494 * Change from weeks to seconds
1496 maxage = maxage * SECONDS_IN_WEEK;
1497 now = time ((long *) 0);
1499 if ((upw.upw_lastupdate + maxage) >= now)
1502 * Password has not expired.
1510 * Could not retrieve system password aging info or maxage set to
1511 * zero. In either case, consider password has having not expired.
1517 * We haven't returned by now, so indicate password has expired.
1523 /***************************************************************************
1524 * dt_failedlogin (AIX)
1526 * log failed login in /etc/security/lastlog
1527 ***************************************************************************/
1539 dt_lastlogin ( char * user, struct lastlogin * llogin);
1542 dt_failedlogin(char *name, char *ttyName, char *hostName)
1544 struct lastlogin last_login;
1546 last_login.stime = 0;
1548 time(&last_login.ftime);
1550 last_login.ftty = ttyName;
1552 last_login.fhost = (char *) malloc (MAXHOSTNAMELEN);
1553 if (hostName == NULL) {
1554 gethostname (last_login.fhost , MAXHOSTNAMELEN);
1556 strncpy(last_login.fhost, hostName, MAXHOSTNAMELEN);
1557 last_login.fhost[MAXHOSTNAMELEN -1] = '\0';
1560 Debug("logging failed lastlogin entry (user=%s)\n",name);
1561 dt_lastlogin(name, &last_login);
1562 free(last_login.fhost);
1567 /***************************************************************************
1569 * Authenticate (AIX)
1573 * return codes indicate authentication results.
1574 ***************************************************************************/
1576 #define MAXATTEMPTS 3
1578 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
1581 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1584 static int login_attempts = 0; /* # failed authentications */
1585 struct passwd *p; /* password structure */
1593 * Nothing to do if no name provided.
1599 * Save provided password.
1602 if (!passwd) passwd = "";
1604 if(strlen(name) > S_NAMELEN)
1607 GetLoginInfo(d, &loginType, tty, &hostname);
1611 if (!p || strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) {
1615 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
1620 Audit(p, " Failed login (bailout)", 1);
1624 dt_failedlogin(name, tty, hostname);
1625 return (VF_INVALID);
1627 return(VF_CHALLENGE);
1630 /* Note: The password should be checked if it is the first time
1631 the user is logging in or whether the sysadm has changed
1632 the password for the user. Code should be added here if
1633 this functionality should be supported. The "upw_flags"
1634 of the password structure gets set to PW_ADMCHG in this
1639 * check password aging...
1642 if ( PasswordAged(name,p) ) return(VF_PASSWD_AGED);
1645 /* Validate for User Account RK 09.13.93 */
1646 if(ckuseracct(name, loginType, tty) == -1) {
1647 dt_failedlogin(name, tty, hostname);
1653 * validate uid and gid...
1657 if ((p->pw_gid < 0) ||
1658 (setgid(p->pw_gid) == -1)) {
1660 Audit(p, " attempted to login - bad group id", 1);
1664 if ((p->pw_uid < 0)) {
1665 Audit(p, " attempted to login - bad user id", 1);
1669 /* Check for max number of logins RK 09.13.93 */
1670 if (tsm_check_login(p->pw_uid) == -1) {
1671 dt_failedlogin(name, tty, hostname);
1675 /* Check for /etc/nologin file RK 09.13.93 */
1676 if ( (access("/etc/nologin",R_OK) == 0) && (p->pw_uid != 0) ) {
1677 dt_failedlogin(name, tty, hostname);
1682 * verify home directory exists...
1685 if(chdir(p->pw_dir) < 0) {
1686 Audit(p, " attempted to login - no home directory", 1);
1694 Audit(p, " Successful login", 0);
1698 /**************************************************************************
1702 * Checks for max number of logins on the system. If the new user trying to
1703 * login exceeds the max limit then the user is not allowed to login.
1706 **************************************************************************/
1708 /**************************************************************************
1712 * Checks for max number of logins on the system. If the new user trying to
1713 * login exceeds the max limit then the user is not allowed to login.
1716 **************************************************************************/
1719 tsm_check_login(uid_t uid)
1726 struct stat stat_buf;
1727 static struct sembuf sop = { 0, -1, (SEM_UNDO|IPC_NOWAIT) };
1728 static struct sembuf initsop = { 0, 0, (IPC_NOWAIT) };
1731 * The login counter semaphore may not be set yet. See if it exists
1732 * and try creating it with the correct count if it doesn't. An
1733 * attempt is made to create the semaphore. Only if that attempt fails
1734 * is the semaphore set to maxlogins from login.cfg.
1739 * Don't Check if the user is already logged. ie running login
1743 * Generate the semaphore key from the init program.
1745 Debug("Start of maxlogin check\n");
1746 if ((key = ftok (CDE_INSTALLATION_TOP "/bin/dtlogin", 1)) != (key_t) -1) {
1747 Debug("key created\n");
1748 if ((semid = semget (key, 1, IPC_CREAT|IPC_EXCL|0600)) != -1) {
1750 Debug("Completed IPCkey\n");
1751 if (! getconfattr ("usw", "maxlogins", &i, SEC_INT)) {
1752 Debug("Max logins from login.cfg is :%d\n",i);
1754 i = 10000; /* a very large number */
1757 if (semop (semid, &initsop, 1))
1759 Debug("failed while decrementing\n");
1763 semctl (semid, 1, IPC_RMID, 0);
1768 * Only 'n' login sessions are allowed on the system.
1769 * This code block decrements a semaphore.
1770 * The semundo value will be set to adjust the
1771 * semaphore when tsm exits.
1773 * This code will be ignored if the appropriate
1774 * semaphore set does not exist.
1777 if ((semid = semget (key, 1, 0)) != -1) {
1778 Debug("getting key for maxlogins\n");
1780 * If the semaphore is zero and we are not
1781 * root, then we fail as there are already the
1782 * allotted number of login sessions on the
1785 if ((semop (semid, &sop, 1) == -1) && uid) {
1786 Debug("reached MAXLOGINS limit\n");
1794 #endif /* !_POWER */
1796 /***************************************************************************
1798 * End authentication routines (AIX)
1800 ***************************************************************************/
1802 /***************************************************************************
1803 ***************************************************************************
1804 ***************************************************************************
1805 ***************************************************************************
1806 ***************************************************************************
1807 ***************************************************************************
1808 ***************************************************************************
1809 ***************************************************************************/
1813 /***************************************************************************
1815 * Start authentication routines (USL)
1817 ***************************************************************************/
1820 #define LOGIN_SUCCESS 0
1821 #define LOGIN_FAIL 1
1831 /***************************************************************************
1833 * External declarations (USL)
1835 ***************************************************************************/
1839 /***************************************************************************
1841 * Procedure declarations (USL)
1843 ***************************************************************************/
1846 static void Audit( struct passwd *p, char *msg, int errnum) ;
1847 static int PasswordAged( register struct passwd *pw) ;
1848 static void WriteBtmp( char *name) ;
1852 /***************************************************************************
1854 * Global variables (USL)
1856 ***************************************************************************/
1858 extern int Slaveptty_fd;
1861 /***************************************************************************
1865 ***************************************************************************/
1868 Audit( struct passwd *p, char *msg, int errnum )
1872 * make sure program is back to super-user...
1883 /***************************************************************************
1887 * log bad login attempts
1889 ***************************************************************************/
1892 WriteBtmp( char *name )
1900 /***************************************************************************
1902 * Authenticate (USL)
1906 * return codes indicate authentication results.
1907 ***************************************************************************/
1909 #define MAXATTEMPTS 3
1912 Authenticate( struct display *d, char *name, char *passwd, char **msg )
1925 * Nothing to do if no name provided.
1931 * Save provided password.
1934 if (!passwd) passwd = "";
1937 * Put the logname and the passwd on the ava stream
1939 if ((ret = dup2 (Slaveptty_fd, 0)) == -1)
1940 Debug ("Problem with dup2\n");
1942 ava = retava(Slaveptty_fd);
1944 (void) bzero (xlogname, strlen (xlogname));
1945 (void) sprintf (xlogname, "XLOGNAME=%s", name);
1946 if ((ava = putava (xlogname, ava)) == NULL)
1948 Debug ("Could not set logname ava\n");
1951 (void) bzero (xpasswd, strlen (xpasswd));
1952 (void) sprintf (xpasswd, "XPASSWD=%s", passwd);
1953 if ((ava = putava (xpasswd, ava)) == NULL)
1955 Debug ("Could not set passwd ava\n");
1958 (void) bzero (xtty, strlen (xtty));
1959 (void) sprintf (xtty, "XTTY=%s", ttyname(Slaveptty_fd));
1960 if ((ava = putava (xtty, ava)) == NULL)
1962 Debug ("Could not set tty ava\n");
1965 if (setava (Slaveptty_fd, ava) != 0)
1967 Debug ("Could not do setava\n");
1971 * invoke identification and authorizarion scheme
1974 switch (ret = invoke (Slaveptty_fd, "login"))
1978 Audit(p, " Successful login", 0);
1981 return(origpw ? VF_INVALID : VF_CHALLENGE);
1983 /* The next three cases need to define special return values */
1984 /* for the aged passwords and accounts. */
1988 /* PasswdAged (linfo); */
1989 return(VF_PASSWD_AGED);
1990 case EXPIRED: /* SS */
1991 /* AccountAged (linfo); */
1992 return(VF_PASSWD_AGED);
1994 /* These 3 cases should allow user to select a new password */
1995 /* after displaying a warning, but current implementation */
1996 /* only displays the warning. */
2001 return(VF_PASSWD_AGED);
2003 return(VF_INVALID); /* SS */
2008 /***************************************************************************
2010 * End authentication routines (USL)
2012 ***************************************************************************/
2016 /***************************************************************************
2018 * Start authentication routines (generic)
2020 ***************************************************************************/
2023 /***************************************************************************
2025 * These are a set of routine to do simple password, home dir, uid, and gid
2026 * validation. They can be used as a first pass validation for future
2029 * When platform specific validation is developed, those routines should be
2030 * included in their own section and the use of these routines discontinued.
2032 ***************************************************************************/
2037 /***************************************************************************
2039 * External declarations (generic)
2041 ***************************************************************************/
2046 /***************************************************************************
2048 * Procedure declarations (generic)
2050 ***************************************************************************/
2052 static void Audit( struct passwd *p, char *msg, int errnum) ;
2053 static int PasswordAged( register struct passwd *pw) ;
2054 static void WriteBtmp( char *name) ;
2059 /***************************************************************************
2061 * Global variables (generic)
2063 ***************************************************************************/
2068 /***************************************************************************
2072 ***************************************************************************/
2075 Audit( struct passwd *p, char *msg, int errnum )
2079 * make sure program is back to super-user...
2081 if(-1 == seteuid(0)) {
2082 perror(strerror(errno));
2091 /***************************************************************************
2093 * WriteBtmp (generic)
2095 * log bad login attempts
2097 ***************************************************************************/
2100 WriteBtmp( char *name )
2108 /***************************************************************************
2110 * PasswordAged (Generic)
2112 * see if password has aged
2113 ***************************************************************************/
2114 #define SECONDS_IN_WEEK 604800L
2117 PasswordAged( register struct passwd *pw )
2124 /***************************************************************************
2126 * Authenticate (generic)
2130 * return codes indicate authentication results.
2131 ***************************************************************************/
2133 #define MAXATTEMPTS 3
2135 struct passwd nouser = {"", "nope"}; /* invalid user password struct */
2138 Authenticate( struct display *d, char *name, char *passwd, char **msg )
2141 static int login_attempts = 0; /* # failed authentications */
2143 struct passwd *p; /* password structure */
2151 * Nothing to do if no name provided.
2157 * Save provided password.
2160 if (!passwd) passwd = "";
2166 * Use the Linux Shadow Password system to get the crypt()ed password
2169 struct spwd *s = getspnam(name);
2171 p->pw_passwd = s->sp_pwdp;
2176 if (!p || strlen(name) == 0 ||
2177 strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) {
2181 if ((++login_attempts % MAXATTEMPTS) == 0 ) {
2186 Audit(p, " Failed login (bailout)", 1);
2190 return(origpw ? VF_INVALID : VF_CHALLENGE);
2195 * check password aging...
2198 if ( PasswordAged(p) ) return(VF_PASSWD_AGED);
2202 * verify home directory exists...
2205 if(chdir(p->pw_dir) < 0) {
2206 Audit(p, " attempted to login - no home directory", 1);
2212 * validate uid and gid...
2216 if (setgid(p->pw_gid) == -1) {
2218 Audit(p, " attempted to login - bad group id", 1);
2222 if (seteuid(p->pw_uid) == -1) {
2224 Audit(p, " attempted to login - bad user id", 1);
2234 Audit(p, " Successful login", 0);
2241 /***************************************************************************
2243 * End authentication routines (generic)
2245 ***************************************************************************/
2246 #endif /* generic */
2250 /***************************************************************************
2251 ***************************************************************************
2252 ***************************************************************************
2253 ***************************************************************************
2254 ***************************************************************************
2255 ***************************************************************************
2256 ***************************************************************************
2257 ***************************************************************************/