/*
Unix SMB/CIFS implementation.
- Copyright (C) Stefan Metzmacher 2006
+ Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "libnet/libnet.h"
#include "libcli/composite/composite.h"
#include "libcli/cldap/cldap.h"
-#include "lib/ldb/include/ldb.h"
-#include "lib/ldb/include/ldb_errors.h"
-#include "lib/db_wrap.h"
+#include <ldb.h>
+#include <ldb_errors.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
+ * from domain controller back to domain member
+ *
+ * We mostly do the same.
+ *****************************************************************************/
+
+/*
+ * lookup DC:
+ * - using nbt name<1C> request and a samlogon mailslot request
+ * or
+ * - using a DNS SRV _ldap._tcp.dc._msdcs. request and a CLDAP netlogon request
+ *
+ * see: unbecomeDC_send_cldap() and unbecomeDC_recv_cldap()
+ */
+
+/*
+ * Open 1st LDAP connection to the DC using admin credentials
+ *
+ * see: unbecomeDC_ldap_connect()
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: unbecomeDC_ldap_rootdse()
+ *
+ * Request:
+ * basedn: ""
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: defaultNamingContext
+ * configurationNamingContext
+ * Result:
+ * ""
+ * defaultNamingContext: <domain_partition>
+ * configurationNamingContext:CN=Configuration,<domain_partition>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: unbecomeDC_ldap_computer_object()
+ *
+ * Request:
+ * basedn: <domain_partition>
+ * scope: sub
+ * filter: (&(|(objectClass=user)(objectClass=computer))(sAMAccountName=<new_dc_account_name>))
+ * attrs: distinguishedName
+ * userAccountControl
+ * Result:
+ * CN=<new_dc_netbios_name>,CN=Domain Controllers,<domain_partition>
+ * distinguishedName: CN=<new_dc_netbios_name>,CN=Domain Controllers,<domain_partition>
+ * userAccoountControl: 532480 <0x82000>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: unbecomeDC_ldap_modify_computer()
+ *
+ * Request:
+ * basedn: CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: userAccountControl
+ * Result:
+ * CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * userAccoountControl: 532480 <0x82000>
+ */
+
+/*
+ * LDAP modify 1st LDAP connection:
+ *
+ * see: unbecomeDC_ldap_modify_computer()
+ *
+ * Request (replace):
+ * CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * userAccoountControl: 4096 <0x1000>
+ * Result:
+ * <success>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: unbecomeDC_ldap_move_computer()
+ *
+ * Request:
+ * basedn: <WKGUID=aa312825768811d1aded00c04fd8d5cd,<domain_partition>>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: 1.1
+ * Result:
+ * CN=Computers,<domain_partition>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * not implemented because it doesn't give any new information
+ *
+ * Request:
+ * basedn: CN=Computers,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: distinguishedName
+ * Result:
+ * CN=Computers,<domain_partition>
+ * distinguishedName: CN=Computers,<domain_partition>
+ */
+
+/*
+ * LDAP modifyRDN 1st LDAP connection:
+ *
+ * see: unbecomeDC_ldap_move_computer()
+ *
+ * Request:
+ * entry: CN=<new_dc_netbios_name>,CN=Domain Controllers,<domain_partition>
+ * newrdn: CN=<new_dc_netbios_name>
+ * deleteoldrdn: TRUE
+ * newparent: CN=Computers,<domain_partition>
+ * Result:
+ * <success>
+ */
+
+/*
+ * LDAP unbind on the 1st LDAP connection
+ *
+ * not implemented, because it's not needed...
+ */
+
+/*
+ * Open 1st DRSUAPI connection to the DC using admin credentials
+ * DsBind with DRSUAPI_DS_BIND_GUID ("e24d201a-4fd6-11d1-a3da-0000f875ae0d")
+ *
+ * see: unbecomeDC_drsuapi_connect_send(), unbecomeDC_drsuapi_connect_recv(),
+ * unbecomeDC_drsuapi_bind_send() and unbecomeDC_drsuapi_bind_recv()
+ */
+
+/*
+ * DsRemoveDsServer to remove the
+ * CN=<machine_name>,CN=Servers,CN=<site_name>,CN=Configuration,<domain_partition>
+ * and CN=NTDS Settings,CN=<machine_name>,CN=Servers,CN=<site_name>,CN=Configuration,<domain_partition>
+ * on the 1st DRSUAPI connection
+ *
+ * see: unbecomeDC_drsuapi_remove_ds_server_send() and unbecomeDC_drsuapi_remove_ds_server_recv()
+ */
+
+/*
+ * DsUnbind on the 1st DRSUAPI connection
+ *
+ * not implemented, because it's not needed...
+ */
+
struct libnet_UnbecomeDC_state {
struct composite_context *creq;
struct {
struct cldap_socket *sock;
struct cldap_netlogon io;
- struct nbt_cldap_netlogon_5 netlogon5;
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX netlogon;
} cldap;
struct {
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_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.domain_guid = NULL;
s->cldap.io.in.domain_sid = NULL;
s->cldap.io.in.acct_control = -1;
- s->cldap.io.in.version = 6;
+ 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);
- 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_common(errno);
+ if (!composite_is_ok(c)) return;
+ }
- req = cldap_netlogon_send(s->cldap.sock, &s->cldap.io);
+ c->status = cldap_socket_init(s, NULL, dest_address, &s->cldap.sock);
+ if (!composite_is_ok(c)) return;
+
+ req = cldap_netlogon_send(s, s->libnet->event_ctx,
+ 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.netlogon5 = s->cldap.io.out.netlogon.logon5;
+ s->cldap.netlogon = s->cldap.io.out.netlogon.data.nt5_ex;
- s->domain.dns_name = s->cldap.netlogon5.dns_domain;
- s->domain.netbios_name = s->cldap.netlogon5.domain;
- s->domain.guid = s->cldap.netlogon5.domain_uuid;
+ s->domain.dns_name = s->cldap.netlogon.dns_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.netlogon5.pdc_dns_name;
- s->source_dsa.netbios_name = s->cldap.netlogon5.pdc_name;
- s->source_dsa.site_name = s->cldap.netlogon5.server_site;
+ s->source_dsa.dns_name = s->cldap.netlogon.pdc_dns_name;
+ s->source_dsa.netbios_name = s->cldap.netlogon.pdc_name;
+ s->source_dsa.site_name = s->cldap.netlogon.server_site;
- s->dest_dsa.site_name = s->cldap.netlogon5.client_site;
+ s->dest_dsa.site_name = s->cldap.netlogon.client_site;
unbecomeDC_connect_ldap(s);
}
url = talloc_asprintf(s, "ldap://%s/", s->source_dsa.dns_name);
NT_STATUS_HAVE_NO_MEMORY(url);
- s->ldap.ldb = ldb_wrap_connect(s, url,
+ 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);
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
- s->dest_dsa.computer_dn_str = samdb_result_string(r->msgs[0], "distinguishedName", NULL);
+ s->dest_dsa.computer_dn_str = ldb_msg_find_attr_as_string(r->msgs[0], "distinguishedName", NULL);
if (!s->dest_dsa.computer_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
talloc_steal(s, s->dest_dsa.computer_dn_str);
- s->dest_dsa.user_account_control = samdb_result_uint(r->msgs[0], "userAccountControl", 0);
+ s->dest_dsa.user_account_control = ldb_msg_find_attr_as_uint(r->msgs[0], "userAccountControl", 0);
talloc_free(r);
return NT_STATUS_OK;
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) {
msg->dn = ldb_dn_new(msg, s->ldap.ldb, s->dest_dsa.computer_dn_str);
NT_STATUS_HAVE_NO_MEMORY(msg->dn);
- ret = ldb_msg_add_fmt(msg, "userAccountControl", "%u", user_account_control);
- if (ret != 0) {
+ ret = samdb_msg_add_uint(s->ldap.ldb, msg, msg, "userAccountControl",
+ user_account_control);
+ if (ret != LDB_SUCCESS) {
talloc_free(msg);
return NT_STATUS_NO_MEMORY;
}
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);
struct composite_context *creq;
char *binding_str;
- binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[seal]", s->source_dsa.dns_name);
+ binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[seal,target_hostname=%s]",
+ s->source_dsa.address,
+ s->source_dsa.dns_name);
if (composite_nomem(binding_str, c)) return;
c->status = dcerpc_parse_binding(s, binding_str, &s->drsuapi.binding);
talloc_free(binding_str);
if (!composite_is_ok(c)) return;
- creq = dcerpc_pipe_connect_b_send(s, s->drsuapi.binding, &dcerpc_table_drsuapi,
- s->libnet->cred, s->libnet->event_ctx);
+ if (DEBUGLEVEL >= 10) {
+ c->status = dcerpc_binding_set_flags(s->drsuapi.binding,
+ DCERPC_DEBUG_PRINT_BOTH,
+ 0);
+ if (!composite_is_ok(c)) return;
+ }
+
+ creq = dcerpc_pipe_connect_b_send(s, s->drsuapi.binding, &ndr_table_drsuapi,
+ s->libnet->cred, s->libnet->event_ctx,
+ s->libnet->lp_ctx);
composite_continue(c, creq, unbecomeDC_drsuapi_connect_recv, s);
}
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->u1 = 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,
+ 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)) {
info24 = &s->drsuapi.bind_r.out.bind_info->info.info24;
s->drsuapi.remote_info28.supported_extensions = info24->supported_extensions;
s->drsuapi.remote_info28.site_guid = info24->site_guid;
- s->drsuapi.remote_info28.u1 = info24->u1;
+ s->drsuapi.remote_info28.pid = info24->pid;
s->drsuapi.remote_info28.repl_epoch = 0;
break;
}
- case 28:
+ case 28: {
s->drsuapi.remote_info28 = s->drsuapi.bind_r.out.bind_info->info.info28;
break;
}
+ case 32: {
+ struct drsuapi_DsBindInfo32 *info32;
+ info32 = &s->drsuapi.bind_r.out.bind_info->info.info32;
+ s->drsuapi.remote_info28.supported_extensions = info32->supported_extensions;
+ s->drsuapi.remote_info28.site_guid = info32->site_guid;
+ s->drsuapi.remote_info28.pid = info32->pid;
+ s->drsuapi.remote_info28.repl_epoch = info32->repl_epoch;
+ break;
+ }
+ case 48: {
+ struct drsuapi_DsBindInfo48 *info48;
+ info48 = &s->drsuapi.bind_r.out.bind_info->info.info48;
+ s->drsuapi.remote_info28.supported_extensions = info48->supported_extensions;
+ s->drsuapi.remote_info28.site_guid = info48->site_guid;
+ s->drsuapi.remote_info28.pid = info48->pid;
+ s->drsuapi.remote_info28.repl_epoch = info48->repl_epoch;
+ break;
+ }
+ case 52: {
+ struct drsuapi_DsBindInfo52 *info52;
+ info52 = &s->drsuapi.bind_r.out.bind_info->info.info52;
+ s->drsuapi.remote_info28.supported_extensions = info52->supported_extensions;
+ s->drsuapi.remote_info28.site_guid = info52->site_guid;
+ s->drsuapi.remote_info28.pid = info52->pid;
+ s->drsuapi.remote_info28.repl_epoch = info52->repl_epoch;
+ break;
+ }
+ default:
+ DEBUG(1, ("Warning: invalid info length in bind info: %d\n",
+ s->drsuapi.bind_r.out.bind_info->length));
+ break;
+ }
}
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,
+ 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);
}
/* Destination DSA dns_name construction */
tmp_name = strlower_talloc(s, s->dest_dsa.netbios_name);
if (composite_nomem(tmp_name, c)) return c;
- s->dest_dsa.dns_name = talloc_asprintf_append(tmp_name, ".%s",
+ s->dest_dsa.dns_name = talloc_asprintf_append_buffer(tmp_name, ".%s",
s->domain.dns_name);
if (composite_nomem(s->dest_dsa.dns_name, c)) return c;