[PATCH 2/2] s4:dsdb/rootdse: Support netlogon request

Benjamin Franzke benjaminfranzke at googlemail.com
Sun Oct 27 12:44:17 MDT 2013


This patch adds support for a netlogon ldap style request
over the tcp socket.  This is available since win2k3+ [1].

The automatic client join & configuration daemon "realmd" makes
use of this ability.
Realmd can now be used to join a computer to a samba 4 domain.
(See also:
https://lists.samba.org/archive/samba-technical/2013-October/095606.html)

Tested with:
ldapsearch -h samba-srv -x -b '' -s base "(&(NtVer=\06\00\00\00)(AAC=\00\00\00\00))" NetLogon

And compared the result in wireshark with cldap request issued by
examples/misc/cldap.pl.

[1]: http://wiki.wireshark.org/MS-CLDAP?action=recall&rev=8
---
 source4/dsdb/samdb/ldb_modules/rootdse.c           | 90 ++++++++++++++++++++++
 .../dsdb/samdb/ldb_modules/wscript_build_server    |  2 +-
 2 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index 167201ec60a1378473b5c4bbc8a42d499bebd65b..6683ebf26ce4ba5a6a22194f6a437a6afde761a3 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -34,6 +34,7 @@
 #include "param/param.h"
 #include "lib/messaging/irpc.h"
 #include "librpc/gen_ndr/ndr_irpc_c.h"
+#include "cldap_server/cldap_server.h"
 
 struct private_data {
 	unsigned int num_controls;
@@ -744,6 +745,88 @@ static int rootdse_filter_operations(struct ldb_module *module, struct ldb_reque
 	return LDB_ERR_OPERATIONS_ERROR;
 }
 
+static int rootdse_handle_netlogon(struct rootdse_context *ac)
+{
+	struct ldb_context *ldb;
+	struct ldb_parse_tree *tree;
+	struct loadparm_context *lp_ctx;
+	TALLOC_CTX *tmp_ctx = talloc_new(ac->req);
+	const char *domain, *host, *user, *domain_guid;
+	struct dom_sid *domain_sid;
+	int acct_control = -1;
+	int version = -1;
+	NTSTATUS status;
+	struct netlogon_samlogon_response netlogon;
+	struct ldb_message *msg = NULL;
+	int ret, error = LDB_ERR_OPERATIONS_ERROR;
+	struct ldb_val blob;
+
+	ldb = ldb_module_get_ctx(ac->module);
+	tree = ac->req->op.search.tree;
+	lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
+				 struct loadparm_context);
+
+	status = parse_netlogon_request(tree, lp_ctx, tmp_ctx,
+					&domain, &host, &user, &domain_guid,
+					&domain_sid, &acct_control, &version);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto failed;
+	}
+
+	status = fill_netlogon_samlogon_response(ldb, tmp_ctx,
+						 domain, NULL, domain_sid,
+						 domain_guid,
+						 user, acct_control,
+						 NULL, /* FIXME: How to retrieve client ip addr here? */
+						 version, lp_ctx,
+						 &netlogon, false);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto failed;
+	}
+
+	status = push_netlogon_samlogon_response(&blob, tmp_ctx, &netlogon);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto failed;
+	}
+
+	msg = ldb_msg_new(tmp_ctx);
+	if (!msg) {
+		error = ldb_oom(ldb);
+		goto failed;
+	}
+
+	msg->dn = ldb_dn_new(tmp_ctx, ldb, "");
+	if (!msg->dn) {
+		error = ldb_oom(ldb);
+		goto failed;
+	}
+
+	ret = ldb_msg_add_value(msg, "netlogon", &blob, NULL);
+	if (ret != LDB_SUCCESS) {
+		error = ret;
+		goto failed;
+	}
+
+	ret = ldb_module_send_entry(ac->req, msg, NULL);
+	if (ret != LDB_SUCCESS) {
+		error = ret;
+		goto failed;
+	}
+
+	ret = ldb_module_done(ac->req, NULL, NULL, LDB_SUCCESS);
+	if (ret != LDB_SUCCESS) {
+		error = ret;
+		goto failed;
+	}
+
+	talloc_free(tmp_ctx);
+	return LDB_SUCCESS;
+
+failed:
+	talloc_free(tmp_ctx);
+	return ldb_module_done(ac->req, NULL, NULL, error);
+}
+
 static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
 {
 	struct ldb_context *ldb;
@@ -774,6 +857,13 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
 		return ldb_operr(ldb);
 	}
 
+	if (req->op.search.attrs &&
+	    req->op.search.attrs[0] &&
+	    req->op.search.attrs[1] == NULL &&
+	    ldb_attr_cmp(req->op.search.attrs[0], "netlogon") == 0) {
+		return rootdse_handle_netlogon(ac);
+	}
+
 	/* in our db we store the rootDSE with a DN of @ROOTDSE */
 	ret = ldb_build_search_req(&down_req, ldb, ac,
 					ldb_dn_new(ac, ldb, "@ROOTDSE"),
diff --git a/source4/dsdb/samdb/ldb_modules/wscript_build_server b/source4/dsdb/samdb/ldb_modules/wscript_build_server
index 41eb0f34e1638e17eee8dd677e48d0cff81d3705..7ad1d3b87d5e59e6c777a9c44f56d1f01d3f19c3 100755
--- a/source4/dsdb/samdb/ldb_modules/wscript_build_server
+++ b/source4/dsdb/samdb/ldb_modules/wscript_build_server
@@ -106,7 +106,7 @@ bld.SAMBA_MODULE('ldb_rootdse',
 	init_function='ldb_rootdse_module_init',
 	module_init_name='ldb_init_module',
 	internal_module=False,
-	deps='talloc samdb MESSAGING samba-security DSDB_MODULE_HELPERS RPC_NDR_IRPC'
+	deps='talloc samdb MESSAGING samba-security DSDB_MODULE_HELPERS RPC_NDR_IRPC CLDAPD'
 	)
 
 
-- 
1.8.1.5



More information about the samba-technical mailing list