change the _RPC levels into _SAMR
authormetze <metze@0c0555d6-39d7-0310-84fc-f1cc0bd64818>
Fri, 20 Aug 2004 10:22:22 +0000 (10:22 +0000)
committermetze <metze@0c0555d6-39d7-0310-84fc-f1cc0bd64818>
Fri, 20 Aug 2004 10:22:22 +0000 (10:22 +0000)
because we may have other rpc levels in future

add more comments about what's going on

check the rsult of samr_OpenUser

metze

git-svn-id: svn+ssh://svn.samba.org/data/svn/samba/branches/SAMBA_4_0@1952 0c0555d6-39d7-0310-84fc-f1cc0bd64818

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

index 72c2fecdad3d92f918e4859b71cff96a7f02b4f6..f527a4ed821e8a2e3df0581107a489c2d9b5d544 100644 (file)
@@ -79,7 +79,7 @@ union libnet_rpc_connect {
 /* struct and enum for doing a remote password change */
 enum libnet_ChangePassword_level {
        LIBNET_CHANGE_PASSWORD_GENERIC,
-       LIBNET_CHANGE_PASSWORD_RPC,
+       LIBNET_CHANGE_PASSWORD_SAMR,
        LIBNET_CHANGE_PASSWORD_KRB5,
        LIBNET_CHANGE_PASSWORD_LDAP,
        LIBNET_CHANGE_PASSWORD_RAP
@@ -105,7 +105,7 @@ union libnet_ChangePassword {
                enum libnet_ChangePassword_level level;
                struct _libnet_ChangePassword_in in;
                struct _libnet_ChangePassword_out out;
-       } rpc;
+       } samr;
 
        struct {
                enum libnet_ChangePassword_level level;
@@ -129,7 +129,7 @@ union libnet_ChangePassword {
 /* struct and enum for doing a remote password set */
 enum libnet_SetPassword_level {
        LIBNET_SET_PASSWORD_GENERIC,
-       LIBNET_SET_PASSWORD_RPC,
+       LIBNET_SET_PASSWORD_SAMR,
        LIBNET_SET_PASSWORD_KRB5,
        LIBNET_SET_PASSWORD_LDAP,
        LIBNET_SET_PASSWORD_RAP
@@ -154,7 +154,7 @@ union libnet_SetPassword {
                enum libnet_SetPassword_level level;
                struct _libnet_SetPassword_in in;
                struct _libnet_SetPassword_out out;
-       } rpc;
+       } samr;
 
        struct {
                enum libnet_SetPassword_level level;
index b1ff12fef241d9645bbd41be57d88ecbef89c7b2..98005b9f414bcc0ead95f8f247e6e7e4bf75fcb5 100644 (file)
 /*
  * do a password change using DCERPC/SAMR calls
  * 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation)
- * 2. try samr_ChangePassword3
+ * 2. try samr_ChangePasswordUser3
+ * 3. try samr_ChangePasswordUser2
+ * 4. try samr_OemChangePasswordUser2
+ * (not yet: 5. try samr_ChangePasswordUser)
  */
-static NTSTATUS libnet_ChangePassword_rpc(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_ChangePassword *r)
+static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_ChangePassword *r)
 {
         NTSTATUS status;
        union libnet_rpc_connect c;
@@ -44,37 +47,38 @@ static NTSTATUS libnet_ChangePassword_rpc(struct libnet_context *ctx, TALLOC_CTX
        uint8_t old_nt_hash[16], new_nt_hash[16];
        uint8_t old_lm_hash[16], new_lm_hash[16];
 
-       /* prepare connect to the SAMR pipe of the */
+       /* prepare connect to the SAMR pipe of the users domain PDC */
        c.pdc.level                     = LIBNET_RPC_CONNECT_PDC;
-       c.pdc.in.domain_name            = r->rpc.in.domain_name;
+       c.pdc.in.domain_name            = r->samr.in.domain_name;
        c.pdc.in.dcerpc_iface_name      = DCERPC_SAMR_NAME;
        c.pdc.in.dcerpc_iface_uuid      = DCERPC_SAMR_UUID;
        c.pdc.in.dcerpc_iface_version   = DCERPC_SAMR_VERSION;
 
-       /* do connect to the SAMR pipe of the */
+       /* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */
        status = libnet_rpc_connect(ctx, mem_ctx, &c);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "Connection to SAMR pipe of PDC of domain '%s' failed: %s\n",
-                                               r->rpc.in.domain_name, nt_errstr(status));
+                                               r->samr.in.domain_name, nt_errstr(status));
                return status;
        }
 
        /* prepare password change for account */
        server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(c.pdc.out.dcerpc_pipe));
-       account.name = r->rpc.in.account_name;
+       account.name = r->samr.in.account_name;
 
-       E_md4hash(r->rpc.in.oldpassword, old_nt_hash);
-       E_md4hash(r->rpc.in.newpassword, new_nt_hash);
+       E_md4hash(r->samr.in.oldpassword, old_nt_hash);
+       E_md4hash(r->samr.in.newpassword, new_nt_hash);
 
-       E_deshash(r->rpc.in.oldpassword, old_lm_hash);
-       E_deshash(r->rpc.in.newpassword, new_lm_hash);
+       E_deshash(r->samr.in.oldpassword, old_lm_hash);
+       E_deshash(r->samr.in.newpassword, new_lm_hash);
 
-       encode_pw_buffer(lm_pass.data, r->rpc.in.newpassword, STR_UNICODE);
+       /* prepare samr_ChangePasswordUser3 */
+       encode_pw_buffer(lm_pass.data, r->samr.in.newpassword, STR_UNICODE);
        arcfour_crypt(lm_pass.data, old_nt_hash, 516);
        E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
 
-       encode_pw_buffer(nt_pass.data,  r->rpc.in.newpassword, STR_UNICODE);
+       encode_pw_buffer(nt_pass.data,  r->samr.in.newpassword, STR_UNICODE);
        arcfour_crypt(nt_pass.data, old_nt_hash, 516);
        E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
 
@@ -87,20 +91,20 @@ static NTSTATUS libnet_ChangePassword_rpc(struct libnet_context *ctx, TALLOC_CTX
        pw3.in.lm_verifier = &lm_verifier;
        pw3.in.password3 = NULL;
 
-       /* do password change for account */
+       /* 2. try samr_ChangePasswordUser3 */
        status = dcerpc_samr_ChangePasswordUser3(c.pdc.out.dcerpc_pipe, mem_ctx, &pw3);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_ChangePasswordUser3 failed: %s\n",
                                                nt_errstr(status));
                goto ChangePasswordUser2;
        }
 
-       /* check result of password change */
+       /* check result of samr_ChangePasswordUser3 */
        if (!NT_STATUS_IS_OK(pw3.out.result)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_ChangePasswordUser3 for '%s\\%s' failed: %s\n",
-                                               r->rpc.in.domain_name, r->rpc.in.account_name, 
+                                               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(status, NT_STATUS_PASSWORD_RESTRICTION)) {
@@ -112,12 +116,12 @@ static NTSTATUS libnet_ChangePassword_rpc(struct libnet_context *ctx, TALLOC_CTX
        goto disconnect;
 
 ChangePasswordUser2:
-
-       encode_pw_buffer(lm_pass.data, r->rpc.in.newpassword, STR_ASCII|STR_TERMINATE);
+       /* 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);
        E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
 
-       encode_pw_buffer(nt_pass.data, r->rpc.in.newpassword, STR_UNICODE);
+       encode_pw_buffer(nt_pass.data, r->samr.in.newpassword, STR_UNICODE);
        arcfour_crypt(nt_pass.data, old_nt_hash, 516);
        E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
 
@@ -129,19 +133,20 @@ ChangePasswordUser2:
        pw2.in.lm_password = &lm_pass;
        pw2.in.lm_verifier = &lm_verifier;
 
+       /* 3. try samr_ChangePasswordUser2 */
        status = dcerpc_samr_ChangePasswordUser2(c.pdc.out.dcerpc_pipe, mem_ctx, &pw2);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_ChangePasswordUser2 failed: %s\n",
                                                nt_errstr(status));
                goto OemChangePasswordUser2;
        }
 
-       /* check result of password change */
+       /* check result of samr_ChangePasswordUser2 */
        if (!NT_STATUS_IS_OK(pw2.out.result)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_ChangePasswordUser2 for '%s\\%s' failed: %s\n",
-                                               r->rpc.in.domain_name, r->rpc.in.account_name, 
+                                               r->samr.in.domain_name, r->samr.in.account_name, 
                                                nt_errstr(pw2.out.result));
                goto OemChangePasswordUser2;
        }
@@ -149,11 +154,11 @@ ChangePasswordUser2:
        goto disconnect;
 
 OemChangePasswordUser2:
-
+       /* prepare samr_OemChangePasswordUser2 */
        a_server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(c.pdc.out.dcerpc_pipe));
-       a_account.name = r->rpc.in.account_name;
+       a_account.name = r->samr.in.account_name;
 
-       encode_pw_buffer(lm_pass.data, r->rpc.in.newpassword, STR_ASCII);
+       encode_pw_buffer(lm_pass.data, r->samr.in.newpassword, STR_ASCII);
        arcfour_crypt(lm_pass.data, old_lm_hash, 516);
        E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
 
@@ -162,19 +167,20 @@ OemChangePasswordUser2:
        oe2.in.password = &lm_pass;
        oe2.in.hash = &lm_verifier;
 
+       /* 4. try samr_OemChangePasswordUser2 */
        status = dcerpc_samr_OemChangePasswordUser2(c.pdc.out.dcerpc_pipe, mem_ctx, &oe2);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_OemChangePasswordUser2 failed: %s\n",
                                                nt_errstr(status));
                goto ChangePasswordUser;
        }
 
-       /* check result of password change */
+       /* check result of samr_OemChangePasswordUser2 */
        if (!NT_STATUS_IS_OK(oe2.out.result)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_OemChangePasswordUser2 for '%s\\%s' failed: %s\n",
-                                               r->rpc.in.domain_name, r->rpc.in.account_name, 
+                                               r->samr.in.domain_name, r->samr.in.account_name, 
                                                nt_errstr(oe2.out.result));
                goto ChangePasswordUser;
        }
@@ -183,6 +189,7 @@ OemChangePasswordUser2:
 
 ChangePasswordUser:
 #if 0
+       /* prepare samr_ChangePasswordUser */
        E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
        E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
        E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
@@ -203,19 +210,20 @@ ChangePasswordUser:
        pw.in.cross2_present = 1;
        pw.in.lm_cross = &hash6;
 
+       /* 5. try samr_ChangePasswordUser */
        status = dcerpc_samr_ChangePasswordUser(c.pdc.out.dcerpc_pipe, mem_ctx, &pw);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_ChangePasswordUser failed: %s\n",
                                                nt_errstr(status));
                goto disconnect;
        }
 
-       /* check result of password change */
+       /* check result of samr_ChangePasswordUser */
        if (!NT_STATUS_IS_OK(pw.out.result)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_ChangePasswordUser for '%s\\%s' failed: %s\n",
-                                               r->rpc.in.domain_name, r->rpc.in.account_name, 
+                                               r->samr.in.domain_name, r->samr.in.account_name, 
                                                nt_errstr(pw.out.result));
                goto disconnect;
        }
@@ -232,15 +240,15 @@ static NTSTATUS libnet_ChangePassword_generic(struct libnet_context *ctx, TALLOC
        NTSTATUS status;
        union libnet_ChangePassword r2;
 
-       r2.rpc.level            = LIBNET_CHANGE_PASSWORD_RPC;
-       r2.rpc.in.account_name  = r->generic.in.account_name;
-       r2.rpc.in.domain_name   = r->generic.in.domain_name;
-       r2.rpc.in.oldpassword   = r->generic.in.oldpassword;
-       r2.rpc.in.newpassword   = r->generic.in.newpassword;
+       r2.samr.level           = LIBNET_CHANGE_PASSWORD_SAMR;
+       r2.samr.in.account_name = r->generic.in.account_name;
+       r2.samr.in.domain_name  = r->generic.in.domain_name;
+       r2.samr.in.oldpassword  = r->generic.in.oldpassword;
+       r2.samr.in.newpassword  = r->generic.in.newpassword;
 
        status = libnet_ChangePassword(ctx, mem_ctx, &r2);
 
-       r->generic.out.error_string = r2.rpc.out.error_string;
+       r->generic.out.error_string = r2.samr.out.error_string;
 
        return status;
 }
@@ -250,8 +258,8 @@ NTSTATUS libnet_ChangePassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
        switch (r->generic.level) {
                case LIBNET_CHANGE_PASSWORD_GENERIC:
                        return libnet_ChangePassword_generic(ctx, mem_ctx, r);
-               case LIBNET_CHANGE_PASSWORD_RPC:
-                       return libnet_ChangePassword_rpc(ctx, mem_ctx, r);
+               case LIBNET_CHANGE_PASSWORD_SAMR:
+                       return libnet_ChangePassword_samr(ctx, mem_ctx, r);
                case LIBNET_CHANGE_PASSWORD_KRB5:
                        return NT_STATUS_NOT_IMPLEMENTED;
                case LIBNET_CHANGE_PASSWORD_LDAP:
@@ -265,10 +273,16 @@ NTSTATUS libnet_ChangePassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
 
 /*
  * set a password with DCERPC/SAMR calls
- *
- * is it correct to contact the the pdc of the domain of the user who's password should be set?
+ * 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation)
+ *    is it correct to contact the the pdc of the domain of the user who's password should be set?
+ * 2. do a samr_Connect to get a policy handle
+ * 3. do a samr_LookupDomain to get the domain sid
+ * 4. do a samr_OpenDomain to get a domain handle
+ * 5. do a samr_LookupNames to get the users rid
+ * 6. do a samr_OpenUser to get a user handle
+ * 7. try samr_SetUserInfo level 26 to set the password
  */
-static NTSTATUS libnet_SetPassword_rpc(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
+static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
 {
        NTSTATUS status;
        union libnet_rpc_connect c;
@@ -288,138 +302,157 @@ static NTSTATUS libnet_SetPassword_rpc(struct libnet_context *ctx, TALLOC_CTX *m
        uint8_t confounder[16]; 
        struct MD5Context md5;
 
-       /* prepare connect to the SAMR pipe of the */
+       /* prepare connect to the SAMR pipe of users domain PDC */
        c.pdc.level                     = LIBNET_RPC_CONNECT_PDC;
-       c.pdc.in.domain_name            = r->rpc.in.domain_name;
+       c.pdc.in.domain_name            = r->samr.in.domain_name;
        c.pdc.in.dcerpc_iface_name      = DCERPC_SAMR_NAME;
        c.pdc.in.dcerpc_iface_uuid      = DCERPC_SAMR_UUID;
        c.pdc.in.dcerpc_iface_version   = DCERPC_SAMR_VERSION;
 
-       /* do connect to the SAMR pipe of the */
+       /* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */
        status = libnet_rpc_connect(ctx, mem_ctx, &c);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "Connection to SAMR pipe of PDC of domain '%s' failed: %s\n",
-                                               r->rpc.in.domain_name, nt_errstr(status));
+                                               r->samr.in.domain_name, nt_errstr(status));
                return status;
        }
 
-       /* do a samr_Connect to get a policy handle */
+       /* prepare samr_Connect */
        ZERO_STRUCT(p_handle);
        sc.in.system_name = 0;
        sc.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
        sc.out.handle = &p_handle;
 
+       /* 2. do a samr_Connect to get a policy handle */
        status = dcerpc_samr_Connect(c.pdc.out.dcerpc_pipe, mem_ctx, &sc);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_Connect failed: %s\n",
                                                nt_errstr(status));
                goto disconnect;
        }
 
-       /* check result of samr_connect */
+       /* check result of samr_Connect */
        if (!NT_STATUS_IS_OK(sc.out.result)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_Connect failed: %s\n", 
                                                nt_errstr(sc.out.result));
                goto disconnect;
        }
 
-       /* do a samr_LookupDomain */
-       d_name.name = r->rpc.in.domain_name;
+       /* prepare samr_LookupDomain */
+       d_name.name = r->samr.in.domain_name;
        ld.in.handle = &p_handle;
        ld.in.domain = &d_name;
 
+       /* 3. do a samr_LookupDomain to get the domain sid */
        status = dcerpc_samr_LookupDomain(c.pdc.out.dcerpc_pipe, mem_ctx, &ld);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_LookupDomain for [%s] failed: %s\n",
-                                               r->rpc.in.domain_name, nt_errstr(status));
+                                               r->samr.in.domain_name, nt_errstr(status));
                goto disconnect;
        }
 
        /* check result of samr_LookupDomain */
        if (!NT_STATUS_IS_OK(ld.out.result)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_LookupDomain for [%s] failed: %s\n",
-                                               r->rpc.in.domain_name, nt_errstr(ld.out.result));
+                                               r->samr.in.domain_name, nt_errstr(ld.out.result));
                goto disconnect;
        }
 
-       /* do a samr_OpenDomain to get a domain handle */
+       /* prepare samr_OpenDomain */
        ZERO_STRUCT(d_handle);
        od.in.handle = &p_handle;
        od.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
        od.in.sid = ld.out.sid;
        od.out.domain_handle = &d_handle;
 
+       /* 4. do a samr_OpenDomain to get a domain handle */
        status = dcerpc_samr_OpenDomain(c.pdc.out.dcerpc_pipe, mem_ctx, &od);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_OpenDomain for [%s] failed: %s\n",
-                                               r->rpc.in.domain_name, nt_errstr(status));
+                                               r->samr.in.domain_name, nt_errstr(status));
                goto disconnect;
        }
 
-       /* check result of samr_LookupDomain */
+       /* check result of samr_OpenDomain */
        if (!NT_STATUS_IS_OK(od.out.result)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_OpenDomain for [%s] failed: %s\n",
-                                               r->rpc.in.domain_name, nt_errstr(od.out.result));
+                                               r->samr.in.domain_name, nt_errstr(od.out.result));
                goto disconnect;
        }
 
-       /* do a samr_LookupNames for the account_name to get the RID */
+       /* prepare samr_LookupNames */
        ln.in.handle = &d_handle;
        ln.in.num_names = 1;
        ln.in.names = talloc_array_p(mem_ctx, struct samr_Name, 1);
        if (!ln.in.names) {
-               r->rpc.out.error_string = "Out of Memory";
+               r->samr.out.error_string = "Out of Memory";
                return NT_STATUS_NO_MEMORY;
        }
-       ln.in.names[0].name = r->rpc.in.account_name;
+       ln.in.names[0].name = r->samr.in.account_name;
 
+       /* 5. do a samr_LookupNames to get the users rid */
        status = dcerpc_samr_LookupNames(c.pdc.out.dcerpc_pipe, mem_ctx, &ln);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_LookupNames for [%s] failed: %s\n",
-                                               r->rpc.in.account_name, nt_errstr(status));
+                                               r->samr.in.account_name, nt_errstr(status));
                goto disconnect;
        }
 
-       /* check result of samr_LookupDomain */
+       /* check result of samr_LookupNames */
        if (!NT_STATUS_IS_OK(ln.out.result)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_LookupNames for [%s] failed: %s\n",
-                                               r->rpc.in.account_name, nt_errstr(ln.out.result));
+                                               r->samr.in.account_name, nt_errstr(ln.out.result));
                goto disconnect;
        }
 
        /* check if we got one RID for the user */
        if (ln.out.rids.count != 1) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_LookupNames for [%s] returns %d RIDs\n",
-                                               r->rpc.in.account_name, ln.out.rids.count);
+                                               r->samr.in.account_name, ln.out.rids.count);
                goto disconnect;        
        }
 
-       /* do samr_OpenUser to get the user handle */
+       /* prepare samr_OpenUser */
        ZERO_STRUCT(u_handle);
        ou.in.handle = &d_handle;
        ou.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
        ou.in.rid = ln.out.rids.ids[0];
        ou.out.acct_handle = &u_handle;
 
+       /* 6. do a samr_OpenUser to get a user handle */
        status = dcerpc_samr_OpenUser(c.pdc.out.dcerpc_pipe, mem_ctx, &ou);
+       if (!NT_STATUS_IS_OK(status)) {
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
+                                               "samr_OpenUser for [%s] failed: %s\n",
+                                               r->samr.in.account_name, nt_errstr(status));
+               goto disconnect;
+       }
+
+       /* check result of samr_OpenUser */
+       if (!NT_STATUS_IS_OK(ou.out.result)) {
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
+                                               "samr_OpenUser for [%s] failed: %s\n",
+                                               r->samr.in.account_name, nt_errstr(ou.out.result));
+               goto disconnect;
+       }
 
-       /* prepare password set with samr_UserInfo26 */
-       encode_pw_buffer(u_info.info26.password.data, r->rpc.in.newpassword, STR_UNICODE);
-       u_info.info26.pw_len = strlen(r->rpc.in.newpassword);
+       /* prepare samr_SetUserInfo level 26 */
+       encode_pw_buffer(u_info.info26.password.data, r->samr.in.newpassword, STR_UNICODE);
+       u_info.info26.pw_len = strlen(r->samr.in.newpassword);
 
        status = dcerpc_fetch_session_key(c.pdc.out.dcerpc_pipe, &session_key);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "dcerpc_fetch_session_key failed: %s\n",
                                                nt_errstr(status));
                goto disconnect;
@@ -439,19 +472,20 @@ static NTSTATUS libnet_SetPassword_rpc(struct libnet_context *ctx, TALLOC_CTX *m
        sui.in.info = &u_info;
        sui.in.level = 26;
 
+       /* 7. try samr_SetUserInfo level 26 to set the password */
        status = dcerpc_samr_SetUserInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &sui);
        if (!NT_STATUS_IS_OK(status)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "SetUserInfo level 26 for [%s] failed: %s\n",
-                                               r->rpc.in.account_name, nt_errstr(status));
+                                               r->samr.in.account_name, nt_errstr(status));
                goto UserInfo25;
        }
 
-       /* check result of samr_LookupDomain */
+       /* check result of samr_SetUserInfo level 26 */
        if (!NT_STATUS_IS_OK(sui.out.result)) {
-               r->rpc.out.error_string = talloc_asprintf(mem_ctx,
+               r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "SetUserInfo level 26 for [%s] failed: %s\n",
-                                               r->rpc.in.account_name, nt_errstr(sui.out.result));
+                                               r->samr.in.account_name, nt_errstr(sui.out.result));
                goto UserInfo25;
        }
 
@@ -469,14 +503,14 @@ static NTSTATUS libnet_SetPassword_generic(struct libnet_context *ctx, TALLOC_CT
        NTSTATUS status;
        union libnet_SetPassword r2;
 
-       r2.rpc.level            = LIBNET_SET_PASSWORD_RPC;
-       r2.rpc.in.account_name  = r->generic.in.account_name;
-       r2.rpc.in.domain_name   = r->generic.in.domain_name;
-       r2.rpc.in.newpassword   = r->generic.in.newpassword;
+       r2.samr.level           = LIBNET_SET_PASSWORD_SAMR;
+       r2.samr.in.account_name = r->generic.in.account_name;
+       r2.samr.in.domain_name  = r->generic.in.domain_name;
+       r2.samr.in.newpassword  = r->generic.in.newpassword;
 
        status = libnet_SetPassword(ctx, mem_ctx, &r2);
 
-       r->generic.out.error_string = r2.rpc.out.error_string;
+       r->generic.out.error_string = r2.samr.out.error_string;
 
        return status;
 }
@@ -486,8 +520,8 @@ NTSTATUS libnet_SetPassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, uni
        switch (r->generic.level) {
                case LIBNET_SET_PASSWORD_GENERIC:
                        return libnet_SetPassword_generic(ctx, mem_ctx, r);
-               case LIBNET_SET_PASSWORD_RPC:
-                       return libnet_SetPassword_rpc(ctx, mem_ctx, r);
+               case LIBNET_SET_PASSWORD_SAMR:
+                       return libnet_SetPassword_samr(ctx, mem_ctx, r);
                case LIBNET_SET_PASSWORD_KRB5:
                        return NT_STATUS_NOT_IMPLEMENTED;
                case LIBNET_SET_PASSWORD_LDAP: