diff options
author | Andrew Bartlett <abartlet@samba.org> | 2010-11-25 16:13:17 +1100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2010-11-26 08:50:42 +1100 |
commit | d184da806550c2edb6113206048ea78c3d2d27a0 (patch) | |
tree | d0bbfd77df11bf5f6edfdccec055f19fcc519f47 /source4/dsdb/samdb/ldb_modules | |
parent | 885ecd7b6b567a50067c9d3298e67c6e0f85b82a (diff) | |
download | samba-d184da806550c2edb6113206048ea78c3d2d27a0.tar.gz samba-d184da806550c2edb6113206048ea78c3d2d27a0.tar.bz2 samba-d184da806550c2edb6113206048ea78c3d2d27a0.zip |
s4-dsdb Add 'block anonymous' checks to the rootdse module
This ensures that one single point checks for and blocks anonymous
read access to the database over LDAP.
Andrew Bartlett
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/rootdse.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 8a3f0cf8ea..263c6f5bd9 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -40,6 +40,7 @@ struct private_data { char **controls; unsigned int num_partitions; struct ldb_dn **partitions; + bool block_anonymous; }; /* @@ -613,6 +614,35 @@ static int rootdse_filter_controls(struct ldb_module *module, struct ldb_request return LDB_SUCCESS; } +/* Ensure that anonymous users are not allowed to make anything other than rootDSE search operations */ + +static int rootdse_filter_operations(struct ldb_module *module, struct ldb_request *req) +{ + struct auth_session_info *session_info; + struct private_data *priv = talloc_get_type(ldb_module_get_private(module), struct private_data); + bool is_untrusted = ldb_req_is_untrusted(req); + bool is_anonymous = true; + if (is_untrusted == false) { + return LDB_SUCCESS; + } + + session_info = (struct auth_session_info *)ldb_get_opaque(ldb_module_get_ctx(module), "sessionInfo"); + if (session_info) { + is_anonymous = security_token_is_anonymous(session_info->security_token); + } + + if (is_anonymous == false || (priv && priv->block_anonymous == false)) { + return LDB_SUCCESS; + } + + if (req->operation == LDB_SEARCH) { + if (req->op.search.scope == LDB_SCOPE_BASE && ldb_dn_is_null(req->op.search.base)) { + return LDB_SUCCESS; + } + } + ldb_set_errstring(ldb_module_get_ctx(module), "Operation unavailable without authentication"); + return LDB_ERR_STRONG_AUTH_REQUIRED; +} static int rootdse_search(struct ldb_module *module, struct ldb_request *req) { @@ -621,6 +651,11 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req) struct ldb_request *down_req; int ret; + ret = rootdse_filter_operations(module, req); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = rootdse_filter_controls(module, req); if (ret != LDB_SUCCESS) { return ret; @@ -735,6 +770,8 @@ static int rootdse_init(struct ldb_module *module) data->controls = NULL; data->num_partitions = 0; data->partitions = NULL; + data->block_anonymous = true; + ldb_module_set_private(module, data); ldb_set_default_dns(ldb); @@ -833,6 +870,8 @@ static int rootdse_init(struct ldb_module *module) } } + data->block_anonymous = dsdb_block_anonymous_ops(module); + talloc_free(mem_ctx); return LDB_SUCCESS; @@ -1092,6 +1131,11 @@ static int rootdse_add(struct ldb_module *module, struct ldb_request *req) struct ldb_context *ldb = ldb_module_get_ctx(module); int ret; + ret = rootdse_filter_operations(module, req); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = rootdse_filter_controls(module, req); if (ret != LDB_SUCCESS) { return ret; @@ -1163,6 +1207,11 @@ static int rootdse_modify(struct ldb_module *module, struct ldb_request *req) struct ldb_context *ldb = ldb_module_get_ctx(module); int ret; + ret = rootdse_filter_operations(module, req); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = rootdse_filter_controls(module, req); if (ret != LDB_SUCCESS) { return ret; @@ -1205,11 +1254,42 @@ static int rootdse_modify(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_UNWILLING_TO_PERFORM; } +static int rootdse_rename(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + int ret; + + ret = rootdse_filter_operations(module, req); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = rootdse_filter_controls(module, req); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* + If dn is not "" we should let it pass through + */ + if (!ldb_dn_is_null(req->op.rename.olddn)) { + return ldb_next_request(module, req); + } + + ldb_set_errstring(ldb, "rootdse_remove: you cannot rename the rootdse entry!"); + return LDB_ERR_NO_SUCH_OBJECT; +} + static int rootdse_delete(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb = ldb_module_get_ctx(module); int ret; + ret = rootdse_filter_operations(module, req); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = rootdse_filter_controls(module, req); if (ret != LDB_SUCCESS) { return ret; @@ -1226,6 +1306,24 @@ static int rootdse_delete(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_NO_SUCH_OBJECT; } +static int rootdse_extended(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + int ret; + + ret = rootdse_filter_operations(module, req); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = rootdse_filter_controls(module, req); + if (ret != LDB_SUCCESS) { + return ret; + } + + return ldb_next_request(module, req); +} + static const struct ldb_module_ops ldb_rootdse_module_ops = { .name = "rootdse", .init_context = rootdse_init, @@ -1233,6 +1331,8 @@ static const struct ldb_module_ops ldb_rootdse_module_ops = { .request = rootdse_request, .add = rootdse_add, .modify = rootdse_modify, + .rename = rootdse_rename, + .extended = rootdse_extended, .del = rootdse_delete }; |