preparing for release of alpha-2.6
[Samba/gbeck.git] / source / pam_ntdom / pam_ntdom_auth.c
blob035fb5c57087c75fe3baf962f127dc1a348a8f70
1 /*
2 * Copyright Alexander O. Yuriev, 1996. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, and the entire permission notice in its entirety,
9 * including the disclaimer of warranties.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote
14 * products derived from this software without specific prior
15 * written permission.
17 * ALTERNATIVELY, this product may be distributed under the terms of
18 * the GNU Public License, in which case the provisions of the GPL are
19 * required INSTEAD OF the above restrictions. (This clause is
20 * necessary due to a potential bad interaction between the GPL and
21 * the restrictions contained in a BSD-style copyright.)
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33 * OF THE POSSIBILITY OF SUCH DAMAGE.
36 /*
37 This code has been changed heavily for smb authentication by
39 pam_ntdom_auth -- David Airlie 1998 v1.3a ( airlied@samba.org )
40 http://www.csn.ul.ie/~airlied
42 all changes are (C) David Airlie 1998.
45 #include "includes.h"
47 #ifdef HAVE_SECURITY_PAM_APPL_H
49 #include <security/pam_appl.h>
51 #endif
53 #define _PAM_EXTERN_FUNCTIONS
55 #ifdef HAVE_SECURITY_PAM_MODULES_H
56 #include <security/pam_modules.h>
57 #endif
59 #ifndef PAM_EXTERN
60 #define PAM_EXTERN extern
61 #endif
63 extern int DEBUGLEVEL;
65 #include "pam_ntdom_proto.h"
67 #if 0
68 extern int converse(pam_handle_t * pamh,
69 int nargs,
70 struct pam_message **message,
71 struct pam_response **response);
73 extern int _set_auth_tok(pam_handle_t * pamh,
74 int flags, int argc, const char **argv);
76 static int _pam_auth_smb(pam_handle_t * pamh,
77 int flags, int argc, const char **argv);
79 static int _pam_set_credentials_smb(pam_handle_t * pamh,
80 int flags, int argc, const char **argv);
83 #endif
85 /*
87 * _pam_auth_smb() actually performs UNIX/shadow authentication and
88 * then performs the NT Validation.
90 * First, if shadow support is available, attempt to perform
91 * authentication using shadow passwords. If shadow is not
92 * available, or user does not have a shadow password, fallback
93 * onto a normal UNIX authentication
94 * If neither shadow nor normal succeed it will send the username
95 * and password to a local server, which will do the authentication.
98 static int _pam_auth_smb(pam_handle_t * pamh,
99 int flags, int argc, const char **argv)
101 int retval;
102 struct passwd *pw;
103 const char *name;
104 char *p, *pp;
105 int w, loop;
106 const char *salt;
107 fstring domain;
108 fstring ntname;
109 int debug = 0, use_first_pass = 0;
110 int unknown_user = 0;
111 int nolocal = 0;
113 #ifdef HAVE_SHADOW_H
115 struct spwd *sp;
117 #endif
119 DEBUGLEVEL = 0;
121 /* Parse Command line options */
123 for (loop = 0; loop < argc; loop++)
125 if (!strcmp(argv[loop], "debug"))
127 debug = 1;
128 DEBUGLEVEL = 100;
130 else if (!strcmp(argv[loop], "use_first_pass"))
131 use_first_pass = 1;
132 else if (!strcmp(argv[loop], "nolocal"))
133 nolocal = 1;
134 #ifdef USE_LOGAUTH
135 else
136 syslog(LOG_AUTHPRIV | LOG_ERR,
137 "pam_ntdom: Unknown Command Line Option in pam.d : %s",
138 argv[loop]);
139 #endif
142 if (!rpc_initialise())
144 #ifdef USE_LOGAUTH
145 if (debug)
147 syslog(LOG_AUTHPRIV | LOG_ERR,
148 "pam_ntdom: initialisation failed\n");
150 #endif
151 return PAM_SERVICE_ERR;
153 /* get the user'name' */
155 if ((retval = pam_get_user(pamh, &name, "login: ")) != PAM_SUCCESS)
157 #ifdef USE_LOGAUTH
158 syslog(LOG_AUTHPRIV | LOG_ERR, "pam_ntdom: User not found");
159 #endif
160 return retval;
163 pam_get_item(pamh, PAM_AUTHTOK, (void *)&p);
165 if (!p)
167 if (use_first_pass != 1)
169 retval = _set_auth_tok(pamh, flags, argc, argv);
170 if (retval != PAM_SUCCESS)
171 return retval;
173 else
174 return PAM_AUTH_ERR;
178 We have to call pam_get_item() again because value of p should
179 change
182 pam_get_item(pamh, PAM_AUTHTOK, (void *)&p);
184 if (!split_domain_name(name, domain, ntname))
186 return PAM_BUF_ERR;
189 /* If nolocal is specified pam_ntdom does not try and do local
190 username/password authentication .. this is a command line option
191 to pam_ntdom_auth.so in /etc/pam.d/ */
193 if (nolocal == 0)
195 pw = getpwnam(name);
197 if (pw)
200 #ifdef HAVE_SHADOW_H
203 * Support for shadow passwords on Linux and SVR4-based
204 * systems. Shadow passwords are optional on Linux - if
205 * there is no shadow password, use the non-shadow one.
208 sp = getspnam(name);
209 if (sp && (!strcmp(pw->pw_passwd, "x")))
211 /* TODO: check if password has expired etc. */
212 salt = sp->sp_pwdp;
214 else
215 #endif
216 salt = pw->pw_passwd;
218 else
219 unknown_user = 1;
221 /* The 'always-encrypt' method does not make sense in PAM
222 because the framework requires return of a different
223 error code for non-existant users -- alex */
224 if (!unknown_user)
226 if ((!pw->pw_passwd) && (!p))
227 if (flags && PAM_DISALLOW_NULL_AUTHTOK)
228 return PAM_SUCCESS;
230 pp = crypt(p, salt);
232 if (strcmp(pp, salt) == 0)
234 if (debug)
235 #ifdef USE_LOGAUTH
236 syslog(LOG_AUTHPRIV | LOG_DEBUG,
237 "pam_ntdom: Local UNIX username/password pair correct.");
238 #endif
239 return PAM_SUCCESS;
242 if (debug)
244 #ifdef USE_LOGAUTH
245 syslog(LOG_AUTHPRIV | LOG_DEBUG,
246 "pam_ntdom: Local UNIX username/password check incorrect.");
247 #endif
250 } /* End of Local Section */
251 else
252 { /* If Local System Authentication is switched off */
253 #ifdef USE_LOGAUTH
254 if (debug)
255 syslog(LOG_AUTHPRIV | LOG_DEBUG,
256 "No Local authentication done, relying on other modules for password file entry.");
257 #endif
260 #ifdef USE_LOGAUTH
261 if (debug)
263 syslog(LOG_AUTHPRIV | LOG_DEBUG,
264 "pam_ntdom: Configuration Data, Domain %s.", domain);
266 #endif
268 #ifdef USE_LOGAUTH
269 if (debug)
271 syslog(LOG_AUTHPRIV | LOG_DEBUG,
272 "pam_ntdom: user: %s domain: %s password: %s",
273 ntname, domain, p);
275 #endif
277 w = Valid_User(ntname, p, domain);
279 /* Users valid user for return value 0 is success
280 1 and 2 indicate Network and protocol failures and
281 3 is not logged on
284 switch (w)
286 case 0:
287 #ifdef USE_LOGAUTH
288 if (debug)
290 syslog(LOG_AUTHPRIV | LOG_DEBUG,
291 "pam_ntdom: Correct NT username/password pair");
293 #endif
294 return PAM_SUCCESS;
295 case 1:
296 case 2:
297 #ifdef USE_LOGAUTH
298 if (debug)
300 syslog(LOG_AUTHPRIV | LOG_DEBUG,
301 "pam_ntdom: Authentication unavailable\n");
303 #endif
304 return PAM_AUTHINFO_UNAVAIL;
305 break;
306 case 3:
307 default:
308 #ifdef USE_LOGAUTH
309 syslog(LOG_AUTHPRIV | LOG_NOTICE,
310 "pam_ntdom: Incorrect NT password for username : %s",
311 ntname);
312 #endif
313 return PAM_AUTH_ERR;
314 break;
317 #ifdef USE_LOGAUTH
318 if (debug)
320 syslog(LOG_AUTHPRIV | LOG_DEBUG,
321 "pam_ntdom: Authentication failed\n");
323 #endif
324 return PAM_AUTH_ERR;
329 * The _pam_set_credentials_smb() does nothing.
332 static int _pam_set_credentials_smb(pam_handle_t * pamh,
333 int flags, int argc, const char **argv)
335 return PAM_SUCCESS; /* This is a wrong result code. From what I
336 remember from reafing one of the guides
337 there's an error-level saying 'N/A func'
338 -- AOY
343 * PAM framework looks for these entry-points to pass control to the
344 * authentication module.
347 PAM_EXTERN
348 int pam_sm_authenticate(pam_handle_t * pamh,
349 int flags, int argc, const char **argv)
351 return _pam_auth_smb(pamh, flags, argc, argv);
354 PAM_EXTERN
355 int pam_sm_setcred(pam_handle_t * pamh,
356 int flags, int argc, const char **argv)
358 return _pam_set_credentials_smb(pamh, flags, argc, argv);