sysauth.c 27 KB

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