r19934: - allow to pass a samr_UserInfo21 struct to be passed to libnet_SetPassword()
authorStefan Metzmacher <metze@samba.org>
Tue, 28 Nov 2006 17:30:43 +0000 (17:30 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:28:38 +0000 (14:28 -0500)
- as the SetUserInfo2() levels 26/25 and 24/23 have the same encryption
  but 26 and 24 change only the password and 25 and 23 take a info21 and change the password,
  we now use 26 with fallback to 24 or 25 with fallback to 23.
- use samr_SetUserInfo2() to match what w2k3 does (works also against nt4)
- pass the info21 to libnet_SetPassword() to set acct_flags and full_name
  together with the password (to match what w2k3 does)

metze

source/libnet/libnet_join.c
source/libnet/libnet_passwd.c
source/libnet/libnet_passwd.h

index ed9869980438aaae66d2c453dfe75204b332cea9..8e3753065e6bc276e1baf320a0ccacede902ff17 100644 (file)
@@ -408,9 +408,9 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
  * - potentially delete and recreate the user
  * - assert the account is of the right type with samrQueryUserInfo
  * 
- * - call libnet_SetPassword_samr_handle to set the password
+ * - call libnet_SetPassword_samr_handle to set the password,
+ *   and pass a samr_UserInfo21 struct to set full_name and the account flags
  *
- * - do a samrSetUserInfo to set the account flags
  * - do some ADS specific things when we join as Domain Controller,
  *    look at libnet_joinADSDomain() for the details
  */
@@ -432,8 +432,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
        struct samr_CreateUser2 cu;
        struct policy_handle *u_handle = NULL;
        struct samr_QueryUserInfo qui;
-       struct samr_SetUserInfo sui;
-       union samr_UserInfo u_info;
+       struct samr_UserInfo21 u_info21;
        union libnet_SetPassword r2;
        struct samr_GetUserPwInfo pwp;
        struct lsa_String samr_account_name;
@@ -756,7 +755,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                acct_flags = qui.out.info->info16.acct_flags;
        }
        
-       acct_flags = (acct_flags & ~ACB_DISABLED);
+       acct_flags = (acct_flags & ~(ACB_DISABLED|ACB_PWNOTREQ));
 
        /* Find out what password policy this user has */
        pwp.in.user_handle = u_handle;
@@ -770,11 +769,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
        
        password_str = generate_random_str(tmp_ctx, MAX(8, policy_min_pw_len)); 
 
+       /* set full_name and reset flags */
+       ZERO_STRUCT(u_info21);
+       u_info21.full_name.string       = r->in.account_name;
+       u_info21.acct_flags             = acct_flags;
+       u_info21.fields_present         = SAMR_FIELD_FULL_NAME | SAMR_FIELD_ACCT_FLAGS;
+
        r2.samr_handle.level            = LIBNET_SET_PASSWORD_SAMR_HANDLE;
        r2.samr_handle.in.account_name  = r->in.account_name;
        r2.samr_handle.in.newpassword   = password_str;
        r2.samr_handle.in.user_handle   = u_handle;
        r2.samr_handle.in.dcerpc_pipe   = samr_pipe;
+       r2.samr_handle.in.info21        = &u_info21;
 
        status = libnet_SetPassword(ctx, tmp_ctx, &r2); 
        if (!NT_STATUS_IS_OK(status)) {
@@ -783,26 +789,6 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                return status;
        }
 
-       /* reset flags (if required) */
-       if (acct_flags != qui.out.info->info16.acct_flags) {
-               ZERO_STRUCT(u_info);
-               u_info.info16.acct_flags = acct_flags;
-
-               sui.in.user_handle = u_handle;
-               sui.in.info = &u_info;
-               sui.in.level = 16;
-               
-               dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
-               if (!NT_STATUS_IS_OK(status)) {
-                       r->out.error_string = talloc_asprintf(mem_ctx,
-                                                       "samr_SetUserInfo for [%s] failed to remove ACB_DISABLED flag: %s",
-                                                       r->in.account_name,
-                                                       nt_errstr(status));
-                       talloc_free(tmp_ctx);
-                       return status;
-               }
-       }
-
        account_sid = dom_sid_add_rid(mem_ctx, connect_with_info->out.domain_sid, rid);
        if (!account_sid) {
                r->out.error_string = NULL;
index 050299f68a27f1b55db9a66b5d77fba71c6f9c22..483be7502da066591824c171b8a874c3fd59feba 100644 (file)
@@ -290,14 +290,18 @@ NTSTATUS libnet_ChangePassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
 static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
 {
        NTSTATUS status;
-       struct samr_SetUserInfo sui;
+       struct samr_SetUserInfo2 sui;
        union samr_UserInfo u_info;
        DATA_BLOB session_key;
        DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
        uint8_t confounder[16]; 
        struct MD5Context md5;
 
-       /* prepare samr_SetUserInfo level 26 */
+       if (r->samr_handle.in.info21) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       /* prepare samr_SetUserInfo2 level 26 */
        ZERO_STRUCT(u_info);
        encode_pw_buffer(u_info.info26.password.data, r->samr_handle.in.newpassword, STR_UNICODE);
        u_info.info26.pw_len = strlen(r->samr_handle.in.newpassword);
@@ -324,13 +328,13 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA
        sui.in.info = &u_info;
        sui.in.level = 26;
        
-       /* 7. try samr_SetUserInfo level 26 to set the password */
-       status = dcerpc_samr_SetUserInfo(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui);
-       /* check result of samr_SetUserInfo level 26 */
+       /* 7. try samr_SetUserInfo2 level 26 to set the password */
+       status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui);
+       /* check result of samr_SetUserInfo2 level 26 */
        if (!NT_STATUS_IS_OK(status)) {
                r->samr_handle.out.error_string
                        = talloc_asprintf(mem_ctx,
-                                         "SetUserInfo level 26 for [%s] failed: %s",
+                                         "SetUserInfo2 level 26 for [%s] failed: %s",
                                          r->samr_handle.in.account_name, nt_errstr(status));
        }
        return status;
@@ -339,16 +343,21 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA
 static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
 {
        NTSTATUS status;
-       struct samr_SetUserInfo sui;
+       struct samr_SetUserInfo2 sui;
        union samr_UserInfo u_info;
        DATA_BLOB session_key;
        DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
        uint8_t confounder[16]; 
        struct MD5Context md5;
 
-       /* prepare samr_SetUserInfo level 25 */
+       if (!r->samr_handle.in.info21) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       /* prepare samr_SetUserInfo2 level 25 */
        ZERO_STRUCT(u_info);
-       u_info.info25.info.fields_present = SAMR_FIELD_PASSWORD;
+       u_info.info25.info = *r->samr_handle.in.info21;
+       u_info.info25.info.fields_present |= SAMR_FIELD_PASSWORD;
        encode_pw_buffer(u_info.info25.password.data, r->samr_handle.in.newpassword, STR_UNICODE);
 
        status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
@@ -373,12 +382,12 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA
        sui.in.info = &u_info;
        sui.in.level = 25;
 
-       /* 8. try samr_SetUserInfo level 25 to set the password */
-       status = dcerpc_samr_SetUserInfo(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui);
+       /* 8. try samr_SetUserInfo2 level 25 to set the password */
+       status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui);
        if (!NT_STATUS_IS_OK(status)) {
                r->samr_handle.out.error_string
                        = talloc_asprintf(mem_ctx,
-                                         "SetUserInfo level 25 for [%s] failed: %s",
+                                         "SetUserInfo2 level 25 for [%s] failed: %s",
                                          r->samr_handle.in.account_name, nt_errstr(status));
        }
        return status;
@@ -387,11 +396,15 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA
 static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
 {
        NTSTATUS status;
-       struct samr_SetUserInfo sui;
+       struct samr_SetUserInfo2 sui;
        union samr_UserInfo u_info;
        DATA_BLOB session_key;
 
-       /* prepare samr_SetUserInfo level 24 */
+       if (r->samr_handle.in.info21) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       /* prepare samr_SetUserInfo2 level 24 */
        ZERO_STRUCT(u_info);
        encode_pw_buffer(u_info.info24.password.data, r->samr_handle.in.newpassword, STR_UNICODE);
        /* w2k3 ignores this length */
@@ -411,12 +424,12 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA
        sui.in.info = &u_info;
        sui.in.level = 24;
 
-       /* 9. try samr_SetUserInfo level 24 to set the password */
-       status = dcerpc_samr_SetUserInfo(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui);
+       /* 9. try samr_SetUserInfo2 level 24 to set the password */
+       status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui);
        if (!NT_STATUS_IS_OK(status)) {
                r->samr_handle.out.error_string
                        = talloc_asprintf(mem_ctx,
-                                         "SetUserInfo level 24 for [%s] failed: %s",
+                                         "SetUserInfo2 level 24 for [%s] failed: %s",
                                          r->samr_handle.in.account_name, nt_errstr(status));
        }
        return status;
@@ -425,13 +438,18 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA
 static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
 {
        NTSTATUS status;
-       struct samr_SetUserInfo sui;
+       struct samr_SetUserInfo2 sui;
        union samr_UserInfo u_info;
        DATA_BLOB session_key;
 
-       /* prepare samr_SetUserInfo level 23 */
+       if (!r->samr_handle.in.info21) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       /* prepare samr_SetUserInfo2 level 23 */
        ZERO_STRUCT(u_info);
-       u_info.info23.info.fields_present = SAMR_FIELD_PASSWORD;
+       u_info.info23.info = *r->samr_handle.in.info21;
+       u_info.info23.info.fields_present |= SAMR_FIELD_PASSWORD;
        encode_pw_buffer(u_info.info23.password.data, r->samr_handle.in.newpassword, STR_UNICODE);
 
        status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
@@ -449,25 +467,26 @@ static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TA
        sui.in.info = &u_info;
        sui.in.level = 23;
 
-       /* 10. try samr_SetUserInfo level 23 to set the password */
-       status = dcerpc_samr_SetUserInfo(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui);
+       /* 10. try samr_SetUserInfo2 level 23 to set the password */
+       status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui);
        if (!NT_STATUS_IS_OK(status)) {
                r->samr_handle.out.error_string
                        = talloc_asprintf(mem_ctx,
-                                         "SetUserInfo level 23 for [%s] failed: %s",
+                                         "SetUserInfo2 level 23 for [%s] failed: %s",
                                          r->samr_handle.in.account_name, nt_errstr(status));
        }
        return status;
 }
 
 /*
- * 1. try samr_SetUserInfo level 26 to set the password
- * 2. try samr_SetUserInfo level 25 to set the password
- * 3. try samr_SetUserInfo level 24 to set the password
- * 4. try samr_SetUserInfo level 23 to set the password
+ * 1. try samr_SetUserInfo2 level 26 to set the password
+ * 2. try samr_SetUserInfo2 level 25 to set the password
+ * 3. try samr_SetUserInfo2 level 24 to set the password
+ * 4. try samr_SetUserInfo2 level 23 to set the password
 */
 static NTSTATUS libnet_SetPassword_samr_handle(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
 {
+
        NTSTATUS status;
        enum libnet_SetPassword_level levels[] = {
                LIBNET_SET_PASSWORD_SAMR_HANDLE_26,
@@ -476,11 +495,12 @@ static NTSTATUS libnet_SetPassword_samr_handle(struct libnet_context *ctx, TALLO
                LIBNET_SET_PASSWORD_SAMR_HANDLE_23,
        };
        int i;
-       
+
        for (i=0; i < ARRAY_SIZE(levels); i++) {
                r->generic.level = levels[i];
                status = libnet_SetPassword(ctx, mem_ctx, r);
                if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)
+                   || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER_MIX)
                    || NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
                        /* Try another password set mechanism */
                        continue;
index d7b284cb74b2ae58784ab569081cfe303e4d627a..52a392f1d666007c666381f94dd4eec8c8a78252 100644 (file)
@@ -104,6 +104,10 @@ union libnet_SetPassword {
                        struct policy_handle *user_handle;
                        struct dcerpc_pipe   *dcerpc_pipe;
                        const char           *newpassword;
+                       struct samr_UserInfo21 *info21; /* can be NULL,
+                                                        * for level 26,24 it must be NULL
+                                                        * for level 25,23 it must be non-NULL
+                                                        */
                } in;
                struct _libnet_SetPassword_out out;
        } samr_handle;