*/
#include "includes.h"
-#include "ldb/include/ldb.h"
-#include "ldb/include/ldb_errors.h"
-#include "ldb/include/ldb_private.h"
+#include "ldb_module.h"
#include "auth/auth.h"
#include "libcli/security/security.h"
#include "dsdb/samdb/samdb.h"
+#include "param/param.h"
+#include "lib/util/tsort.h"
/* Kludge ACL rules:
*
struct kludge_private_data {
const char **password_attrs;
+ bool acl_perform;
};
static enum security_user_level what_is_user(struct ldb_module *module)
{
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
struct auth_session_info *session_info
- = (struct auth_session_info *)ldb_get_opaque(module->ldb, "sessionInfo");
- return security_session_user_level(session_info);
+ = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo");
+ return security_session_user_level(session_info, NULL);
}
static const char *user_name(TALLOC_CTX *mem_ctx, struct ldb_module *module)
{
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
struct auth_session_info *session_info
- = (struct auth_session_info *)ldb_get_opaque(module->ldb, "sessionInfo");
+ = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo");
if (!session_info) {
return "UNKNOWN (NULL)";
}
{
struct ldb_message_element *oc_el;
struct ldb_message_element *allowedAttributes;
- const struct dsdb_schema *schema = dsdb_get_schema(ldb);
+ /* We need to ensure that the strings returned are valid for as long as the msg is valid */
+ const struct dsdb_schema *schema = dsdb_get_schema(ldb, msg);
TALLOC_CTX *mem_ctx;
- char **objectclass_list, **attr_list;
- int i, ret;
+ const char **attr_list;
+ unsigned int i;
+ int ret;
/* If we don't have a schema yet, we can't do anything... */
if (schema == NULL) {
mem_ctx = talloc_new(msg);
if (!mem_ctx) {
- ldb_oom(ldb);
- return LDB_ERR_OPERATIONS_ERROR;
+ return ldb_oom(ldb);
}
/* To ensure that oc_el is valid, we must look for it after
we alter the element array in ldb_msg_add_empty() */
oc_el = ldb_msg_find_element(msg, "objectClass");
- objectclass_list = talloc_array(mem_ctx, char *, oc_el->num_values + 1);
- if (!objectclass_list) {
- ldb_oom(ldb);
- talloc_free(mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- for (i=0; oc_el && i < oc_el->num_values; i++) {
- objectclass_list[i] = (char *)oc_el->values[i].data;
- }
- objectclass_list[i] = NULL;
-
- attr_list = dsdb_full_attribute_list(mem_ctx, schema, (const char **)objectclass_list, DSDB_SCHEMA_ALL);
+ attr_list = dsdb_full_attribute_list(mem_ctx, schema, oc_el, DSDB_SCHEMA_ALL);
if (!attr_list) {
ldb_asprintf_errstring(ldb, "kludge_acl: Failed to get list of attributes create %s attribute", attrName);
talloc_free(mem_ctx);
{
struct ldb_message_element *oc_el;
struct ldb_message_element *allowedClasses;
- const struct dsdb_schema *schema = dsdb_get_schema(ldb);
- const struct dsdb_class *class;
- int i, j, ret;
+
+ /* We need to ensure that the strings returned are valid for as long as the msg is valid */
+ const struct dsdb_schema *schema = dsdb_get_schema(ldb, msg);
+ const struct dsdb_class *sclass;
+ unsigned int i, j;
+ int ret;
/* If we don't have a schema yet, we can't do anything... */
if (schema == NULL) {
oc_el = ldb_msg_find_element(msg, "objectClass");
for (i=0; oc_el && i < oc_el->num_values; i++) {
- class = dsdb_class_by_lDAPDisplayName(schema, (const char *)oc_el->values[i].data);
- if (!class) {
+ sclass = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &oc_el->values[i]);
+ if (!sclass) {
/* We don't know this class? what is going on? */
continue;
}
- for (j=0; class->possibleInferiors && class->possibleInferiors[j]; j++) {
- ldb_msg_add_string(msg, attrName, class->possibleInferiors[j]);
+ for (j=0; sclass->possibleInferiors && sclass->possibleInferiors[j]; j++) {
+ ldb_msg_add_string(msg, attrName, sclass->possibleInferiors[j]);
}
}
if (allowedClasses->num_values > 1) {
- qsort(allowedClasses->values,
- allowedClasses->num_values,
- sizeof(*allowedClasses->values),
- (comparison_fn_t)data_blob_cmp);
+ TYPESAFE_QSORT(allowedClasses->values, allowedClasses->num_values, data_blob_cmp);
for (i=1 ; i < allowedClasses->num_values; i++) {
}
return LDB_SUCCESS;
-
}
/* find all attributes allowed by all these objectClasses */
static int kludge_acl_callback(struct ldb_request *req, struct ldb_reply *ares)
{
+ struct ldb_context *ldb;
struct kludge_acl_context *ac;
struct kludge_private_data *data;
- int i, ret;
+ unsigned int i;
+ int ret;
ac = talloc_get_type(req->context, struct kludge_acl_context);
- data = talloc_get_type(ac->module->private_data, struct kludge_private_data);
+ data = talloc_get_type(ldb_module_get_private(ac->module), struct kludge_private_data);
+ ldb = ldb_module_get_ctx(ac->module);
if (!ares) {
return ldb_module_done(ac->req, NULL, NULL,
switch (ares->type) {
case LDB_REPLY_ENTRY:
if (ac->allowedAttributes) {
- ret = kludge_acl_allowedAttributes(ac->module->ldb,
+ ret = kludge_acl_allowedAttributes(ldb,
ares->message,
"allowedAttributes");
if (ret != LDB_SUCCESS) {
}
}
if (ac->allowedChildClasses) {
- ret = kludge_acl_childClasses(ac->module->ldb,
+ ret = kludge_acl_childClasses(ldb,
ares->message,
"allowedChildClasses");
if (ret != LDB_SUCCESS) {
switch (ac->user_type) {
case SECURITY_SYSTEM:
if (ac->allowedAttributesEffective) {
- ret = kludge_acl_allowedAttributes(ac->module->ldb, ares->message,
+ ret = kludge_acl_allowedAttributes(ldb, ares->message,
"allowedAttributesEffective");
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
}
if (ac->allowedChildClassesEffective) {
- ret = kludge_acl_childClasses(ac->module->ldb, ares->message,
+ ret = kludge_acl_childClasses(ldb, ares->message,
"allowedChildClassesEffective");
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
case SECURITY_ADMINISTRATOR:
if (ac->allowedAttributesEffective) {
- ret = kludge_acl_allowedAttributes(ac->module->ldb, ares->message,
+ ret = kludge_acl_allowedAttributes(ldb, ares->message,
"allowedAttributesEffective");
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
}
if (ac->allowedChildClassesEffective) {
- ret = kludge_acl_childClasses(ac->module->ldb, ares->message,
+ ret = kludge_acl_childClasses(ldb, ares->message,
"allowedChildClassesEffective");
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
{
+ struct ldb_context *ldb;
struct kludge_acl_context *ac;
struct ldb_request *down_req;
struct kludge_private_data *data;
const char * const *attrs;
- int ret, i;
- struct ldb_control *sd_control;
- struct ldb_control **sd_saved_controls;
+ int ret;
+ unsigned int i;
+
+ ldb = ldb_module_get_ctx(module);
ac = talloc(req, struct kludge_acl_context);
if (ac == NULL) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
+ return ldb_oom(ldb);
}
- data = talloc_get_type(module->private_data, struct kludge_private_data);
+ data = talloc_get_type(ldb_module_get_private(module), struct kludge_private_data);
+
+ if (data && data->acl_perform)
+ return ldb_next_request(module, req);
ac->module = module;
ac->req = req;
}
ret = ldb_build_search_req_ex(&down_req,
- module->ldb, ac,
+ ldb, ac,
req->op.search.base,
req->op.search.scope,
req->op.search.tree,
ac, kludge_acl_callback,
req);
if (ret != LDB_SUCCESS) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* check if there's an SD_FLAGS control */
- sd_control = ldb_request_get_control(down_req, LDB_CONTROL_SD_FLAGS_OID);
- if (sd_control) {
- /* save it locally and remove it from the list */
- /* we do not need to replace them later as we
- * are keeping the original req intact */
- if (!save_controls(sd_control, down_req, &sd_saved_controls)) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
+ return ret;
}
/* perform the search */
/* ANY change type */
static int kludge_acl_change(struct ldb_module *module, struct ldb_request *req)
{
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
enum security_user_level user_type = what_is_user(module);
+ struct kludge_private_data *data = talloc_get_type(ldb_module_get_private(module),
+ struct kludge_private_data);
+
+ if (data->acl_perform)
+ return ldb_next_request(module, req);
+
switch (user_type) {
case SECURITY_SYSTEM:
case SECURITY_ADMINISTRATOR:
return ldb_next_request(module, req);
default:
- ldb_asprintf_errstring(module->ldb,
+ ldb_asprintf_errstring(ldb,
"kludge_acl_change: "
"attempted database modify not permitted. "
"User %s is not SYSTEM or an administrator",
static int kludge_acl_extended(struct ldb_module *module, struct ldb_request *req)
{
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
enum security_user_level user_type;
/* allow everybody to read the sequence number */
case SECURITY_ADMINISTRATOR:
return ldb_next_request(module, req);
default:
- ldb_asprintf_errstring(module->ldb,
+ ldb_asprintf_errstring(ldb,
"kludge_acl_change: "
"attempted database modify not permitted. "
"User %s is not SYSTEM or an administrator",
static int kludge_acl_init(struct ldb_module *module)
{
- int ret, i;
+ struct ldb_context *ldb;
+ int ret;
+ unsigned int i;
TALLOC_CTX *mem_ctx = talloc_new(module);
static const char *attrs[] = { "passwordAttribute", NULL };
struct ldb_result *res;
struct kludge_private_data *data;
+ ldb = ldb_module_get_ctx(module);
+
data = talloc(module, struct kludge_private_data);
if (data == NULL) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
+ return ldb_oom(ldb);
}
data->password_attrs = NULL;
- module->private_data = data;
+ data->acl_perform = lp_parm_bool(ldb_get_opaque(ldb, "loadparm"),
+ NULL, "acl", "perform", false);
+ ldb_module_set_private(module, data);
if (!mem_ctx) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
+ return ldb_oom(ldb);
}
- ret = ldb_search(module->ldb, mem_ctx, &res,
- ldb_dn_new(mem_ctx, module->ldb, "@KLUDGEACL"),
+ ret = ldb_search(ldb, mem_ctx, &res,
+ ldb_dn_new(mem_ctx, ldb, "@KLUDGEACL"),
LDB_SCOPE_BASE, attrs, NULL);
if (ret != 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);
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
+ return ldb_oom(ldb);
}
for (i=0; i < password_attributes->num_values; i++) {
data->password_attrs[i] = (const char *)password_attributes->values[i].data;
}
data->password_attrs[i] = NULL;
- ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
- if (ret != LDB_SUCCESS) {
- ldb_debug(module->ldb, LDB_DEBUG_ERROR,
- "partition: Unable to register control with rootdse!\n");
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
done:
talloc_free(mem_ctx);
return ldb_next_init(module);
_PUBLIC_ const struct ldb_module_ops ldb_kludge_acl_module_ops = {
.name = "kludge_acl",
- .search = kludge_acl_search,
+/* .search = kludge_acl_search,
.add = kludge_acl_change,
.modify = kludge_acl_change,
.del = kludge_acl_change,
- .rename = kludge_acl_change,
+ .rename = kludge_acl_change, */
.extended = kludge_acl_extended,
.init_context = kludge_acl_init
};