s4:torture: Migrate smbtorture to new cmdline option parser
[samba.git] / source4 / torture / rpc / testjoin.c
index 725799f2ddf76f8a93fe78fe732fc64554611e10..0a3c96f55ea8382b1ca87eb6da614c8d32a03ffd 100644 (file)
 */
 
 #include "includes.h"
-#include "torture/torture.h"
 #include "system/time.h"
-#include "lib/crypto/crypto.h"
 #include "libnet/libnet.h"
-#include "lib/cmdline/popt_common.h"
-#include "lib/ldb/include/ldb.h"
+#include "lib/cmdline/cmdline.h"
+#include "librpc/gen_ndr/ndr_lsa_c.h"
 #include "librpc/gen_ndr/ndr_samr_c.h"
 
 #include "libcli/auth/libcli_auth.h"
-#include "torture/rpc/rpc.h"
+#include "torture/rpc/torture_rpc.h"
 #include "libcli/security/security.h"
 #include "param/param.h"
+#include "source3/rpc_client/init_samr.h"
 
 struct test_join {
        struct dcerpc_pipe *p;
        struct policy_handle user_handle;
+       struct policy_handle domain_handle;
        struct libnet_JoinDomain *libnet_r;
        struct dom_sid *dom_sid;
        const char *dom_netbios_name;
@@ -51,7 +51,9 @@ struct test_join {
 };
 
 
-static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+static NTSTATUS DeleteUser_byname(struct torture_context *tctx,
+                                 struct dcerpc_binding_handle *b,
+                                 TALLOC_CTX *mem_ctx,
                                  struct policy_handle *handle, const char *name)
 {
        NTSTATUS status;
@@ -59,6 +61,7 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        struct policy_handle user_handle;
        uint32_t rid;
        struct samr_LookupNames n;
+       struct samr_Ids rids, types;
        struct lsa_String sname;
        struct samr_OpenUser r;
 
@@ -67,31 +70,43 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        n.in.domain_handle = handle;
        n.in.num_names = 1;
        n.in.names = &sname;
+       n.out.rids = &rids;
+       n.out.types = &types;
 
-       status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
-       if (NT_STATUS_IS_OK(status)) {
-               rid = n.out.rids.ids[0];
-       } else {
+       status = dcerpc_samr_LookupNames_r(b, mem_ctx, &n);
+       if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
+       if (NT_STATUS_IS_OK(n.out.result)) {
+               rid = n.out.rids->ids[0];
+       } else {
+               return n.out.result;
+       }
 
        r.in.domain_handle = handle;
        r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        r.in.rid = rid;
        r.out.user_handle = &user_handle;
 
-       status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
+       status = dcerpc_samr_OpenUser_r(b, mem_ctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("OpenUser(%s) failed - %s\n", name, nt_errstr(status));
+               torture_comment(tctx, "OpenUser(%s) failed - %s\n", name, nt_errstr(status));
                return status;
        }
+       if (!NT_STATUS_IS_OK(r.out.result)) {
+               torture_comment(tctx, "OpenUser(%s) failed - %s\n", name, nt_errstr(r.out.result));
+               return r.out.result;
+       }
 
        d.in.user_handle = &user_handle;
        d.out.user_handle = &user_handle;
-       status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
+       status = dcerpc_samr_DeleteUser_r(b, mem_ctx, &d);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
+       if (!NT_STATUS_IS_OK(d.out.result)) {
+               return d.out.result;
+       }
 
        return NT_STATUS_OK;
 }
@@ -102,22 +117,24 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
   when finished
 */
 
-struct test_join *torture_create_testuser(struct torture_context *torture,
-                                         const char *username, 
-                                         const char *domain,
-                                         uint16_t acct_type,
-                                         const char **random_password)
+struct test_join *torture_create_testuser_max_pwlen(struct torture_context *tctx,
+                                                   const char *username,
+                                                   const char *domain,
+                                                   uint16_t acct_type,
+                                                   const char **random_password,
+                                                   int max_pw_len)
 {
        NTSTATUS status;
        struct samr_Connect c;
        struct samr_CreateUser2 r;
        struct samr_OpenDomain o;
        struct samr_LookupDomain l;
+       struct dom_sid2 *sid = NULL;
        struct samr_GetUserPwInfo pwp;
+       struct samr_PwInfo info;
        struct samr_SetUserInfo s;
        union samr_UserInfo u;
        struct policy_handle handle;
-       struct policy_handle domain_handle;
        uint32_t access_granted;
        uint32_t rid;
        DATA_BLOB session_key;
@@ -126,8 +143,8 @@ struct test_join *torture_create_testuser(struct torture_context *torture,
        int policy_min_pw_len = 0;
        struct test_join *join;
        char *random_pw;
-       const char *dc_binding = lp_parm_string(global_loadparm, NULL, "torture", "dc_binding");
-
+       const char *dc_binding = torture_setting_string(tctx, "dc_binding", NULL);
+       struct dcerpc_binding_handle *b = NULL;
        join = talloc(NULL, struct test_join);
        if (join == NULL) {
                return NULL;
@@ -135,71 +152,139 @@ struct test_join *torture_create_testuser(struct torture_context *torture,
 
        ZERO_STRUCTP(join);
 
-       printf("Connecting to SAMR\n");
+       torture_comment(tctx, "Connecting to SAMR\n");
        
        if (dc_binding) {
                status = dcerpc_pipe_connect(join,
                                             &join->p,
                                             dc_binding,
                                             &ndr_table_samr,
-                                            cmdline_credentials, NULL);
+                                            samba_cmdline_get_creds(),
+                                       NULL, tctx->lp_ctx);
                                             
        } else {
-               status = torture_rpc_connection(torture, 
+               status = torture_rpc_connection(tctx,
                                                &join->p, 
                                                &ndr_table_samr);
        }
        if (!NT_STATUS_IS_OK(status)) {
                return NULL;
        }
+       b = join->p->binding_handle;
 
        c.in.system_name = NULL;
        c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        c.out.connect_handle = &handle;
 
-       status = dcerpc_samr_Connect(join->p, join, &c);
+       status = dcerpc_samr_Connect_r(b, join, &c);
        if (!NT_STATUS_IS_OK(status)) {
                const char *errstr = nt_errstr(status);
-               if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
-                       errstr = dcerpc_errstr(join, join->p->last_fault_code);
-               }
-               printf("samr_Connect failed - %s\n", errstr);
+               torture_comment(tctx, "samr_Connect failed - %s\n", errstr);
+               return NULL;
+       }
+       if (!NT_STATUS_IS_OK(c.out.result)) {
+               const char *errstr = nt_errstr(c.out.result);
+               torture_comment(tctx, "samr_Connect failed - %s\n", errstr);
                return NULL;
        }
 
-       printf("Opening domain %s\n", domain);
+       if (domain) {
+               torture_comment(tctx, "Opening domain %s\n", domain);
 
-       name.string = domain;
-       l.in.connect_handle = &handle;
-       l.in.domain_name = &name;
+               name.string = domain;
+               l.in.connect_handle = &handle;
+               l.in.domain_name = &name;
+               l.out.sid = &sid;
 
-       status = dcerpc_samr_LookupDomain(join->p, join, &l);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("LookupDomain failed - %s\n", nt_errstr(status));
-               goto failed;
+               status = dcerpc_samr_LookupDomain_r(b, join, &l);
+               if (!NT_STATUS_IS_OK(status)) {
+                       torture_comment(tctx, "LookupDomain failed - %s\n", nt_errstr(status));
+                       goto failed;
+               }
+               if (!NT_STATUS_IS_OK(l.out.result)) {
+                       torture_comment(tctx, "LookupDomain failed - %s\n", nt_errstr(l.out.result));
+                       goto failed;
+               }
+       } else {
+               struct samr_EnumDomains e;
+               uint32_t resume_handle = 0, num_entries;
+               struct samr_SamArray *sam;
+               int i;
+
+               e.in.connect_handle = &handle;
+               e.in.buf_size = (uint32_t)-1;
+               e.in.resume_handle = &resume_handle;
+               e.out.sam = &sam;
+               e.out.num_entries = &num_entries;
+               e.out.resume_handle = &resume_handle;
+
+               status = dcerpc_samr_EnumDomains_r(b, join, &e);
+               if (!NT_STATUS_IS_OK(status)) {
+                       torture_comment(tctx, "EnumDomains failed - %s\n", nt_errstr(status));
+                       goto failed;
+               }
+               if (!NT_STATUS_IS_OK(e.out.result)) {
+                       torture_comment(tctx, "EnumDomains failed - %s\n", nt_errstr(e.out.result));
+                       goto failed;
+               }
+               if ((num_entries != 2) || (sam && sam->count != 2)) {
+                       torture_comment(tctx, "unexpected number of domains\n");
+                       goto failed;
+               }
+               for (i=0; i < 2; i++) {
+                       if (!strequal(sam->entries[i].name.string, "builtin")) {
+                               domain = sam->entries[i].name.string;
+                               break;
+                       }
+               }
+               if (domain) {
+                       torture_comment(tctx, "Opening domain %s\n", domain);
+
+                       name.string = domain;
+                       l.in.connect_handle = &handle;
+                       l.in.domain_name = &name;
+                       l.out.sid = &sid;
+
+                       status = dcerpc_samr_LookupDomain_r(b, join, &l);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               torture_comment(tctx, "LookupDomain failed - %s\n", nt_errstr(status));
+                               goto failed;
+                       }
+                       if (!NT_STATUS_IS_OK(l.out.result)) {
+                               torture_comment(tctx, "LookupDomain failed - %s\n", nt_errstr(l.out.result));
+                               goto failed;
+                       }
+               } else {
+                       torture_comment(tctx, "cannot proceed without domain name\n");
+                       goto failed;
+               }
        }
 
-       talloc_steal(join, l.out.sid);
-       join->dom_sid = l.out.sid;
+       talloc_steal(join, *l.out.sid);
+       join->dom_sid = *l.out.sid;
        join->dom_netbios_name = talloc_strdup(join, domain);
        if (!join->dom_netbios_name) goto failed;
 
        o.in.connect_handle = &handle;
        o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       o.in.sid = l.out.sid;
-       o.out.domain_handle = &domain_handle;
+       o.in.sid = *l.out.sid;
+       o.out.domain_handle = &join->domain_handle;
 
-       status = dcerpc_samr_OpenDomain(join->p, join, &o);
+       status = dcerpc_samr_OpenDomain_r(b, join, &o);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("OpenDomain failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "OpenDomain failed - %s\n", nt_errstr(status));
+               goto failed;
+       }
+       if (!NT_STATUS_IS_OK(o.out.result)) {
+               torture_comment(tctx, "OpenDomain failed - %s\n", nt_errstr(o.out.result));
                goto failed;
        }
 
-       printf("Creating account %s\n", username);
+       torture_comment(tctx, "Creating account %s\n", username);
 
 again:
        name.string = username;
-       r.in.domain_handle = &domain_handle;
+       r.in.domain_handle = &join->domain_handle;
        r.in.account_name = &name;
        r.in.acct_flags = acct_type;
        r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -207,54 +292,67 @@ again:
        r.out.access_granted = &access_granted;
        r.out.rid = &rid;
 
-       status = dcerpc_samr_CreateUser2(join->p, join, &r);
+       status = dcerpc_samr_CreateUser2_r(b, join, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               torture_comment(tctx, "CreateUser2 failed - %s\n", nt_errstr(status));
+               goto failed;
+       }
 
-       if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
-               status = DeleteUser_byname(join->p, join, &domain_handle, name.string);
+       if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
+               status = DeleteUser_byname(tctx, b, join, &join->domain_handle, name.string);
                if (NT_STATUS_IS_OK(status)) {
                        goto again;
                }
        }
 
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("CreateUser2 failed - %s\n", nt_errstr(status));
+       if (!NT_STATUS_IS_OK(r.out.result)) {
+               torture_comment(tctx, "CreateUser2 failed - %s\n", nt_errstr(r.out.result));
                goto failed;
        }
 
        join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid);
 
        pwp.in.user_handle = &join->user_handle;
+       pwp.out.info = &info;
 
-       status = dcerpc_samr_GetUserPwInfo(join->p, join, &pwp);
-       if (NT_STATUS_IS_OK(status)) {
-               policy_min_pw_len = pwp.out.info.min_password_length;
+       status = dcerpc_samr_GetUserPwInfo_r(b, join, &pwp);
+       if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(pwp.out.result)) {
+               policy_min_pw_len = pwp.out.info->min_password_length;
        }
 
-       random_pw = generate_random_str(join, MAX(8, policy_min_pw_len));
+       random_pw = generate_random_password(join, MAX(8, policy_min_pw_len), max_pw_len);
 
-       printf("Setting account password '%s'\n", random_pw);
+       torture_comment(tctx, "Setting account password '%s'\n", random_pw);
 
        ZERO_STRUCT(u);
        s.in.user_handle = &join->user_handle;
        s.in.info = &u;
        s.in.level = 24;
 
-       encode_pw_buffer(u.info24.password.data, random_pw, STR_UNICODE);
-       u.info24.pw_len = strlen(random_pw);
+       u.info24.password_expired = 0;
 
        status = dcerpc_fetch_session_key(join->p, &session_key);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("SetUserInfo level %u - no session key - %s\n",
+               torture_comment(tctx, "SetUserInfo level %u - no session key - %s\n",
                       s.in.level, nt_errstr(status));
-               torture_leave_domain(join);
+               torture_leave_domain(tctx, join);
                goto failed;
        }
 
-       arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
+       status = init_samr_CryptPassword(random_pw,
+                                        &session_key,
+                                        &u.info24.password);
+       torture_assert_ntstatus_ok(tctx,
+                                  status,
+                                  "init_samr_CryptPassword failed");
 
-       status = dcerpc_samr_SetUserInfo(join->p, join, &s);
+       status = dcerpc_samr_SetUserInfo_r(b, join, &s);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("SetUserInfo failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "SetUserInfo failed - %s\n", nt_errstr(status));
+               goto failed;
+       }
+       if (!NT_STATUS_IS_OK(s.out.result)) {
+               torture_comment(tctx, "SetUserInfo failed - %s\n", nt_errstr(s.out.result));
                goto failed;
        }
 
@@ -276,14 +374,18 @@ again:
        
        u.info21.description.string = talloc_asprintf(join, 
                                         "Samba4 torture account created by host %s: %s", 
-                                        lp_netbios_name(global_loadparm), 
+                                        lpcfg_netbios_name(tctx->lp_ctx),
                                         timestring(join, time(NULL)));
 
-       printf("Resetting ACB flags, force pw change time\n");
+       torture_comment(tctx, "Resetting ACB flags, force pw change time\n");
 
-       status = dcerpc_samr_SetUserInfo(join->p, join, &s);
+       status = dcerpc_samr_SetUserInfo_r(b, join, &s);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("SetUserInfo failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "SetUserInfo failed - %s\n", nt_errstr(status));
+               goto failed;
+       }
+       if (!NT_STATUS_IS_OK(s.out.result)) {
+               torture_comment(tctx, "SetUserInfo failed - %s\n", nt_errstr(s.out.result));
                goto failed;
        }
 
@@ -294,12 +396,110 @@ again:
        return join;
 
 failed:
-       torture_leave_domain(join);
+       torture_leave_domain(tctx, join);
        return NULL;
 }
 
+/*
+ * Set privileges on an account.
+ */
+
+static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
+{
+       name->string = s;
+}
+static void init_lsa_String(struct lsa_String *name, const char *s)
+{
+       name->string = s;
+}
+
+bool torture_setup_privs(struct torture_context *tctx,
+                       struct dcerpc_pipe *p,
+                       uint32_t num_privs,
+                       const char **privs,
+                       const struct dom_sid *user_sid)
+{
+       struct dcerpc_binding_handle *b = p->binding_handle;
+       struct policy_handle *handle;
+       int i;
+
+       torture_assert(tctx,
+               test_lsa_OpenPolicy2(b, tctx, &handle),
+               "failed to open policy");
+
+       for (i=0; i < num_privs; i++) {
+               struct lsa_LookupPrivValue r;
+               struct lsa_LUID luid;
+               struct lsa_String name;
+
+               init_lsa_String(&name, privs[i]);
+
+               r.in.handle = handle;
+               r.in.name = &name;
+               r.out.luid = &luid;
+
+               torture_assert_ntstatus_ok(tctx,
+                       dcerpc_lsa_LookupPrivValue_r(b, tctx, &r),
+                       "lsa_LookupPrivValue failed");
+               if (!NT_STATUS_IS_OK(r.out.result)) {
+                       torture_comment(tctx, "lsa_LookupPrivValue failed for '%s' with %s\n",
+                               privs[i], nt_errstr(r.out.result));
+                       return false;
+               }
+       }
+
+       {
+               struct lsa_AddAccountRights r;
+               struct lsa_RightSet rights;
+
+               rights.count = num_privs;
+               rights.names = talloc_zero_array(tctx, struct lsa_StringLarge, rights.count);
+               for (i=0; i < rights.count; i++) {
+                       init_lsa_StringLarge(&rights.names[i], privs[i]);
+               }
+
+               r.in.handle = handle;
+               r.in.sid = discard_const_p(struct dom_sid, user_sid);
+               r.in.rights = &rights;
+
+               torture_assert_ntstatus_ok(tctx,
+                       dcerpc_lsa_AddAccountRights_r(b, tctx, &r),
+                       "lsa_AddAccountRights failed");
+               torture_assert_ntstatus_ok(tctx, r.out.result,
+                       "lsa_AddAccountRights failed");
+       }
+
+       test_lsa_Close(b, tctx, handle);
+
+       return true;
+}
+
+struct test_join *torture_create_testuser(struct torture_context *torture,
+                                         const char *username,
+                                         const char *domain,
+                                         uint16_t acct_type,
+                                         const char **random_password)
+{
+       return torture_create_testuser_max_pwlen(torture, username, domain, acct_type, random_password, 255);
+}
+
+NTSTATUS torture_delete_testuser(struct torture_context *torture,
+                                struct test_join *join,
+                                const char *username)
+{
+       NTSTATUS status;
+
+       status = DeleteUser_byname(torture,
+                                  join->p->binding_handle,
+                                  torture,
+                                  &join->domain_handle,
+                                  username);
 
-_PUBLIC_ struct test_join *torture_join_domain(const char *machine_name, 
+       return status;
+}
+
+_PUBLIC_ struct test_join *torture_join_domain(struct torture_context *tctx,
+                                              const char *machine_name, 
                                      uint32_t acct_flags,
                                      struct cli_credentials **machine_credentials)
 {
@@ -309,17 +509,43 @@ _PUBLIC_ struct test_join *torture_join_domain(const char *machine_name,
        struct test_join *tj;
        struct samr_SetUserInfo s;
        union samr_UserInfo u;
-       
-       tj = talloc(NULL, struct test_join);
+       const char *binding_str = NULL;
+       struct dcerpc_binding *binding = NULL;
+       enum dcerpc_transport_t transport;
+
+       tj = talloc_zero(tctx, struct test_join);
        if (!tj) return NULL;
 
-       libnet_r = talloc(tj, struct libnet_JoinDomain);
+       binding_str = torture_setting_string(tctx, "binding", NULL);
+       if (binding_str == NULL) {
+               const char *host = torture_setting_string(tctx, "host", NULL);
+               binding_str = talloc_asprintf(tj, "ncacn_np:%s", host);
+       }
+       status = dcerpc_parse_binding(tj, binding_str, &binding);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("dcerpc_parse_binding(%s) failed - %s\n",
+                         binding_str, nt_errstr(status)));
+               talloc_free(tj);
+               return NULL;
+       }
+       transport = dcerpc_binding_get_transport(binding);
+       switch (transport) {
+       case NCALRPC:
+       case NCACN_UNIX_STREAM:
+               break;
+       default:
+               dcerpc_binding_set_transport(binding, NCACN_NP);
+               dcerpc_binding_set_flags(binding, 0, DCERPC_AUTH_OPTIONS);
+               break;
+       }
+
+       libnet_r = talloc_zero(tj, struct libnet_JoinDomain);
        if (!libnet_r) {
                talloc_free(tj);
                return NULL;
        }
        
-       libnet_ctx = libnet_context_init(NULL); 
+       libnet_ctx = libnet_context_init(tctx->ev, tctx->lp_ctx);
        if (!libnet_ctx) {
                talloc_free(tj);
                return NULL;
@@ -327,10 +553,11 @@ _PUBLIC_ struct test_join *torture_join_domain(const char *machine_name,
        
        tj->libnet_r = libnet_r;
                
-       libnet_ctx->cred = cmdline_credentials;
-       libnet_r->in.binding = lp_parm_string(global_loadparm, NULL, "torture", "binding");
-       if (!libnet_r->in.binding) {
-               libnet_r->in.binding = talloc_asprintf(libnet_r, "ncacn_np:%s", lp_parm_string(global_loadparm, NULL, "torture", "host"));
+       libnet_ctx->cred = samba_cmdline_get_creds();
+       libnet_r->in.binding = dcerpc_binding_string(libnet_r, binding);
+       if (libnet_r->in.binding == NULL) {
+               talloc_free(tj);
+               return NULL;
        }
        libnet_r->in.level = LIBNET_JOINDOMAIN_SPECIFIED;
        libnet_r->in.netbios_name = machine_name;
@@ -383,15 +610,18 @@ _PUBLIC_ struct test_join *torture_join_domain(const char *machine_name,
        
        u.info21.description.string = talloc_asprintf(tj, 
                                                      "Samba4 torture account created by host %s: %s", 
-                                                     lp_netbios_name(global_loadparm), timestring(tj, time(NULL)));
+                                                     lpcfg_netbios_name(tctx->lp_ctx), timestring(tj, time(NULL)));
 
-       status = dcerpc_samr_SetUserInfo(tj->p, tj, &s);
+       status = dcerpc_samr_SetUserInfo_r(tj->p->binding_handle, tj, &s);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("SetUserInfo (non-critical) failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "SetUserInfo (non-critical) failed - %s\n", nt_errstr(status));
+       }
+       if (!NT_STATUS_IS_OK(s.out.result)) {
+               torture_comment(tctx, "SetUserInfo (non-critical) failed - %s\n", nt_errstr(s.out.result));
        }
 
        *machine_credentials = cli_credentials_init(tj);
-       cli_credentials_set_conf(*machine_credentials, global_loadparm);
+       cli_credentials_set_conf(*machine_credentials, tctx->lp_ctx);
        cli_credentials_set_workstation(*machine_credentials, machine_name, CRED_SPECIFIED);
        cli_credentials_set_domain(*machine_credentials, libnet_r->out.domain_name, CRED_SPECIFIED);
        if (libnet_r->out.realm) {
@@ -399,6 +629,7 @@ _PUBLIC_ struct test_join *torture_join_domain(const char *machine_name,
        }
        cli_credentials_set_username(*machine_credentials, libnet_r->in.account_name, CRED_SPECIFIED);
        cli_credentials_set_password(*machine_credentials, libnet_r->out.join_password, CRED_SPECIFIED);
+       cli_credentials_set_kvno(*machine_credentials, libnet_r->out.kvno);
        if (acct_flags & ACB_SVRTRUST) {
                cli_credentials_set_secure_channel_type(*machine_credentials,
                                                        SEC_CHAN_BDC);
@@ -424,7 +655,9 @@ struct policy_handle *torture_join_samr_user_policy(struct test_join *join)
        return &join->user_handle;
 }
 
-static NTSTATUS torture_leave_ads_domain(TALLOC_CTX *mem_ctx, struct libnet_JoinDomain *libnet_r)
+static NTSTATUS torture_leave_ads_domain(struct torture_context *torture,
+                                        TALLOC_CTX *mem_ctx,
+                                        struct libnet_JoinDomain *libnet_r)
 {
        int rtn;
        TALLOC_CTX *tmp_ctx;
@@ -445,7 +678,7 @@ static NTSTATUS torture_leave_ads_domain(TALLOC_CTX *mem_ctx, struct libnet_Join
                return NT_STATUS_NO_MEMORY;
        }
 
-       ldb_ctx = ldb_init(tmp_ctx);
+       ldb_ctx = ldb_init(tmp_ctx, torture->ev);
        if (!ldb_ctx) {
                libnet_r->out.error_string = NULL;
                talloc_free(tmp_ctx);
@@ -460,24 +693,26 @@ static NTSTATUS torture_leave_ads_domain(TALLOC_CTX *mem_ctx, struct libnet_Join
                return NT_STATUS_NO_MEMORY;
        }
 
-       remote_ldb_url = talloc_asprintf(tmp_ctx, "ldap://%s", libnet_r->out.samr_binding->host);
+       remote_ldb_url = talloc_asprintf(tmp_ctx, "ldap://%s",
+               dcerpc_binding_get_string_option(libnet_r->out.samr_binding, "host"));
        if (!remote_ldb_url) {
                libnet_r->out.error_string = NULL;
                talloc_free(tmp_ctx);
                return NT_STATUS_NO_MEMORY;
        }
 
-       ldb_set_opaque(ldb_ctx, "credentials", cmdline_credentials);
+       ldb_set_opaque(ldb_ctx, "credentials", samba_cmdline_get_creds());
+       ldb_set_opaque(ldb_ctx, "loadparm", samba_cmdline_get_lp_ctx());
 
        rtn = ldb_connect(ldb_ctx, remote_ldb_url, 0, NULL);
-       if (rtn != 0) {
+       if (rtn != LDB_SUCCESS) {
                libnet_r->out.error_string = NULL;
                talloc_free(tmp_ctx);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
        rtn = ldb_delete(ldb_ctx, server_dn);
-       if (rtn != 0) {
+       if (rtn != LDB_SUCCESS) {
                libnet_r->out.error_string = NULL;
                talloc_free(tmp_ctx);
                return NT_STATUS_UNSUCCESSFUL;
@@ -493,7 +728,7 @@ static NTSTATUS torture_leave_ads_domain(TALLOC_CTX *mem_ctx, struct libnet_Join
   leave the domain, deleting the machine acct
 */
 
-_PUBLIC_ void torture_leave_domain(struct test_join *join)
+_PUBLIC_ void torture_leave_domain(struct torture_context *tctx, struct test_join *join)
 {
        struct samr_DeleteUser d;
        NTSTATUS status;
@@ -503,17 +738,21 @@ _PUBLIC_ void torture_leave_domain(struct test_join *join)
        }
        d.in.user_handle = &join->user_handle;
        d.out.user_handle = &join->user_handle;
-                                       
-       /* Delete machine account */                                                                                                                                                                                                                                                                                                                    
-       status = dcerpc_samr_DeleteUser(join->p, join, &d);
+
+       /* Delete machine account */
+       status = dcerpc_samr_DeleteUser_r(join->p->binding_handle, join, &d);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("Delete of machine account failed\n");
+               torture_comment(tctx, "DeleteUser failed\n");
+       } else if (!NT_STATUS_IS_OK(d.out.result)) {
+               torture_comment(tctx, "Delete of machine account %s failed\n",
+                      join->netbios_name);
        } else {
-               printf("Delete of machine account was successful.\n");
+               torture_comment(tctx, "Delete of machine account %s was successful.\n",
+                      join->netbios_name);
        }
 
        if (join->libnet_r) {
-               status = torture_leave_ads_domain(join, join->libnet_r);
+               status = torture_leave_ads_domain(tctx, join, join->libnet_r);
        }
        
        talloc_free(join);
@@ -552,7 +791,6 @@ const char *torture_join_dom_dns_name(struct test_join *join)
        return join->dom_dns_name;
 }
 
-
 #if 0 /* Left as the documentation of the join process, but see new implementation in libnet_become_dc.c */
 struct test_join_ads_dc {
        struct test_join *join;