"Fossies" - the Fresh Open Source Software Archive

Member "citadel/auth.c" (5 Jun 2021, 3144 Bytes) of package /linux/www/citadel.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "auth.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.01_vs_902.

    1 // system-level password checking for host auth mode
    2 // by Nathan Bryant, March 1999
    3 // updated by Trey van Riper, June 2005
    4 //
    5 // Copyright (c) 1999-2016 by the citadel.org team
    6 //
    7 // This program is open source software.  Use, duplication, or disclosure
    8 // is subject to the terms of the GNU General Public License, version 3.
    9 // The program is distributed without any warranty, expressed or implied.
   10 
   11 #if defined(__linux) || defined(__sun)  // needed for crypt():
   12 #define _XOPEN_SOURCE
   13 #define _XOPEN_SOURCE_EXTENDED 1
   14 #endif
   15 
   16 #include <pwd.h>
   17 #include <stdlib.h>
   18 #include <string.h>
   19 #include <unistd.h>
   20 #include <sys/types.h>
   21 
   22 #include "auth.h"
   23 #include "sysdep.h"
   24 
   25 #ifdef HAVE_GETSPNAM
   26 #include <shadow.h>
   27 #endif
   28 
   29 #ifdef HAVE_PAM_START
   30 #include <security/pam_appl.h>
   31 
   32 // struct appdata: passed to the conversation function
   33 struct appdata {
   34     const char *name;
   35     const char *pw;
   36 };
   37 
   38 // conv(): the PAM conversation function. this assumes that a
   39 // PAM_PROMPT_ECHO_ON is asking for a username, and a PAM_PROMPT_ECHO_OFF is
   40 // asking for a password. esoteric authentication modules will fail with this
   41 // code, but we can't really support them with the existing client protocol
   42 // anyway. the failure mode should be to deny access, in any case.
   43 static int conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) {
   44     struct pam_response *temp_resp;
   45     struct appdata *data = appdata_ptr;
   46 
   47     if ((temp_resp =
   48          malloc(sizeof(struct pam_response[num_msg]))) == NULL)
   49         return PAM_CONV_ERR;
   50 
   51     while (num_msg--) {
   52         switch ((*msg)[num_msg].msg_style) {
   53         case PAM_PROMPT_ECHO_ON:
   54             temp_resp[num_msg].resp = strdup(data->name);
   55             break;
   56         case PAM_PROMPT_ECHO_OFF:
   57             temp_resp[num_msg].resp = strdup(data->pw);
   58             break;
   59         default:
   60             temp_resp[num_msg].resp = NULL;
   61         }
   62         temp_resp[num_msg].resp_retcode = 0;
   63     }
   64 
   65     *resp = temp_resp;
   66     return PAM_SUCCESS;
   67 }
   68 #endif              // HAVE_PAM_START
   69 
   70 
   71 // check that `pass' is the correct password for `uid'
   72 // returns zero if no, nonzero if yes
   73 int validate_password(uid_t uid, const char *pass) {
   74     if (pass == NULL) {
   75         return (0);
   76     }
   77 #ifdef HAVE_PAM_START
   78     struct pam_conv pc;
   79     struct appdata data;
   80     pam_handle_t *ph;
   81     int i;
   82 #else
   83     char *crypted_pwd;
   84 #ifdef HAVE_GETSPNAM
   85     struct spwd *sp;
   86 #endif
   87 #endif
   88     struct passwd *pw;
   89     int retval = 0;
   90 
   91     pw = getpwuid(uid);
   92     if (pw == NULL) {
   93         return retval;
   94     }
   95 #ifdef HAVE_PAM_START
   96 
   97 #ifdef PAM_DATA_SILENT
   98     int flags = PAM_DATA_SILENT;
   99 #else
  100     int flags = 0;
  101 #endif
  102 
  103     pc.conv = conv;
  104     pc.appdata_ptr = &data;
  105     data.name = pw->pw_name;
  106     data.pw = pass;
  107     if (pam_start("citadel", pw->pw_name, &pc, &ph) != PAM_SUCCESS)
  108         return (0);
  109 
  110     if ((i = pam_authenticate(ph, flags)) == PAM_SUCCESS) {
  111         if ((i = pam_acct_mgmt(ph, flags)) == PAM_SUCCESS) {
  112             retval = -1;
  113         }
  114     }
  115 
  116     pam_end(ph, i | flags);
  117 #else
  118     crypted_pwd = pw->pw_passwd;
  119 
  120 #ifdef HAVE_GETSPNAM
  121     if (pw == NULL)
  122         return (0);
  123     if (pw->pw_name == NULL)
  124         return (0);
  125     if ((sp = getspnam(pw->pw_name)) != NULL) {
  126         crypted_pwd = sp->sp_pwdp;
  127     }
  128 #endif
  129 
  130     if (!strcmp(crypt(pass, crypted_pwd), crypted_pwd)) {
  131         retval = -1;
  132     }
  133 #endif              // HAVE_PAM_START
  134 
  135     return retval;
  136 }