fixed the client side password change code
[ira/wip.git] / source4 / libnet / libnet_passwd.c
index de2ed01abd8690218f32052e4eb6c26b92fb5968..2c969169373ef955511361bdd524d99d5ba6178f 100644 (file)
@@ -50,6 +50,8 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT
        struct samr_Password nt_verifier, lm_verifier;
        uint8_t old_nt_hash[16], new_nt_hash[16];
        uint8_t old_lm_hash[16], new_lm_hash[16];
+       struct samr_DomInfo1 *dominfo = NULL;
+       struct samr_ChangeReject *reject = NULL;
 
        /* prepare connect to the SAMR pipe of the users domain PDC */
        c.level                    = LIBNET_RPC_CONNECT_PDC;
@@ -92,33 +94,24 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT
        pw3.in.lm_password = &lm_pass;
        pw3.in.lm_verifier = &lm_verifier;
        pw3.in.password3 = NULL;
+       pw3.out.dominfo = &dominfo;
+       pw3.out.reject = &reject;
 
        /* 2. try samr_ChangePasswordUser3 */
        status = dcerpc_samr_ChangePasswordUser3(c.out.dcerpc_pipe, mem_ctx, &pw3);
-       if (!NT_STATUS_IS_OK(status)) {
-               r->samr.out.error_string = talloc_asprintf(mem_ctx,
-                                               "samr_ChangePasswordUser3 failed: %s",
-                                               nt_errstr(status));
-               goto ChangePasswordUser2;
-       }
-
-       /* check result of samr_ChangePasswordUser3 */
-       if (!NT_STATUS_IS_OK(pw3.out.result)) {
-               r->samr.out.error_string = talloc_asprintf(mem_ctx,
-                                               "samr_ChangePasswordUser3 for '%s\\%s' failed: %s",
-                                               r->samr.in.domain_name, r->samr.in.account_name, 
-                                               nt_errstr(pw3.out.result));
-                                               /* TODO: give the reason of the reject */
-               if (NT_STATUS_EQUAL(pw3.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
-                       status = pw3.out.result;
-                       goto disconnect;
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+               if (!NT_STATUS_IS_OK(status)) {
+                       r->samr.out.error_string = talloc_asprintf(mem_ctx,
+                                                                  "samr_ChangePasswordUser3 failed: %s",
+                                                                  nt_errstr(status));
+                       r->samr.out.error_string = talloc_asprintf(mem_ctx,
+                                                                  "samr_ChangePasswordUser3 for '%s\\%s' failed: %s",
+                                                                  r->samr.in.domain_name, r->samr.in.account_name, 
+                                                                  nt_errstr(status));
                }
-               goto ChangePasswordUser2;
-       }
-
-       goto disconnect;
+               goto disconnect;
+       } 
 
-ChangePasswordUser2:
        /* prepare samr_ChangePasswordUser2 */
        encode_pw_buffer(lm_pass.data, r->samr.in.newpassword, STR_ASCII|STR_TERMINATE);
        arcfour_crypt(lm_pass.data, old_lm_hash, 516);
@@ -138,29 +131,17 @@ ChangePasswordUser2:
 
        /* 3. try samr_ChangePasswordUser2 */
        status = dcerpc_samr_ChangePasswordUser2(c.out.dcerpc_pipe, mem_ctx, &pw2);
-       if (!NT_STATUS_IS_OK(status)) {
-               r->samr.out.error_string = talloc_asprintf(mem_ctx,
-                                               "samr_ChangePasswordUser2 failed: %s",
-                                               nt_errstr(status));
-               goto OemChangePasswordUser2;
-       }
-
-       /* check result of samr_ChangePasswordUser2 */
-       if (!NT_STATUS_IS_OK(pw2.out.result)) {
-               r->samr.out.error_string = talloc_asprintf(mem_ctx,
-                                               "samr_ChangePasswordUser2 for '%s\\%s' failed: %s",
-                                               r->samr.in.domain_name, r->samr.in.account_name, 
-                                               nt_errstr(pw2.out.result));
-               if (NT_STATUS_EQUAL(pw2.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
-                       status = pw2.out.result;
-                       goto disconnect;
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+               if (!NT_STATUS_IS_OK(status)) {
+                       r->samr.out.error_string = talloc_asprintf(mem_ctx,
+                                                                  "samr_ChangePasswordUser2 for '%s\\%s' failed: %s",
+                                                                  r->samr.in.domain_name, r->samr.in.account_name, 
+                                                                  nt_errstr(status));
                }
-               goto OemChangePasswordUser2;
+               goto disconnect;
        }
 
-       goto disconnect;
 
-OemChangePasswordUser2:
        /* prepare samr_OemChangePasswordUser2 */
        a_server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(c.out.dcerpc_pipe));
        a_account.string = r->samr.in.account_name;
@@ -176,29 +157,16 @@ OemChangePasswordUser2:
 
        /* 4. try samr_OemChangePasswordUser2 */
        status = dcerpc_samr_OemChangePasswordUser2(c.out.dcerpc_pipe, mem_ctx, &oe2);
-       if (!NT_STATUS_IS_OK(status)) {
-               r->samr.out.error_string = talloc_asprintf(mem_ctx,
-                                               "samr_OemChangePasswordUser2 failed: %s",
-                                               nt_errstr(status));
-               goto ChangePasswordUser;
-       }
-
-       /* check result of samr_OemChangePasswordUser2 */
-       if (!NT_STATUS_IS_OK(oe2.out.result)) {
-               r->samr.out.error_string = talloc_asprintf(mem_ctx,
-                                               "samr_OemChangePasswordUser2 for '%s\\%s' failed: %s",
-                                               r->samr.in.domain_name, r->samr.in.account_name, 
-                                               nt_errstr(oe2.out.result));
-               if (NT_STATUS_EQUAL(oe2.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
-                       status = oe2.out.result;
-                       goto disconnect;
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+               if (!NT_STATUS_IS_OK(oe2.out.result)) {
+                       r->samr.out.error_string = talloc_asprintf(mem_ctx,
+                                                                  "samr_OemChangePasswordUser2 for '%s\\%s' failed: %s",
+                                                                  r->samr.in.domain_name, r->samr.in.account_name, 
+                                                                  nt_errstr(status));
                }
-               goto ChangePasswordUser;
+               goto disconnect;
        }
 
-       goto disconnect;
-
-ChangePasswordUser:
 #if 0
        /* prepare samr_ChangePasswordUser */
        E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
@@ -303,7 +271,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA
        /* 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);
+       u_info.info26.password_expired = 0;
        
        status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
        if (!NT_STATUS_IS_OK(status)) {
@@ -356,7 +324,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA
        /* prepare samr_SetUserInfo2 level 25 */
        ZERO_STRUCT(u_info);
        u_info.info25.info = *r->samr_handle.in.info21;
-       u_info.info25.info.fields_present |= SAMR_FIELD_PASSWORD;
+       u_info.info25.info.fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
        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);
@@ -406,8 +374,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA
        /* 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 */
-       u_info.info24.pw_len = strlen_m(r->samr_handle.in.newpassword)*2;
+       u_info.info24.password_expired = 0;
 
        status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
        if (!NT_STATUS_IS_OK(status)) {
@@ -448,7 +415,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TA
        /* prepare samr_SetUserInfo2 level 23 */
        ZERO_STRUCT(u_info);
        u_info.info23.info = *r->samr_handle.in.info21;
-       u_info.info23.info.fields_present |= SAMR_FIELD_PASSWORD;
+       u_info.info23.info.fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
        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);
@@ -527,10 +494,12 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        struct samr_Connect sc;
        struct policy_handle p_handle;
        struct samr_LookupDomain ld;
+       struct dom_sid2 *sid = NULL;
        struct lsa_String d_name;
        struct samr_OpenDomain od;
        struct policy_handle d_handle;
        struct samr_LookupNames ln;
+       struct samr_Ids rids, types;
        struct samr_OpenUser ou;
        struct policy_handle u_handle;
        union libnet_SetPassword r2;
@@ -568,6 +537,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        d_name.string = r->samr.in.domain_name;
        ld.in.connect_handle = &p_handle;
        ld.in.domain_name = &d_name;
+       ld.out.sid = &sid;
 
        /* 3. do a samr_LookupDomain to get the domain sid */
        status = dcerpc_samr_LookupDomain(c.out.dcerpc_pipe, mem_ctx, &ld);
@@ -582,7 +552,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        ZERO_STRUCT(d_handle);
        od.in.connect_handle = &p_handle;
        od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       od.in.sid = ld.out.sid;
+       od.in.sid = *ld.out.sid;
        od.out.domain_handle = &d_handle;
 
        /* 4. do a samr_OpenDomain to get a domain handle */
@@ -598,6 +568,8 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        ln.in.domain_handle = &d_handle;
        ln.in.num_names = 1;
        ln.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
+       ln.out.rids = &rids;
+       ln.out.types = &types;
        if (!ln.in.names) {
                r->samr.out.error_string = "Out of Memory";
                return NT_STATUS_NO_MEMORY;
@@ -614,10 +586,10 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        }
 
        /* check if we got one RID for the user */
-       if (ln.out.rids.count != 1) {
+       if (ln.out.rids->count != 1) {
                r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_LookupNames for [%s] returns %d RIDs",
-                                               r->samr.in.account_name, ln.out.rids.count);
+                                               r->samr.in.account_name, ln.out.rids->count);
                status = NT_STATUS_INVALID_PARAMETER;
                goto disconnect;        
        }
@@ -626,7 +598,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        ZERO_STRUCT(u_handle);
        ou.in.domain_handle = &d_handle;
        ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       ou.in.rid = ln.out.rids.ids[0];
+       ou.in.rid = ln.out.rids->ids[0];
        ou.out.user_handle = &u_handle;
 
        /* 6. do a samr_OpenUser to get a user handle */