mirror of
https://github.com/samba-team/samba.git
synced 2025-02-15 05:57:49 +03:00
supportedSASLMechanism in the rootdse. (Second half of a patch commited earlier today). Andrew Bartlett (This used to be commit 4b67b5d688493c385e12734fd2c0c9dbc1b238e4)
166 lines
4.0 KiB
C
166 lines
4.0 KiB
C
/*
|
|
Unix SMB/CIFS implementation.
|
|
|
|
rootDSE ldb module
|
|
|
|
Copyright (C) Andrew Tridgell 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
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include "includes.h"
|
|
#include "lib/ldb/include/ldb.h"
|
|
#include "lib/ldb/include/ldb_errors.h"
|
|
#include "lib/ldb/include/ldb_private.h"
|
|
#include "auth/gensec/gensec.h"
|
|
#include <time.h>
|
|
|
|
/*
|
|
return 1 if a specific attribute has been requested
|
|
*/
|
|
static int do_attribute(const char * const *attrs, const char *name)
|
|
{
|
|
return attrs == NULL ||
|
|
ldb_attr_in_list(attrs, name) ||
|
|
ldb_attr_in_list(attrs, "*");
|
|
}
|
|
|
|
/*
|
|
add dynamically generated attributes to rootDSE result
|
|
*/
|
|
static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_request *req)
|
|
{
|
|
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 (s->res->msgs == NULL) {
|
|
return LDB_SUCCESS;
|
|
}
|
|
|
|
msg = s->res->msgs[0];
|
|
|
|
msg->dn = ldb_dn_explode(msg, "");
|
|
|
|
if (do_attribute(s->attrs, "currentTime")) {
|
|
if (ldb_msg_add_string(msg, "currentTime",
|
|
ldb_timestring(msg, time(NULL))) != 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;
|
|
|
|
failed:
|
|
return LDB_ERR_OPERATIONS_ERROR;
|
|
}
|
|
|
|
/*
|
|
handle search requests
|
|
*/
|
|
static int rootdse_search_bytree(struct ldb_module *module, struct ldb_request *req)
|
|
{
|
|
struct ldb_search *s = &req->op.search;
|
|
int ret;
|
|
TALLOC_CTX *tmp_ctx;
|
|
|
|
/* see if its for the rootDSE */
|
|
if (s->scope != LDB_SCOPE_BASE ||
|
|
(s->base && s->base->comp_num != 0)) {
|
|
return ldb_next_request(module, req);
|
|
}
|
|
|
|
tmp_ctx = talloc_new(module);
|
|
|
|
/* in our db we store the rootDSE with a DN of cn=rootDSE */
|
|
s->base = ldb_dn_explode(tmp_ctx, "cn=rootDSE");
|
|
s->tree = ldb_parse_tree(tmp_ctx, "dn=*");
|
|
if (s->base == NULL || s->tree == NULL) {
|
|
ldb_oom(module->ldb);
|
|
talloc_free(tmp_ctx);
|
|
return LDB_ERR_OPERATIONS_ERROR;
|
|
}
|
|
|
|
/* grab the static contents of the record */
|
|
ret = ldb_next_request(module, req);
|
|
|
|
req->op.search.res = s->res;
|
|
|
|
if (ret == LDB_SUCCESS) {
|
|
ret = rootdse_add_dynamic(module, req);
|
|
}
|
|
|
|
talloc_free(tmp_ctx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
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);
|
|
default:
|
|
break;
|
|
}
|
|
return ldb_next_request(module, req);
|
|
}
|
|
|
|
static const struct ldb_module_ops rootdse_ops = {
|
|
.name = "rootdse",
|
|
.request = rootdse_request
|
|
};
|
|
|
|
struct ldb_module *rootdse_module_init(struct ldb_context *ldb, const char *options[])
|
|
{
|
|
struct ldb_module *ctx;
|
|
|
|
ctx = talloc(ldb, struct ldb_module);
|
|
if (!ctx)
|
|
return NULL;
|
|
|
|
ctx->ldb = ldb;
|
|
ctx->prev = ctx->next = NULL;
|
|
ctx->ops = &rootdse_ops;
|
|
ctx->private_data = NULL;
|
|
|
|
return ctx;
|
|
}
|
|
|