summaryrefslogtreecommitdiff
path: root/source4/libnet
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libnet')
-rw-r--r--source4/libnet/libnet_become_dc.c189
1 files changed, 177 insertions, 12 deletions
diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c
index c446eea411..2d43bd95bb 100644
--- a/source4/libnet/libnet_become_dc.c
+++ b/source4/libnet/libnet_become_dc.c
@@ -22,6 +22,9 @@
#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"
struct libnet_BecomeDC_state {
struct composite_context *creq;
@@ -36,7 +39,7 @@ struct libnet_BecomeDC_state {
struct becomeDC_ldap {
struct ldb_context *ldb;
- struct ldb_message *rootdse;
+ const struct ldb_message *rootdse;
} ldap1;
struct {
@@ -46,12 +49,13 @@ struct libnet_BecomeDC_state {
/* constructed */
struct GUID guid;
- const char *domain_dn_str;
+ const char *dn_str;
} domain;
struct {
/* constructed */
const char *dns_name;
+ const char *root_dn_str;
const char *config_dn_str;
const char *schema_dn_str;
} forest;
@@ -79,8 +83,16 @@ struct libnet_BecomeDC_state {
const char *server_dn_str;
const char *ntds_dn_str;
} dest_dsa;
+
+ struct {
+ uint32_t domain_behavior_version;
+ uint32_t config_behavior_version;
+ uint32_t schema_object_version;
+ } ads_options;
};
+static void becomeDC_connect_ldap1(struct libnet_BecomeDC_state *s);
+
static void becomeDC_recv_cldap(struct cldap_request *req)
{
struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
@@ -104,7 +116,7 @@ static void becomeDC_recv_cldap(struct cldap_request *req)
s->dest_dsa.site_name = s->cldap.netlogon5.client_site;
- composite_error(c, NT_STATUS_NOT_IMPLEMENTED);
+ becomeDC_connect_ldap1(s);
}
static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
@@ -132,12 +144,171 @@ static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
static NTSTATUS becomeDC_ldap_connect(struct libnet_BecomeDC_state *s, struct becomeDC_ldap *ldap)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ char *url;
+
+ url = talloc_asprintf(s, "ldap://%s/", s->source_dsa.dns_name);
+ NT_STATUS_HAVE_NO_MEMORY(url);
+
+ ldap->ldb = ldb_wrap_connect(s, url,
+ NULL,
+ s->libnet->cred,
+ 0, NULL);
+ talloc_free(url);
+ if (ldap->ldb == NULL) {
+ return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS becomeDC_ldap1_rootdse(struct libnet_BecomeDC_state *s)
+{
+ int ret;
+ struct ldb_result *r;
+ struct ldb_dn *basedn;
+ static const char *attrs[] = {
+ "*",
+ NULL
+ };
+
+ basedn = ldb_dn_new(s, s->ldap1.ldb, NULL);
+
+ ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
+ "(objectClass=*)", attrs, &r);
+ talloc_free(basedn);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_LDAP(ret);
+ } else if (r->count != 1) {
+ talloc_free(r);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ talloc_steal(s, r);
+
+ s->ldap1.rootdse = r->msgs[0];
+
+ s->domain.dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "defaultNamingContext", NULL);
+ if (!s->domain.dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
+
+ s->forest.root_dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "rootDomainNamingContext", NULL);
+ if (!s->forest.root_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ s->forest.config_dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "configurationNamingContext", NULL);
+ if (!s->forest.config_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ s->forest.schema_dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "schemaNamingContext", NULL);
+ if (!s->forest.schema_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
+
+ s->source_dsa.server_dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "serverName", NULL);
+ if (!s->source_dsa.server_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ s->source_dsa.ntds_dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "dsServiceName", NULL);
+ if (!s->source_dsa.ntds_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
+
+ return NT_STATUS_OK;
}
-static NTSTATUS becomeDC_ldap1_requests(struct libnet_BecomeDC_state *s)
+static NTSTATUS becomeDC_ldap1_config_behavior_version(struct libnet_BecomeDC_state *s)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ int ret;
+ struct ldb_result *r;
+ struct ldb_dn *basedn;
+ static const char *attrs[] = {
+ "msDs-Behavior-Version",
+ NULL
+ };
+
+ basedn = ldb_dn_new(s, s->ldap1.ldb, s->forest.config_dn_str);
+
+ ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_ONELEVEL,
+ "(cn=Partitions)", attrs, &r);
+ talloc_free(basedn);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_LDAP(ret);
+ } else if (r->count != 1) {
+ talloc_free(r);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ s->ads_options.config_behavior_version = ldb_msg_find_attr_as_uint(r->msgs[0], "msDs-Behavior-Version", 0);
+
+ talloc_free(r);
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS becomeDC_ldap1_domain_behavior_version(struct libnet_BecomeDC_state *s)
+{
+ int ret;
+ struct ldb_result *r;
+ struct ldb_dn *basedn;
+ static const char *attrs[] = {
+ "msDs-Behavior-Version",
+ NULL
+ };
+
+ basedn = ldb_dn_new(s, s->ldap1.ldb, s->domain.dn_str);
+
+ ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
+ "(objectClass=*)", attrs, &r);
+ talloc_free(basedn);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_LDAP(ret);
+ } else if (r->count != 1) {
+ talloc_free(r);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ s->ads_options.domain_behavior_version = ldb_msg_find_attr_as_uint(r->msgs[0], "msDs-Behavior-Version", 0);
+
+ talloc_free(r);
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS becomeDC_ldap1_schema_object_version(struct libnet_BecomeDC_state *s)
+{
+ int ret;
+ struct ldb_result *r;
+ struct ldb_dn *basedn;
+ static const char *attrs[] = {
+ "objectVersion",
+ NULL
+ };
+
+ basedn = ldb_dn_new(s, s->ldap1.ldb, s->forest.schema_dn_str);
+
+ ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
+ "(objectClass=*)", attrs, &r);
+ talloc_free(basedn);
+ if (ret != LDB_SUCCESS) {
+ return NT_STATUS_LDAP(ret);
+ } else if (r->count != 1) {
+ talloc_free(r);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ s->ads_options.schema_object_version = ldb_msg_find_attr_as_uint(r->msgs[0], "objectVersion", 0);
+
+ talloc_free(r);
+ return NT_STATUS_OK;
+}
+
+
+static void becomeDC_connect_ldap1(struct libnet_BecomeDC_state *s)
+{
+ struct composite_context *c = s->creq;
+
+ c->status = becomeDC_ldap_connect(s, &s->ldap1);
+ if (!composite_is_ok(c)) return;
+
+ c->status = becomeDC_ldap1_rootdse(s);
+ if (!composite_is_ok(c)) return;
+
+ c->status = becomeDC_ldap1_config_behavior_version(s);
+ if (!composite_is_ok(c)) return;
+
+ c->status = becomeDC_ldap1_domain_behavior_version(s);
+ if (!composite_is_ok(c)) return;
+
+ c->status = becomeDC_ldap1_schema_object_version(s);
+ if (!composite_is_ok(c)) return;
+
+ composite_error(c, NT_STATUS_NOT_IMPLEMENTED);
}
struct composite_context *libnet_BecomeDC_send(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_BecomeDC *r)
@@ -177,12 +348,6 @@ struct composite_context *libnet_BecomeDC_send(struct libnet_context *ctx, TALLO
if (composite_nomem(s->dest_dsa.dns_name, c)) return c;
becomeDC_send_cldap(s);
-/* c->status = becomeDC_ldap_connect(s, &s->ldap1);
- if (!composite_is_ok(c)) return c;
-
- c->status = becomeDC_ldap1_requests(s);
- if (!composite_is_ok(c)) return c;
-*/
return c;
}