00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #define PAM_SM_AUTH
00020
00021 #include "includes.h"
00022 #include "debug.h"
00023
00024 #ifndef LINUX
00025
00026
00027 #include <security/pam_appl.h>
00028
00029 #endif
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 \
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
00055
00056
00057
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
00074 char *p = NULL;
00075
00076
00077 load_case_tables();
00078 setup_logging("pam_smbpass",False);
00079 in_client = True;
00080
00081 ctrl = set_ctrl(flags, argc, argv);
00082
00083
00084
00085 ret_data = SMB_MALLOC_P(int);
00086
00087
00088
00089
00090 oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
00091
00092
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
00140
00141 if (_smb_blankpasswd( ctrl, sampass )) {
00142 TALLOC_FREE(sampass);
00143 retval = PAM_SUCCESS;
00144 AUTH_RETURN;
00145 }
00146
00147
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
00157
00158 retval = _smb_verify_password( pamh, sampass, p, ctrl );
00159 TALLOC_FREE(sampass);
00160 p = NULL;
00161 AUTH_RETURN;
00162 }
00163
00164
00165
00166
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
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
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
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
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
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