summaryrefslogtreecommitdiffstats
path: root/source4/dsdb/samdb
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2013-10-27 06:55:48 +0100
committerAndrew Bartlett <abartlet@samba.org>2013-11-11 23:00:54 +0100
commit0620c79d76b69811fd6c00d912db05477d894724 (patch)
treefa4004473dc57dc665555004e5ee9561c4851a84 /source4/dsdb/samdb
parent7a5a62547bc10053fb1e4850e0acacb6a837f36f (diff)
downloadsamba-0620c79d76b69811fd6c00d912db05477d894724.tar.gz
samba-0620c79d76b69811fd6c00d912db05477d894724.tar.xz
samba-0620c79d76b69811fd6c00d912db05477d894724.zip
s4:dsdb/rootdse: Support netlogon request
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 Reviewed-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Nadezhda Ivanova <nivanova@symas.com>
Diffstat (limited to 'source4/dsdb/samdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/rootdse.c83
-rwxr-xr-xsource4/dsdb/samdb/ldb_modules/wscript_build_server2
2 files changed, 74 insertions, 11 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index bcae804945..f905aa2423 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -34,6 +34,8 @@
#include "param/param.h"
#include "lib/messaging/irpc.h"
#include "librpc/gen_ndr/ndr_irpc_c.h"
+#include "lib/tsocket/tsocket.h"
+#include "cldap_server/cldap_server.h"
struct private_data {
unsigned int num_controls;
@@ -46,6 +48,7 @@ struct private_data {
struct rootdse_context {
struct ldb_module *module;
struct ldb_request *req;
+ struct ldb_val netlogon;
};
/*
@@ -477,6 +480,12 @@ static int rootdse_add_dynamic(struct rootdse_context *ac, struct ldb_message *m
}
}
+ if (ac->netlogon.length > 0) {
+ if (ldb_msg_add_steal_value(msg, "netlogon", &ac->netlogon) != LDB_SUCCESS) {
+ goto failed;
+ }
+ }
+
/* TODO: lots more dynamic attributes should be added here */
edn_control = ldb_request_get_control(ac->req, LDB_CONTROL_EXTENDED_DN_OID);
@@ -597,16 +606,6 @@ static int rootdse_callback(struct ldb_request *req, struct ldb_reply *ares)
switch (ares->type) {
case LDB_REPLY_ENTRY:
- /*
- * if the client explicit asks for the 'netlogon' attribute
- * the reply_entry needs to be skipped
- */
- if (ac->req->op.search.attrs &&
- ldb_attr_in_list(ac->req->op.search.attrs, "netlogon")) {
- talloc_free(ares);
- return LDB_SUCCESS;
- }
-
/* for each record returned post-process to add any dynamic
attributes that have been asked for */
ret = rootdse_add_dynamic(ac, ares->message);
@@ -743,6 +742,62 @@ 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;
+ struct tsocket_address *src_addr;
+ TALLOC_CTX *tmp_ctx = talloc_new(ac->req);
+ const char *domain, *host, *user, *domain_guid;
+ char *src_addr_s = NULL;
+ struct dom_sid *domain_sid;
+ int acct_control = -1;
+ int version = -1;
+ NTSTATUS status;
+ struct netlogon_samlogon_response netlogon;
+ int ret = LDB_ERR_OPERATIONS_ERROR;
+
+ 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);
+ src_addr = talloc_get_type(ldb_get_opaque(ldb, "remoteAddress"),
+ struct tsocket_address);
+ if (src_addr) {
+ src_addr_s = tsocket_address_inet_addr_string(src_addr,
+ tmp_ctx);
+ }
+
+ 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,
+ src_addr_s,
+ version, lp_ctx,
+ &netlogon, false);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+
+ status = push_netlogon_samlogon_response(&ac->netlogon, ac, &netlogon);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+
+ ret = LDB_SUCCESS;
+failed:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
{
struct ldb_context *ldb;
@@ -773,6 +828,14 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
return ldb_operr(ldb);
}
+ if (do_attribute_explicit(req->op.search.attrs, "netlogon")) {
+ ret = rootdse_handle_netlogon(ac);
+ /* We have to return an empty result, so dont forward `ret' */
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, LDB_SUCCESS);
+ }
+ }
+
/* 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 41eb0f34e1..7ad1d3b87d 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'
)