From f0a28534de216feaaa8c6e0ab27e88f0eebc019b Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 30 Oct 2013 11:54:21 +0100 Subject: s4:dsdb/rootdse: Netlogon maybe requested with other attrs MS AD allows netlogon requests to request other attributes, as long as the search parameter is correct, e.g: ldapsearch -h 192.168.122.2 -x -b '' -s base \ "(&(NtVer=\06\00\00\00)(AAC=\00\00\00\00))" \ supportedLDAPPolicies netlogon This also removes an old check that for requests having a netlogon attribute returned zero elements. This is not true, if there is a valid netlogon filter. This patch is to be squashed into "s4:dsdb/rootdse: Support netlogon request". --- source4/dsdb/samdb/ldb_modules/rootdse.c | 70 ++++++++------------------------ 1 file changed, 17 insertions(+), 53 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 9cc2e65df6..99e8844ba1 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -47,6 +47,7 @@ struct private_data { struct rootdse_context { struct ldb_module *module; struct ldb_request *req; + struct ldb_val netlogon; }; /* @@ -478,6 +479,12 @@ static int rootdse_add_dynamic(struct rootdse_context *ac, struct ldb_message *m } } + if (ac->netlogon.length > 0) { + if (ldb_msg_add_value(msg, "netlogon", &ac->netlogon, NULL) != 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); @@ -598,16 +605,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); @@ -756,9 +753,7 @@ static int rootdse_handle_netlogon(struct rootdse_context *ac) 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; + int ret = LDB_ERR_OPERATIONS_ERROR; ldb = ldb_module_get_ctx(ac->module); tree = ac->req->op.search.tree; @@ -783,47 +778,15 @@ static int rootdse_handle_netlogon(struct rootdse_context *ac) goto failed; } - status = push_netlogon_samlogon_response(&blob, tmp_ctx, &netlogon); + status = push_netlogon_samlogon_response(&ac->netlogon, ac, &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(msg, 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; - + ret = LDB_SUCCESS; failed: talloc_free(tmp_ctx); - return ldb_module_done(ac->req, NULL, NULL, error); + return ret; } static int rootdse_search(struct ldb_module *module, struct ldb_request *req) @@ -856,11 +819,12 @@ 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); + 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 */ -- cgit