Patch from Steve Langasek <corlon@netexpress.net>
authorJohn Terpstra <jht@samba.org>
Tue, 8 Apr 2003 04:44:26 +0000 (04:44 +0000)
committerJohn Terpstra <jht@samba.org>
Tue, 8 Apr 2003 04:44:26 +0000 (04:44 +0000)
fix up two issues in
pam_smbpass.  The first, more important issue is adding support for the
(apparently new) LOCAL_SET_PASSWORD flag to local_password_change(),
without which pam_smbpass is a complete and utter no-op.  The second,
lesser issue is that with the advent of ldapsam, it's possible for
pam_smbpass to generate a SIGPIPE that isn't handled by the calling
application.  The most basic signal wrapping is put in place to prevent
this.

Beyond that, the only thing in the patch is a bit of reformatting to
make pam_smb_passwd.c look a bit more like the rest of the code in CVS.
(This used to be commit 7cb5af35273097f913bff6894fe03050a18e1def)

source3/pam_smbpass/pam_smb_acct.c
source3/pam_smbpass/pam_smb_auth.c
source3/pam_smbpass/pam_smb_passwd.c

index 0803ef82a23c6b432a88bc557c5f7be16afa5131..2ea7eea7d87a3a8ed9152d0ccc8b82225eb37fd1 100644 (file)
@@ -47,7 +47,7 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
 
     const char *name;
     SAM_ACCOUNT *sampass = NULL;
-
+    void (*oldsig_handler)(int);
     extern BOOL in_client;
 
     /* Samba initialization. */
@@ -69,8 +69,12 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
         _log_err( LOG_DEBUG, "acct: username [%s] obtained", name );
     }
 
+    /* Getting into places that might use LDAP -- protect the app
+       from a SIGPIPE it's not expecting */
+    oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
     if (!initialize_password_db(True)) {
         _log_err( LOG_ALERT, "Cannot access samba password database" );
+        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
         return PAM_AUTHINFO_UNAVAIL;
     }
 
@@ -78,8 +82,10 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
     pdb_init_sam(&sampass);
     pdb_getsampwnam(sampass, name );
 
-    if (!sampass)
+    if (!sampass) {
+        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
         return PAM_USER_UNKNOWN;
+    }
 
     if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
         if (on( SMB_DEBUG, ctrl )) {
@@ -90,11 +96,13 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
                      , "Your account has been disabled; "
                        "please see your system administrator." );
 
+        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
         return PAM_ACCT_EXPIRED;
     }
 
     /* TODO: support for expired passwords. */
 
+    CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
     return PAM_SUCCESS;
 }
 
index e5cc12e2f6d40bc4a095ca5ef2ee13b22dcf3139..f4cbb59af31e4fe6c2632fbf08c2b13d84e93bdc 100644 (file)
@@ -36,6 +36,8 @@
 
 #define AUTH_RETURN                                            \
 do {                                                           \
+       /* Restore application signal handler */                \
+       CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);       \
        if(ret_data) {                                          \
                *ret_data = retval;                             \
                pam_set_data( pamh, "smb_setcred_return"        \
@@ -65,6 +67,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
     SAM_ACCOUNT *sampass = NULL;
     extern BOOL in_client;
     const char *name;
+    void (*oldsig_handler)(int);
     BOOL found;
 
     /* Points to memory managed by the PAM library. Do not free. */
@@ -93,6 +96,10 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
         _log_err( LOG_DEBUG, "username [%s] obtained", name );
     }
 
+    /* Getting into places that might use LDAP -- protect the app
+       from a SIGPIPE it's not expecting */
+    oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
+
     if (!initialize_password_db(True)) {
         _log_err( LOG_ALERT, "Cannot access samba password database" );
         retval = PAM_AUTHINFO_UNAVAIL;
index 91eae3c7a1960712a8810a5e9b5394a6de47af5b..9e75efccf4d6ba4890d6a298e0bcd70c310062c6 100644 (file)
@@ -1,18 +1,22 @@
-/* Unix NT password database implementation, version 0.7.5.
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
+/*
+   Unix SMB/CIFS implementation.
+   Use PAM to update user passwords in the local SAM
+   Copyright (C) Steve Langasek                1998-2003
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
 */
 
 /* indicate the following groups are defined */
 
 #include "includes.h"
 
-#ifndef LINUX
+/* This is only used in the Sun implementation.  FIXME: we really
+   want a define here that distinguishes between the Solaris PAM
+   and others (including FreeBSD). */
 
-/* This is only used in the Sun implementation. */
+#ifndef LINUX
 #include <security/pam_appl.h>
-
-#endif  /* LINUX */
+#endif
 
 #include <security/pam_modules.h>
 
 
 int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user,  const char *pass_new )
 {
- int           retval;
- pstring       err_str;
- pstring       msg_str;
-
-    err_str[0] = '\0';
-    msg_str[0] = '\0';
-
-    retval = local_password_change( user, 0, pass_new, err_str, sizeof(err_str),
-                                   msg_str, sizeof(msg_str) );
-
-    if (!retval) {
-        if (*err_str) {
-            err_str[PSTRING_LEN-1] = '\0';
-            make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str );
-        }
-
-        /* FIXME: what value is appropriate here? */
-        retval = PAM_AUTHTOK_ERR;
-    } else {
-        if (*msg_str) {
-            msg_str[PSTRING_LEN-1] = '\0';
-            make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str );
-        }
-        retval = PAM_SUCCESS;
-    }
-
-    return retval;      
+       int retval;
+       pstring err_str;
+       pstring msg_str;
+
+       err_str[0] = '\0';
+       msg_str[0] = '\0';
+
+       retval = local_password_change( user, LOCAL_SET_PASSWORD, pass_new,
+                                       err_str, sizeof(err_str),
+                                       msg_str, sizeof(msg_str) );
+
+       if (!retval) {
+               if (*err_str) {
+                       err_str[PSTRING_LEN-1] = '\0';
+                       make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str );
+               }
+
+               /* FIXME: what value is appropriate here? */
+               retval = PAM_AUTHTOK_ERR;
+       } else {
+               if (*msg_str) {
+                       msg_str[PSTRING_LEN-1] = '\0';
+                       make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str );
+               }
+               retval = PAM_SUCCESS;
+       }
 
+       return retval;      
 }
 
 
@@ -92,6 +97,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
     extern BOOL in_client;
 
     SAM_ACCOUNT *sampass = NULL;
+    void (*oldsig_handler)(int);
     const char *user;
     char *pass_old;
     char *pass_new;
@@ -120,18 +126,25 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
         _log_err( LOG_DEBUG, "username [%s] obtained", user );
     }
 
+    /* Getting into places that might use LDAP -- protect the app
+       from a SIGPIPE it's not expecting */
+    oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
+
     if (!initialize_password_db(True)) {
         _log_err( LOG_ALERT, "Cannot access samba password database" );
+        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
         return PAM_AUTHINFO_UNAVAIL;
     }
 
     /* obtain user record */
     if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) {
-           return nt_status_to_pam(nt_status);
+        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
+        return nt_status_to_pam(nt_status);
     }
 
     if (!pdb_getsampwnam(sampass,user)) {
         _log_err( LOG_ALERT, "Failed to find entry for user %s.", user );
+        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
         return PAM_USER_UNKNOWN;
     }
 
@@ -146,6 +159,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
         if (_smb_blankpasswd( ctrl, sampass )) {
 
             pdb_free_sam(&sampass);
+            CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
             return PAM_SUCCESS;
         }
 
@@ -159,6 +173,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
             if (Announce == NULL) {
                 _log_err(LOG_CRIT, "password: out of memory");
                 pdb_free_sam(&sampass);
+                CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
                 return PAM_BUF_ERR;
             }
             strncpy( Announce, greeting, sizeof(greeting) );
@@ -174,6 +189,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
                 _log_err( LOG_NOTICE
                           , "password - (old) token not obtained" );
                 pdb_free_sam(&sampass);
+                CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
                 return retval;
             }
 
@@ -188,19 +204,11 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
 
         pass_old = NULL;
         pdb_free_sam(&sampass);
+        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
         return retval;
 
     } else if (flags & PAM_UPDATE_AUTHTOK) {
 
-#if 0
-        /* We used to return when this flag was set, but that breaks
-           password synchronization when /other/ tokens are expired.  For
-           now, we change the password whenever we're asked. SRL */
-        if (flags & PAM_CHANGE_EXPIRED_AUTHTOK) {
-            pdb_free_sam(&sampass);
-            return PAM_SUCCESS;
-        }
-#endif
         /*
          * obtain the proposed password
          */
@@ -226,6 +234,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
         if (retval != PAM_SUCCESS) {
             _log_err( LOG_NOTICE, "password: user not authenticated" );
             pdb_free_sam(&sampass);
+            CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
             return retval;
         }
 
@@ -253,6 +262,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
             }
             pass_old = NULL;                               /* tidy up */
             pdb_free_sam(&sampass);
+            CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
             return retval;
         }
 
@@ -272,6 +282,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
             _log_err(LOG_NOTICE, "new password not acceptable");
             pass_new = pass_old = NULL;               /* tidy up */
             pdb_free_sam(&sampass);
+            CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
             return retval;
         }
 
@@ -312,6 +323,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
     }
 
     pdb_free_sam(&sampass);
+    CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
     return retval;
 }