ldb database library
Copyright (C) Andrew Bartlett 2005
+ Copyright (C) Simo Sorce 2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "ldb/include/ldb_errors.h"
#include "ldb/include/ldb_private.h"
#include "auth/auth.h"
+#include "libcli/security/security.h"
/* Kludge ACL rules:
*
return ANONYMOUS;
}
- if (is_system_token(session_info->security_token)) {
+ if (security_token_is_system(session_info->security_token)) {
return SYSTEM;
}
- if (is_administrator_token(session_info->security_token)) {
+ if (security_token_is_anonymous(session_info->security_token)) {
+ return ANONYMOUS;
+ }
+
+ if (security_token_has_builtin_administrators(session_info->security_token)) {
return ADMINISTRATOR;
}
- if (is_authenticated_token(session_info->security_token)) {
+
+ if (security_token_has_nt_authenticated_users(session_info->security_token)) {
return USER;
}
- if (is_anonymous_token(session_info->security_token)) {
- return ANONYMOUS;
- }
+
return ANONYMOUS;
}
return talloc_asprintf(mem_ctx, "%s\\%s",
session_info->server_info->domain_name,
session_info->server_info->account_name);
- return ANONYMOUS;
}
/* search */
-static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
-{
- struct kludge_private_data *data = talloc_get_type(module->private_data, struct kludge_private_data);
- struct ldb_message *msg;
+struct kludge_acl_context {
+
+ struct ldb_module *module;
+ void *up_context;
+ int (*up_callback)(struct ldb_context *, void *, struct ldb_reply *);
+
enum user_is user_type;
- int i, j, ret;
+};
- /* go down the path and wait for reply to filter out stuff if needed */
- ret = ldb_next_request(module, req);
+static int kludge_acl_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares)
+{
+ struct kludge_acl_context *ac;
+ struct kludge_private_data *data;
+ int i;
- /* We may not be fully initialised yet, or we might have just
- * got an error */
- if (ret != LDB_SUCCESS || !data->password_attrs) {
- return ret;
+ if (!context || !ares) {
+ ldb_set_errstring(ldb, "NULL Context or Result in callback");
+ goto error;
}
- user_type = what_is_user(module);
- switch (user_type) {
- case SYSTEM:
- case ADMINISTRATOR:
- return ret;
- default:
- /* For every message, remove password attributes */
- for (i=0; i < req->op.search.res->count; i++) {
- msg = req->op.search.res->msgs[i];
- for (j=0; data->password_attrs[j]; j++) {
- ldb_msg_remove_attr(msg, data->password_attrs[j]);
+ ac = talloc_get_type(context, struct kludge_acl_context);
+ data = talloc_get_type(ac->module->private_data, struct kludge_private_data);
+
+ if (ares->type == LDB_REPLY_ENTRY
+ && data && data->password_attrs) /* if we are not initialized just get through */
+ {
+ switch (ac->user_type) {
+ case SYSTEM:
+ case ADMINISTRATOR:
+ break;
+ default:
+ /* remove password attributes */
+ for (i = 0; data->password_attrs[i]; i++) {
+ ldb_msg_remove_attr(ares->message, data->password_attrs[i]);
}
}
}
- return ret;
+
+ return ac->up_callback(ldb, ac->up_context, ares);
+
+error:
+ talloc_free(ares);
+ return LDB_ERR_OPERATIONS_ERROR;
}
-/* ANY change type */
-static int kludge_acl_change(struct ldb_module *module, struct ldb_request *req){
- enum user_is user_type = what_is_user(module);
- switch (user_type) {
+static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
+{
+ struct kludge_acl_context *ac;
+ struct ldb_request *down_req;
+ struct kludge_private_data *data;
+ int ret, i;
+
+ req->handle = NULL;
+
+ ac = talloc(req, struct kludge_acl_context);
+ if (ac == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ data = talloc_get_type(module->private_data, struct kludge_private_data);
+
+ ac->module = module;
+ ac->up_context = req->context;
+ ac->up_callback = req->callback;
+ ac->user_type = what_is_user(module);
+
+ down_req = talloc_zero(req, struct ldb_request);
+ if (down_req == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ down_req->operation = req->operation;
+ down_req->op.search.base = req->op.search.base;
+ down_req->op.search.scope = req->op.search.scope;
+ down_req->op.search.tree = req->op.search.tree;
+ down_req->op.search.attrs = req->op.search.attrs;
+
+
+ /* FIXME: I hink we should copy the tree and keep the original
+ * unmodified. SSS */
+ /* replace any attributes in the parse tree that are private,
+ so we don't allow a search for 'sambaPassword=penguin',
+ just as we would not allow that attribute to be returned */
+ switch (ac->user_type) {
case SYSTEM:
case ADMINISTRATOR:
- return ldb_next_request(module, req);
+ break;
default:
- ldb_set_errstring(module,
- talloc_asprintf(req, "kludge_acl_change: "
- "attempted database modify not permitted. User %s is not SYSTEM or an administrator",
- user_name(req, module)));
- return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+ /* remove password attributes */
+ for (i = 0; data && data->password_attrs && data->password_attrs[i]; i++) {
+ ldb_parse_tree_attr_replace(down_req->op.search.tree,
+ data->password_attrs[i],
+ "kludgeACLredactedattribute");
+ }
}
-}
-/* start a transaction */
-static int kludge_acl_start_trans(struct ldb_module *module)
-{
- return ldb_next_start_trans(module);
-}
+ down_req->controls = req->controls;
-/* end a transaction */
-static int kludge_acl_end_trans(struct ldb_module *module)
-{
- return ldb_next_end_trans(module);
-}
+ down_req->context = ac;
+ down_req->callback = kludge_acl_callback;
+ ldb_set_timeout_from_prev_req(module->ldb, req, down_req);
-/* delete a transaction */
-static int kludge_acl_del_trans(struct ldb_module *module)
-{
- return ldb_next_del_trans(module);
+ /* perform the search */
+ ret = ldb_next_request(module, down_req);
+
+ /* do not free down_req as the call results may be linked to it,
+ * it will be freed when the upper level request get freed */
+ if (ret == LDB_SUCCESS) {
+ req->handle = down_req->handle;
+ }
+
+ return ret;
}
-static int kludge_acl_request(struct ldb_module *module, struct ldb_request *req)
+/* ANY change type */
+static int kludge_acl_change(struct ldb_module *module, struct ldb_request *req)
{
- switch (req->operation) {
-
- case LDB_REQ_SEARCH:
- return kludge_acl_search(module, req);
- case LDB_REQ_REGISTER:
+ enum user_is user_type = what_is_user(module);
+ switch (user_type) {
+ case SYSTEM:
+ case ADMINISTRATOR:
return ldb_next_request(module, req);
default:
- /* anything else must be a change of some kind */
- return kludge_acl_change(module, req);
+ ldb_asprintf_errstring(module->ldb,
+ "kludge_acl_change: "
+ "attempted database modify not permitted. "
+ "User %s is not SYSTEM or an administrator",
+ user_name(req, module));
+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
}
}
-static int kludge_acl_init_2(struct ldb_module *module)
+static int kludge_acl_init(struct ldb_module *module)
{
int ret, i;
TALLOC_CTX *mem_ctx = talloc_new(module);
- const char *attrs[] = { "attribute", NULL };
+ static const char *attrs[] = { "passwordAttribute", NULL };
struct ldb_result *res;
struct ldb_message *msg;
struct ldb_message_element *password_attributes;
- struct kludge_private_data *data = talloc_get_type(module->private_data, struct kludge_private_data);
+ struct kludge_private_data *data;
+
+ data = talloc(module, struct kludge_private_data);
+ if (data == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
data->password_attrs = NULL;
+ module->private_data = data;
if (!mem_ctx) {
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ldb_search(module->ldb, ldb_dn_explode(mem_ctx, "@KLUDGEACL"),
+ ret = ldb_search(module->ldb, ldb_dn_new(mem_ctx, module->ldb, "@KLUDGEACL"),
LDB_SCOPE_BASE,
NULL, attrs,
&res);
if (ret != LDB_SUCCESS) {
- talloc_free(mem_ctx);
- return ret;
+ goto done;
}
+ talloc_steal(mem_ctx, res);
if (res->count == 0) {
- talloc_free(mem_ctx);
- data->password_attrs = NULL;
- return LDB_SUCCESS;
+ goto done;
}
if (res->count > 1) {
- return LDB_ERR_CONSTRAINT_VIOLAION;
+ talloc_free(mem_ctx);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
}
msg = res->msgs[0];
password_attributes = ldb_msg_find_element(msg, "passwordAttribute");
if (!password_attributes) {
- return LDB_SUCCESS;
+ goto done;
}
data->password_attrs = talloc_array(data, const char *, password_attributes->num_values + 1);
if (!data->password_attrs) {
+ talloc_free(mem_ctx);
return LDB_ERR_OPERATIONS_ERROR;
}
for (i=0; i < password_attributes->num_values; i++) {
talloc_steal(data->password_attrs, password_attributes->values[i].data);
}
data->password_attrs[i] = NULL;
- return LDB_SUCCESS;
+
+done:
+ talloc_free(mem_ctx);
+ return ldb_next_init(module);
}
static const struct ldb_module_ops kludge_acl_ops = {
.name = "kludge_acl",
- .request = kludge_acl_request,
- .start_transaction = kludge_acl_start_trans,
- .end_transaction = kludge_acl_end_trans,
- .del_transaction = kludge_acl_del_trans,
- .second_stage_init = kludge_acl_init_2
+ .search = kludge_acl_search,
+ .add = kludge_acl_change,
+ .modify = kludge_acl_change,
+ .del = kludge_acl_change,
+ .rename = kludge_acl_change,
+ .init_context = kludge_acl_init
};
-struct ldb_module *kludge_acl_module_init(struct ldb_context *ldb, const char *options[])
+int ldb_kludge_acl_init(void)
{
- struct ldb_module *ctx;
- struct kludge_private_data *data;
-
- ctx = talloc(ldb, struct ldb_module);
- if (!ctx)
- return NULL;
-
- data = talloc(ctx, struct kludge_private_data);
- if (data == NULL) {
- talloc_free(ctx);
- return NULL;
- }
-
- data->password_attrs = NULL;
- ctx->private_data = data;
-
- ctx->ldb = ldb;
- ctx->prev = ctx->next = NULL;
- ctx->ops = &kludge_acl_ops;
-
- return ctx;
+ return ldb_register_module(&kludge_acl_ops);
}