diff options
| -rw-r--r-- | source4/cldap_server/cldap_server.h | 3 | ||||
| -rw-r--r-- | source4/cldap_server/netlogon.c | 43 | ||||
| -rw-r--r-- | source4/dsdb/samdb/ldb_modules/rootdse.c | 101 | 
3 files changed, 81 insertions, 66 deletions
| diff --git a/source4/cldap_server/cldap_server.h b/source4/cldap_server/cldap_server.h index 995ceed3a2..181edbd176 100644 --- a/source4/cldap_server/cldap_server.h +++ b/source4/cldap_server/cldap_server.h @@ -56,6 +56,7 @@ NTSTATUS parse_netlogon_request(struct ldb_parse_tree *tree,  				const char **domain_guid,  				struct dom_sid **domain_sid,  				int *acct_control, -				int *version); +				int *version, +				bool filter_from_tree);  #include "cldap_server/proto.h" diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index 0894b2bea7..a5c12df1fb 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -38,6 +38,7 @@  #include "../lib/tsocket/tsocket.h"  #include "libds/common/flag_mapping.h"  #include "lib/util/util_net.h" +#include "lib/ldb/include/ldb_module.h"  /*    fill in the cldap netlogon union for a given version @@ -369,6 +370,21 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,  	return NT_STATUS_OK;  } +/* +  create a always matching node from a equality node + */ +static void set_parse_tree_true(struct ldb_parse_tree *tree) +{ +	const char *attr = tree->u.equality.attr; +	struct ldb_val value = tree->u.equality.value; + +	tree->operation = LDB_OP_EXTENDED; +	tree->u.extended.attr = attr; +	tree->u.extended.value = value; +	tree->u.extended.rule_id = SAMBA_LDAP_MATCH_ALWAYS_TRUE; +	tree->u.extended.dnAttributes = 0; +} +  NTSTATUS parse_netlogon_request(struct ldb_parse_tree *tree,  				struct loadparm_context *lp_ctx,  				TALLOC_CTX *tmp_ctx, @@ -378,7 +394,8 @@ NTSTATUS parse_netlogon_request(struct ldb_parse_tree *tree,  				const char **domain_guid,  				struct dom_sid **domain_sid,  				int *acct_control, -				int *version) +				int *version, +				bool filter_from_tree)  {  	unsigned int i; @@ -400,11 +417,17 @@ NTSTATUS parse_netlogon_request(struct ldb_parse_tree *tree,  			*domain = talloc_strndup(tmp_ctx,  						(const char *)t->u.equality.value.data,  						t->u.equality.value.length); +			if (filter_from_tree) { +				set_parse_tree_true(t); +			}  		}  		if (strcasecmp(t->u.equality.attr, "Host") == 0) {  			*host = talloc_strndup(tmp_ctx,  					      (const char *)t->u.equality.value.data,  					      t->u.equality.value.length); +			if (filter_from_tree) { +				set_parse_tree_true(t); +			}  		}  		if (strcasecmp(t->u.equality.attr, "DomainGuid") == 0) {  			NTSTATUS enc_status; @@ -413,6 +436,9 @@ NTSTATUS parse_netlogon_request(struct ldb_parse_tree *tree,  							  t->u.equality.value, &guid);  			if (NT_STATUS_IS_OK(enc_status)) {  				*domain_guid = GUID_string(tmp_ctx, &guid); +				if (filter_from_tree) { +					set_parse_tree_true(t); +				}  			}  		}  		if (strcasecmp(t->u.equality.attr, "DomainSid") == 0) { @@ -429,19 +455,31 @@ NTSTATUS parse_netlogon_request(struct ldb_parse_tree *tree,  				talloc_free(*domain_sid);  				goto failed;  			} +			if (filter_from_tree) { +				set_parse_tree_true(t); +			}  		}  		if (strcasecmp(t->u.equality.attr, "User") == 0) {  			*user = talloc_strndup(tmp_ctx,  					       (const char *)t->u.equality.value.data,  					       t->u.equality.value.length); +			if (filter_from_tree) { +				set_parse_tree_true(t); +			}  		}  		if (strcasecmp(t->u.equality.attr, "NtVer") == 0 &&  		    t->u.equality.value.length == 4) {  			*version = IVAL(t->u.equality.value.data, 0); +			if (filter_from_tree) { +				set_parse_tree_true(t); +			}  		}  		if (strcasecmp(t->u.equality.attr, "AAC") == 0 &&  		    t->u.equality.value.length == 4) {  			*acct_control = IVAL(t->u.equality.value.data, 0); +			if (filter_from_tree) { +				set_parse_tree_true(t); +			}  		}  	} @@ -480,7 +518,8 @@ void cldapd_netlogon_request(struct cldap_socket *cldap,  	status = parse_netlogon_request(tree, cldapd->task->lp_ctx, tmp_ctx,  					&domain, &host, &user, &domain_guid, -					&domain_sid, &acct_control, &version); +					&domain_sid, &acct_control, &version, +					false);  	if (!NT_STATUS_IS_OK(status)) {  		goto failed;  	} diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index baffd1766c..3ec6248302 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -45,6 +45,12 @@ struct private_data {  	bool block_anonymous;  }; +struct rootdse_context { +	struct ldb_module *module; +	struct ldb_request *req; +	struct ldb_val netlogon; +}; +  /*    return 1 if a specific attribute has been requested  */ @@ -556,11 +562,6 @@ failed:    handle search requests  */ -struct rootdse_context { -	struct ldb_module *module; -	struct ldb_request *req; -}; -  static struct rootdse_context *rootdse_init_context(struct ldb_module *module,  						    struct ldb_request *req)  { @@ -599,16 +600,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, @@ -618,6 +609,17 @@ static int rootdse_callback(struct ldb_request *req, struct ldb_reply *ares)  			return ldb_module_done(ac->req, NULL, NULL, ret);  		} +		/* This should of cause be in rootdse_add_dynamic, +		 * but therefore we need ac there. */ +		if (ac->netlogon.length > 0) { +			ret = ldb_msg_add_value(ares->message, "netlogon", +						&ac->netlogon, NULL); +			if (ret != LDB_SUCCESS) { +				return ret; +			} +		} + +  		return ldb_module_send_entry(ac->req, ares->message, ares->controls);  	case LDB_REPLY_REFERRAL: @@ -760,9 +762,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_SUCCESS;  	ldb = ldb_module_get_ctx(ac->module);  	tree = ac->req->op.search.tree; @@ -774,9 +774,12 @@ static int rootdse_handle_netlogon(struct rootdse_context *ac)  	status = parse_netlogon_request(tree, lp_ctx, tmp_ctx,  					&domain, &host, &user, &domain_guid, -					&domain_sid, &acct_control, &version); +					&domain_sid, &acct_control, &version, +					true);  	if (!NT_STATUS_IS_OK(status)) { -		goto failed; +		/* We have to return an empty search if the filter +		 * does not match, no an error. */ +		goto done;  	}  	status = fill_netlogon_samlogon_response(ldb, tmp_ctx, @@ -787,50 +790,19 @@ static int rootdse_handle_netlogon(struct rootdse_context *ac)  						 version, lp_ctx,  						 &netlogon, false);  	if (!NT_STATUS_IS_OK(status)) { -		goto failed; +		ret = LDB_ERR_OPERATIONS_ERROR; +		goto done;  	} -	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; +		ret = LDB_ERR_OPERATIONS_ERROR; +		goto done;  	} +done:  	talloc_free(tmp_ctx); -	return 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) @@ -863,11 +835,14 @@ 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); +		/* Finish with an empty reply here, either if: +		 *  - An error was returned, or +		 *  - No valid netlogon generated (i.e filter didn't match). */ +		if (ret != LDB_SUCCESS || ac->netlogon.length == 0) { +			return ldb_module_done(ac->req, NULL, NULL, ret); +		}  	}  	/* in our db we store the rootDSE with a DN of @ROOTDSE */ | 
