sysauth.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  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
  22. */
  23. /* $XConsortium: sysauth.c /main/7 1996/10/30 11:12:45 drk $ */
  24. /* *
  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. *
  29. */
  30. /************************************<+>*************************************
  31. ****************************************************************************
  32. **
  33. ** File: sysauth.c
  34. **
  35. ** Project: DT
  36. **
  37. ** Description: Dtgreet user authentication routines
  38. **
  39. ** These routines validate the user; checking name, password,
  40. ** number of users on the system, password aging, etc.
  41. **
  42. **
  43. ** (c) Copyright 1987, 1988, 1989 by Hewlett-Packard Company
  44. **
  45. **
  46. ** Conditional compiles for HPUX:
  47. **
  48. ** OSMAJORVERSION < 8
  49. ** HP-UX 7.0/7.03 restricted license counting algorithms
  50. ** are used. Otherwise HP-UX 8.0 and beyond is used
  51. **
  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
  56. ** #ifdef SecureWare
  57. **
  58. ** __AFS AFS 3 authentication mechanism
  59. ** __KERBEROS Kerberos authentication mechanism
  60. ** __PASSWD_ETC Domain/OS Registry from HP-UX authentication mechanism
  61. **
  62. ** Platform identification:
  63. **
  64. ** sun SUN OS only
  65. ** SVR4 SUN OS et al.
  66. ** _AIX AIX only
  67. ** _POWER AIX version 4 only
  68. **
  69. ****************************************************************************
  70. ************************************<+>*************************************/
  71. /***************************************************************************
  72. *
  73. * Includes & Defines
  74. *
  75. ***************************************************************************/
  76. #include <stdio.h>
  77. #include <fcntl.h>
  78. #include <stdlib.h>
  79. #include <pwd.h>
  80. #if defined(PAM) || defined(HAS_PAM_LIBRARY)
  81. #include <security/pam_appl.h>
  82. #include "pam_svc.h"
  83. #endif
  84. #ifdef _AIX
  85. #include <usersec.h>
  86. #include <login.h>
  87. #include <sys/access.h>
  88. #include <sys/sem.h>
  89. #include <sys/stat.h>
  90. #include <sys/ipc.h>
  91. #include <sys/audit.h>
  92. #endif
  93. /* necessary for bzero */
  94. #ifdef SVR4
  95. #include <X11/Xfuncs.h>
  96. #if defined(sun)
  97. #include <shadow.h>
  98. #endif
  99. #endif
  100. #include "dm.h"
  101. #include "vg.h"
  102. #include "vgmsg.h"
  103. #include "sysauth.h"
  104. /*
  105. * Define as generic those without platform specific code.
  106. */
  107. #if !(defined(_AIX) || defined(sun) || \
  108. defined(HAS_PAM_LIBRARY))
  109. #define generic
  110. #endif
  111. #if defined(__linux__)
  112. # include <shadow.h>
  113. #endif
  114. #if defined(sun) || defined(HAS_PAM_LIBRARY)
  115. /***************************************************************************
  116. *
  117. * Start authentication routines (SUN)
  118. *
  119. ***************************************************************************/
  120. #include "solaris.h"
  121. #ifdef SUNAUTH
  122. #include <security/ia_appl.h>
  123. #endif
  124. /***************************************************************************
  125. *
  126. * Procedure declarations (SUN)
  127. *
  128. ***************************************************************************/
  129. static void Audit( struct passwd *p, char *msg, int errnum) ;
  130. /***************************************************************************
  131. *
  132. * Audit (SUN)
  133. *
  134. ***************************************************************************/
  135. static void
  136. Audit( struct passwd *p, char *msg, int errnum )
  137. {
  138. /*
  139. * make sure program is back to super-user...
  140. */
  141. seteuid(0);
  142. Debug("Audit: %s\n", msg);
  143. return;
  144. }
  145. /***************************************************************************
  146. *
  147. * Authenticate (SUN)
  148. *
  149. * verify the user
  150. *
  151. * return codes indicate authentication results.
  152. ***************************************************************************/
  153. int
  154. Authenticate( struct display *d, char *name, char *passwd, char **msg )
  155. {
  156. int status;
  157. char* ttyLine = d->gettyLine;
  158. /*
  159. * Nothing to do if no name provided.
  160. */
  161. if (!name) {
  162. return(VF_INVALID);
  163. }
  164. /*
  165. * Construct device line
  166. */
  167. #ifdef DEF_NETWORK_DEV
  168. /*
  169. * If location is not local (remote XDMCP dtlogin) and
  170. * remote accouting is enabled (networkDev start with /dev/...)
  171. * Set tty line name to match network device for accouting.
  172. * Unless the resource was specifically set, default is value
  173. * of DEF_NETWORK_DEV define (/dev/dtremote)
  174. */
  175. if ( d->displayType.location != Local &&
  176. networkDev && !strncmp(networkDev,"/dev/",5)) {
  177. ttyLine = networkDev+5;
  178. }
  179. #endif
  180. /*
  181. * Authenticate user and return status
  182. */
  183. #if defined(PAM) || defined(HAS_PAM_LIBRARY)
  184. status =
  185. #ifdef PAM
  186. PamAuthenticate
  187. #else
  188. _DtAuthentication
  189. #endif
  190. ("dtlogin", d->name, passwd, name, ttyLine);
  191. switch(status) {
  192. case PAM_SUCCESS:
  193. return(VF_OK);
  194. case PAM_NEW_AUTHTOK_REQD:
  195. return(VF_PASSWD_AGED);
  196. default:
  197. return(passwd ? VF_INVALID : VF_CHALLENGE);
  198. }
  199. #else
  200. status = solaris_authenticate("dtlogin", d->name, passwd, name, ttyLine);
  201. switch(status) {
  202. case IA_SUCCESS:
  203. return(VF_OK);
  204. case IA_NEWTOK_REQD:
  205. return(VF_PASSWD_AGED);
  206. default:
  207. return(passwd ? VF_INVALID : VF_CHALLENGE);
  208. }
  209. #endif /* !PAM */
  210. }
  211. /***************************************************************************
  212. *
  213. * End authentication routines (SUN)
  214. *
  215. ***************************************************************************/
  216. #endif /* sun */
  217. /***************************************************************************
  218. ***************************************************************************
  219. ***************************************************************************
  220. ***************************************************************************
  221. ***************************************************************************/
  222. #ifdef _AIX
  223. /***************************************************************************
  224. *
  225. * GetLoginInfo
  226. *
  227. * get the information from the display about local/remote login and
  228. * create a dummy tty name for loginrestrictions.
  229. *
  230. ***************************************************************************/
  231. void
  232. GetLoginInfo(struct display *d, int *loginType, char *ttyName, char **hostname)
  233. {
  234. char workarea[128];
  235. CleanUpName(d->name, workarea, 128);
  236. sprintf(ttyName, "/dev/dtlogin/%s", workarea);
  237. if (d->displayType.location == Foreign) {
  238. *loginType = S_RLOGIN;
  239. *hostname = d->name;
  240. Debug("Login Info - Remote user on tty=%s.\n", ttyName);
  241. } else {
  242. *loginType = S_LOGIN;
  243. *hostname = NULL;
  244. Debug("Login Info - Local user on tty=%s.\n", ttyName);
  245. }
  246. }
  247. #ifdef _POWER
  248. /***************************************************************************
  249. *
  250. * Authenticate (AIX version 4.1)
  251. *
  252. * verify the user
  253. *
  254. * return codes indicate authentication results.
  255. ***************************************************************************/
  256. Authenticate( struct display *d, char *name, char *passwd, char **msg )
  257. {
  258. int arc;
  259. int rc;
  260. int reenter;
  261. static int unknown;
  262. static char *msgpending;
  263. int loginType;
  264. char tty[128];
  265. char *hostname;
  266. GetLoginInfo(d, &loginType, tty, &hostname);
  267. if (name == NULL)
  268. {
  269. unknown = 0;
  270. }
  271. if (unknown)
  272. {
  273. /*
  274. * No more challenges. User failed login.
  275. */
  276. unknown = 0;
  277. loginfailed(name, hostname, tty);
  278. return(VF_INVALID);
  279. }
  280. /*
  281. * Authenticate with response to last challenge.
  282. */
  283. rc = authenticate(name, passwd, &reenter, msg);
  284. if (reenter)
  285. {
  286. /*
  287. * System has presented user with new challenge.
  288. */
  289. return(VF_CHALLENGE);
  290. }
  291. if (rc && errno == ENOENT)
  292. {
  293. /*
  294. * User is unknown to the system. Simulate a password
  295. * challenge, but save message for display for next call.
  296. */
  297. unknown = 1;
  298. return(VF_CHALLENGE);
  299. }
  300. if (rc)
  301. {
  302. /*
  303. * No more challenges. User failed login.
  304. */
  305. loginfailed(name, hostname, tty);
  306. return(VF_INVALID);
  307. }
  308. /*
  309. * User authenticated. Check login restrictions.
  310. */
  311. rc = loginrestrictions(name, loginType, tty, msg);
  312. if (rc)
  313. {
  314. /*
  315. * Login restrictions disallow login.
  316. */
  317. loginfailed(name, hostname, tty);
  318. return(VF_MESSAGE);
  319. }
  320. /*
  321. * Check password expiration.
  322. */
  323. rc = passwdexpired(name, msg);
  324. if (rc)
  325. {
  326. /*
  327. * Login succeeded, but password expired.
  328. */
  329. return(VF_PASSWD_AGED);
  330. }
  331. /*
  332. * Login succeeded.
  333. */
  334. loginsuccess(name, hostname, tty, msg);
  335. return(VF_OK);
  336. }
  337. #else /* !_POWER */
  338. /***************************************************************************
  339. *
  340. * Start authentication routines (AIX)
  341. *
  342. ***************************************************************************/
  343. #include <time.h>
  344. #include <sys/types.h>
  345. #include <sys/errno.h>
  346. #include <usersec.h>
  347. #include <userpw.h>
  348. #include <userconf.h>
  349. #include <utmp.h>
  350. #include <time.h>
  351. /***************************************************************************
  352. *
  353. * External declarations (AIX)
  354. *
  355. ***************************************************************************/
  356. /***************************************************************************
  357. *
  358. * Procedure declarations (AIX)
  359. *
  360. ***************************************************************************/
  361. static void Audit( struct passwd *p, char *msg, int errnum) ;
  362. static int PasswordAged(char *name, struct passwd *pw) ;
  363. static void WriteBtmp( char *name) ;
  364. /***************************************************************************
  365. *
  366. * Global variables (AIX)
  367. *
  368. ***************************************************************************/
  369. /***************************************************************************
  370. *
  371. * Audit (AIX)
  372. *
  373. ***************************************************************************/
  374. static void
  375. Audit( struct passwd *p, char *msg, int errnum )
  376. {
  377. /*
  378. * make sure program is back to super-user...
  379. */
  380. seteuid(0);
  381. if ( (auditwrite ("USER_Login", AUDIT_OK,
  382. p->pw_name, strlen (p->pw_name) + 1,
  383. msg, strlen (msg) + 1, NULL)) == -1 )
  384. Debug(" Could not do Auditing\n");
  385. }
  386. /***************************************************************************
  387. *
  388. * WriteBtmp (AIX)
  389. *
  390. * log bad login attempts to /etc/security/failedlogin file
  391. *
  392. * RK 09.13.93
  393. ***************************************************************************/
  394. static void
  395. WriteBtmp( char *name )
  396. {
  397. int fd;
  398. struct utmp ut;
  399. if( (fd = open("/etc/security/failedlogin",O_CREAT|O_RDWR,0644)) != -1) {
  400. bzero(&ut,sizeof(struct utmp));
  401. if(name)
  402. strncpy(ut.ut_user, name, sizeof ut.ut_user);
  403. ut.ut_type = USER_PROCESS;
  404. ut.ut_pid = getpid();
  405. ut.ut_time = time((time_t *)0);
  406. write(fd, (char *)&ut, sizeof(struct utmp));
  407. close(fd);
  408. }
  409. }
  410. /***************************************************************************
  411. *
  412. * PasswordAged (AIX)
  413. *
  414. * see if password has aged
  415. ***************************************************************************/
  416. #define SECONDS_IN_WEEK 604800L
  417. static int
  418. PasswordAged(char *name, struct passwd *pw )
  419. {
  420. struct userpw *pupw; /* authentication information from getuserpw() */
  421. struct userpw upw; /* working authentication information */
  422. int err; /* return code from getconfattr() */
  423. ulong maxage; /* maximun age from getconfattr() */
  424. ulong now; /* time now */
  425. #ifdef _POWER
  426. return(FALSE);
  427. #else /* _POWER */
  428. /*
  429. * Determine user password aging criteria. Note that only
  430. * the 'lastupdate' and 'flags' fields are set by this operation.
  431. */
  432. setpwdb(S_READ);
  433. if ((pupw = getuserpw(name)) != NULL)
  434. {
  435. upw.upw_lastupdate = pupw->upw_lastupdate;
  436. upw.upw_flags = pupw->upw_flags;
  437. }
  438. else
  439. {
  440. upw.upw_lastupdate = 0;
  441. upw.upw_flags = 0;
  442. }
  443. endpwdb();
  444. /*
  445. * Consider password as having not expired if nocheck set.
  446. */
  447. if (upw.upw_flags & PW_NOCHECK) return(FALSE);
  448. /*
  449. * Get system password aging criteria.
  450. */
  451. err = getconfattr (SC_SYS_PASSWD, SC_MAXAGE, (void *)&maxage, SEC_INT);
  452. if (!err && maxage)
  453. {
  454. /*
  455. * Change from weeks to seconds
  456. */
  457. maxage = maxage * SECONDS_IN_WEEK;
  458. now = time ((long *) 0);
  459. if ((upw.upw_lastupdate + maxage) >= now)
  460. {
  461. /*
  462. * Password has not expired.
  463. */
  464. return(FALSE);
  465. }
  466. }
  467. else
  468. {
  469. /*
  470. * Could not retrieve system password aging info or maxage set to
  471. * zero. In either case, consider password has having not expired.
  472. */
  473. return(FALSE);
  474. }
  475. /*
  476. * We haven't returned by now, so indicate password has expired.
  477. */
  478. return(TRUE);
  479. #endif /* _POWER */
  480. }
  481. /***************************************************************************
  482. * dt_failedlogin (AIX)
  483. *
  484. * log failed login in /etc/security/lastlog
  485. ***************************************************************************/
  486. struct lastlogin {
  487. time_t ftime;
  488. time_t stime;
  489. int fcount;
  490. char user[32];
  491. char *stty;
  492. char *ftty;
  493. char *shost;
  494. char *fhost;
  495. };
  496. extern void
  497. dt_lastlogin ( char * user, struct lastlogin * llogin);
  498. void
  499. dt_failedlogin(char *name, char *ttyName, char *hostName)
  500. {
  501. struct lastlogin last_login;
  502. last_login.stime = 0;
  503. time(&last_login.ftime);
  504. last_login.ftty = ttyName;
  505. last_login.fhost = (char *) malloc (MAXHOSTNAMELEN);
  506. if (hostName == NULL) {
  507. gethostname (last_login.fhost , MAXHOSTNAMELEN);
  508. } else {
  509. strncpy(last_login.fhost, hostName, MAXHOSTNAMELEN);
  510. last_login.fhost[MAXHOSTNAMELEN -1] = '\0';
  511. }
  512. Debug("logging failed lastlogin entry (user=%s)\n",name);
  513. dt_lastlogin(name, &last_login);
  514. free(last_login.fhost);
  515. }
  516. /***************************************************************************
  517. *
  518. * Authenticate (AIX)
  519. *
  520. * verify the user
  521. *
  522. * return codes indicate authentication results.
  523. ***************************************************************************/
  524. #define MAXATTEMPTS 3
  525. struct passwd nouser = {"", "nope"}; /* invalid user password struct */
  526. int
  527. Authenticate( struct display *d, char *name, char *passwd, char **msg )
  528. {
  529. static int login_attempts = 0; /* # failed authentications */
  530. struct passwd *p; /* password structure */
  531. char *crypt();
  532. char *origpw;
  533. int loginType;
  534. char tty[128];
  535. char *hostname;
  536. /*
  537. * Nothing to do if no name provided.
  538. */
  539. if (!name)
  540. return(VF_INVALID);
  541. /*
  542. * Save provided password.
  543. */
  544. origpw = passwd;
  545. if (!passwd) passwd = "";
  546. if(strlen(name) > S_NAMELEN)
  547. return(VF_INVALID);
  548. GetLoginInfo(d, &loginType, tty, &hostname);
  549. p = getpwnam(name);
  550. if (!p || strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) {
  551. WriteBtmp(name);
  552. if ((++login_attempts % MAXATTEMPTS) == 0 ) {
  553. if (p == NULL )
  554. p = &nouser;
  555. Audit(p, " Failed login (bailout)", 1);
  556. }
  557. if (origpw) {
  558. dt_failedlogin(name, tty, hostname);
  559. return (VF_INVALID);
  560. } else
  561. return(VF_CHALLENGE);
  562. }
  563. /* Note: The password should be checked if it is the first time
  564. the user is logging in or whether the sysadm has changed
  565. the password for the user. Code should be added here if
  566. this functionality should be supported. The "upw_flags"
  567. of the password structure gets set to PW_ADMCHG in this
  568. case. RK 09.13.93.
  569. */
  570. /*
  571. * check password aging...
  572. */
  573. if ( PasswordAged(name,p) ) return(VF_PASSWD_AGED);
  574. /* Validate for User Account RK 09.13.93 */
  575. if(ckuseracct(name, loginType, tty) == -1) {
  576. dt_failedlogin(name, tty, hostname);
  577. return(VF_INVALID);
  578. }
  579. /*
  580. * validate uid and gid...
  581. */
  582. if ((p->pw_gid < 0) ||
  583. (setgid(p->pw_gid) == -1)) {
  584. Audit(p, " attempted to login - bad group id", 1);
  585. return(VF_BAD_GID);
  586. }
  587. if ((p->pw_uid < 0)) {
  588. Audit(p, " attempted to login - bad user id", 1);
  589. return(VF_BAD_UID);
  590. }
  591. /* Check for max number of logins RK 09.13.93 */
  592. if (tsm_check_login(p->pw_uid) == -1) {
  593. dt_failedlogin(name, tty, hostname);
  594. return(VF_INVALID);
  595. }
  596. /* Check for /etc/nologin file RK 09.13.93 */
  597. if ( (access("/etc/nologin",R_OK) == 0) && (p->pw_uid != 0) ) {
  598. dt_failedlogin(name, tty, hostname);
  599. return(VF_INVALID);
  600. }
  601. /*
  602. * verify home directory exists...
  603. */
  604. if(chdir(p->pw_dir) < 0) {
  605. Audit(p, " attempted to login - no home directory", 1);
  606. return(VF_HOME);
  607. }
  608. /*
  609. * verify ok...
  610. */
  611. Audit(p, " Successful login", 0);
  612. return(VF_OK);
  613. }
  614. /**************************************************************************
  615. *
  616. * tsm_check_login()
  617. *
  618. * Checks for max number of logins on the system. If the new user trying to
  619. * login exceeds the max limit then the user is not allowed to login.
  620. *
  621. * RK 09.13.93
  622. **************************************************************************/
  623. /**************************************************************************
  624. *
  625. * tsm_check_login()
  626. *
  627. * Checks for max number of logins on the system. If the new user trying to
  628. * login exceeds the max limit then the user is not allowed to login.
  629. *
  630. * RK 09.13.93
  631. **************************************************************************/
  632. int
  633. tsm_check_login(uid_t uid)
  634. {
  635. key_t key;
  636. char *buffer;
  637. int semid;
  638. int fd;
  639. struct stat stat_buf;
  640. static struct sembuf sop = { 0, -1, (SEM_UNDO|IPC_NOWAIT) };
  641. static struct sembuf initsop = { 0, 0, (IPC_NOWAIT) };
  642. /*
  643. * The login counter semaphore may not be set yet. See if it exists
  644. * and try creating it with the correct count if it doesn't. An
  645. * attempt is made to create the semaphore. Only if that attempt fails
  646. * is the semaphore set to maxlogins from login.cfg.
  647. */
  648. /*
  649. * Don't Check if the user is already logged. ie running login
  650. * from a shell
  651. */
  652. /*
  653. * Generate the semaphore key from the init program.
  654. */
  655. Debug("Start of maxlogin check\n");
  656. if ((key = ftok (CDE_INSTALLATION_TOP "/bin/dtlogin", 1)) != (key_t) -1) {
  657. Debug("key created\n");
  658. if ((semid = semget (key, 1, IPC_CREAT|IPC_EXCL|0600)) != -1) {
  659. int i;
  660. Debug("Completed IPCkey\n");
  661. if (! getconfattr ("usw", "maxlogins", &i, SEC_INT)) {
  662. Debug("Max logins from login.cfg is :%d\n",i);
  663. if (i <= 0)
  664. i = 10000; /* a very large number */
  665. initsop.sem_op = i;
  666. if (semop (semid, &initsop, 1))
  667. {
  668. Debug("failed while decrementing\n");
  669. return(-1);
  670. }
  671. } else {
  672. semctl (semid, 1, IPC_RMID, 0);
  673. }
  674. }
  675. /*
  676. * Only 'n' login sessions are allowed on the system.
  677. * This code block decrements a semaphore.
  678. * The semundo value will be set to adjust the
  679. * semaphore when tsm exits.
  680. *
  681. * This code will be ignored if the appropriate
  682. * semaphore set does not exist.
  683. */
  684. if ((semid = semget (key, 1, 0)) != -1) {
  685. Debug("getting key for maxlogins\n");
  686. /*
  687. * If the semaphore is zero and we are not
  688. * root, then we fail as there are already the
  689. * allotted number of login sessions on the
  690. * system.
  691. */
  692. if ((semop (semid, &sop, 1) == -1) && uid) {
  693. Debug("reached MAXLOGINS limit\n");
  694. errno = EAGAIN;
  695. return(-1);
  696. }
  697. }
  698. }
  699. }
  700. #endif /* !_POWER */
  701. #endif /* _AIX */
  702. /***************************************************************************
  703. *
  704. * End authentication routines (AIX)
  705. *
  706. ***************************************************************************/
  707. /***************************************************************************
  708. ***************************************************************************
  709. ***************************************************************************
  710. ***************************************************************************
  711. ***************************************************************************
  712. ***************************************************************************
  713. ***************************************************************************
  714. ***************************************************************************/
  715. #ifdef generic
  716. /***************************************************************************
  717. *
  718. * Start authentication routines (generic)
  719. *
  720. ***************************************************************************/
  721. /***************************************************************************
  722. *
  723. * These are a set of routine to do simple password, home dir, uid, and gid
  724. * validation. They can be used as a first pass validation for future
  725. * porting efforts.
  726. *
  727. * When platform specific validation is developed, those routines should be
  728. * included in their own section and the use of these routines discontinued.
  729. *
  730. ***************************************************************************/
  731. /***************************************************************************
  732. *
  733. * External declarations (generic)
  734. *
  735. ***************************************************************************/
  736. /***************************************************************************
  737. *
  738. * Procedure declarations (generic)
  739. *
  740. ***************************************************************************/
  741. static void Audit( struct passwd *p, char *msg, int errnum) ;
  742. static int PasswordAged( struct passwd *pw) ;
  743. static void WriteBtmp( char *name) ;
  744. /***************************************************************************
  745. *
  746. * Global variables (generic)
  747. *
  748. ***************************************************************************/
  749. /***************************************************************************
  750. *
  751. * Audit (generic)
  752. *
  753. ***************************************************************************/
  754. static void
  755. Audit( struct passwd *p, char *msg, int errnum )
  756. {
  757. /*
  758. * make sure program is back to super-user...
  759. */
  760. if(-1 == seteuid(0)) {
  761. perror(strerror(errno));
  762. }
  763. return;
  764. }
  765. /***************************************************************************
  766. *
  767. * WriteBtmp (generic)
  768. *
  769. * log bad login attempts
  770. *
  771. ***************************************************************************/
  772. static void
  773. WriteBtmp( char *name )
  774. {
  775. return;
  776. }
  777. /***************************************************************************
  778. *
  779. * PasswordAged (Generic)
  780. *
  781. * see if password has aged
  782. ***************************************************************************/
  783. #define SECONDS_IN_WEEK 604800L
  784. static int
  785. PasswordAged( struct passwd *pw )
  786. {
  787. return(FALSE);
  788. }
  789. /***************************************************************************
  790. *
  791. * Authenticate (generic)
  792. *
  793. * verify the user
  794. *
  795. * return codes indicate authentication results.
  796. ***************************************************************************/
  797. #define MAXATTEMPTS 3
  798. struct passwd nouser = {"", "nope"}; /* invalid user password struct */
  799. int
  800. Authenticate( struct display *d, char *name, char *passwd, char **msg )
  801. {
  802. static int login_attempts = 0; /* # failed authentications */
  803. struct passwd *p; /* password structure */
  804. char *crypt();
  805. int n;
  806. char *origpw;
  807. /*
  808. * Nothing to do if no name provided.
  809. */
  810. if (!name)
  811. return(VF_INVALID);
  812. /*
  813. * Save provided password.
  814. */
  815. origpw = passwd;
  816. if (!passwd) passwd = "";
  817. p = getpwnam(name);
  818. #if defined(__linux__)
  819. /*
  820. * Use the Linux Shadow Password system to get the crypt()ed password
  821. */
  822. if(p) {
  823. struct spwd *s = getspnam(name);
  824. if(s) {
  825. p->pw_passwd = s->sp_pwdp;
  826. }
  827. }
  828. #endif
  829. #if defined(__OpenBSD__) && OSMAJORVERSION > 5
  830. /*
  831. * Use the OpenBSD getpwnam_shadow function to get the crypt()ed password
  832. */
  833. p = getpwnam_shadow(name);
  834. #endif
  835. if (!p || strlen(name) == 0 ||
  836. strcmp (crypt (passwd, p->pw_passwd), p->pw_passwd)) {
  837. WriteBtmp(name);
  838. if ((++login_attempts % MAXATTEMPTS) == 0 ) {
  839. if (p == NULL )
  840. p = &nouser;
  841. Audit(p, " Failed login (bailout)", 1);
  842. }
  843. return(origpw ? VF_INVALID : VF_CHALLENGE);
  844. }
  845. /*
  846. * check password aging...
  847. */
  848. if ( PasswordAged(p) ) return(VF_PASSWD_AGED);
  849. /*
  850. * verify home directory exists...
  851. */
  852. if(chdir(p->pw_dir) < 0) {
  853. Audit(p, " attempted to login - no home directory", 1);
  854. return(VF_HOME);
  855. }
  856. /*
  857. * validate uid and gid...
  858. */
  859. if (setgid(p->pw_gid) == -1) {
  860. Audit(p, " attempted to login - bad group id", 1);
  861. return(VF_BAD_GID);
  862. }
  863. if (seteuid(p->pw_uid) == -1) {
  864. Audit(p, " attempted to login - bad user id", 1);
  865. return(VF_BAD_UID);
  866. }
  867. /*
  868. * verify ok...
  869. */
  870. Audit(p, " Successful login", 0);
  871. return(VF_OK);
  872. }
  873. /***************************************************************************
  874. *
  875. * End authentication routines (generic)
  876. *
  877. ***************************************************************************/
  878. #endif /* generic */
  879. /***************************************************************************
  880. ***************************************************************************
  881. ***************************************************************************
  882. ***************************************************************************
  883. ***************************************************************************
  884. ***************************************************************************
  885. ***************************************************************************
  886. ***************************************************************************/