diff options
author | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2013-10-27 06:55:48 +0100 |
---|---|---|
committer | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2013-11-08 11:28:34 +0100 |
commit | c930fad1c05d98563572386fe350f2cec7b3557f (patch) | |
tree | 204785c0226741986a52dd8566dcb6c41d8eaf56 /source4 | |
parent | 9186981c49f0b60bc843b89e5ea1304b12889fd7 (diff) | |
download | samba-c930fad1c05d98563572386fe350f2cec7b3557f.tar.gz samba-c930fad1c05d98563572386fe350f2cec7b3557f.tar.bz2 samba-c930fad1c05d98563572386fe350f2cec7b3557f.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
Diffstat (limited to 'source4')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/rootdse.c | 83 | ||||
-rwxr-xr-x | source4/dsdb/samdb/ldb_modules/wscript_build_server | 2 | ||||
-rw-r--r-- | source4/ldap_server/ldap_backend.c | 3 |
3 files changed, 77 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' ) diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c index 2760cdb470..3432594209 100644 --- a/source4/ldap_server/ldap_backend.c +++ b/source4/ldap_server/ldap_backend.c @@ -226,6 +226,9 @@ NTSTATUS ldapsrv_backend_Init(struct ldapsrv_connection *conn) ldb_set_opaque(conn->ldb, "supportedSASLMechanisms", sasl_mechs); } + ldb_set_opaque(conn->ldb, "remoteAddress", + conn->connection->remote_address); + return NT_STATUS_OK; } |