diff options
author | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2013-10-27 06:55:48 +0100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2013-11-11 23:00:54 +0100 |
commit | 0620c79d76b69811fd6c00d912db05477d894724 (patch) | |
tree | fa4004473dc57dc665555004e5ee9561c4851a84 /source4/dsdb/samdb | |
parent | 7a5a62547bc10053fb1e4850e0acacb6a837f36f (diff) | |
download | samba-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.c | 83 | ||||
-rwxr-xr-x | source4/dsdb/samdb/ldb_modules/wscript_build_server | 2 |
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' ) |