2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-2001
6 Copyright (C) John H Terpsta 1999-2001
7 Copyright (C) Andrew Bartlett 2001
8 Copyright (C) Jeremy Allison 2001
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * This module provides PAM based functions for validation of
27 * username/password pairs, account managment, session and access control.
28 * Note: SMB password checking is done in smbpass.c
33 extern int DEBUGLEVEL;
37 /*******************************************************************
38 * Handle PAM authentication
39 * - Access, Authentication, Session, Password
40 * Note: See PAM Documentation and refer to local system PAM implementation
41 * which determines what actions/limitations/allowances become affected.
42 *********************************************************************/
44 #include <security/pam_appl.h>
47 * Structure used to communicate between the conversation function
48 * and the server_login/change password functions.
51 struct smb_pam_userdata {
54 char *PAM_newpassword;
57 typedef int (*smb_pam_conv_fn)(int, const struct pam_message **, struct pam_response **, void *appdata_ptr);
60 * Macros to help make life easy
62 #define COPY_STRING(s) (s) ? strdup(s) : NULL
64 /*******************************************************************
66 *********************************************************************/
68 static BOOL smb_pam_error_handler(pam_handle_t *pamh, int pam_error, char *msg, int dbglvl)
71 if( pam_error != PAM_SUCCESS) {
72 DEBUG(dbglvl, ("smb_pam_error_handler: PAM: %s : %s\n",
73 msg, pam_strerror(pamh, pam_error)));
80 /*******************************************************************
81 This function is a sanity check, to make sure that we NEVER report
83 *********************************************************************/
85 static BOOL smb_pam_nt_status_error_handler(pam_handle_t *pamh, int pam_error,
86 char *msg, int dbglvl,
89 if (smb_pam_error_handler(pamh, pam_error, msg, dbglvl))
92 if (NT_STATUS_IS_OK(*nt_status)) {
94 DEBUG(0, ("smb_pam_nt_status_error_handler: PAM: BUG: PAM and NT_STATUS \
95 error MISMATCH, forcing to NT_STATUS_LOGON_FAILURE"));
96 *nt_status = NT_STATUS_LOGON_FAILURE;
102 * PAM conversation function
103 * Here we assume (for now, at least) that echo on means login name, and
104 * echo off means password.
107 static int smb_pam_conv(int num_msg,
108 const struct pam_message **msg,
109 struct pam_response **resp,
113 struct pam_response *reply = NULL;
114 struct smb_pam_userdata *udp = (struct smb_pam_userdata *)appdata_ptr;
122 * Apparantly HPUX has a buggy PAM that doesn't support the
123 * appdata_ptr. Fail if this is the case. JRA.
127 DEBUG(0,("smb_pam_conv: PAM on this system is broken - appdata_ptr == NULL !\n"));
131 reply = malloc(sizeof(struct pam_response) * num_msg);
135 memset(reply, '\0', sizeof(struct pam_response) * num_msg);
137 for (replies = 0; replies < num_msg; replies++) {
138 switch (msg[replies]->msg_style) {
139 case PAM_PROMPT_ECHO_ON:
140 reply[replies].resp_retcode = PAM_SUCCESS;
141 reply[replies].resp = COPY_STRING(udp->PAM_username);
145 case PAM_PROMPT_ECHO_OFF:
146 reply[replies].resp_retcode = PAM_SUCCESS;
147 reply[replies].resp = COPY_STRING(udp->PAM_password);
156 reply[replies].resp_retcode = PAM_SUCCESS;
157 reply[replies].resp = NULL;
161 /* Must be an error of some sort... */
172 * PAM password change conversation function
173 * Here we assume (for now, at least) that echo on means login name, and
174 * echo off means password.
177 static void special_char_sub(char *buf)
179 all_string_sub(buf, "\\n", "", 0);
180 all_string_sub(buf, "\\r", "", 0);
181 all_string_sub(buf, "\\s", " ", 0);
182 all_string_sub(buf, "\\t", "\t", 0);
185 static void pwd_sub(char *buf, char *username, char *oldpass, char *newpass)
187 pstring_sub(buf, "%u", username);
188 all_string_sub(buf, "%o", oldpass, sizeof(fstring));
189 all_string_sub(buf, "%n", newpass, sizeof(fstring));
194 struct chat_struct *next, *prev;
199 /**************************************************************
200 Create a linked list containing chat data.
201 ***************************************************************/
203 static struct chat_struct *make_pw_chat(char *p)
207 struct chat_struct *list = NULL;
208 struct chat_struct *t;
209 struct chat_struct *tmp;
212 t = (struct chat_struct *)malloc(sizeof(*t));
214 DEBUG(0,("make_pw_chat: malloc failed!\n"));
220 DLIST_ADD_END(list, t, tmp);
222 if (!next_token(&p, prompt, NULL, sizeof(fstring)))
225 if (strequal(prompt,"."))
228 special_char_sub(prompt);
229 fstrcpy(t->prompt, prompt);
231 trim_string(t->prompt, " ", " ");
233 if (!next_token(&p, reply, NULL, sizeof(fstring)))
236 if (strequal(reply,"."))
239 special_char_sub(reply);
240 fstrcpy(t->reply, reply);
242 trim_string(t->reply, " ", " ");
248 static void free_pw_chat(struct chat_struct *list)
251 struct chat_struct *old_head = list;
252 DLIST_REMOVE(list, list);
257 static int smb_pam_passchange_conv(int num_msg,
258 const struct pam_message **msg,
259 struct pam_response **resp,
263 struct pam_response *reply = NULL;
264 fstring current_prompt;
265 fstring current_reply;
266 struct smb_pam_userdata *udp = (struct smb_pam_userdata *)appdata_ptr;
267 struct chat_struct *pw_chat= make_pw_chat(lp_passwd_chat());
268 struct chat_struct *t;
272 DEBUG(10,("smb_pam_passchange_conv: starting converstation for %d messages\n", num_msg));
281 * Apparantly HPUX has a buggy PAM that doesn't support the
282 * appdata_ptr. Fail if this is the case. JRA.
286 DEBUG(0,("smb_pam_passchange_conv: PAM on this system is broken - appdata_ptr == NULL !\n"));
287 free_pw_chat(pw_chat);
291 reply = malloc(sizeof(struct pam_response) * num_msg);
293 DEBUG(0,("smb_pam_passchange_conv: malloc for reply failed!\n"));
294 free_pw_chat(pw_chat);
298 for (replies = 0; replies < num_msg; replies++) {
300 DEBUG(10,("smb_pam_passchange_conv: Processing message %d\n", replies));
301 switch (msg[replies]->msg_style) {
302 case PAM_PROMPT_ECHO_ON:
303 DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: PAM said: %s\n", msg[replies]->msg));
304 fstrcpy(current_prompt, msg[replies]->msg);
305 trim_string(current_prompt, " ", " ");
306 for (t=pw_chat; t; t=t->next) {
308 DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: trying to match |%s| to |%s|\n",
309 t->prompt, current_prompt ));
311 if (wild_match(t->prompt, current_prompt) == 0) {
312 fstrcpy(current_reply, t->reply);
313 DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We sent: %s\n", current_reply));
314 pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword);
315 #ifdef DEBUG_PASSWORD
316 DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We actualy sent: %s\n", current_reply));
318 reply[replies].resp_retcode = PAM_SUCCESS;
319 reply[replies].resp = COPY_STRING(current_reply);
326 DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg));
327 free_pw_chat(pw_chat);
334 case PAM_PROMPT_ECHO_OFF:
335 DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: PAM said: %s\n", msg[replies]->msg));
336 fstrcpy(current_prompt, msg[replies]->msg);
337 trim_string(current_prompt, " ", " ");
338 for (t=pw_chat; t; t=t->next) {
340 DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: trying to match |%s| to |%s|\n",
341 t->prompt, current_prompt ));
343 if (wild_match(t->prompt, current_prompt) == 0) {
344 fstrcpy(current_reply, t->reply);
345 DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We sent: %s\n", current_reply));
346 pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword);
347 reply[replies].resp_retcode = PAM_SUCCESS;
348 reply[replies].resp = COPY_STRING(current_reply);
349 #ifdef DEBUG_PASSWORD
350 DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We actualy sent: %s\n", current_reply));
359 DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg));
360 free_pw_chat(pw_chat);
372 reply[replies].resp_retcode = PAM_SUCCESS;
373 reply[replies].resp = NULL;
377 /* Must be an error of some sort... */
378 free_pw_chat(pw_chat);
385 free_pw_chat(pw_chat);
391 /***************************************************************************
392 Free up a malloced pam_conv struct.
393 ****************************************************************************/
395 static void smb_free_pam_conv(struct pam_conv *pconv)
398 safe_free(pconv->appdata_ptr);
403 /***************************************************************************
404 Allocate a pam_conv struct.
405 ****************************************************************************/
407 static struct pam_conv *smb_setup_pam_conv(smb_pam_conv_fn smb_pam_conv_fnptr, char *user,
408 char *passwd, char *newpass)
410 struct pam_conv *pconv = (struct pam_conv *)malloc(sizeof(struct pam_conv));
411 struct smb_pam_userdata *udp = (struct smb_pam_userdata *)malloc(sizeof(struct smb_pam_userdata));
413 if (pconv == NULL || udp == NULL) {
419 udp->PAM_username = user;
420 udp->PAM_password = passwd;
421 udp->PAM_newpassword = newpass;
423 pconv->conv = smb_pam_conv_fnptr;
424 pconv->appdata_ptr = (void *)udp;
429 * PAM Closing out cleanup handler
432 static BOOL smb_pam_end(pam_handle_t *pamh, struct pam_conv *smb_pam_conv_ptr)
436 smb_free_pam_conv(smb_pam_conv_ptr);
439 pam_error = pam_end(pamh, 0);
440 if(smb_pam_error_handler(pamh, pam_error, "End Cleanup Failed", 2) == True) {
441 DEBUG(4, ("smb_pam_end: PAM: PAM_END OK.\n"));
445 DEBUG(2,("smb_pam_end: PAM: not initialised"));
450 * Start PAM authentication for specified account
453 static BOOL smb_pam_start(pam_handle_t **pamh, char *user, char *rhost, struct pam_conv *pconv)
457 *pamh = (pam_handle_t *)NULL;
459 DEBUG(4,("smb_pam_start: PAM: Init user: %s\n", user));
461 pam_error = pam_start("samba", user, pconv, pamh);
462 if( !smb_pam_error_handler(*pamh, pam_error, "Init Failed", 0)) {
463 *pamh = (pam_handle_t *)NULL;
468 rhost = client_name();
469 if (strequal(rhost,"UNKNOWN"))
470 rhost = client_addr();
474 DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", rhost));
475 pam_error = pam_set_item(*pamh, PAM_RHOST, rhost);
476 if(!smb_pam_error_handler(*pamh, pam_error, "set rhost failed", 0)) {
477 smb_pam_end(*pamh, pconv);
478 *pamh = (pam_handle_t *)NULL;
483 DEBUG(4,("smb_pam_start: PAM: setting tty\n"));
484 pam_error = pam_set_item(*pamh, PAM_TTY, "samba");
485 if (!smb_pam_error_handler(*pamh, pam_error, "set tty failed", 0)) {
486 smb_pam_end(*pamh, pconv);
487 *pamh = (pam_handle_t *)NULL;
491 DEBUG(4,("smb_pam_start: PAM: Init passed for user: %s\n", user));
496 * PAM Authentication Handler
498 static NTSTATUS smb_pam_auth(pam_handle_t *pamh, char *user)
501 NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
504 * To enable debugging set in /etc/pam.d/samba:
505 * auth required /lib/security/pam_pwdb.so nullok shadow audit
508 DEBUG(4,("smb_pam_auth: PAM: Authenticate User: %s\n", user));
509 pam_error = pam_authenticate(pamh, PAM_SILENT | lp_null_passwords() ? 0 : PAM_DISALLOW_NULL_AUTHTOK);
512 DEBUG(2, ("smb_pam_auth: PAM: Athentication Error for user %s\n", user));
513 nt_status = NT_STATUS_WRONG_PASSWORD;
515 case PAM_CRED_INSUFFICIENT:
516 DEBUG(2, ("smb_pam_auth: PAM: Insufficient Credentials for user %s\n", user));
517 nt_status = NT_STATUS_INSUFFICIENT_LOGON_INFO;
519 case PAM_AUTHINFO_UNAVAIL:
520 DEBUG(2, ("smb_pam_auth: PAM: Authentication Information Unavailable for user %s\n", user));
521 nt_status = NT_STATUS_LOGON_FAILURE;
523 case PAM_USER_UNKNOWN:
524 DEBUG(2, ("smb_pam_auth: PAM: Username %s NOT known to Authentication system\n", user));
525 nt_status = NT_STATUS_NO_SUCH_USER;
528 DEBUG(2, ("smb_pam_auth: PAM: One or more authentication modules reports user limit for user %s exceeeded\n", user));
529 nt_status = NT_STATUS_REMOTE_SESSION_LIMIT;
532 DEBUG(0, ("smb_pam_auth: PAM: One or more PAM modules failed to load for user %s\n", user));
533 nt_status = NT_STATUS_LOGON_FAILURE;
536 DEBUG(4, ("smb_pam_auth: PAM: User %s Authenticated OK\n", user));
537 nt_status = NT_STATUS_OK;
540 DEBUG(0, ("smb_pam_auth: PAM: UNKNOWN ERROR while authenticating user %s\n", user));
541 nt_status = NT_STATUS_LOGON_FAILURE;
545 smb_pam_nt_status_error_handler(pamh, pam_error, "Authentication Failure", 2, &nt_status);
550 * PAM Account Handler
552 static NTSTATUS smb_pam_account(pam_handle_t *pamh, char * user)
555 NTSTATUS nt_status = NT_STATUS_ACCOUNT_DISABLED;
557 DEBUG(4,("smb_pam_account: PAM: Account Management for User: %s\n", user));
558 pam_error = pam_acct_mgmt(pamh, PAM_SILENT); /* Is user account enabled? */
559 switch( pam_error ) {
560 case PAM_AUTHTOK_EXPIRED:
561 DEBUG(2, ("smb_pam_account: PAM: User %s is valid but password is expired\n", user));
562 nt_status = NT_STATUS_PASSWORD_EXPIRED;
564 case PAM_ACCT_EXPIRED:
565 DEBUG(2, ("smb_pam_account: PAM: User %s no longer permitted to access system\n", user));
566 nt_status = NT_STATUS_ACCOUNT_EXPIRED;
569 DEBUG(2, ("smb_pam_account: PAM: There was an authentication error for user %s\n", user));
570 nt_status = NT_STATUS_LOGON_FAILURE;
572 case PAM_PERM_DENIED:
573 DEBUG(0, ("smb_pam_account: PAM: User %s is NOT permitted to access system at this time\n", user));
574 nt_status = NT_STATUS_ACCOUNT_RESTRICTION;
576 case PAM_USER_UNKNOWN:
577 DEBUG(0, ("smb_pam_account: PAM: User \"%s\" is NOT known to account management\n", user));
578 nt_status = NT_STATUS_NO_SUCH_USER;
581 DEBUG(4, ("smb_pam_account: PAM: Account OK for User: %s\n", user));
582 nt_status = NT_STATUS_OK;
585 nt_status = NT_STATUS_ACCOUNT_DISABLED;
586 DEBUG(0, ("smb_pam_account: PAM: UNKNOWN PAM ERROR (%d) during Account Management for User: %s\n", pam_error, user));
590 smb_pam_nt_status_error_handler(pamh, pam_error, "Account Check Failed", 2, &nt_status);
595 * PAM Credential Setting
598 static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, char * user)
601 NTSTATUS nt_status = NT_STATUS_NO_TOKEN;
604 * This will allow samba to aquire a kerberos token. And, when
605 * exporting an AFS cell, be able to /write/ to this cell.
608 DEBUG(4,("PAM: Account Management SetCredentials for User: %s\n", user));
609 pam_error = pam_setcred(pamh, (PAM_ESTABLISH_CRED|PAM_SILENT));
610 switch( pam_error ) {
611 case PAM_CRED_UNAVAIL:
612 DEBUG(0, ("smb_pam_setcred: PAM: Credentials not found for user:%s\n", user ));
613 nt_status = NT_STATUS_NO_TOKEN;
615 case PAM_CRED_EXPIRED:
616 DEBUG(0, ("smb_pam_setcred: PAM: Credentials for user: \"%s\" EXPIRED!\n", user ));
617 nt_status = NT_STATUS_PASSWORD_EXPIRED;
619 case PAM_USER_UNKNOWN:
620 DEBUG(0, ("smb_pam_setcred: PAM: User: \"%s\" is NOT known so can not set credentials!\n", user ));
621 nt_status = NT_STATUS_NO_SUCH_USER;
624 DEBUG(0, ("smb_pam_setcred: PAM: Unknown setcredentials error - unable to set credentials for %s\n", user ));
625 nt_status = NT_STATUS_LOGON_FAILURE;
628 DEBUG(4, ("smb_pam_setcred: PAM: SetCredentials OK for User: %s\n", user));
629 nt_status = NT_STATUS_OK;
632 DEBUG(0, ("smb_pam_setcred: PAM: UNKNOWN PAM ERROR (%d) during SetCredentials for User: %s\n", pam_error, user));
633 nt_status = NT_STATUS_NO_TOKEN;
637 smb_pam_nt_status_error_handler(pamh, pam_error, "Set Credential Failure", 2, &nt_status);
642 * PAM Internal Session Handler
644 static BOOL smb_internal_pam_session(pam_handle_t *pamh, char *user, char *tty, BOOL flag)
649 DEBUG(4,("smb_internal_pam_session: PAM: tty set to: %s\n", tty));
650 pam_error = pam_set_item(pamh, PAM_TTY, tty);
651 if (!smb_pam_error_handler(pamh, pam_error, "set tty failed", 0))
656 pam_error = pam_open_session(pamh, PAM_SILENT);
657 if (!smb_pam_error_handler(pamh, pam_error, "session setup failed", 0))
660 pam_setcred(pamh, (PAM_DELETE_CRED|PAM_SILENT)); /* We don't care if this fails */
661 pam_error = pam_close_session(pamh, PAM_SILENT); /* This will probably pick up the error anyway */
662 if (!smb_pam_error_handler(pamh, pam_error, "session close failed", 0))
669 * Internal PAM Password Changer.
672 static BOOL smb_pam_chauthtok(pam_handle_t *pamh, char * user)
676 DEBUG(4,("smb_pam_chauthtok: PAM: Password Change for User: %s\n", user));
678 pam_error = pam_chauthtok(pamh, PAM_SILENT); /* Change Password */
680 switch( pam_error ) {
681 case PAM_AUTHTOK_ERR:
682 DEBUG(2, ("PAM: unable to obtain the new authentication token - is password to weak?\n"));
685 /* This doesn't seem to be defined on Solaris. JRA */
686 #ifdef PAM_AUTHTOK_RECOVER_ERR
687 case PAM_AUTHTOK_RECOVER_ERR:
688 DEBUG(2, ("PAM: unable to obtain the old authentication token - was the old password wrong?.\n"));
692 case PAM_AUTHTOK_LOCK_BUSY:
693 DEBUG(2, ("PAM: unable to change the authentication token since it is currently locked.\n"));
695 case PAM_AUTHTOK_DISABLE_AGING:
696 DEBUG(2, ("PAM: Authentication token aging has been disabled.\n"));
698 case PAM_PERM_DENIED:
699 DEBUG(0, ("PAM: Permission denied.\n"));
702 DEBUG(0, ("PAM: Could not update all authentication token(s). No authentication tokens were updated.\n"));
704 case PAM_USER_UNKNOWN:
705 DEBUG(0, ("PAM: User not known to PAM\n"));
708 DEBUG(4, ("PAM: Account OK for User: %s\n", user));
711 DEBUG(0, ("PAM: UNKNOWN PAM ERROR (%d) for User: %s\n", pam_error, user));
714 if(!smb_pam_error_handler(pamh, pam_error, "Password Change Failed", 2)) {
718 /* If this point is reached, the password has changed. */
723 * PAM Externally accessible Session handler
726 BOOL smb_pam_claim_session(char *user, char *tty, char *rhost)
728 pam_handle_t *pamh = NULL;
729 struct pam_conv *pconv = NULL;
731 /* Ignore PAM if told to. */
733 if (!lp_obey_pam_restrictions())
736 if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL)
739 if (!smb_pam_start(&pamh, user, rhost, pconv))
742 if (!smb_internal_pam_session(pamh, user, tty, True)) {
743 smb_pam_end(pamh, pconv);
747 return smb_pam_end(pamh, pconv);
751 * PAM Externally accessible Session handler
754 BOOL smb_pam_close_session(char *user, char *tty, char *rhost)
756 pam_handle_t *pamh = NULL;
757 struct pam_conv *pconv = NULL;
759 /* Ignore PAM if told to. */
761 if (!lp_obey_pam_restrictions())
764 if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL)
767 if (!smb_pam_start(&pamh, user, rhost, pconv))
770 if (!smb_internal_pam_session(pamh, user, tty, False)) {
771 smb_pam_end(pamh, pconv);
775 return smb_pam_end(pamh, pconv);
779 * PAM Externally accessible Account handler
782 NTSTATUS smb_pam_accountcheck(char * user)
784 NTSTATUS nt_status = NT_STATUS_ACCOUNT_DISABLED;
785 pam_handle_t *pamh = NULL;
786 struct pam_conv *pconv = NULL;
788 /* Ignore PAM if told to. */
790 if (!lp_obey_pam_restrictions())
793 if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL)
794 return NT_STATUS_NO_MEMORY;
796 if (!smb_pam_start(&pamh, user, NULL, pconv))
797 return NT_STATUS_ACCOUNT_DISABLED;
799 if (!NT_STATUS_IS_OK(nt_status = smb_pam_account(pamh, user)))
800 DEBUG(0, ("smb_pam_accountcheck: PAM: Account Validation Failed - Rejecting User %s!\n", user));
802 smb_pam_end(pamh, pconv);
807 * PAM Password Validation Suite
810 NTSTATUS smb_pam_passcheck(char * user, char * password)
812 pam_handle_t *pamh = NULL;
813 NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
814 struct pam_conv *pconv = NULL;
817 * Note we can't ignore PAM here as this is the only
818 * way of doing auths on plaintext passwords when
819 * compiled --with-pam.
822 if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, password, NULL)) == NULL)
823 return NT_STATUS_LOGON_FAILURE;
825 if (!smb_pam_start(&pamh, user, NULL, pconv))
826 return NT_STATUS_LOGON_FAILURE;
828 if (!NT_STATUS_IS_OK(nt_status = smb_pam_auth(pamh, user))) {
829 DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_auth failed - Rejecting User %s !\n", user));
830 smb_pam_end(pamh, pconv);
834 if (!NT_STATUS_IS_OK(nt_status = smb_pam_account(pamh, user))) {
835 DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_account failed - Rejecting User %s !\n", user));
836 smb_pam_end(pamh, pconv);
840 if (!NT_STATUS_IS_OK(nt_status = smb_pam_setcred(pamh, user))) {
841 DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_setcred failed - Rejecting User %s !\n", user));
842 smb_pam_end(pamh, pconv);
846 smb_pam_end(pamh, pconv);
851 * PAM Password Change Suite
854 BOOL smb_pam_passchange(char * user, char * oldpassword, char * newpassword)
856 /* Appropriate quantities of root should be obtained BEFORE calling this function */
857 struct pam_conv *pconv = NULL;
858 pam_handle_t *pamh = NULL;
860 if ((pconv = smb_setup_pam_conv(smb_pam_passchange_conv, user, oldpassword, newpassword)) == NULL)
863 if(!smb_pam_start(&pamh, user, NULL, pconv))
866 if (!smb_pam_chauthtok(pamh, user)) {
867 DEBUG(0, ("smb_pam_passchange: PAM: Password Change Failed for user %s!\n", user));
868 smb_pam_end(pamh, pconv);
872 return smb_pam_end(pamh, pconv);
877 /* If PAM not used, no PAM restrictions on accounts. */
878 uint32 smb_pam_accountcheck(char * user)
883 /* If PAM not used, also no PAM restrictions on sessions. */
884 BOOL smb_pam_claim_session(char *user, char *tty, char *rhost)
889 /* If PAM not used, also no PAM restrictions on sessions. */
890 BOOL smb_pam_close_session(char *in_user, char *tty, char *rhost)
894 #endif /* WITH_PAM */