#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
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;
} 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;
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;
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;
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);
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;
int ret;
struct ldb_result *r;
struct ldb_dn *basedn;
- char *filter;
static const char *attrs[] = {
"distinguishedName",
"userAccountControl",
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);
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) {
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);
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;
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)) {
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)) {
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);
}