Hey again,

I'm just starting to make sense of all this fun password change code.

I've started writing a function which I intended to be a master 
function, but I see now that it really more of a super 
pdb_set_plaintext_password, with a little extra something.

>From what I can tell, it seems that the sequence of password changes, 
while sometimes skipping a step, goes like this:

  pass_oem_change -> change_oem_password -> 
      check_oem_password -> pdb_set_plaintext_password
                        
Ideally, (if this diagram is somewhat correct), I'd like to write 
something that merges all those steps into something a bit more logical.

How far off base am I?

Oh, and Andrew, thanks for putting up with my constant pestering and 
questions =)

--
Patrick McCarty
Video Technician
Azusa Pacific University

Logic is a systematic method of coming to the wrong conclusion with confidence.
NTSTATUS master_change_password(const char *user_name, const char *new_passwd, int 
*pcb_flags)
{
        SAM_ACCOUNT     *sam_pass=NULL;
        uint16 acct_ctrl;
        uint32 min_pass_len;
        uchar new_lanman_p16[16];
        uchar new_nt_p16[16];

    /* Validate existence of arguments */
    if (!user_name || !new_passwd || !pcb_flags)
       return NT_STATUS_UNSUCCESSFUL;
       
        /* Get the smb passwd entry for this user */
        pdb_init_sam(&sam_pass);

        if(!pdb_getsampwnam(sam_pass, user_name)) {
                pdb_free_sam(&sam_pass);
                return NT_STATUS_UNSUCCESSFUL;
        }

        acct_ctrl = pdb_get_acct_ctrl(sampass);

        /* Check to see if the account is disabled */
        if (acct_ctrl & ACB_DISABLED) {
            DEBUG(0,("master_change_password: account %s disabled.\n",
                   pdb_get_username(sampass)));
            return NT_STATUS_UNSUCCESSFUL;
        }

        /* Check to see if user's password is locked */
        if (acct_ctrl & ACB_PWLOCK) {
            DEBUG(0,("master_change_password: account %s password locked.\n",
                   pdb_get_username(sampass)));
            return NT_STATUS_ACCESS_DENIED;
        }
           
        /* Generate hashes */
        nt_lm_owf_gen(new_passwd, new_nt_p16, new_lanman_p16);

        /* Check to see if we were passed a LANMAN hash only */
        if (pcb_flags & PCB_LMHASH)
        {
        if (!pdb_set_lanman_passwd (sampass, new_lanman_p16))
                    return NT_STATUS_UNSUCCESSFUL;

                if (!pdb_set_pass_changed_now (sampass))
                        return NT_STATUS_UNSUCCESSFUL;

                DEBUG(0,("master_change_password: changed lanman password for: %s.\n",
                                        pdb_get_username(sampass)));
                return NT_STATUS_OK;
        }

        /* If we get here, we have a plaintext password, so we can check length, etc 
*/

        /* Check minimum password length */
        account_policy_get(AP_MIN_PASSWORD_LEN, &min_pass_len);
        
        if (strlen(new_passwd) < min_pass_len) {
        DEBUG(0,("master_change_password: min_passwd_length %i, not changed.\n",
                                min_pass_len));
                return NT_STATUS_UNSUCCESSFUL;
        }

        /* TODO: Add cracklib check here */

        /* Lets go set our passwords now */
    if (!pdb_set_nt_passwd (sampass, new_nt_p16))
                return NT_STATUS_UNSUCCESSFUL;
           
        if (!pdb_set_lanman_passwd (sampass, new_lanman_p16))
            return NT_STATUS_UNSUCCESSFUL;

        if (!pdb_set_pass_changed_now (sampass))
                return NT_STATUS_UNSUCCESSFUL;

        return NT_STATUS_OK;
}

Reply via email to