summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2013-10-27 06:55:48 +0100
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2013-11-08 11:28:34 +0100
commitc930fad1c05d98563572386fe350f2cec7b3557f (patch)
tree204785c0226741986a52dd8566dcb6c41d8eaf56
parent9186981c49f0b60bc843b89e5ea1304b12889fd7 (diff)
downloadsamba-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
-rw-r--r--source4/dsdb/samdb/ldb_modules/rootdse.c83
-rwxr-xr-xsource4/dsdb/samdb/ldb_modules/wscript_build_server2
-rw-r--r--source4/ldap_server/ldap_backend.c3
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;
}