pam_smbpass/pam_smb_auth.c

説明を見る。
00001 /* Unix NT password database implementation, version 0.7.5.
00002  *
00003  * This program is free software; you can redistribute it and/or modify it under
00004  * the terms of the GNU General Public License as published by the Free
00005  * Software Foundation; either version 2 of the License, or (at your option)
00006  * any later version.
00007  *
00008  * This program is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00010  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00011  * more details.
00012  *
00013  * You should have received a copy of the GNU General Public License along with
00014  * this program; if not, write to the Free Software Foundation, Inc., 675
00015  * Mass Ave, Cambridge, MA 02139, USA.
00016 */
00017 
00018 /* indicate the following groups are defined */
00019 #define PAM_SM_AUTH
00020 
00021 #include "includes.h"
00022 #include "debug.h"
00023 
00024 #ifndef LINUX
00025 
00026 /* This is only used in the Sun implementation. */
00027 #include <security/pam_appl.h>
00028 
00029 #endif  /* LINUX */
00030 
00031 #include <security/pam_modules.h>
00032 
00033 #include "general.h"
00034 
00035 #include "support.h"
00036 
00037 #define AUTH_RETURN                                             \
00038 do {                                                            \
00039         /* Restore application signal handler */                \
00040         CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);       \
00041         if(ret_data) {                                          \
00042                 *ret_data = retval;                             \
00043                 pam_set_data( pamh, "smb_setcred_return"        \
00044                               , (void *) ret_data, NULL );      \
00045         }                                                       \
00046         return retval;                                          \
00047 } while (0)
00048 
00049 static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
00050                          const char *name, struct samu *sampass, BOOL exist);
00051 
00052 
00053 /*
00054  * pam_sm_authenticate() authenticates users against the samba password file.
00055  *
00056  *      First, obtain the password from the user. Then use a
00057  *      routine in 'support.c' to authenticate the user.
00058  */
00059 
00060 #define _SMB_AUTHTOK  "-SMB-PASS"
00061 
00062 int pam_sm_authenticate(pam_handle_t *pamh, int flags,
00063                         int argc, const char **argv)
00064 {
00065         unsigned int ctrl;
00066         int retval, *ret_data = NULL;
00067         struct samu *sampass = NULL;
00068         extern BOOL in_client;
00069         const char *name;
00070         void (*oldsig_handler)(int) = NULL;
00071         BOOL found;
00072 
00073         /* Points to memory managed by the PAM library. Do not free. */
00074         char *p = NULL;
00075 
00076         /* Samba initialization. */
00077         load_case_tables();
00078         setup_logging("pam_smbpass",False);
00079         in_client = True;
00080 
00081         ctrl = set_ctrl(flags, argc, argv);
00082 
00083         /* Get a few bytes so we can pass our return value to
00084                 pam_sm_setcred(). */
00085         ret_data = SMB_MALLOC_P(int);
00086 
00087         /* we need to do this before we call AUTH_RETURN */
00088         /* Getting into places that might use LDAP -- protect the app
00089         from a SIGPIPE it's not expecting */
00090         oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
00091 
00092         /* get the username */
00093         retval = pam_get_user( pamh, &name, "Username: " );
00094         if ( retval != PAM_SUCCESS ) {
00095                 if (on( SMB_DEBUG, ctrl )) {
00096                         _log_err(LOG_DEBUG, "auth: could not identify user");
00097                 }
00098                 AUTH_RETURN;
00099         }
00100         if (on( SMB_DEBUG, ctrl )) {
00101                 _log_err( LOG_DEBUG, "username [%s] obtained", name );
00102         }
00103 
00104         if (geteuid() != 0) {
00105                 _log_err(LOG_DEBUG, "Cannot access samba password database, not running as root.");
00106                 retval = PAM_AUTHINFO_UNAVAIL;
00107                 AUTH_RETURN;
00108         }
00109 
00110         if (!initialize_password_db(True)) {
00111                 _log_err( LOG_ALERT, "Cannot access samba password database" );
00112                 retval = PAM_AUTHINFO_UNAVAIL;
00113                 AUTH_RETURN;
00114         }
00115 
00116         sampass = samu_new( NULL );
00117         if (!sampass) {
00118                 _log_err( LOG_ALERT, "Cannot talloc a samu struct" );
00119                 retval = nt_status_to_pam(NT_STATUS_NO_MEMORY);
00120                 AUTH_RETURN;
00121         }
00122 
00123         found = pdb_getsampwnam( sampass, name );
00124 
00125         if (on( SMB_MIGRATE, ctrl )) {
00126                 retval = _smb_add_user(pamh, ctrl, name, sampass, found);
00127                 TALLOC_FREE(sampass);
00128                 AUTH_RETURN;
00129         }
00130 
00131         if (!found) {
00132                 _log_err(LOG_ALERT, "Failed to find entry for user %s.", name);
00133                 retval = PAM_USER_UNKNOWN;
00134                 TALLOC_FREE(sampass);
00135                 sampass = NULL;
00136                 AUTH_RETURN;
00137         }
00138    
00139         /* if this user does not have a password... */
00140 
00141         if (_smb_blankpasswd( ctrl, sampass )) {
00142                 TALLOC_FREE(sampass);
00143                 retval = PAM_SUCCESS;
00144                 AUTH_RETURN;
00145         }
00146 
00147         /* get this user's authentication token */
00148 
00149         retval = _smb_read_password(pamh, ctrl, NULL, "Password: ", NULL, _SMB_AUTHTOK, &p);
00150         if (retval != PAM_SUCCESS ) {
00151                 _log_err(LOG_CRIT, "auth: no password provided for [%s]", name);
00152                 TALLOC_FREE(sampass);
00153                 AUTH_RETURN;
00154         }
00155 
00156         /* verify the password of this user */
00157 
00158         retval = _smb_verify_password( pamh, sampass, p, ctrl );
00159         TALLOC_FREE(sampass);
00160         p = NULL;
00161         AUTH_RETURN;
00162 }
00163 
00164 /*
00165  * This function is for setting samba credentials.  If anyone comes up
00166  * with any credentials they think should be set, let me know.
00167  */
00168 
00169 int pam_sm_setcred(pam_handle_t *pamh, int flags,
00170                    int argc, const char **argv)
00171 {
00172     int retval, *pretval = NULL;
00173 
00174     retval = PAM_SUCCESS;
00175 
00176     pam_get_data(pamh, "smb_setcred_return", (const void **) &pretval);
00177     if(pretval) {
00178         retval = *pretval;
00179         SAFE_FREE(pretval);
00180     }
00181     pam_set_data(pamh, "smb_setcred_return", NULL, NULL);
00182 
00183     return retval;
00184 }
00185 
00186 
00187 /* Helper function for adding a user to the db. */
00188 static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
00189                          const char *name, struct samu *sampass, BOOL exist)
00190 {
00191     pstring err_str;
00192     pstring msg_str;
00193     const char *pass = NULL;
00194     int retval;
00195 
00196     err_str[0] = '\0';
00197     msg_str[0] = '\0';
00198 
00199     /* Get the authtok; if we don't have one, silently fail. */
00200     retval = pam_get_item( pamh, PAM_AUTHTOK, (const void **) &pass );
00201 
00202     if (retval != PAM_SUCCESS) {
00203         _log_err( LOG_ALERT
00204                   , "pam_get_item returned error to pam_sm_authenticate" );
00205         return PAM_AUTHTOK_RECOVER_ERR;
00206     } else if (pass == NULL) {
00207         return PAM_AUTHTOK_RECOVER_ERR;
00208     }
00209 
00210     /* Add the user to the db if they aren't already there. */
00211    if (!exist) {
00212         retval = NT_STATUS_IS_OK(local_password_change( name, LOCAL_ADD_USER|LOCAL_SET_PASSWORD,
00213                                          pass, err_str,
00214                                          sizeof(err_str),
00215                                          msg_str, sizeof(msg_str) ));
00216         if (!retval && *err_str)
00217         {
00218             err_str[PSTRING_LEN-1] = '\0';
00219             make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str );
00220         }
00221         else if (*msg_str)
00222         {
00223             msg_str[PSTRING_LEN-1] = '\0';
00224             make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str );
00225         }
00226         pass = NULL;
00227 
00228         return PAM_IGNORE;
00229    }
00230    else {
00231     /* mimick 'update encrypted' as long as the 'no pw req' flag is not set */
00232     if ( pdb_get_acct_ctrl(sampass) & ~ACB_PWNOTREQ )
00233     {
00234         retval = NT_STATUS_IS_OK(local_password_change( name, LOCAL_SET_PASSWORD, pass, err_str, sizeof(err_str),
00235                                          msg_str, sizeof(msg_str) ));
00236         if (!retval && *err_str)
00237         {
00238             err_str[PSTRING_LEN-1] = '\0';
00239             make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str );
00240         }
00241         else if (*msg_str)
00242         {
00243             msg_str[PSTRING_LEN-1] = '\0';
00244             make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str );
00245         }
00246     }
00247    }
00248     
00249     pass = NULL;
00250 
00251     return PAM_IGNORE;
00252 }
00253 
00254 
00255 /* static module data */
00256 #ifdef PAM_STATIC
00257 struct pam_module _pam_smbpass_auth_modstruct = {
00258      "pam_smbpass",
00259      pam_sm_authenticate,
00260      pam_sm_setcred,
00261      NULL,
00262      NULL,
00263      NULL,
00264      NULL
00265 };
00266 #endif

Sambaに対してSat Aug 29 21:23:11 2009に生成されました。  doxygen 1.4.7