s4-loadparm: 2nd half of lp_ to lpcfg_ conversion
[samba.git] / source4 / libnet / libnet_unbecome_dc.c
index 4463569e71660a7fd38ec1bd85c4234f6e4c2e6f..cf0142da8625caa7b80d3f6e4694a7fef0a3f12a 100644 (file)
 #include "libcli/cldap/cldap.h"
 #include "lib/ldb/include/ldb.h"
 #include "lib/ldb/include/ldb_errors.h"
-#include "lib/ldb_wrap.h"
+#include "ldb_wrap.h"
 #include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
 #include "param/param.h"
+#include "lib/tsocket/tsocket.h"
 
 /*****************************************************************************
  * Windows 2003 (w2k3) does the following steps when changing the server role
@@ -203,6 +204,7 @@ struct libnet_UnbecomeDC_state {
        struct {
                struct dcerpc_binding *binding;
                struct dcerpc_pipe *pipe;
+               struct dcerpc_binding_handle *drsuapi_handle;
                struct drsuapi_DsBind bind_r;
                struct GUID bind_guid;
                struct drsuapi_DsBindInfoCtr bind_info_ctr;
@@ -250,15 +252,17 @@ struct libnet_UnbecomeDC_state {
        } dest_dsa;
 };
 
-static void unbecomeDC_recv_cldap(struct cldap_request *req);
+static void unbecomeDC_recv_cldap(struct tevent_req *req);
 
 static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s)
 {
        struct composite_context *c = s->creq;
-       struct cldap_request *req;
+       struct tevent_req *req;
+       struct tsocket_address *dest_address;
+       int ret;
 
-       s->cldap.io.in.dest_address     = s->source_dsa.address;
-       s->cldap.io.in.dest_port        = lp_cldap_port(s->libnet->lp_ctx);
+       s->cldap.io.in.dest_address     = NULL;
+       s->cldap.io.in.dest_port        = 0;
        s->cldap.io.in.realm            = s->domain.dns_name;
        s->cldap.io.in.host             = s->dest_dsa.netbios_name;
        s->cldap.io.in.user             = NULL;
@@ -268,31 +272,40 @@ static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s)
        s->cldap.io.in.version          = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
        s->cldap.io.in.map_response     = true;
 
-       s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx,
-                                         lp_iconv_convenience(s->libnet->lp_ctx));
-       if (composite_nomem(s->cldap.sock, c)) return;
+       ret = tsocket_address_inet_from_strings(s, "ip",
+                                               s->source_dsa.address,
+                                               lpcfg_cldap_port(s->libnet->lp_ctx),
+                                               &dest_address);
+       if (ret != 0) {
+               c->status = map_nt_error_from_unix(errno);
+               if (!composite_is_ok(c)) return;
+       }
+
+       c->status = cldap_socket_init(s, s->libnet->event_ctx,
+                                     NULL, dest_address, &s->cldap.sock);
+       if (!composite_is_ok(c)) return;
 
-       req = cldap_netlogon_send(s->cldap.sock, &s->cldap.io);
+       req = cldap_netlogon_send(s, s->cldap.sock, &s->cldap.io);
        if (composite_nomem(req, c)) return;
-       req->async.fn           = unbecomeDC_recv_cldap;
-       req->async.private      = s;
+       tevent_req_set_callback(req, unbecomeDC_recv_cldap, s);
 }
 
 static void unbecomeDC_connect_ldap(struct libnet_UnbecomeDC_state *s);
 
-static void unbecomeDC_recv_cldap(struct cldap_request *req)
+static void unbecomeDC_recv_cldap(struct tevent_req *req)
 {
-       struct libnet_UnbecomeDC_state *s = talloc_get_type(req->async.private,
+       struct libnet_UnbecomeDC_state *s = tevent_req_callback_data(req,
                                            struct libnet_UnbecomeDC_state);
        struct composite_context *c = s->creq;
 
        c->status = cldap_netlogon_recv(req, s, &s->cldap.io);
+       talloc_free(req);
        if (!composite_is_ok(c)) return;
 
-       s->cldap.netlogon = s->cldap.io.out.netlogon.nt5_ex;
+       s->cldap.netlogon = s->cldap.io.out.netlogon.data.nt5_ex;
 
        s->domain.dns_name              = s->cldap.netlogon.dns_domain;
-       s->domain.netbios_name          = s->cldap.netlogon.domain;
+       s->domain.netbios_name          = s->cldap.netlogon.domain_name;
        s->domain.guid                  = s->cldap.netlogon.domain_uuid;
 
        s->source_dsa.dns_name          = s->cldap.netlogon.pdc_dns_name;
@@ -314,7 +327,7 @@ static NTSTATUS unbecomeDC_ldap_connect(struct libnet_UnbecomeDC_state *s)
        s->ldap.ldb = ldb_wrap_connect(s, s->libnet->event_ctx, s->libnet->lp_ctx, url,
                                       NULL,
                                       s->libnet->cred,
-                                      0, NULL);
+                                      0);
        talloc_free(url);
        if (s->ldap.ldb == NULL) {
                return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
@@ -337,8 +350,8 @@ static NTSTATUS unbecomeDC_ldap_rootdse(struct libnet_UnbecomeDC_state *s)
        basedn = ldb_dn_new(s, s->ldap.ldb, NULL);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap.ldb, basedn, LDB_SCOPE_BASE, 
-                        "(objectClass=*)", attrs, &r);
+       ret = ldb_search(s->ldap.ldb, s, &r, basedn, LDB_SCOPE_BASE, attrs,
+                        "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -346,7 +359,6 @@ static NTSTATUS unbecomeDC_ldap_rootdse(struct libnet_UnbecomeDC_state *s)
                talloc_free(r);
                return NT_STATUS_INVALID_NETWORK_RESPONSE;
        }
-       talloc_steal(s, r);
 
        s->domain.dn_str        = ldb_msg_find_attr_as_string(r->msgs[0], "defaultNamingContext", NULL);
        if (!s->domain.dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
@@ -371,7 +383,6 @@ static NTSTATUS unbecomeDC_ldap_computer_object(struct libnet_UnbecomeDC_state *
        int ret;
        struct ldb_result *r;
        struct ldb_dn *basedn;
-       char *filter;
        static const char *attrs[] = {
                "distinguishedName",
                "userAccountControl",
@@ -381,12 +392,9 @@ static NTSTATUS unbecomeDC_ldap_computer_object(struct libnet_UnbecomeDC_state *
        basedn = ldb_dn_new(s, s->ldap.ldb, s->domain.dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       filter = talloc_asprintf(basedn, "(&(|(objectClass=user)(objectClass=computer))(sAMAccountName=%s$))",
-                                s->dest_dsa.netbios_name);
-       NT_STATUS_HAVE_NO_MEMORY(filter);
-
-       ret = ldb_search(s->ldap.ldb, basedn, LDB_SCOPE_SUBTREE, 
-                        filter, attrs, &r);
+       ret = ldb_search(s->ldap.ldb, s, &r, basedn, LDB_SCOPE_SUBTREE, attrs,
+                        "(&(|(objectClass=user)(objectClass=computer))(sAMAccountName=%s$))",
+                        s->dest_dsa.netbios_name);
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -410,7 +418,7 @@ static NTSTATUS unbecomeDC_ldap_modify_computer(struct libnet_UnbecomeDC_state *
        int ret;
        struct ldb_message *msg;
        uint32_t user_account_control = UF_WORKSTATION_TRUST_ACCOUNT;
-       uint32_t i;
+       unsigned int i;
 
        /* as the value is already as we want it to be, we're done */
        if (s->dest_dsa.user_account_control == user_account_control) {
@@ -462,8 +470,8 @@ static NTSTATUS unbecomeDC_ldap_move_computer(struct libnet_UnbecomeDC_state *s)
                                s->domain.dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap.ldb, basedn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", _1_1_attrs, &r);
+       ret = ldb_search(s->ldap.ldb, s, &r, basedn, LDB_SCOPE_BASE,
+                        _1_1_attrs, "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -558,23 +566,25 @@ static void unbecomeDC_drsuapi_connect_recv(struct composite_context *req)
        c->status = dcerpc_pipe_connect_b_recv(req, s, &s->drsuapi.pipe);
        if (!composite_is_ok(c)) return;
 
+       s->drsuapi.drsuapi_handle = s->drsuapi.pipe->binding_handle;
+
        unbecomeDC_drsuapi_bind_send(s);
 }
 
-static void unbecomeDC_drsuapi_bind_recv(struct rpc_request *req);
+static void unbecomeDC_drsuapi_bind_recv(struct tevent_req *subreq);
 
 static void unbecomeDC_drsuapi_bind_send(struct libnet_UnbecomeDC_state *s)
 {
        struct composite_context *c = s->creq;
-       struct rpc_request *req;
        struct drsuapi_DsBindInfo28 *bind_info28;
+       struct tevent_req *subreq;
 
        GUID_from_string(DRSUAPI_DS_BIND_GUID, &s->drsuapi.bind_guid);
 
        bind_info28                             = &s->drsuapi.local_info28;
        bind_info28->supported_extensions       = 0;
        bind_info28->site_guid                  = GUID_zero();
-       bind_info28->pid                        = 508;
+       bind_info28->pid                        = 0;
        bind_info28->repl_epoch                 = 0;
 
        s->drsuapi.bind_info_ctr.length         = 28;
@@ -584,19 +594,23 @@ static void unbecomeDC_drsuapi_bind_send(struct libnet_UnbecomeDC_state *s)
        s->drsuapi.bind_r.in.bind_info = &s->drsuapi.bind_info_ctr;
        s->drsuapi.bind_r.out.bind_handle = &s->drsuapi.bind_handle;
 
-       req = dcerpc_drsuapi_DsBind_send(s->drsuapi.pipe, s, &s->drsuapi.bind_r);
-       composite_continue_rpc(c, req, unbecomeDC_drsuapi_bind_recv, s);
+       subreq = dcerpc_drsuapi_DsBind_r_send(s, c->event_ctx,
+                                             s->drsuapi.drsuapi_handle,
+                                             &s->drsuapi.bind_r);
+       if (composite_nomem(subreq, c)) return;
+       tevent_req_set_callback(subreq, unbecomeDC_drsuapi_bind_recv, s);
 }
 
 static void unbecomeDC_drsuapi_remove_ds_server_send(struct libnet_UnbecomeDC_state *s);
 
-static void unbecomeDC_drsuapi_bind_recv(struct rpc_request *req)
+static void unbecomeDC_drsuapi_bind_recv(struct tevent_req *subreq)
 {
-       struct libnet_UnbecomeDC_state *s = talloc_get_type(req->async.private_data,
+       struct libnet_UnbecomeDC_state *s = tevent_req_callback_data(subreq,
                                            struct libnet_UnbecomeDC_state);
        struct composite_context *c = s->creq;
 
-       c->status = dcerpc_ndr_request_recv(req);
+       c->status = dcerpc_drsuapi_DsBind_r_recv(subreq, s);
+       TALLOC_FREE(subreq);
        if (!composite_is_ok(c)) return;
 
        if (!W_ERROR_IS_OK(s->drsuapi.bind_r.out.result)) {
@@ -634,32 +648,40 @@ static void unbecomeDC_drsuapi_bind_recv(struct rpc_request *req)
        unbecomeDC_drsuapi_remove_ds_server_send(s);
 }
 
-static void unbecomeDC_drsuapi_remove_ds_server_recv(struct rpc_request *req);
+static void unbecomeDC_drsuapi_remove_ds_server_recv(struct tevent_req *subreq);
 
 static void unbecomeDC_drsuapi_remove_ds_server_send(struct libnet_UnbecomeDC_state *s)
 {
        struct composite_context *c = s->creq;
-       struct rpc_request *req;
        struct drsuapi_DsRemoveDSServer *r = &s->drsuapi.rm_ds_srv_r;
+       struct tevent_req *subreq;
 
        r->in.bind_handle       = &s->drsuapi.bind_handle;
        r->in.level             = 1;
-       r->in.req.req1.server_dn= s->dest_dsa.server_dn_str;
-       r->in.req.req1.domain_dn= s->domain.dn_str;
-       r->in.req.req1.unknown  = 0x00000001;
-
-       req = dcerpc_drsuapi_DsRemoveDSServer_send(s->drsuapi.pipe, s, r);
-       composite_continue_rpc(c, req, unbecomeDC_drsuapi_remove_ds_server_recv, s);
+       r->in.req               = talloc(s, union drsuapi_DsRemoveDSServerRequest);
+       r->in.req->req1.server_dn = s->dest_dsa.server_dn_str;
+       r->in.req->req1.domain_dn = s->domain.dn_str;
+       r->in.req->req1.commit  = true;
+
+       r->out.level_out        = talloc(s, uint32_t);
+       r->out.res              = talloc(s, union drsuapi_DsRemoveDSServerResult);
+
+       subreq = dcerpc_drsuapi_DsRemoveDSServer_r_send(s, c->event_ctx,
+                                                       s->drsuapi.drsuapi_handle,
+                                                       r);
+       if (composite_nomem(subreq, c)) return;
+       tevent_req_set_callback(subreq, unbecomeDC_drsuapi_remove_ds_server_recv, s);
 }
 
-static void unbecomeDC_drsuapi_remove_ds_server_recv(struct rpc_request *req)
+static void unbecomeDC_drsuapi_remove_ds_server_recv(struct tevent_req *subreq)
 {
-       struct libnet_UnbecomeDC_state *s = talloc_get_type(req->async.private_data,
+       struct libnet_UnbecomeDC_state *s = tevent_req_callback_data(subreq,
                                            struct libnet_UnbecomeDC_state);
        struct composite_context *c = s->creq;
        struct drsuapi_DsRemoveDSServer *r = &s->drsuapi.rm_ds_srv_r;
 
-       c->status = dcerpc_ndr_request_recv(req);
+       c->status = dcerpc_drsuapi_DsRemoveDSServer_r_recv(subreq, s);
+       TALLOC_FREE(subreq);
        if (!composite_is_ok(c)) return;
 
        if (!W_ERROR_IS_OK(r->out.result)) {
@@ -667,15 +689,10 @@ static void unbecomeDC_drsuapi_remove_ds_server_recv(struct rpc_request *req)
                return;
        }
 
-       if (r->out.level != 1) {
+       if (*r->out.level_out != 1) {
                composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
                return;
        }
-               
-       if (!W_ERROR_IS_OK(r->out.res.res1.status)) {
-               composite_error(c, werror_to_ntstatus(r->out.res.res1.status));
-               return;
-       }
 
        composite_done(c);
 }