s3-samr: implement _samr_ChangePasswordUser().
authorGünther Deschner <gd@samba.org>
Thu, 7 May 2009 22:16:43 +0000 (00:16 +0200)
committerGünther Deschner <gd@samba.org>
Thu, 7 May 2009 22:46:49 +0000 (00:46 +0200)
This is vastly copied from samba4 samr server.

Guenther

source3/rpc_server/srv_samr_nt.c

index cef8c08c6403efe9290c81bccef4beba6b5254e8..1a1b5e9a747c1cf24facbfe2f428a271a45de915 100644 (file)
@@ -1769,6 +1769,112 @@ NTSTATUS _samr_LookupNames(pipes_struct *p,
        return status;
 }
 
        return status;
 }
 
+/****************************************************************
+ _samr_ChangePasswordUser
+****************************************************************/
+
+NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
+                                 struct samr_ChangePasswordUser *r)
+{
+       NTSTATUS status;
+       bool ret = false;
+       struct samr_user_info *uinfo;
+       struct samu *pwd;
+       struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
+       struct samr_Password lm_pwd, nt_pwd;
+
+       uinfo = policy_handle_find(p, r->in.user_handle,
+                                  SAMR_USER_ACCESS_SET_PASSWORD, NULL,
+                                  struct samr_user_info, &status);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
+                 sid_string_dbg(&uinfo->sid)));
+
+       if (!(pwd = samu_new(NULL))) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       become_root();
+       ret = pdb_getsampwsid(pwd, &uinfo->sid);
+       unbecome_root();
+
+       if (!ret) {
+               TALLOC_FREE(pwd);
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
+       {
+               const uint8_t *lm_pass, *nt_pass;
+
+               lm_pass = pdb_get_lanman_passwd(pwd);
+               nt_pass = pdb_get_nt_passwd(pwd);
+
+               memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
+               memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
+       }
+
+       /* basic sanity checking on parameters.  Do this before any database ops */
+       if (!r->in.lm_present || !r->in.nt_present ||
+           !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
+           !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
+               /* we should really handle a change with lm not
+                  present */
+               status = NT_STATUS_INVALID_PARAMETER_MIX;
+               goto out;
+       }
+
+       /* decrypt and check the new lm hash */
+       D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
+       D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
+       if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
+               status = NT_STATUS_WRONG_PASSWORD;
+               goto out;
+       }
+
+       /* decrypt and check the new nt hash */
+       D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
+       D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
+       if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
+               status = NT_STATUS_WRONG_PASSWORD;
+               goto out;
+       }
+
+       /* The NT Cross is not required by Win2k3 R2, but if present
+          check the nt cross hash */
+       if (r->in.cross1_present && r->in.nt_cross) {
+               D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
+               if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
+                       status = NT_STATUS_WRONG_PASSWORD;
+                       goto out;
+               }
+       }
+
+       /* The LM Cross is not required by Win2k3 R2, but if present
+          check the lm cross hash */
+       if (r->in.cross2_present && r->in.lm_cross) {
+               D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
+               if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
+                       status = NT_STATUS_WRONG_PASSWORD;
+                       goto out;
+               }
+       }
+
+       if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
+           !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
+               status = NT_STATUS_ACCESS_DENIED;
+               goto out;
+       }
+
+       status = pdb_update_sam_account(pwd);
+ out:
+       TALLOC_FREE(pwd);
+
+       return status;
+}
+
 /*******************************************************************
  _samr_ChangePasswordUser2
  ********************************************************************/
 /*******************************************************************
  _samr_ChangePasswordUser2
  ********************************************************************/
@@ -6108,16 +6214,6 @@ NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
-                                 struct samr_ChangePasswordUser *r)
-{
-       p->rng_fault_state = true;
-       return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/****************************************************************
-****************************************************************/
-
 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
                                          struct samr_TestPrivateFunctionsDomain *r)
 {
 NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
                                          struct samr_TestPrivateFunctionsDomain *r)
 {