r12842: don't include system headers directly
[abartlet/samba.git/.git] / source4 / dsdb / samdb / ldb_modules / rootdse.c
index a42119903834ea10ee41eeee9eeae2be3a17a9c0..0bf63f30aecf6128bfcd5d5adb7e9630d4e6eba4 100644 (file)
@@ -4,6 +4,7 @@
    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
@@ -41,8 +48,10 @@ static int do_attribute(const char * const *attrs, const char *name)
 */
 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 :-) */
@@ -61,6 +70,35 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_request *re
                }
        }
 
+       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;
@@ -109,12 +147,35 @@ static int rootdse_search_bytree(struct ldb_module *module, struct ldb_request *
        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;
        }
@@ -129,15 +190,25 @@ static const struct ldb_module_ops rootdse_ops = {
 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;
 }