📄 support.c
字号:
name = pdb_get_username(sampass);#ifdef HAVE_PAM_FAIL_DELAY if (off( SMB_NODELAY, ctrl )) { (void) pam_fail_delay( pamh, 1000000 ); /* 1 sec delay for on failure */ }#endif if (!pdb_get_lanman_passwd(sampass)) { _log_err( LOG_DEBUG, "user %s has null SMB password" , name ); if (off( SMB__NONULL, ctrl ) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) { /* this means we've succeeded */ return PAM_SUCCESS; } else { const char *service; pam_get_item( pamh, PAM_SERVICE, (const void **)&service ); _log_err( LOG_NOTICE, "failed auth request by %s for service %s as %s", uidtoname(getuid()), service ? service : "**unknown**", name); return PAM_AUTH_ERR; } } data_name = SMB_MALLOC_ARRAY(char, sizeof(FAIL_PREFIX) + strlen( name )); if (data_name == NULL) { _log_err( LOG_CRIT, "no memory for data-name" ); } strncpy( data_name, FAIL_PREFIX, sizeof(FAIL_PREFIX) ); strncpy( data_name + sizeof(FAIL_PREFIX) - 1, name, strlen( name ) + 1 ); /* * The password we were given wasn't an encrypted password, or it * didn't match the one we have. We encrypt the password now and try * again. */ nt_lm_owf_gen(p, nt_pw, lm_pw); /* the moment of truth -- do we agree with the password? */ if (!memcmp( nt_pw, pdb_get_nt_passwd(sampass), 16 )) { retval = PAM_SUCCESS; if (data_name) { /* reset failures */ pam_set_data(pamh, data_name, NULL, _cleanup_failures); } } else { const char *service; pam_get_item( pamh, PAM_SERVICE, (const void **)&service ); if (data_name != NULL) { struct _pam_failed_auth *newauth = NULL; const struct _pam_failed_auth *old = NULL; /* get a failure recorder */ newauth = SMB_MALLOC_P( struct _pam_failed_auth ); if (newauth != NULL) { /* any previous failures for this user ? */ pam_get_data(pamh, data_name, (const void **) &old); if (old != NULL) { newauth->count = old->count + 1; if (newauth->count >= SMB_MAX_RETRIES) { retval = PAM_MAXTRIES; } } else { _log_err(LOG_NOTICE, "failed auth request by %s for service %s as %s", uidtoname(getuid()), service ? service : "**unknown**", name); newauth->count = 1; } if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sampass), &(newauth->id)))) { _log_err(LOG_NOTICE, "failed auth request by %s for service %s as %s", uidtoname(getuid()), service ? service : "**unknown**", name); } newauth->user = smbpXstrDup( name ); newauth->agent = smbpXstrDup( uidtoname( getuid() ) ); pam_set_data( pamh, data_name, newauth, _cleanup_failures ); } else { _log_err( LOG_CRIT, "no memory for failure recorder" ); _log_err(LOG_NOTICE, "failed auth request by %s for service %s as %s(%d)", uidtoname(getuid()), service ? service : "**unknown**", name); } } else { _log_err(LOG_NOTICE, "failed auth request by %s for service %s as %s(%d)", uidtoname(getuid()), service ? service : "**unknown**", name); retval = PAM_AUTH_ERR; } } _pam_delete( data_name ); return retval;}/* * _smb_blankpasswd() is a quick check for a blank password * * returns TRUE if user does not have a password * - to avoid prompting for one in such cases (CG) */int _smb_blankpasswd( unsigned int ctrl, SAM_ACCOUNT *sampass ){ int retval; /* * This function does not have to be too smart if something goes * wrong, return FALSE and let this case to be treated somewhere * else (CG) */ if (on( SMB__NONULL, ctrl )) return 0; /* will fail but don't let on yet */ if (pdb_get_lanman_passwd(sampass) == NULL) retval = 1; else retval = 0; return retval;}/* * obtain a password from the user */int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl, const char *comment, const char *prompt1, const char *prompt2, const char *data_name, char **pass ){ int authtok_flag; int retval; char *item = NULL; char *token; struct pam_message msg[3], *pmsg[3]; struct pam_response *resp; int i, expect; /* make sure nothing inappropriate gets returned */ *pass = token = NULL; /* which authentication token are we getting? */ authtok_flag = on(SMB__OLD_PASSWD, ctrl) ? PAM_OLDAUTHTOK : PAM_AUTHTOK; /* should we obtain the password from a PAM item ? */ if (on(SMB_TRY_FIRST_PASS, ctrl) || on(SMB_USE_FIRST_PASS, ctrl)) { retval = pam_get_item( pamh, authtok_flag, (const void **) &item ); if (retval != PAM_SUCCESS) { /* very strange. */ _log_err( LOG_ALERT , "pam_get_item returned error to smb_read_password" ); return retval; } else if (item != NULL) { /* we have a password! */ *pass = item; item = NULL; return PAM_SUCCESS; } else if (on( SMB_USE_FIRST_PASS, ctrl )) { return PAM_AUTHTOK_RECOVER_ERR; /* didn't work */ } else if (on( SMB_USE_AUTHTOK, ctrl ) && off( SMB__OLD_PASSWD, ctrl )) { return PAM_AUTHTOK_RECOVER_ERR; } } /* * getting here implies we will have to get the password from the * user directly. */ /* prepare to converse */ if (comment != NULL && off(SMB__QUIET, ctrl)) { pmsg[0] = &msg[0]; msg[0].msg_style = PAM_TEXT_INFO; msg[0].msg = comment; i = 1; } else { i = 0; } pmsg[i] = &msg[i]; msg[i].msg_style = PAM_PROMPT_ECHO_OFF; msg[i++].msg = prompt1; if (prompt2 != NULL) { pmsg[i] = &msg[i]; msg[i].msg_style = PAM_PROMPT_ECHO_OFF; msg[i++].msg = prompt2; expect = 2; } else expect = 1; resp = NULL; retval = converse( pamh, ctrl, i, pmsg, &resp ); if (resp != NULL) { int j = comment ? 1 : 0; /* interpret the response */ if (retval == PAM_SUCCESS) { /* a good conversation */ token = smbpXstrDup(resp[j++].resp); if (token != NULL) { if (expect == 2) { /* verify that password entered correctly */ if (!resp[j].resp || strcmp( token, resp[j].resp )) { _pam_delete( token ); retval = PAM_AUTHTOK_RECOVER_ERR; make_remark( pamh, ctrl, PAM_ERROR_MSG , MISTYPED_PASS ); } } } else { _log_err(LOG_NOTICE, "could not recover authentication token"); } } /* tidy up */ _pam_drop_reply( resp, expect ); } else { retval = (retval == PAM_SUCCESS) ? PAM_AUTHTOK_RECOVER_ERR : retval; } if (retval != PAM_SUCCESS) { if (on( SMB_DEBUG, ctrl )) _log_err( LOG_DEBUG, "unable to obtain a password" ); return retval; } /* 'token' is the entered password */ if (off( SMB_NOT_SET_PASS, ctrl )) { /* we store this password as an item */ retval = pam_set_item( pamh, authtok_flag, (const void *)token ); _pam_delete( token ); /* clean it up */ if (retval != PAM_SUCCESS || (retval = pam_get_item( pamh, authtok_flag ,(const void **)&item )) != PAM_SUCCESS) { _log_err( LOG_CRIT, "error manipulating password" ); return retval; } } else { /* * then store it as data specific to this module. pam_end() * will arrange to clean it up. */ retval = pam_set_data( pamh, data_name, (void *) token, _cleanup ); if (retval != PAM_SUCCESS || (retval = pam_get_data( pamh, data_name, (const void **)&item )) != PAM_SUCCESS) { _log_err( LOG_CRIT, "error manipulating password data [%s]" , pam_strerror( pamh, retval )); _pam_delete( token ); item = NULL; return retval; } token = NULL; /* break link to password */ } *pass = item; item = NULL; /* break link to password */ return PAM_SUCCESS;}int _pam_smb_approve_pass(pam_handle_t * pamh, unsigned int ctrl, const char *pass_old, const char *pass_new ){ /* Further checks should be handled through module stacking. -SRL */ if (pass_new == NULL || (pass_old && !strcmp( pass_old, pass_new ))) { if (on(SMB_DEBUG, ctrl)) { _log_err( LOG_DEBUG, "passwd: bad authentication token (null or unchanged)" ); } make_remark( pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ? "No password supplied" : "Password unchanged" ); return PAM_AUTHTOK_ERR; } return PAM_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -