home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Mail / qpopper-2.4-MIHS / pop_pass.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-15  |  16.2 KB  |  638 lines

  1. /*
  2.  * Copyright (c) 1989 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6.  
  7. /*
  8.  * Copyright (c) 1997 by Qualcomm Incorporated.
  9.  */
  10.  
  11. #include <config.h>
  12. #include <stdio.h>
  13. #include <sys/types.h>
  14. #include <string.h>
  15. #if HAVE_STRINGS_H
  16. # include <strings.h>
  17. #endif
  18.  
  19. #include <pwd.h>
  20. #include "popper.h"
  21.  
  22. #define    SLEEP_SECONDS 10
  23.  
  24.  
  25. /* This error message is vague on purpose to help reduce help improve
  26.    security at the inconvience of administrators and users */
  27.  
  28. char    *pwerrmsg = "Password supplied for \"%s\" is incorrect.";
  29.  
  30.  
  31. #ifdef NONAUTHFILE
  32. checknonauthfile(user) 
  33.      char *user;
  34. {
  35.     char buf[MAXUSERNAMELEN+1];
  36.     FILE *fp;
  37.     char cool = 0;
  38.  
  39.     if ((fp = fopen(NONAUTHFILE, "r")) != NULL) {
  40.     while (fgets(buf, MAXUSERNAMELEN+1, fp)) {
  41.         buf[strlen(buf) -1] = '\0';
  42.         if (!strcmp(buf, user)) {
  43.         fclose(fp);
  44.         return(-1);
  45.         }
  46.     }
  47.  
  48.     fclose(fp);
  49.     }
  50.     return(0);
  51. }
  52. #endif
  53.  
  54. #ifdef AUTHFILE
  55. checkauthfile(user) 
  56.      char *user;
  57. {
  58.     char buf[MAXUSERNAMELEN+1];
  59.     FILE *fp;
  60.     char cool = 0;
  61.  
  62.     if ((fp = fopen(AUTHFILE, "r")) != NULL) {
  63.     while (fgets(buf, MAXUSERNAMELEN+1, fp)) {
  64.         buf[strlen(buf) -1] = '\0';
  65.         if (!strcmp(buf, user)) {
  66.         fclose(fp);
  67.         return(0);
  68.         }
  69.     }
  70.  
  71.     fclose(fp);
  72.     }
  73.     return(-1);
  74. }
  75. #endif
  76.  
  77. int auth_user_kerberos (p, pw)
  78. POP     *   p;
  79. struct passwd *pw;
  80. {
  81. #ifdef KERBEROS
  82.     char lrealm[REALM_SZ];
  83.     int status;
  84.     struct passwd *pwp;
  85.  
  86.     if ((status = krb_get_lrealm(lrealm,1)) == KFAILURE) {
  87.         pop_log(p, LOG_WARNING, "%s: (%s.%s@%s) %s", p->client, kdata.pname, 
  88.         kdata.pinst, kdata.prealm, krb_err_txt[status]);
  89.         return(pop_msg(p,POP_FAILURE,
  90.             "Kerberos error:  \"%s\".", krb_err_txt[status]));
  91.     }
  92.  
  93. # ifdef KUSEROK
  94.     if (kuserok(&kdata, p->user)) {
  95.         pop_log(p, LOG_WARNING, "%s: (%s.%s@%s): not in %s's ACL.",
  96.         p->client, kdata.pname, kdata.pinst, kdata.prealm, p->user);
  97.     return(pop_msg(p,POP_FAILURE, "Not in %s's ACL.", p->user));
  98.     }
  99. # else
  100.     if (strcmp(kdata.prealm,lrealm))  {
  101.          pop_log(p, LOG_WARNING, "%s: (%s.%s@%s) realm not accepted.", 
  102.          p->client, kdata.pname, kdata.pinst, kdata.prealm);
  103.      return(pop_msg(p,POP_FAILURE,
  104.              "Kerberos realm \"%s\" not accepted.", kdata.prealm));
  105.     }
  106.  
  107.     if (strcmp(kdata.pinst,"")) {
  108.         pop_log(p, LOG_WARNING, "%s: (%s.%s@%s) instance not accepted.", 
  109.          p->client, kdata.pname, kdata.pinst, kdata.prealm);
  110.         return(pop_msg(p,POP_FAILURE,
  111.           "Must use null Kerberos(tm) instance -  \"%s.%s\" not accepted.",
  112.           kdata.pname, kdata.pinst));
  113.     }
  114. # endif /* KUSEROK */
  115.     return(POP_SUCCESS);
  116. #else    /* Kerberos not defined */
  117.     return(pop_log(p, LOG_WARNING,
  118.     "Kerberos failure: The popper has not been compiled with -DKERBEROS"));
  119. #endif    /* KERBEROS */
  120. }
  121.  
  122.  
  123. #ifdef AUTH
  124.     char *crypt();
  125.  
  126. #if defined(SUNOS4) && !defined(ISC)
  127.  
  128. #include <sys/label.h>
  129. #include <sys/audit.h>
  130. #include <pwdadj.h>
  131.  
  132. static int
  133. auth_user(p, pw)
  134. POP     *   p;
  135. struct passwd *pw;
  136. {
  137.     struct passwd_adjunct *pwadj;
  138.  
  139.     /*  Look for the user in the shadow password file */
  140.     if ((pwadj = getpwanam(p->user)) == NULL) {
  141.     sleep(SLEEP_SECONDS);
  142.     return (pop_msg(p,POP_FAILURE,
  143.         "(shadow) Password supplied for \"%s\" is empty.",p->user));
  144.     } else {
  145.         pw->pw_passwd = (char *)strdup(pwadj->pwa_passwd);
  146.     }
  147.  
  148.     /*  We don't accept connections from users with null passwords */
  149.     /*  Compare the supplied password with the password file entry */
  150.     if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == '\0') ||
  151.         strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
  152.     sleep(SLEEP_SECONDS);
  153.     return (pop_msg(p,POP_FAILURE,pwerrmsg, p->user));
  154.     }
  155.  
  156.     return(POP_SUCCESS);
  157. }
  158.  
  159. #endif    /* SUNOS4 */
  160.  
  161. #if defined(SOLARIS2) || defined(AUX)
  162.  
  163. #include <shadow.h>
  164.  
  165. static int
  166. auth_user(p, pw)
  167. POP     *   p;
  168. struct passwd *pw;
  169. {
  170.     register struct spwd * pwd;
  171.     long today;
  172.  
  173.     /*  Look for the user in the shadow password file */
  174.     if ((pwd = getspnam(p->user)) == NULL) {
  175.         if (!strcmp(pw->pw_passwd, "x")) {    /* This my be a YP entry */
  176.         sleep(SLEEP_SECONDS);
  177.         return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  178.     }
  179.     } else {
  180.     today = (long)time((time_t *)NULL)/24/60/60;
  181.  
  182.     /* Check for expiration date */
  183.     if (pwd->sp_expire > 0 && today > pwd->sp_expire) {
  184.         sleep(SLEEP_SECONDS);
  185.         return (pop_msg(p,POP_FAILURE,"\"%s\": account expired.",p->user));
  186.     }
  187.  
  188.     /* Check if password is valid */
  189.     if (pwd->sp_max > 0 && today > pwd->sp_lstchg+pwd->sp_max) {
  190.         sleep(SLEEP_SECONDS);
  191.         return (pop_msg(p,POP_FAILURE,"\"%s\": account expired.",p->user));
  192.     }
  193.  
  194.     pw->pw_passwd = (char *)strdup(pwd->sp_pwdp);
  195.     endspent();
  196.     }
  197.  
  198.     /*  We don't accept connections from users with null passwords */
  199.     /*  Compare the supplied password with the password file entry */
  200.     if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == '\0') ||
  201.         strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
  202.     sleep(SLEEP_SECONDS);
  203.     return (pop_msg(p, POP_FAILURE, pwerrmsg, p->user));
  204.     }
  205.  
  206.     return(POP_SUCCESS);
  207. }
  208.  
  209. #endif    /* SOLARIS2 || AUX */
  210.  
  211. #if defined(PTX) || defined(ISC)
  212.  
  213. #include <shadow.h>
  214.  
  215. static int
  216. auth_user(p, pw)
  217. POP     *   p;
  218. struct passwd *pw;
  219. {
  220.     register struct spwd * pwd;
  221.     long today;
  222.  
  223.     /*  Look for the user in the shadow password file */
  224.     if ((pwd = getspnam(p->user)) == NULL) {
  225.         if (!strcmp(pw->pw_passwd, "x")) {    /* This my be a YP entry */
  226.         sleep(SLEEP_SECONDS);
  227.         return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  228.     }
  229.     } else {
  230.     pw->pw_passwd = (char *)strdup(pwd->sp_pwdp);
  231.     }
  232.  
  233.     /*  We don't accept connections from users with null passwords */
  234.     /*  Compare the supplied password with the password file entry */
  235.     if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == '\0') ||
  236.         strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
  237.     sleep(SLEEP_SECONDS);
  238.     return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  239.     }
  240.  
  241.     return(POP_SUCCESS);
  242. }
  243.  
  244. #endif    /* PTX */
  245.  
  246. #if defined(POPSCO) || defined(HPUX10)
  247.  
  248. #ifdef POPSCO
  249. # include <sys/security.h>
  250. # include <sys/audit.h>
  251. #else
  252. # include <hpsecurity.h>
  253. #endif
  254.  
  255. #include <prot.h>
  256. #define PASSWD(p)    p->ufld.fd_encrypt
  257.  
  258. static int
  259. auth_user(p, pw)
  260. POP     *   p;
  261. struct passwd *pw;
  262. {
  263.     register struct pr_passwd *pr;
  264.  
  265.     if ((pr = getprpwnam(p->user)) == NULL) {
  266.         if (!strcmp(pw->pw_passwd, "x")) {
  267.         sleep(SLEEP_SECONDS);
  268.         return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  269.     }
  270.  
  271.     /*  We don't accept connections from users with null passwords */
  272.     if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == '\0') ||
  273.              (strcmp(bigcrypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) &&
  274.           strcmp(crypt (p->pop_parm[1], pw->pw_passwd), pw->pw_passwd))) {
  275.         sleep(SLEEP_SECONDS);
  276.         return(pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  277.     }
  278.     } else {
  279.     /*  We don't accept connections from users with null passwords */
  280.     /*  Compare the supplied password with the password file entry */
  281.     if ((PASSWD(pr) == NULL) || (*PASSWD(pr) == '\0')) {
  282.         sleep(SLEEP_SECONDS);
  283.         return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  284.     }
  285.     
  286.     if (strcmp(bigcrypt(p->pop_parm[1], PASSWD(pr)), PASSWD(pr)) &&
  287.             strcmp(crypt(p->pop_parm[1], PASSWD(pr)), PASSWD(pr))) {
  288.         sleep(SLEEP_SECONDS);
  289.         return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  290.     }
  291.     }
  292.  
  293.     return(POP_SUCCESS);
  294. }
  295.  
  296. #endif    /* POPSCO || HPUX10 */
  297.  
  298. #ifdef ULTRIX
  299.  
  300. #include <auth.h>
  301.  
  302. static int
  303. auth_user(p, pw)
  304. struct passwd  *   pw;
  305. POP     *   p;
  306. {
  307.     AUTHORIZATION *auth, *getauthuid();
  308.  
  309.     if ((auth = getauthuid(pw->pw_uid)) == NULL) {
  310.         if (!strcmp(pw->pw_passwd, "x")) {    /* This my be a YP entry */
  311.         sleep(SLEEP_SECONDS);
  312.         return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  313.     }
  314.     } else {
  315.     pw->pw_passwd = (char *)strdup(auth->a_password);
  316.     }
  317.  
  318.     /*  We don't accept connections from users with null passwords */
  319.     /*  Compare the supplied password with the password file entry */
  320.     if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == '\0')) {
  321.     sleep(SLEEP_SECONDS);
  322.     return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  323.     }
  324.  
  325.     if (strcmp(crypt16(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) &&
  326.         strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
  327.     sleep(SLEEP_SECONDS);
  328.     return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  329.     }
  330.  
  331.     return(POP_SUCCESS);
  332. }
  333.  
  334. #endif    /* ULTRIX */
  335.  
  336. #ifdef OSF1
  337. #include <sys/types.h>
  338. #include <sys/security.h>
  339. #include <prot.h>
  340. #define   PASSWD(p)   (p->ufld.fd_encrypt)
  341. static int
  342. auth_user(p, pw)
  343. POP     *   p;
  344. struct passwd *pw;
  345. {
  346.     register struct pr_passwd *pr;
  347.  
  348.     if ((pr = getprpwnam(p->user)) == NULL) {
  349.         if (!strcmp(pw->pw_passwd, "x")) {    /* This my be a YP entry */
  350.         sleep(SLEEP_SECONDS);
  351.         return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  352.     }
  353.     } else {
  354.     pw->pw_passwd = (char *)strdup(PASSWD(pr));
  355.     }
  356.  
  357.     /*  We don't accept connections from users with null passwords */
  358.     /*  Compare the supplied password with the password file entry */
  359.     if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == '\0')) {
  360.     sleep(SLEEP_SECONDS);
  361.     return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  362.     }
  363.  
  364.     if (strcmp(bigcrypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) &&
  365.         strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
  366.     sleep(SLEEP_SECONDS);
  367.     return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  368.     }
  369.  
  370.     return(POP_SUCCESS);
  371. }
  372.  
  373. #endif        /* OSF1 */
  374.  
  375. #ifdef UNIXWARE
  376.  
  377. #include <shadow.h>
  378.  
  379. static int
  380. auth_user(p, pw)
  381. struct passwd  *   pw;
  382. POP     *   p;
  383. {
  384.     register struct spwd * pwd;
  385.     long today;
  386.  
  387.     /*  Look for the user in the shadow password file */
  388.     if ((pwd = getspnam(p->user)) == NULL) {
  389.         if (!strcmp(pw->pw_passwd, "x")) {    /* This my be a YP entry */
  390.         sleep(SLEEP_SECONDS);
  391.         return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  392.     }
  393.     } else {
  394.     today = (long)time((time_t *)NULL)/24/60/60;
  395.  
  396.     /* Check for expiration date */
  397.     if (pwd->sp_expire > 0 && today > pwd->sp_expire) {
  398.         sleep(SLEEP_SECONDS);
  399.         return (pop_msg(p,POP_FAILURE,"\"%s\": account expired.",p->user));
  400.     }
  401.  
  402.     /* Check if password is valid */
  403.     if (pwd->sp_max > 0 && today > pwd->sp_lstchg+pwd->sp_max) {
  404.         sleep(SLEEP_SECONDS);
  405.         return (pop_msg(p,POP_FAILURE,"\"%s\": account expired.",p->user));
  406.     }
  407.  
  408.     pw->pw_passwd = (char *)strdup(pwd->sp_pwdp);
  409.     endspent();
  410.     }
  411.  
  412.     /*  We don't accept connections from users with null passwords */
  413.     /*  Compare the supplied password with the password file entry */
  414.     if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == '\0') ||
  415.         strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
  416.     sleep(SLEEP_SECONDS);
  417.     return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  418.     }
  419.  
  420.     return(POP_SUCCESS);
  421. }
  422.  
  423. #endif    /* UNIXWARE */
  424.  
  425. #ifdef LINUX
  426. #include <shadow.h>
  427.  
  428. static int
  429. auth_user(p, pw)
  430. POP     *   p;
  431. struct passwd *pw;
  432. {
  433.     register struct spwd * pwd;
  434.     long today;
  435.  
  436.     /*  Look for the user in the shadow password file */
  437.     if ((pwd = getspnam(p->user)) == NULL) {
  438.         if (!strcmp(pw->pw_passwd, "x")) {    /* This my be a YP entry */
  439.         sleep(SLEEP_SECONDS);
  440.         return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  441.     }
  442.     } else {
  443.     today = (long)time((time_t *)NULL)/24/60/60;
  444.  
  445.     /* Check for expiration date */
  446.     if (pwd->sp_expire > 0 && today > pwd->sp_expire) {
  447.         sleep(SLEEP_SECONDS);
  448.         return (pop_msg(p,POP_FAILURE,"\"%s\": account expired.",p->user));
  449.     }
  450.  
  451.     /* Check if password is valid */
  452.     if (pwd->sp_max > 0 && today > pwd->sp_lstchg+pwd->sp_max) {
  453.         sleep(SLEEP_SECONDS);
  454.         return (pop_msg(p,POP_FAILURE,"\"%s\": account expired.",p->user));
  455.     }
  456.  
  457.     pw->pw_passwd = (char *)strdup(pwd->sp_pwdp);
  458.     endspent();
  459.     }
  460.  
  461.     /*  We don't accept connections from users with null passwords */
  462.     /*  Compare the supplied password with the password file entry */
  463.     /*  pw_encrypt() ??                                            */
  464.     if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == '\0') || 
  465.         (strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) &&
  466.          strcmp(pw_encrypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd))){
  467.     sleep(SLEEP_SECONDS);
  468.     return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  469.     }
  470.  
  471.     return(POP_SUCCESS);
  472. }
  473.  
  474. #endif  /* LINUX */
  475.  
  476. #else    /* NOT AUTH */
  477.  
  478. char *crypt();
  479.  
  480. static int
  481. auth_user(p, pw)
  482. POP     *   p;
  483. struct passwd  *   pw;
  484. {
  485.     /*  We don't accept connections from users with null passwords */
  486.     /*  Compare the supplied password with the password file entry */
  487.  
  488.     if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == '\0') ||
  489.         strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
  490.     sleep(SLEEP_SECONDS);
  491.     return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  492.     }
  493.  
  494.     return(POP_SUCCESS);
  495. }
  496.  
  497. #endif    /* AUTH */
  498.  
  499. /* 
  500.  *  pass:   Obtain the user password from a POP client
  501.  */
  502.  
  503. #ifdef SECURENISPLUS
  504. /* AUTH gets defined in rpc/... */
  505. # ifdef AUTH
  506. #  undef AUTH
  507. # endif
  508. # include <rpc/rpc.h>
  509. # include <rpc/key_prot.h>
  510. #endif
  511.  
  512. int pop_pass (p)
  513. POP     *   p;
  514. {
  515.     struct passwd pw, *pwp;
  516. #ifdef CHECK_SHELL
  517.     char *getusershell();
  518.     void endusershell();
  519.     char *shell;
  520.     char *cp;
  521.     int shellvalid;
  522. #endif
  523.  
  524. #ifdef SECURENISPLUS
  525.     UID_T uid_save;
  526.     char net_name[MAXNETNAMELEN],
  527.      secretkey[HEXKEYBYTES + 1];
  528.  
  529.     *secretkey = '\0';
  530. #endif
  531.  
  532. #ifdef NONAUTHFILE
  533.     /* Is the user not authorized to use POP? */
  534.     if (checknonauthfile(p->user) != 0) {
  535.     sleep(SLEEP_SECONDS);
  536.     return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  537.     }
  538. #endif
  539.  
  540. #ifdef AUTHFILE
  541.     /* Is the user authorized to use POP? */
  542.     if (checkauthfile(p->user) != 0) {
  543.     sleep(SLEEP_SECONDS);
  544.     return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  545.     }
  546. #endif
  547.  
  548.     /*  Look for the user in the password file */
  549.     if ((pwp = getpwnam(p->user)) == NULL) {
  550.     sleep(SLEEP_SECONDS);
  551.     return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  552.     }
  553.  
  554.     pw = *pwp;
  555.  
  556. #ifdef SECURENISPLUS
  557.     /*  we must do this keyserv stuff (as well as auth_user()!) as the user */
  558.     uid_save = geteuid();
  559.     seteuid(pw.pw_uid);
  560.  
  561.     /*  see if DES keys are already known to the keyserv(1m) */
  562.     if (! key_secretkey_is_set()) {
  563.     /*  keys are not known, so we must get the DES keys
  564.         and register with the keyserv(1m) */
  565.  
  566.     getnetname(net_name);
  567.  
  568.     if (getpublickey(net_name, secretkey)) {
  569.         if (strlen(p->pop_parm[1]) > 8) (p->pop_parm[1])[8] = '\0';
  570.  
  571.         if (! getsecretkey(net_name, secretkey, p->pop_parm[1]) ||
  572.                             *secretkey == '\0') {
  573.         sleep(SLEEP_SECONDS);
  574.         return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
  575.         }
  576.  
  577.         key_setsecret(secretkey);
  578.         memset(secretkey, '\0', sizeof(secretkey));
  579.     } else {
  580.         /* if there are no keys defined, we assume that password entry
  581.            either resides in /etc/shadow or "root" has access to the
  582.            corresponding NIS+ entry */
  583.         seteuid(0);
  584.     }
  585.     }
  586. #endif
  587.  
  588. #ifdef BLOCK_UID
  589.     if (pw.pw_uid <= BLOCK_UID)
  590.     return (pop_msg(p,POP_FAILURE,
  591.                 "Access is blocked for UIDs below %d", BLOCK_UID));
  592. #endif
  593.  
  594. #ifdef CHECK_SHELL
  595.     /*  Disallow anyone who does not have a standard shell as returned by
  596.      *  getusershell(), unless the sys admin has included the wildcard
  597.      *  shell in /etc/shells.  (default wildcard - /POPPER/ANY/SHELL)
  598.      */
  599.     if ((shell = pw.pw_shell) == NULL || *shell == 0)
  600. /* You can default the shell, but I don't think it's a good idea */
  601. /*    shell = "/usr/bin/sh"; */
  602.     return(pop_msg(p, POP_FAILURE, "No user shell defined"));
  603.     
  604.     for (shellvalid = 0; !shellvalid && ((cp = getusershell()) != NULL);)
  605.     if (!strcmp(cp, WILDCARD_SHELL) || !strcmp(cp, shell))
  606.          shellvalid = 1;
  607.     endusershell();
  608.  
  609.     if (!shellvalid)
  610.     return(pop_msg(p, POP_FAILURE, "\"%s\": shell not found.", p->user));
  611. #endif
  612.  
  613.     if ((p->kerberos ? auth_user_kerberos(p, pw) : auth_user(p, pwp))
  614.                             != POP_SUCCESS) {
  615.         pop_log(p,POP_PRIORITY,"Failed attempted login to %s from host %s",
  616.                                 p->user, p->client);
  617.     return(POP_FAILURE);
  618.     }
  619.  
  620. #ifdef SECURENISPLUS
  621.     seteuid(uid_save);
  622. #endif
  623.  
  624.     /*  Make a temporary copy of the user's maildrop */
  625.     /*    and set the group and user id */
  626.     /*    and get information about the maildrop */
  627.     if (pop_dropcopy(p, &pw) != POP_SUCCESS) return (POP_FAILURE);
  628.  
  629.     /*  Initialize the last-message-accessed number */
  630.     p->last_msg = 0;
  631.  
  632.     /*  Authorization completed successfully */
  633.     return (pop_msg (p,POP_SUCCESS,
  634.         "%s has %d message%s (%d octets).",
  635.             p->user,p->msg_count, p->msg_count == 1 ? "" : "s", p->drop_size));
  636. }
  637.  
  638.