rootDSE ldb module
Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Simo Sorce 2005
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 "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
#include "lib/ldb/include/ldb_private.h"
-#include <time.h>
+#include "auth/gensec/gensec.h"
+#include "system/time.h"
+
+struct private_data {
+ int num_controls;
+ char **controls;
+};
/*
return 1 if a specific attribute has been requested
*/
static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_request *req)
{
+ struct private_data *priv = talloc_get_type(module->private_data, struct private_data);
struct ldb_search *s = &req->op.search;
struct ldb_message *msg;
+ struct cli_credentials *server_creds;
/* this is gross, and will be removed when I change ldb_result not
to be so pointer crazy :-) */
}
}
+ if (do_attribute(s->attrs, "supportedControl")) {
+ int i;
+ for (i = 0; i < priv->num_controls; i++) {
+ if (ldb_msg_add_string(msg, "supportedControl",
+ priv->controls[i]) != 0) {
+ goto failed;
+ }
+ }
+ }
+
+ server_creds = talloc_get_type(ldb_get_opaque(module->ldb, "server_credentials"),
+ struct cli_credentials);
+ if (do_attribute(s->attrs, "supportedSASLMechanisms")) {
+ const struct gensec_security_ops **ops = cli_credentials_gensec_list(server_creds);
+ int i;
+ for (i = 0; ops && ops[i]; i++) {
+ if (ops[i]->sasl_name) {
+ const char *sasl_name = talloc_strdup(msg, ops[i]->sasl_name);
+ if (!sasl_name) {
+ goto failed;
+ }
+ if (ldb_msg_add_string(msg, "supportedSASLMechanisms",
+ sasl_name) != 0) {
+ goto failed;
+ }
+ }
+ }
+ }
+
/* TODO: lots more dynamic attributes should be added here */
return 0;
return ret;
}
+static int rootdse_register_control(struct ldb_module *module, struct ldb_request *req)
+{
+ struct private_data *priv = talloc_get_type(module->private_data, struct private_data);
+ char **list;
+
+ list = talloc_realloc(priv, priv->controls, char *, priv->num_controls + 1);
+ if (!list) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ list[priv->num_controls] = talloc_strdup(list, req->op.reg.oid);
+ if (!list[priv->num_controls]) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ priv->num_controls += 1;
+ priv->controls = list;
+
+ return LDB_SUCCESS;
+}
+
static int rootdse_request(struct ldb_module *module, struct ldb_request *req)
{
switch (req->operation) {
case LDB_REQ_SEARCH:
return rootdse_search_bytree(module, req);
+ case LDB_REQ_REGISTER:
+ return rootdse_register_control(module, req);
default:
break;
}
struct ldb_module *rootdse_module_init(struct ldb_context *ldb, const char *options[])
{
struct ldb_module *ctx;
+ struct private_data *data;
ctx = talloc(ldb, struct ldb_module);
if (!ctx)
return NULL;
+ data = talloc(ctx, struct private_data);
+ if (data == NULL) {
+ talloc_free(ctx);
+ return NULL;
+ }
+
+ data->num_controls = 0;
+ data->controls = NULL;
+ ctx->private_data = data;
+
ctx->ldb = ldb;
ctx->prev = ctx->next = NULL;
ctx->ops = &rootdse_ops;
- ctx->private_data = NULL;
return ctx;
}