Merge branch 'master' of ssh://git.samba.org/data/git/samba
[ira/wip.git] / source4 / libnet / libnet_join.c
index 4549cd6e9349c05096c890d18011fa1873f35f1f..70fcb4a894eac46bc86a1a6208f27c2fe2b0daf6 100644 (file)
@@ -27,7 +27,7 @@
 #include "param/secrets.h"
 #include "dsdb/samdb/samdb.h"
 #include "ldb_wrap.h"
-#include "util/util_ldb.h"
+#include "../lib/util/util_ldb.h"
 #include "libcli/security/security.h"
 #include "auth/credentials/credentials.h"
 #include "auth/credentials/credentials_krb5.h"
@@ -162,13 +162,19 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
        ZERO_STRUCT(r_crack_names);
        r_crack_names.in.bind_handle            = &drsuapi_bind_handle;
        r_crack_names.in.level                  = 1;
-       r_crack_names.in.req.req1.codepage      = 1252; /* western european */
-       r_crack_names.in.req.req1.language      = 0x00000407; /* german */
-       r_crack_names.in.req.req1.count         = 1;
-       r_crack_names.in.req.req1.names         = names;
-       r_crack_names.in.req.req1.format_flags  = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
-       r_crack_names.in.req.req1.format_offered= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
-       r_crack_names.in.req.req1.format_desired= DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+       r_crack_names.in.req                    = talloc(r, union drsuapi_DsNameRequest);
+       if (!r_crack_names.in.req) {
+               r->out.error_string = NULL;
+               talloc_free(tmp_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
+       r_crack_names.in.req->req1.codepage     = 1252; /* western european */
+       r_crack_names.in.req->req1.language     = 0x00000407; /* german */
+       r_crack_names.in.req->req1.count        = 1;
+       r_crack_names.in.req->req1.names        = names;
+       r_crack_names.in.req->req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
+       r_crack_names.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
+       r_crack_names.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
        names[0].str = dom_sid_string(tmp_ctx, r->out.account_sid);
        if (!names[0].str) {
                r->out.error_string = NULL;
@@ -176,6 +182,14 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
                return NT_STATUS_NO_MEMORY;
        }
 
+       r_crack_names.out.ctr                   = talloc(r, union drsuapi_DsNameCtr);
+       r_crack_names.out.level_out             = talloc(r, int32_t);
+       if (!r_crack_names.out.ctr || !r_crack_names.out.level_out) {
+               r->out.error_string = NULL;
+               talloc_free(tmp_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        status = dcerpc_drsuapi_DsCrackNames(drsuapi_pipe, tmp_ctx, &r_crack_names);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
@@ -201,24 +215,24 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
                                                  "DsCrackNames failed - %s", win_errstr(r_crack_names.out.result));
                talloc_free(tmp_ctx);
                return NT_STATUS_UNSUCCESSFUL;
-       } else if (r_crack_names.out.level != 1 
-                  || !r_crack_names.out.ctr.ctr1 
-                  || r_crack_names.out.ctr.ctr1->count != 1) {
+       } else if (*r_crack_names.out.level_out != 1
+                  || !r_crack_names.out.ctr->ctr1
+                  || r_crack_names.out.ctr->ctr1->count != 1) {
                r->out.error_string = talloc_asprintf(r, "DsCrackNames failed");
                talloc_free(tmp_ctx);
                return NT_STATUS_INVALID_PARAMETER;
-       } else if (r_crack_names.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
-               r->out.error_string = talloc_asprintf(r, "DsCrackNames failed: %d", r_crack_names.out.ctr.ctr1->array[0].status);
+       } else if (r_crack_names.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
+               r->out.error_string = talloc_asprintf(r, "DsCrackNames failed: %d", r_crack_names.out.ctr->ctr1->array[0].status);
                talloc_free(tmp_ctx);
                return NT_STATUS_UNSUCCESSFUL;
-       } else if (r_crack_names.out.ctr.ctr1->array[0].result_name == NULL) {
+       } else if (r_crack_names.out.ctr->ctr1->array[0].result_name == NULL) {
                r->out.error_string = talloc_asprintf(r, "DsCrackNames failed: no result name");
                talloc_free(tmp_ctx);
                return NT_STATUS_INVALID_PARAMETER;
        }
 
        /* Store the DN of our machine account. */
-       account_dn_str = r_crack_names.out.ctr.ctr1->array[0].result_name;
+       account_dn_str = r_crack_names.out.ctr->ctr1->array[0].result_name;
 
        /* Now we know the user's DN, open with LDAP, read and modify a few things */
 
@@ -230,7 +244,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
                return NT_STATUS_NO_MEMORY;
        }
 
-       remote_ldb = ldb_wrap_connect(tmp_ctx, ctx->lp_ctx, 
+       remote_ldb = ldb_wrap_connect(tmp_ctx, ctx->event_ctx, ctx->lp_ctx, 
                                      remote_ldb_url, 
                                      NULL, ctx->cred, 0, NULL);
        if (!remote_ldb) {
@@ -248,8 +262,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
        }
 
        /* search for the user's record */
-       ret = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE, 
-                        NULL, attrs, &res);
+       ret = ldb_search(remote_ldb, tmp_ctx, &res,
+                        account_dn, LDB_SCOPE_BASE, attrs, NULL);
        if (ret != LDB_SUCCESS) {
                r->out.error_string = talloc_asprintf(r, "ldb_search for %s failed - %s",
                                                      account_dn_str, ldb_errstring(remote_ldb));
@@ -257,8 +271,6 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       talloc_steal(tmp_ctx, res);
-
        if (res->count != 1) {
                r->out.error_string = talloc_asprintf(r, "ldb_search for %s failed - found %d entries",
                                                      account_dn_str, res->count);
@@ -330,8 +342,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
        }
                                
        /* DsCrackNames to find out the DN of the domain. */
-       r_crack_names.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
-       r_crack_names.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+       r_crack_names.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+       r_crack_names.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
        names[0].str = talloc_asprintf(tmp_ctx, "%s\\", r->out.domain_name);
        if (!names[0].str) {
                r->out.error_string = NULL;
@@ -364,11 +376,11 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
                                          "DsCrackNames failed - %s", win_errstr(r_crack_names.out.result));
                talloc_free(tmp_ctx);
                return NT_STATUS_UNSUCCESSFUL;
-       } else if (r_crack_names.out.level != 1 
-                  || !r_crack_names.out.ctr.ctr1 
-                  || r_crack_names.out.ctr.ctr1->count != 1
-                  || !r_crack_names.out.ctr.ctr1->array[0].result_name           
-                  || r_crack_names.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
+       } else if (*r_crack_names.out.level_out != 1
+                  || !r_crack_names.out.ctr->ctr1
+                  || r_crack_names.out.ctr->ctr1->count != 1
+                  || !r_crack_names.out.ctr->ctr1->array[0].result_name
+                  || r_crack_names.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
                r->out.error_string = talloc_asprintf(r, "DsCrackNames failed");
                talloc_free(tmp_ctx);
                return NT_STATUS_UNSUCCESSFUL;
@@ -379,8 +391,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
        talloc_steal(r, account_dn_str);
 
        /* Store the domain DN. */
-       r->out.domain_dn_str = r_crack_names.out.ctr.ctr1->array[0].result_name;
-       talloc_steal(r, r_crack_names.out.ctr.ctr1->array[0].result_name);
+       r->out.domain_dn_str = r_crack_names.out.ctr->ctr1->array[0].result_name;
+       talloc_steal(r, r_crack_names.out.ctr->ctr1->array[0].result_name);
 
        /* Store the KVNO of the account, critical for some kerberos
         * operations */
@@ -432,13 +444,16 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
        struct samr_OpenDomain od;
        struct policy_handle d_handle;
        struct samr_LookupNames ln;
+       struct samr_Ids rids, types;
        struct samr_OpenUser ou;
        struct samr_CreateUser2 cu;
        struct policy_handle *u_handle = NULL;
        struct samr_QueryUserInfo qui;
+       union samr_UserInfo *uinfo;
        struct samr_UserInfo21 u_info21;
        union libnet_SetPassword r2;
        struct samr_GetUserPwInfo pwp;
+       struct samr_PwInfo info;
        struct lsa_String samr_account_name;
        
        uint32_t acct_flags, old_acct_flags;
@@ -547,9 +562,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
        if (!connect_with_info->out.domain_sid) {
                struct lsa_String name;
                struct samr_LookupDomain l;
+               struct dom_sid2 *sid = NULL;
                name.string = connect_with_info->out.domain_name;
                l.in.connect_handle = &p_handle;
                l.in.domain_name = &name;
+               l.out.sid = &sid;
                
                status = dcerpc_samr_LookupDomain(samr_pipe, tmp_ctx, &l);
                if (!NT_STATUS_IS_OK(status)) {
@@ -559,7 +576,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                        talloc_free(tmp_ctx);
                        return status;
                }
-               connect_with_info->out.domain_sid = l.out.sid;
+               connect_with_info->out.domain_sid = *l.out.sid;
        }
 
        /* prepare samr_OpenDomain */
@@ -599,6 +616,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                ln.in.domain_handle = &d_handle;
                ln.in.num_names = 1;
                ln.in.names = talloc_array(tmp_ctx, struct lsa_String, 1);
+               ln.out.rids = &rids;
+               ln.out.types = &types;
                if (!ln.in.names) {
                        r->out.error_string = NULL;
                        talloc_free(tmp_ctx);
@@ -618,10 +637,10 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                }
                
                /* check if we got one RID for the user */
-               if (ln.out.rids.count != 1) {
+               if (ln.out.rids->count != 1) {
                        r->out.error_string = talloc_asprintf(mem_ctx,
                                                              "samr_LookupNames for [%s] returns %d RIDs",
-                                                             r->in.account_name, ln.out.rids.count);
+                                                             r->in.account_name, ln.out.rids->count);
                        talloc_free(tmp_ctx);
                        return NT_STATUS_INVALID_PARAMETER;
                }
@@ -630,7 +649,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                ZERO_STRUCTP(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];
                rid = ou.in.rid;
                ou.out.user_handle = u_handle;
                
@@ -682,6 +701,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
        /* prepare samr_QueryUserInfo (get flags) */
        qui.in.user_handle = u_handle;
        qui.in.level = 16;
+       qui.out.info = &uinfo;
        
        status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
        if (!NT_STATUS_IS_OK(status)) {
@@ -693,7 +713,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                return status;
        }
        
-       if (!qui.out.info) {
+       if (!uinfo) {
                status = NT_STATUS_INVALID_PARAMETER;
                r->out.error_string
                        = talloc_asprintf(mem_ctx,
@@ -703,7 +723,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                return status;
        }
 
-       old_acct_flags = (qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST));
+       old_acct_flags = (uinfo->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST));
        /* Possibly bail if the account is of the wrong type */
        if (old_acct_flags
            != r->in.acct_type) {
@@ -759,17 +779,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                        return NT_STATUS_USER_EXISTS;
                }
        } else {
-               acct_flags = qui.out.info->info16.acct_flags;
+               acct_flags = uinfo->info16.acct_flags;
        }
        
        acct_flags = (acct_flags & ~(ACB_DISABLED|ACB_PWNOTREQ));
 
        /* Find out what password policy this user has */
        pwp.in.user_handle = u_handle;
+       pwp.out.info = &info;
 
        status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp);                           
        if (NT_STATUS_IS_OK(status)) {
-               policy_min_pw_len = pwp.out.info.min_password_length;
+               policy_min_pw_len = pwp.out.info->min_password_length;
        }
        
        /* Grab a password of that minimum length */
@@ -865,7 +886,7 @@ NTSTATUS libnet_set_join_secrets(struct libnet_context *ctx,
        }
 
        /* Open the secrets database */
-       ldb = secrets_db_connect(tmp_mem, ctx->lp_ctx);
+       ldb = secrets_db_connect(tmp_mem, ctx->event_ctx, ctx->lp_ctx);
        if (!ldb) {
                r->out.error_string
                        = talloc_asprintf(mem_ctx,