s4-smbtorture: add test for setting passwords via samr_UserInfo18.
authorGünther Deschner <gd@samba.org>
Fri, 5 Dec 2008 14:19:22 +0000 (15:19 +0100)
committerGünther Deschner <gd@samba.org>
Fri, 5 Dec 2008 15:03:04 +0000 (16:03 +0100)
Guenther

source4/libcli/auth/session.c
source4/torture/rpc/samr.c

index 29af7fafe848edb2bba6570154c9262e177c2a3a..10c728662db392547aee46c452ff94cfe062a4b0 100644 (file)
@@ -29,7 +29,7 @@
   before calling, the out blob must be initialised to be the same size
   as the in blob
 */
-static void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key,
+void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key,
                     bool forward)
 {
        int i, k;
index dc1be429d9ded5d7cffdb810700bd74304798ef9..373b4dac2038d3080e4ef861b12053f6d61907d7 100644 (file)
@@ -849,6 +849,77 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t
        return ret;
 }
 
+static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
+                               struct policy_handle *handle, char **password)
+{
+       NTSTATUS status;
+       struct samr_SetUserInfo s;
+       union samr_UserInfo u;
+       bool ret = true;
+       DATA_BLOB session_key;
+       char *newpass;
+       struct samr_GetUserPwInfo pwp;
+       struct samr_PwInfo info;
+       int policy_min_pw_len = 0;
+       uint8_t lm_hash[16], nt_hash[16];
+
+       pwp.in.user_handle = handle;
+       pwp.out.info = &info;
+
+       status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
+       if (NT_STATUS_IS_OK(status)) {
+               policy_min_pw_len = pwp.out.info->min_password_length;
+       }
+       newpass = samr_rand_pass(tctx, policy_min_pw_len);
+
+       s.in.user_handle = handle;
+       s.in.info = &u;
+       s.in.level = 18;
+
+       ZERO_STRUCT(u);
+
+       u.info18.nt_pwd_active = true;
+       u.info18.lm_pwd_active = true;
+
+       E_md4hash(newpass, nt_hash);
+       E_deshash(newpass, lm_hash);
+
+       status = dcerpc_fetch_session_key(p, &session_key);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("SetUserInfo level %u - no session key - %s\n",
+                      s.in.level, nt_errstr(status));
+               return false;
+       }
+
+       {
+               DATA_BLOB in,out;
+               in = data_blob_const(nt_hash, 16);
+               out = data_blob_talloc_zero(tctx, 16);
+               sess_crypt_blob(&out, &in, &session_key, true);
+               memcpy(u.info18.nt_pwd.hash, out.data, out.length);
+       }
+       {
+               DATA_BLOB in,out;
+               in = data_blob_const(lm_hash, 16);
+               out = data_blob_talloc_zero(tctx, 16);
+               sess_crypt_blob(&out, &in, &session_key, true);
+               memcpy(u.info18.lm_pwd.hash, out.data, out.length);
+       }
+
+       torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
+
+       status = dcerpc_samr_SetUserInfo(p, tctx, &s);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("SetUserInfo level %u failed - %s\n",
+                      s.in.level, nt_errstr(status));
+               ret = false;
+       } else {
+               *password = newpass;
+       }
+
+       return ret;
+}
+
 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
                                      struct torture_context *tctx,
                                      struct policy_handle *handle,
@@ -2894,6 +2965,19 @@ static bool test_user_ops(struct dcerpc_pipe *p,
                        ret = false;
                }       
 
+               if (torture_setting_bool(tctx, "samba4", false)) {
+                       printf("skipping Set Password level 18 against Samba4\n");
+               } else {
+
+                       if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
+                               ret = false;
+                       }
+
+                       if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
+                               ret = false;
+                       }
+               }
+
                q.in.user_handle = user_handle;
                q.in.level = 5;
                q.out.info = &info;