* When saving a Task, if the status is COMPLETED then also set PERCENT-COMPLETE:100...
[citadel.git] / citadel / auth.c
bloba689c9006634c56711bf6717096cc193c9bc7d8a
1 /*
2 * $Id$
4 * system-level password checking for host auth mode
5 * by Nathan Bryant, March 1999
6 * updated by Trey van Riper, June 2005
8 */
10 #if defined(__linux) || defined(__sun) /* needed for crypt(): */
11 #define _XOPEN_SOURCE
12 #define _XOPEN_SOURCE_EXTENDED 1
13 #endif
15 #include <pwd.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <sys/types.h>
21 #include "auth.h"
22 #include "sysdep.h"
24 #ifdef HAVE_GETSPNAM
25 #include <shadow.h>
26 #endif
28 #ifdef HAVE_PAM_START
29 #include <security/pam_appl.h>
32 * struct appdata: passed to the conversation function
35 struct appdata
37 const char *name;
38 const char *pw;
42 * conv(): the PAM conversation function. this assumes that a
43 * PAM_PROMPT_ECHO_ON is asking for a username, and a PAM_PROMPT_ECHO_OFF is
44 * asking for a password. esoteric authentication modules will fail with this
45 * code, but we can't really support them with the existing client protocol
46 * anyway. the failure mode should be to deny access, in any case.
49 static int conv(int num_msg, const struct pam_message **msg,
50 struct pam_response **resp, void *appdata_ptr)
52 struct pam_response *temp_resp;
53 struct appdata *data = appdata_ptr;
55 if ((temp_resp = malloc(sizeof(struct pam_response[num_msg]))) == NULL)
56 return PAM_CONV_ERR;
58 while (num_msg--)
60 switch ((*msg)[num_msg].msg_style)
62 case PAM_PROMPT_ECHO_ON:
63 temp_resp[num_msg].resp = strdup(data->name);
64 break;
65 case PAM_PROMPT_ECHO_OFF:
66 temp_resp[num_msg].resp = strdup(data->pw);
67 break;
68 default:
69 temp_resp[num_msg].resp = NULL;
71 temp_resp[num_msg].resp_retcode = 0;
74 *resp = temp_resp;
75 return PAM_SUCCESS;
77 #endif /* HAVE_PAM_START */
81 * check that `pass' is the correct password for `uid'
82 * returns zero if no, nonzero if yes
85 int validate_password(uid_t uid, const char *pass)
87 #ifdef HAVE_PAM_START
88 struct pam_conv pc;
89 struct appdata data;
90 pam_handle_t *ph;
91 int i;
92 #else
93 char *crypted_pwd;
94 #ifdef HAVE_GETSPNAM
95 struct spwd *sp;
96 #endif
97 #endif
98 struct passwd *pw;
99 int retval = 0;
100 int flags = 0;
102 flags = 0; /* silences compiler warning */
104 #ifdef PAM_DATA_SILENT
105 flags = ( flags | PAM_DATA_SILENT ) ;
106 #endif /* PAM_DATA_SILENT */
107 if ((pw = getpwuid(uid)) == NULL) {
108 return retval;
111 #ifdef HAVE_PAM_START
112 pc.conv = conv;
113 pc.appdata_ptr = &data;
114 data.name = pw->pw_name;
115 data.pw = pass;
116 if (pam_start("citadel", pw->pw_name, &pc, &ph) != PAM_SUCCESS)
117 return retval;
119 if ((i = pam_authenticate(ph, flags)) == PAM_SUCCESS)
120 if ((i = pam_acct_mgmt(ph, flags)) == PAM_SUCCESS)
121 retval = -1;
123 pam_end(ph, i | flags);
124 #else
125 crypted_pwd = pw->pw_passwd;
127 #ifdef HAVE_GETSPNAM
128 if ((sp = getspnam(pw->pw_name)) != NULL)
129 crypted_pwd = sp->sp_pwdp;
130 #endif
132 if (!strcmp(crypt(pass, crypted_pwd), crypted_pwd))
133 retval = -1;
134 #endif /* HAVE_PAM_START */
136 return retval;