diff options
author | Andrew Bartlett <abartlet@samba.org> | 2005-10-07 11:31:45 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:39:32 -0500 |
commit | 1377cca5f4beb43cf67fcc65eed79f14178d6349 (patch) | |
tree | 79a693899d0c1377e4009e4088018bc561ea9af4 /source4/ldap_server | |
parent | 5158636aff545de3115e747b53ce68f753151bd7 (diff) | |
download | samba-1377cca5f4beb43cf67fcc65eed79f14178d6349.tar.gz samba-1377cca5f4beb43cf67fcc65eed79f14178d6349.tar.bz2 samba-1377cca5f4beb43cf67fcc65eed79f14178d6349.zip |
r10810: This adds the hooks required to communicate the current user from the
authenticated session down into LDB. This associates a session info
structure with the open LDB, allowing a future ldb_ntacl module to
allow/deny operations on that basis.
Along the way, I cleaned up a few things, and added new helper functions
to assist. In particular the LSA pipe uses simpler queries for some of
the setup.
In ldap_server, I have removed the 'ldasrv:hacked' module, which hasn't
been worked on (other than making it continue to compile) since January,
and I think the features of this module are being put into ldb anyway.
I have also changed the partitions in ldap_server to be initialised
after the connection, with the private pointer used to associate the ldb
with the incoming session.
Andrew Bartlett
(This used to be commit fd7203789a2c0929eecea8125b57b833a67fed71)
Diffstat (limited to 'source4/ldap_server')
-rw-r--r-- | source4/ldap_server/config.mk | 3 | ||||
-rw-r--r-- | source4/ldap_server/ldap_backend.c | 16 | ||||
-rw-r--r-- | source4/ldap_server/ldap_bind.c | 23 | ||||
-rw-r--r-- | source4/ldap_server/ldap_hacked_ldb.c | 1038 | ||||
-rw-r--r-- | source4/ldap_server/ldap_rootdse.c | 17 | ||||
-rw-r--r-- | source4/ldap_server/ldap_server.c | 62 | ||||
-rw-r--r-- | source4/ldap_server/ldap_server.h | 9 | ||||
-rw-r--r-- | source4/ldap_server/ldap_simple_ldb.c | 76 |
8 files changed, 141 insertions, 1103 deletions
diff --git a/source4/ldap_server/config.mk b/source4/ldap_server/config.mk index 3d39b397bd..59f1d5c178 100644 --- a/source4/ldap_server/config.mk +++ b/source4/ldap_server/config.mk @@ -8,8 +8,7 @@ INIT_OBJ_FILES = \ ldap_server/ldap_backend.o \ ldap_server/ldap_bind.o \ ldap_server/ldap_rootdse.o \ - ldap_server/ldap_simple_ldb.o \ - ldap_server/ldap_hacked_ldb.o + ldap_server/ldap_simple_ldb.o REQUIRED_SUBSYSTEMS = \ LIBCLI_LDAP SAMDB # End SUBSYSTEM SMB diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c index 96c9b16f5d..65e6d9d4d4 100644 --- a/source4/ldap_server/ldap_backend.c +++ b/source4/ldap_server/ldap_backend.c @@ -53,10 +53,10 @@ struct ldapsrv_partition *ldapsrv_get_partition(struct ldapsrv_connection *conn, { if (scope == LDAP_SEARCH_SCOPE_BASE && strcasecmp("", dn) == 0) { - return conn->service->rootDSE; + return conn->rootDSE; } - return conn->service->default_partition; + return conn->default_partition; } NTSTATUS ldapsrv_unwilling(struct ldapsrv_call *call, int error) @@ -257,15 +257,3 @@ NTSTATUS ldapsrv_do_call(struct ldapsrv_call *call) } -/* - connect to the sam database -*/ -struct ldb_context *ldapsrv_sam_connect(struct ldapsrv_call *call) -{ - const char *url; - url = lp_parm_string(-1, "ldapsrv", "samdb"); - if (url) { - return ldb_wrap_connect(call, url, 0, NULL); - } - return samdb_connect(call); -} diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index 166bd31ede..9c9cca362b 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -32,6 +32,8 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) DEBUG(10, ("BindSimple dn: %s\n",req->dn)); + /* When we add authentication here, we also need to handle telling the backends */ + reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse); if (!reply) { return NT_STATUS_NO_MEMORY; @@ -102,14 +104,33 @@ reply: result = LDAP_SASL_BIND_IN_PROGRESS; errstr = NULL; } else if (NT_STATUS_IS_OK(status)) { + struct ldapsrv_partition *part; + result = LDAP_SUCCESS; errstr = NULL; if (gensec_have_feature(call->conn->gensec, GENSEC_FEATURE_SEAL) || gensec_have_feature(call->conn->gensec, GENSEC_FEATURE_SIGN)) { call->conn->enable_wrap = True; } + status = gensec_session_info(call->conn->gensec, &call->conn->session_info); + if (!NT_STATUS_IS_OK(status)) { + result = LDAP_OPERATIONS_ERROR; + errstr = talloc_asprintf(reply, "SASL:[%s]: Failed to get session info: %s", req->creds.SASL.mechanism, nt_errstr(status)); + } else { + for (part = call->conn->partitions; part; part = part->next) { + if (!part->ops->Bind) { + continue; + } + status = part->ops->Bind(part, conn); + if (!NT_STATUS_IS_OK(status)) { + result = LDAP_OPERATIONS_ERROR; + errstr = talloc_asprintf(reply, "SASL:[%s]: Failed to advise partition %s of new credentials: %s", req->creds.SASL.mechanism, part->base_dn, nt_errstr(status)); + } + } + } } else { - result = 49; + status = auth_nt_status_squash(status); + result = LDAP_INVALID_CREDENTIALS; errstr = talloc_asprintf(reply, "SASL:[%s]: %s", req->creds.SASL.mechanism, nt_errstr(status)); } diff --git a/source4/ldap_server/ldap_hacked_ldb.c b/source4/ldap_server/ldap_hacked_ldb.c deleted file mode 100644 index 8923bc5a1b..0000000000 --- a/source4/ldap_server/ldap_hacked_ldb.c +++ /dev/null @@ -1,1038 +0,0 @@ -/* - Unix SMB/CIFS implementation. - LDAP server HACKED LDB implementation to hopefully get a DsGetNCChanges() request from a - w2k3 box - - Copyright (C) Stefan Metzmacher 2004-2005 - Copyright (C) Simo Sorce 2004 - - 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 "ldap_server/ldap_server.h" -#include "lib/ldb/include/ldb.h" -#include "librpc/gen_ndr/ndr_security.h" -#include "librpc/gen_ndr/ndr_misc.h" -#include "db_wrap.h" - - -#define VALID_DN_SYNTAX(dn,i) do {\ - if (!(dn)) {\ - return NT_STATUS_NO_MEMORY;\ - } else if ((dn)->comp_num < (i)) {\ - result = LDAP_INVALID_DN_SYNTAX;\ - errstr = "Invalid DN (" #i " components needed for '" #dn "')";\ - goto reply;\ - }\ -} while(0) - -#define ATTR_BLOB_CONST(val) data_blob_talloc(mem_ctx, val, sizeof(val)-1) - -#define ATTR_SINGLE_NOVAL(ctx, attr, blob, num, nam) do { \ - attr->name = talloc_strdup(ctx, nam);\ - NT_STATUS_HAVE_NO_MEMORY(attr->name);\ - attr->num_values = num; \ - attr->values = blob;\ -} while(0) - - -static NTSTATUS convert_values(TALLOC_CTX *mem_ctx, - struct ldb_message_element *elem, - struct ldb_message_element *attrs, - struct ldb_context *samdb, - const char **dn, - struct ldap_SearchRequest *r) -{ - NTSTATUS status; - DEBUG(10, ("convert_values for %s\n", attrs[0].name)); - - attrs->name = talloc_steal(mem_ctx, elem->name); - attrs->values[0].length = elem->values[0].length; - attrs->values[0].data = talloc_steal(mem_ctx, elem->values[0].data); - - if (strcasecmp(attrs->name, "objectGUID") == 0 || - strcasecmp(attrs->name, "invocationID") == 0) - { - struct GUID guid; - DATA_BLOB blob; - - status = GUID_from_string((const char *)elem->values[0].data, &guid); - NT_STATUS_NOT_OK_RETURN(status); - - status = ndr_push_struct_blob(&blob, mem_ctx, &guid, - (ndr_push_flags_fn_t)ndr_push_GUID); - NT_STATUS_NOT_OK_RETURN(status); - - attrs->values[0].length = blob.length; - attrs->values[0].data = talloc_steal(mem_ctx, blob.data); - } - - if (strcasecmp(attrs->name, "objectSID") == 0) - { - struct dom_sid *sid; - DATA_BLOB blob; - - sid = dom_sid_parse_talloc(mem_ctx, (const char *)elem->values[0].data); - NT_STATUS_HAVE_NO_MEMORY(sid); - - status = ndr_push_struct_blob(&blob, mem_ctx, sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - NT_STATUS_NOT_OK_RETURN(status); - - attrs->values[0].length = blob.length; - attrs->values[0].data = talloc_steal(mem_ctx, blob.data); - } - - if (strcasecmp(attrs->name, "ncname") == 0) - { - char *filter = ldb_filter_from_tree(mem_ctx, r->tree); - struct ldb_message **res = NULL; - int count; - const char *dom_dn; - const char *dom_filter; - - const char *dom_sid_str; - struct dom_sid *dom_sid; - DATA_BLOB dom_sid_blob; - const char *dom_sid_hex; - - const char *dom_guid_str; - struct GUID dom_guid; - DATA_BLOB dom_guid_blob; - const char *dom_guid_hex; - - const char *nc_filter; - const char *nc_guid_str; - struct GUID nc_guid; - DATA_BLOB nc_guid_blob; - char *nc_guid_hex; - const char *ncname; - - const char *s_attrs[] = {"objectGUID", "objectSid", NULL}; - char *p2; - - nc_filter = talloc_asprintf(mem_ctx, "(dn=%s)", *dn); -DEBUG(0, (__location__": convert_values(ncname): nc dn = '%s'\n", nc_filter)); - - - /* first the NC stuff */ - count = ldb_search(samdb, NULL, LDB_SCOPE_BASE, nc_filter, s_attrs, &res); - if (count != 1) { - DEBUG(0, (__location__": convert_values(ncname): nc_count: %d \n", count)); - return NT_STATUS_FOOBAR; - } -DEBUG(0, (__location__": convert_values(ncname): nc_res '%s'\n", ldb_dn_linearize(mem_ctx, res[0]->dn))); - nc_guid_str = samdb_result_string(res[0], "objectGUID", NULL); - - status = GUID_from_string(nc_guid_str, &nc_guid); - - status = ndr_push_struct_blob(&nc_guid_blob, mem_ctx, &nc_guid, - (ndr_push_flags_fn_t)ndr_push_GUID); - - nc_guid_hex = data_blob_hex_string(mem_ctx, &nc_guid_blob); - - /* overwrite the dn of the search result */ - *dn = talloc_asprintf(mem_ctx, "<GUID=%s>;%s", nc_guid_hex, *dn); -DEBUG(0, (__location__": convert_values(ncname): dn='%s'\n",*dn)); - /* now the domain stuff */ - - dom_dn = strchr(filter, '='); - dom_dn++; - - p2 = strchr(filter, ')'); - *p2 ='\0'; - - dom_filter = talloc_asprintf(mem_ctx, "(dn=%s)", dom_dn); -DEBUG(0, (__location__": convert_values(ncname): dom dn = '%s'\n", dom_filter)); - count = ldb_search(samdb, NULL, LDB_SCOPE_BASE, dom_filter, s_attrs, &res); - if (count != 1) { - DEBUG(0, (__location__": convert_values(ncname): dom_count: %d \n", count)); - return NT_STATUS_OK; - } - - dom_guid_str = samdb_result_string(res[0], "objectGUID", NULL); - - status = GUID_from_string(dom_guid_str, &dom_guid); - - status = ndr_push_struct_blob(&dom_guid_blob, mem_ctx, &dom_guid, - (ndr_push_flags_fn_t)ndr_push_GUID); - - dom_guid_hex = data_blob_hex_string(mem_ctx, &dom_guid_blob); - - dom_sid_str = samdb_result_string(res[0], "objectSid", NULL); - - dom_sid = dom_sid_parse_talloc(mem_ctx, dom_sid_str); - - status = ndr_push_struct_blob(&dom_sid_blob, mem_ctx, dom_sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - - dom_sid_hex = data_blob_hex_string(mem_ctx, &dom_sid_blob); - - ncname = talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s", - dom_guid_hex, dom_sid_hex, dom_dn); -DEBUG(0, (__location__": convert_values(ncname): ncname='%s'\n",ncname)); - - attrs->values[0].length = strlen(ncname); - attrs->values[0].data = talloc_steal(mem_ctx, ncname); -DEBUG(0, (__location__": convert_values(ncname): end ok\n")); - } - - return NT_STATUS_OK; -} - -static NTSTATUS hacked_wellknown_Search(struct ldapsrv_partition *partition, struct ldapsrv_call *call, - struct ldap_SearchRequest *r) -{ - void *local_ctx; - struct ldap_SearchResEntry *ent; - struct ldap_Result *done; - struct ldapsrv_reply *ent_r, *done_r; - int count; - const char *dn_prefix; - const char *wkdn; - char *p, *p2; - enum ldb_scope scope = LDB_SCOPE_DEFAULT; - char *basedn_str; - - local_ctx = talloc_named(call, 0, "hacked_wellknown_Search local memory context"); - NT_STATUS_HAVE_NO_MEMORY(local_ctx); - - switch (r->scope) { - case LDAP_SEARCH_SCOPE_BASE: - scope = LDB_SCOPE_BASE; - break; - default: - return NT_STATUS_NOT_IMPLEMENTED; - } - -#define WKGUID_prefix "<WKGUID=" - if (strncasecmp(WKGUID_prefix, r->basedn, strlen(WKGUID_prefix)) != 0) { - return NT_STATUS_NOT_IMPLEMENTED; - } - - basedn_str = talloc_strdup(call, r->basedn); - -#define WKGUID_Infrastructure "<WKGUID=2FBAC1870ADE11D297C400C04FD8D5CD," -#define WKGUID_Infrastructure_DN "CN=Infrastructure," - if (strncasecmp(WKGUID_Infrastructure, r->basedn, strlen(WKGUID_Infrastructure)) == 0) { - dn_prefix = WKGUID_Infrastructure_DN; - } else -#define WKGUID_Domain_Controllers "<WKGUID=A361B2FFFFD211D1AA4B00C04FD7D83A," -#define WKGUID_Domain_Controllers_DN "OU=Domain Controllers," - if (strncasecmp(WKGUID_Domain_Controllers, r->basedn, strlen(WKGUID_Domain_Controllers)) == 0) { - dn_prefix = WKGUID_Domain_Controllers_DN; - } else { - DEBUG(0,("UKNOWN dn '%s'\n", basedn_str)); - return NT_STATUS_NOT_IMPLEMENTED; - } - - p = strchr(basedn_str, ','); - p++; - - p2 = strchr(basedn_str, '>'); - *p2 ='\0'; - - wkdn = talloc_asprintf(call, "%s%s", dn_prefix, p); - - count = 1; - ent_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultEntry); - NT_STATUS_HAVE_NO_MEMORY(ent_r); - - ent = &ent_r->msg->r.SearchResultEntry; - ent->dn = talloc_steal(ent_r, wkdn); - DEBUG(0,("hacked result [0] dn: %s\n", ent->dn)); - ent->num_attributes = 0; - ent->attributes = NULL; - - ldapsrv_queue_reply(call, ent_r); - - done_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultDone); - NT_STATUS_HAVE_NO_MEMORY(done_r); - - DEBUG(10,("hacked_Search: results: [%d]\n",count)); - - done = &done_r->msg->r.SearchResultDone; - done->dn = NULL; - done->resultcode = LDAP_SUCCESS; - done->errormessage = NULL; - done->referral = NULL; - - talloc_free(local_ctx); - - ldapsrv_queue_reply(call, done_r); - return NT_STATUS_OK; -} - -static NTSTATUS hacked_Search(struct ldapsrv_partition *partition, struct ldapsrv_call *call, - struct ldap_SearchRequest *r, struct ldb_context *samdb) -{ - NTSTATUS status; - void *local_ctx; - struct ldap_SearchResEntry *ent; - struct ldap_Result *done; - struct ldb_message **res = NULL; - int result = LDAP_SUCCESS; - struct ldapsrv_reply *ent_r, *done_r; - const char *errstr = NULL; - int count, j, y, i; - const char **attrs = NULL; - enum ldb_scope scope = LDB_SCOPE_DEFAULT; - struct ldb_dn *basedn; - - local_ctx = talloc_named(call, 0, "hacked_Search local memory context"); - NT_STATUS_HAVE_NO_MEMORY(local_ctx); - - basedn = ldb_dn_explode(local_ctx, r->basedn); - - switch (r->scope) { - case LDAP_SEARCH_SCOPE_BASE: - DEBUG(10,("hldb_Search: scope: [BASE]\n")); - scope = LDB_SCOPE_BASE; - break; - case LDAP_SEARCH_SCOPE_SINGLE: - DEBUG(10,("hldb_Search: scope: [ONE]\n")); - scope = LDB_SCOPE_ONELEVEL; - break; - case LDAP_SEARCH_SCOPE_SUB: - DEBUG(10,("hldb_Search: scope: [SUB]\n")); - scope = LDB_SCOPE_SUBTREE; - break; - } - - if (r->num_attributes >= 1) { - attrs = talloc_array(samdb, const char *, r->num_attributes+1); - NT_STATUS_HAVE_NO_MEMORY(attrs); - - for (j=0; j < r->num_attributes; j++) { - DEBUG(10,("hacked_Search: attrs: [%s]\n",r->attributes[j])); - attrs[j] = r->attributes[j]; - } - attrs[j] = NULL; - } -DEBUG(0,("hacked basedn: %s\n", ldb_dn_linearize(local_ctx, basedn))); -DEBUGADD(0,("hacked filter: %s\n", ldb_filter_from_tree(r, r->tree))); - count = ldb_search_bytree(samdb, basedn, scope, r->tree, attrs, &res); - talloc_steal(samdb, res); - - if (count < 1) { - DEBUG(0,("hacked not found\n")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - if (scope == LDAP_SEARCH_SCOPE_BASE) { - ent_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultEntry); - NT_STATUS_HAVE_NO_MEMORY(ent_r); - - ent = &ent_r->msg->r.SearchResultEntry; - ent->dn = ldb_dn_linearize(ent_r, res[0]->dn); - DEBUG(0,("hacked result [0] dn: %s\n", ent->dn)); - ent->num_attributes = 0; - ent->attributes = NULL; - if (res[0]->num_elements == 0) { - goto queue_reply; - } - ent->num_attributes = res[0]->num_elements; - ent->attributes = talloc_array(ent_r, struct ldb_message_element, ent->num_attributes); - NT_STATUS_HAVE_NO_MEMORY(ent->attributes); - for (j=0; j < ent->num_attributes; j++) { - ent->attributes[j].name = talloc_steal(ent->attributes, res[0]->elements[j].name); - ent->attributes[j].num_values = 0; - ent->attributes[j].values = NULL; - ent->attributes[j].num_values = res[0]->elements[j].num_values; - if (ent->attributes[j].num_values == 1) { - ent->attributes[j].values = talloc_array(ent->attributes, - DATA_BLOB, ent->attributes[j].num_values); - NT_STATUS_HAVE_NO_MEMORY(ent->attributes[j].values); - status = convert_values(ent_r, - &(res[0]->elements[j]), - &(ent->attributes[j]), - samdb, &ent->dn, r); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - } else { - ent->attributes[j].values = talloc_array(ent->attributes, - DATA_BLOB, ent->attributes[j].num_values); - NT_STATUS_HAVE_NO_MEMORY(ent->attributes[j].values); - for (y=0; y < ent->attributes[j].num_values; y++) { - ent->attributes[j].values[y].length = res[0]->elements[j].values[y].length; - ent->attributes[j].values[y].data = talloc_steal(ent->attributes[j].values, - res[0]->elements[j].values[y].data); - } - } - } -queue_reply: - ldapsrv_queue_reply(call, ent_r); - } else { - for (i=0; i < count; i++) { - ent_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultEntry); - NT_STATUS_HAVE_NO_MEMORY(ent_r); - - ent = &ent_r->msg->r.SearchResultEntry; - ent->dn = ldb_dn_linearize(ent_r, res[i]->dn); - DEBUG(0,("hacked result [%d] dn: %s\n", i, ent->dn)); - ent->num_attributes = 0; - ent->attributes = NULL; - if (res[i]->num_elements == 0) { - goto queue_reply2; - } - ent->num_attributes = res[i]->num_elements; - ent->attributes = talloc_array(ent_r, struct ldb_message_element, ent->num_attributes); - NT_STATUS_HAVE_NO_MEMORY(ent->attributes); - for (j=0; j < ent->num_attributes; j++) { - ent->attributes[j].name = talloc_steal(ent->attributes, res[i]->elements[j].name); - ent->attributes[j].num_values = 0; - ent->attributes[j].values = NULL; - if (r->attributesonly && (res[i]->elements[j].num_values == 0)) { - continue; - } - ent->attributes[j].num_values = res[i]->elements[j].num_values; - ent->attributes[j].values = talloc_array(ent->attributes, - DATA_BLOB, ent->attributes[j].num_values); - NT_STATUS_HAVE_NO_MEMORY(ent->attributes[j].values); - if (ent->attributes[j].num_values == 1) { - status = convert_values(ent_r, - &(res[0]->elements[j]), - &(ent->attributes[j]), - samdb, &ent->dn, r); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - } else { - for (y=0; y < ent->attributes[j].num_values; y++) { - ent->attributes[j].values[y].length = res[i]->elements[j].values[y].length; - ent->attributes[j].values[y].data = talloc_steal(ent->attributes[j].values, - res[i]->elements[j].values[y].data); - } - } - } -queue_reply2: - ldapsrv_queue_reply(call, ent_r); - } - } - - done_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultDone); - NT_STATUS_HAVE_NO_MEMORY(done_r); - - if (count > 0) { - DEBUG(10,("hacked_Search: results: [%d]\n",count)); - result = LDAP_SUCCESS; - errstr = NULL; - } else if (count == 0) { - DEBUG(10,("hacked_Search: no results\n")); - result = LDAP_NO_SUCH_OBJECT; - errstr = ldb_errstring(samdb); - } else if (count == -1) { - DEBUG(10,("hacked_Search: error\n")); - result = LDAP_OTHER; - errstr = ldb_errstring(samdb); - } - - done = &done_r->msg->r.SearchResultDone; - done->dn = NULL; - done->resultcode = result; - done->errormessage = (errstr?talloc_strdup(done_r,errstr):NULL);; - done->referral = NULL; - - talloc_free(local_ctx); - - ldapsrv_queue_reply(call, done_r); - return NT_STATUS_OK; -} - -static NTSTATUS hldb_Search(struct ldapsrv_partition *partition, struct ldapsrv_call *call, - struct ldap_SearchRequest *r) -{ - NTSTATUS status; - void *local_ctx; - struct ldb_context *samdb; -#if 0 - struct ldap_dn *basedn; - struct ldap_Result *done; - struct ldap_SearchResEntry *ent; - struct ldapsrv_reply *ent_r, *done_r; - int result = LDAP_SUCCESS; - struct ldb_message **res = NULL; - int i, j, y, count = 0; - enum ldb_scope scope = LDB_SCOPE_DEFAULT; - const char **attrs = NULL; - const char *errstr = NULL; -#endif - local_ctx = talloc_named(call, 0, "hldb_Search local memory context"); - NT_STATUS_HAVE_NO_MEMORY(local_ctx); - - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); - - status = hacked_Search(partition, call, r, samdb); - talloc_free(local_ctx); - NT_STATUS_IS_OK_RETURN(status); - status = hacked_wellknown_Search(partition, call, r); - NT_STATUS_IS_OK_RETURN(status); - return status; -#if 0 - basedn = ldap_parse_dn(local_ctx, r->basedn); - VALID_DN_SYNTAX(basedn,0); - - DEBUG(10, ("hldb_Search: basedn: [%s]\n", basedn->dn)); - DEBUG(10, ("hldb_Search: filter: [%s]\n", r->filter)); - - switch (r->scope) { - case LDAP_SEARCH_SCOPE_BASE: - DEBUG(10,("hldb_Search: scope: [BASE]\n")); - scope = LDB_SCOPE_BASE; - break; - case LDAP_SEARCH_SCOPE_SINGLE: - DEBUG(10,("hldb_Search: scope: [ONE]\n")); - scope = LDB_SCOPE_ONELEVEL; - break; - case LDAP_SEARCH_SCOPE_SUB: - DEBUG(10,("hldb_Search: scope: [SUB]\n")); - scope = LDB_SCOPE_SUBTREE; - break; - } - - if (r->num_attributes >= 1) { - attrs = talloc_array(samdb, const char *, r->num_attributes+1); - NT_STATUS_HAVE_NO_MEMORY(attrs); - - for (i=0; i < r->num_attributes; i++) { - DEBUG(10,("hldb_Search: attrs: [%s]\n",r->attributes[i])); - attrs[i] = r->attributes[i]; - } - attrs[i] = NULL; - } - - count = ldb_search(samdb, basedn->dn, scope, r->filter, attrs, &res); - talloc_steal(samdb, res); - - if (count < 1) { - status = hacked_Search(partition, call, r, samdb); - NT_STATUS_IS_OK_RETURN(status); - status = hacked_wellknown_Search(partition, call, r); - NT_STATUS_IS_OK_RETURN(status); - } - - for (i=0; i < count; i++) { - ent_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultEntry); - NT_STATUS_HAVE_NO_MEMORY(ent_r); - - ent = &ent_r->msg.r.SearchResultEntry; - ent->dn = talloc_steal(ent_r, res[i]->dn); - ent->num_attributes = 0; - ent->attributes = NULL; - if (res[i]->num_elements == 0) { - goto queue_reply; - } - ent->num_attributes = res[i]->num_elements; - ent->attributes = talloc_array(ent_r, struct ldb_message_element, ent->num_attributes); - NT_STATUS_HAVE_NO_MEMORY(ent->attributes); - for (j=0; j < ent->num_attributes; j++) { - ent->attributes[j].name = talloc_steal(ent->attributes, res[i]->elements[j].name); - ent->attributes[j].num_values = 0; - ent->attributes[j].values = NULL; - if (r->attributesonly && (res[i]->elements[j].num_values == 0)) { - continue; - } - ent->attributes[j].num_values = res[i]->elements[j].num_values; - ent->attributes[j].values = talloc_array(ent->attributes, - DATA_BLOB, ent->attributes[j].num_values); - NT_STATUS_HAVE_NO_MEMORY(ent->attributes[j].values); - for (y=0; y < ent->attributes[j].num_values; y++) { - ent->attributes[j].values[y].length = res[i]->elements[j].values[y].length; - ent->attributes[j].values[y].data = talloc_steal(ent->attributes[j].values, - res[i]->elements[j].values[y].data); - } - } -queue_reply: - ldapsrv_queue_reply(call, ent_r); - } - -reply: - done_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultDone); - NT_STATUS_HAVE_NO_MEMORY(done_r); - - if (result == LDAP_SUCCESS) { - if (count > 0) { - DEBUG(10,("hldb_Search: results: [%d]\n",count)); - result = LDAP_SUCCESS; - errstr = NULL; - } else if (count == 0) { - DEBUG(10,("hldb_Search: no results\n")); - result = LDAP_NO_SUCH_OBJECT; - errstr = ldb_errstring(samdb); - } else if (count == -1) { - DEBUG(10,("hldb_Search: error\n")); - result = LDAP_OTHER; - errstr = ldb_errstring(samdb); - } - } - - done = &done_r->msg.r.SearchResultDone; - done->dn = NULL; - done->resultcode = result; - done->errormessage = (errstr?talloc_strdup(done_r,errstr):NULL); - done->referral = NULL; - - talloc_free(local_ctx); - - ldapsrv_queue_reply(call, done_r); - return NT_STATUS_OK; -#endif -} - -static NTSTATUS hldb_Add(struct ldapsrv_partition *partition, struct ldapsrv_call *call, - struct ldap_AddRequest *r) -{ - void *local_ctx; - struct ldb_dn *dn; - struct ldap_Result *add_result; - struct ldapsrv_reply *add_reply; - int ldb_ret; - struct ldb_context *samdb; - struct ldb_message *msg = NULL; - int result = LDAP_SUCCESS; - const char *errstr = NULL; - int i,j; - - local_ctx = talloc_named(call, 0, "hldb_Add local memory context"); - NT_STATUS_HAVE_NO_MEMORY(local_ctx); - - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); - - msg = talloc(local_ctx, struct ldb_message); - NT_STATUS_HAVE_NO_MEMORY(msg); - - msg->dn = ldb_dn_explode(local_ctx, r->dn); - VALID_DN_SYNTAX(dn, 1); - - DEBUG(10, ("hldb_add: dn: [%s]\n", ldb_dn_linearize(local_ctx, dn))); - - msg->private_data = NULL; - msg->num_elements = 0; - msg->elements = NULL; - - if (r->num_attributes > 0) { - msg->num_elements = r->num_attributes; - msg->elements = talloc_array(msg, struct ldb_message_element, msg->num_elements); - NT_STATUS_HAVE_NO_MEMORY(msg->elements); - - for (i=0; i < msg->num_elements; i++) { - msg->elements[i].name = discard_const_p(char, r->attributes[i].name); - msg->elements[i].flags = 0; - msg->elements[i].num_values = 0; - msg->elements[i].values = NULL; - - if (r->attributes[i].num_values > 0) { - msg->elements[i].num_values = r->attributes[i].num_values; - msg->elements[i].values = talloc_array(msg, struct ldb_val, msg->elements[i].num_values); - NT_STATUS_HAVE_NO_MEMORY(msg->elements[i].values); - - for (j=0; j < msg->elements[i].num_values; j++) { - if (!(r->attributes[i].values[j].length > 0)) { - result = LDAP_OTHER; - errstr = "Empty attribute values are not allowed"; - goto reply; - } - msg->elements[i].values[j].length = r->attributes[i].values[j].length; - msg->elements[i].values[j].data = r->attributes[i].values[j].data; - } - } else { - result = LDAP_OTHER; - errstr = "No attribute values are not allowed"; - goto reply; - } - } - } else { - result = LDAP_OTHER; - errstr = "No attributes are not allowed"; - goto reply; - } - -reply: - add_reply = ldapsrv_init_reply(call, LDAP_TAG_AddResponse); - NT_STATUS_HAVE_NO_MEMORY(add_reply); - - if (result == LDAP_SUCCESS) { - ldb_ret = ldb_add(samdb, msg); - if (ldb_ret == 0) { - DEBUG(0,("hldb_Add: added: '%s'\n", ldb_dn_linearize(msg, msg->dn))); - result = LDAP_SUCCESS; - errstr = NULL; - } else { - /* currently we have no way to tell if there was an internal ldb error - * or if the object was not found, return the most probable error - */ - result = LDAP_OPERATIONS_ERROR; - errstr = ldb_errstring(samdb); - } - } - - add_result = &add_reply->msg->r.AddResponse; - add_result->dn = NULL; - add_result->resultcode = result; - add_result->errormessage = (errstr?talloc_strdup(add_reply,errstr):NULL); - add_result->referral = NULL; - - talloc_free(local_ctx); - - ldapsrv_queue_reply(call, add_reply); - return NT_STATUS_OK; -} - -static NTSTATUS hldb_Del(struct ldapsrv_partition *partition, struct ldapsrv_call *call, - struct ldap_DelRequest *r) -{ - void *local_ctx; - struct ldb_dn *dn; - struct ldap_Result *del_result; - struct ldapsrv_reply *del_reply; - int ldb_ret; - struct ldb_context *samdb; - const char *errstr = NULL; - int result = LDAP_SUCCESS; - - local_ctx = talloc_named(call, 0, "hldb_Del local memory context"); - NT_STATUS_HAVE_NO_MEMORY(local_ctx); - - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); - - dn = ldb_dn_explode(local_ctx, r->dn); - VALID_DN_SYNTAX(dn,1); - - DEBUG(10, ("hldb_Del: dn: [%s]\n", ldb_dn_linearize(local_ctx, dn))); - -reply: - del_reply = ldapsrv_init_reply(call, LDAP_TAG_DelResponse); - NT_STATUS_HAVE_NO_MEMORY(del_reply); - - if (result == LDAP_SUCCESS) { - ldb_ret = ldb_delete(samdb, dn); - if (ldb_ret == 0) { - result = LDAP_SUCCESS; - errstr = NULL; - } else { - /* currently we have no way to tell if there was an internal ldb error - * or if the object was not found, return the most probable error - */ - result = LDAP_NO_SUCH_OBJECT; - errstr = ldb_errstring(samdb); - } - } - - del_result = &del_reply->msg->r.DelResponse; - del_result->dn = NULL; - del_result->resultcode = result; - del_result->errormessage = (errstr?talloc_strdup(del_reply,errstr):NULL); - del_result->referral = NULL; - - talloc_free(local_ctx); - - ldapsrv_queue_reply(call, del_reply); - return NT_STATUS_OK; -} - -static NTSTATUS hldb_Modify(struct ldapsrv_partition *partition, struct ldapsrv_call *call, - struct ldap_ModifyRequest *r) -{ - void *local_ctx; - struct ldb_dn *dn; - struct ldap_Result *modify_result; - struct ldapsrv_reply *modify_reply; - int ldb_ret; - struct ldb_context *samdb; - struct ldb_message *msg = NULL; - int result = LDAP_SUCCESS; - const char *errstr = NULL; - int i,j; - - local_ctx = talloc_named(call, 0, "hldb_Modify local memory context"); - NT_STATUS_HAVE_NO_MEMORY(local_ctx); - - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); - - msg = talloc(local_ctx, struct ldb_message); - NT_STATUS_HAVE_NO_MEMORY(msg); - - msg->dn = ldb_dn_explode(local_ctx, r->dn); - VALID_DN_SYNTAX(dn,1); - - DEBUG(10, ("hldb_modify: dn: [%s]\n", ldb_dn_linearize(local_ctx, dn))); - - msg->private_data = NULL; - msg->num_elements = 0; - msg->elements = NULL; - - if (r->num_mods > 0) { - msg->num_elements = r->num_mods; - msg->elements = talloc_array(msg, struct ldb_message_element, r->num_mods); - NT_STATUS_HAVE_NO_MEMORY(msg->elements); - - for (i=0; i < msg->num_elements; i++) { - msg->elements[i].name = discard_const_p(char, r->mods[i].attrib.name); - msg->elements[i].num_values = 0; - msg->elements[i].values = NULL; - - switch (r->mods[i].type) { - default: - result = LDAP_PROTOCOL_ERROR; - errstr = "Invalid LDAP_MODIFY_* type"; - goto reply; - case LDAP_MODIFY_ADD: - msg->elements[i].flags = LDB_FLAG_MOD_ADD; - break; - case LDAP_MODIFY_DELETE: - msg->elements[i].flags = LDB_FLAG_MOD_DELETE; - break; - case LDAP_MODIFY_REPLACE: - msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; - break; - } - - msg->elements[i].num_values = r->mods[i].attrib.num_values; - if (msg->elements[i].num_values > 0) { - msg->elements[i].values = talloc_array(msg, struct ldb_val, msg->elements[i].num_values); - NT_STATUS_HAVE_NO_MEMORY(msg->elements[i].values); - - for (j=0; j < msg->elements[i].num_values; j++) { - if (!(r->mods[i].attrib.values[j].length > 0)) { - result = LDAP_OTHER; - errstr = "Empty attribute values are not allowed"; - goto reply; - } - msg->elements[i].values[j].length = r->mods[i].attrib.values[j].length; - msg->elements[i].values[j].data = r->mods[i].attrib.values[j].data; - } - } - } - } else { - result = LDAP_OTHER; - errstr = "No mods are not allowed"; - goto reply; - } - -reply: - modify_reply = ldapsrv_init_reply(call, LDAP_TAG_ModifyResponse); - NT_STATUS_HAVE_NO_MEMORY(modify_reply); - - if (result == LDAP_SUCCESS) { - ldb_ret = ldb_modify(samdb, msg); - if (ldb_ret == 0) { - result = LDAP_SUCCESS; - errstr = NULL; - } else { - /* currently we have no way to tell if there was an internal ldb error - * or if the object was not found, return the most probable error - */ - result = LDAP_ATTRIBUTE_OR_VALUE_EXISTS; - result = LDAP_OPERATIONS_ERROR; - errstr = ldb_errstring(samdb); - if (strcmp("Type or value exists", errstr) ==0){ - result = LDAP_ATTRIBUTE_OR_VALUE_EXISTS; - } - DEBUG(0,("failed to modify: %s - %u - %s\n", ldb_dn_linearize(local_ctx, msg->dn), result, errstr)); - } - } - - modify_result = &modify_reply->msg->r.AddResponse; - modify_result->dn = NULL; - modify_result->resultcode = result; - modify_result->errormessage = (errstr?talloc_strdup(modify_reply,errstr):NULL); - modify_result->referral = NULL; - - talloc_free(local_ctx); - - ldapsrv_queue_reply(call, modify_reply); - return NT_STATUS_OK; -} - -static NTSTATUS hldb_Compare(struct ldapsrv_partition *partition, struct ldapsrv_call *call, - struct ldap_CompareRequest *r) -{ - void *local_ctx; - struct ldb_dn *dn; - struct ldap_Result *compare; - struct ldapsrv_reply *compare_r; - int result = LDAP_SUCCESS; - struct ldb_context *samdb; - struct ldb_message **res = NULL; - const char *attrs[1]; - const char *errstr = NULL; - const char *filter = NULL; - int count; - - local_ctx = talloc_named(call, 0, "hldb_Compare local_memory_context"); - NT_STATUS_HAVE_NO_MEMORY(local_ctx); - - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); - - dn = ldb_dn_explode(local_ctx, r->dn); - VALID_DN_SYNTAX(dn,1); - - DEBUG(10, ("hldb_Compare: dn: [%s]\n", ldb_dn_linearize(local_ctx, dn))); - filter = talloc_asprintf(local_ctx, "(%s=%*s)", r->attribute, - (int)r->value.length, r->value.data); - NT_STATUS_HAVE_NO_MEMORY(filter); - - DEBUGADD(10, ("hldb_Compare: attribute: [%s]\n", filter)); - - attrs[0] = NULL; - -reply: - compare_r = ldapsrv_init_reply(call, LDAP_TAG_CompareResponse); - NT_STATUS_HAVE_NO_MEMORY(compare_r); - - if (result == LDAP_SUCCESS) { - count = ldb_search(samdb, dn, LDB_SCOPE_BASE, filter, attrs, &res); - talloc_steal(samdb, res); - if (count == 1) { - DEBUG(10,("hldb_Compare: matched\n")); - result = LDAP_COMPARE_TRUE; - errstr = NULL; - } else if (count == 0) { - DEBUG(10,("hldb_Compare: doesn't matched\n")); - result = LDAP_COMPARE_FALSE; - errstr = NULL; - } else if (count > 1) { - result = LDAP_OTHER; - errstr = "too many objects match"; - DEBUG(10,("hldb_Compare: %d results: %s\n", count, errstr)); - } else if (count == -1) { - result = LDAP_OTHER; - errstr = ldb_errstring(samdb); - DEBUG(10,("hldb_Compare: error: %s\n", errstr)); - } - } - - compare = &compare_r->msg->r.CompareResponse; - compare->dn = NULL; - compare->resultcode = result; - compare->errormessage = (errstr?talloc_strdup(compare_r,errstr):NULL); - compare->referral = NULL; - - talloc_free(local_ctx); - - ldapsrv_queue_reply(call, compare_r); - return NT_STATUS_OK; -} - -static NTSTATUS hldb_ModifyDN(struct ldapsrv_partition *partition, struct ldapsrv_call *call, struct ldap_ModifyDNRequest *r) -{ - void *local_ctx; - struct ldb_dn *olddn, *newrdn, *newsuperior; - struct ldap_Result *modifydn; - struct ldapsrv_reply *modifydn_r; - int ldb_ret; - struct ldb_context *samdb; - const char *errstr = NULL; - int result = LDAP_SUCCESS; - const struct ldb_dn *newdn = NULL; - struct ldb_dn *parentdn = NULL; - - local_ctx = talloc_named(call, 0, "hldb_ModifyDN local memory context"); - NT_STATUS_HAVE_NO_MEMORY(local_ctx); - - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); - - olddn = ldb_dn_explode(local_ctx, r->dn); - VALID_DN_SYNTAX(olddn,2); - - newrdn = ldb_dn_explode(local_ctx, r->newrdn); - VALID_DN_SYNTAX(newrdn,1); - - DEBUG(10, ("hldb_ModifyDN: olddn: [%s]\n", ldb_dn_linearize(local_ctx, olddn))); - DEBUG(10, ("hldb_ModifyDN: newrdn: [%s]\n", ldb_dn_linearize(local_ctx, newrdn))); - - /* we can't handle the rename if we should not remove the old dn */ - if (!r->deleteolddn) { - result = LDAP_UNWILLING_TO_PERFORM; - errstr = "Old RDN must be deleted"; - goto reply; - } - - if (newrdn->comp_num > 1) { - result = LDAP_NAMING_VIOLATION; - errstr = "Error new RDN invalid"; - goto reply; - } - - if (r->newsuperior) { - newsuperior = ldb_dn_explode(local_ctx, r->newsuperior); - VALID_DN_SYNTAX(newsuperior,0); - DEBUG(10, ("hldb_ModifyDN: newsuperior: [%s]\n", ldb_dn_linearize(local_ctx, newsuperior))); - - if (newsuperior->comp_num < 1) { - result = LDAP_AFFECTS_MULTIPLE_DSAS; - errstr = "Error new Superior DN invalid"; - goto reply; - } - parentdn = newsuperior; - } - - if (!parentdn) { - parentdn = ldb_dn_get_parent(local_ctx, olddn); - } - newdn = ldb_dn_make_child(local_ctx, ldb_dn_get_rdn(local_ctx, newrdn), parentdn); - NT_STATUS_HAVE_NO_MEMORY(newdn); - -reply: - modifydn_r = ldapsrv_init_reply(call, LDAP_TAG_ModifyDNResponse); - NT_STATUS_HAVE_NO_MEMORY(modifydn_r); - - if (result == LDAP_SUCCESS) { - ldb_ret = ldb_rename(samdb, olddn, newdn); - if (ldb_ret == 0) { - result = LDAP_SUCCESS; - errstr = NULL; - } else { - /* currently we have no way to tell if there was an internal ldb error - * or if the object was not found, return the most probable error - */ - result = LDAP_NO_SUCH_OBJECT; - errstr = ldb_errstring(samdb); - } - } - - modifydn = &modifydn_r->msg->r.ModifyDNResponse; - modifydn->dn = NULL; - modifydn->resultcode = result; - modifydn->errormessage = (errstr?talloc_strdup(modifydn_r,errstr):NULL); - modifydn->referral = NULL; - - talloc_free(local_ctx); - - ldapsrv_queue_reply(call, modifydn_r); - return NT_STATUS_OK; -} - -static const struct ldapsrv_partition_ops hldb_ops = { - .Search = hldb_Search, - .Add = hldb_Add, - .Del = hldb_Del, - .Modify = hldb_Modify, - .Compare = hldb_Compare, - .ModifyDN = hldb_ModifyDN -}; - -const struct ldapsrv_partition_ops *ldapsrv_get_hldb_partition_ops(void) -{ - return &hldb_ops; -} diff --git a/source4/ldap_server/ldap_rootdse.c b/source4/ldap_server/ldap_rootdse.c index 2392f23799..75429b1843 100644 --- a/source4/ldap_server/ldap_rootdse.c +++ b/source4/ldap_server/ldap_rootdse.c @@ -52,25 +52,28 @@ static void rootdse_db_debug(void *context, enum ldb_debug_level level, const ch /* connect to the SAM database */ -static struct ldb_context *rootdse_db_connect(TALLOC_CTX *mem_ctx) +NTSTATUS rootdse_Init(struct ldapsrv_partition *partition, struct ldapsrv_connection *conn) { char *db_path; struct ldb_context *ldb; + TALLOC_CTX *mem_ctx = talloc_new(partition); db_path = talloc_asprintf(mem_ctx, "tdb://%s", private_path(mem_ctx, "rootdse.ldb")); if (db_path == NULL) { - return NULL; + return NT_STATUS_NO_MEMORY; } ldb = ldb_wrap_connect(mem_ctx, db_path, 0, NULL); if (ldb == NULL) { - return NULL; + return NT_STATUS_INTERNAL_DB_CORRUPTION; } ldb_set_debug(ldb, rootdse_db_debug, NULL); - return ldb; + talloc_steal(partition, ldb); + partition->private = ldb; + return NT_STATUS_OK; } @@ -258,7 +261,7 @@ static NTSTATUS fill_dynamic_values(void *mem_ctx, struct ldb_message_element *a } static NTSTATUS rootdse_Search(struct ldapsrv_partition *partition, struct ldapsrv_call *call, - struct ldap_SearchRequest *r) + struct ldap_SearchRequest *r) { NTSTATUS status; void *local_ctx; @@ -279,8 +282,7 @@ static NTSTATUS rootdse_Search(struct ldapsrv_partition *partition, struct ldaps local_ctx = talloc_named(call, 0, "rootdse_Search local memory context"); NT_STATUS_HAVE_NO_MEMORY(local_ctx); - ldb = rootdse_db_connect(local_ctx); - NT_STATUS_HAVE_NO_MEMORY(ldb); + ldb = partition->private; if (r->num_attributes >= 1) { attrs = talloc_array(ldb, const char *, r->num_attributes+1); @@ -359,6 +361,7 @@ queue_reply: } static const struct ldapsrv_partition_ops rootdse_ops = { + .Init = rootdse_Init, .Search = rootdse_Search }; diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index 83ce059756..dac7feecfb 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -356,6 +356,8 @@ static void ldapsrv_send(struct stream_connection *c, uint16_t flags) */ static void ldapsrv_accept(struct stream_connection *c) { + struct ldapsrv_partition *rootDSE_part; + struct ldapsrv_partition *part; struct ldapsrv_service *ldapsrv_service = talloc_get_type(c->private, struct ldapsrv_service); struct ldapsrv_connection *conn; @@ -386,6 +388,42 @@ static void ldapsrv_accept(struct stream_connection *c) return; } + /* Connections start out anonymous */ + if (!NT_STATUS_IS_OK(auth_anonymous_session_info(conn, &conn->session_info))) { + ldapsrv_terminate_connection(conn, "failed to setup anonymous session info"); + return; + } + + rootDSE_part = talloc(conn, struct ldapsrv_partition); + if (rootDSE_part == NULL) { + ldapsrv_terminate_connection(conn, "talloc failed"); + return; + } + + rootDSE_part->base_dn = ""; /* RootDSE */ + rootDSE_part->ops = ldapsrv_get_rootdse_partition_ops(); + if (!NT_STATUS_IS_OK(rootDSE_part->ops->Init(rootDSE_part, conn))) { + ldapsrv_terminate_connection(conn, "rootDSE Init failed"); + } + + conn->rootDSE = rootDSE_part; + DLIST_ADD_END(conn->partitions, rootDSE_part, struct ldapsrv_partition *); + + part = talloc(conn, struct ldapsrv_partition); + if (part == NULL) { + ldapsrv_terminate_connection(conn, "talloc failed"); + return; + } + + part->base_dn = "*"; /* default partition */ + part->ops = ldapsrv_get_sldb_partition_ops(); + if (!NT_STATUS_IS_OK(part->ops->Init(part, conn))) { + ldapsrv_terminate_connection(conn, "default partition Init failed"); + } + + conn->default_partition = part; + DLIST_ADD_END(conn->partitions, part, struct ldapsrv_partition *); + irpc_add_name(c->msg_ctx, "ldap_server"); } @@ -433,8 +471,6 @@ static NTSTATUS add_socket(struct event_context *event_context, static void ldapsrv_task_init(struct task_server *task) { struct ldapsrv_service *ldap_service; - struct ldapsrv_partition *rootDSE_part; - struct ldapsrv_partition *part; NTSTATUS status; ldap_service = talloc_zero(task, struct ldapsrv_service); @@ -443,28 +479,6 @@ static void ldapsrv_task_init(struct task_server *task) ldap_service->tls_params = tls_initialise(ldap_service); if (ldap_service->tls_params == NULL) goto failed; - rootDSE_part = talloc(ldap_service, struct ldapsrv_partition); - if (rootDSE_part == NULL) goto failed; - - rootDSE_part->base_dn = ""; /* RootDSE */ - rootDSE_part->ops = ldapsrv_get_rootdse_partition_ops(); - - ldap_service->rootDSE = rootDSE_part; - DLIST_ADD_END(ldap_service->partitions, rootDSE_part, struct ldapsrv_partition *); - - part = talloc(ldap_service, struct ldapsrv_partition); - if (part == NULL) goto failed; - - part->base_dn = "*"; /* default partition */ - if (lp_parm_bool(-1, "ldapsrv", "hacked", False)) { - part->ops = ldapsrv_get_hldb_partition_ops(); - } else { - part->ops = ldapsrv_get_sldb_partition_ops(); - } - - ldap_service->default_partition = part; - DLIST_ADD_END(ldap_service->partitions, part, struct ldapsrv_partition *); - if (lp_interfaces() && lp_bind_interfaces_only()) { int num_interfaces = iface_count(); int i; diff --git a/source4/ldap_server/ldap_server.h b/source4/ldap_server/ldap_server.h index 2aa6530f9f..8eb02a97db 100644 --- a/source4/ldap_server/ldap_server.h +++ b/source4/ldap_server/ldap_server.h @@ -27,6 +27,9 @@ struct ldapsrv_connection { struct auth_session_info *session_info; struct ldapsrv_service *service; struct tls_context *tls; + struct ldapsrv_partition *rootDSE; + struct ldapsrv_partition *default_partition; + struct ldapsrv_partition *partitions; /* partially received request */ DATA_BLOB partial; @@ -58,6 +61,7 @@ struct ldapsrv_partition; struct ldapsrv_partition_ops { const char *name; NTSTATUS (*Init)(struct ldapsrv_partition *partition, struct ldapsrv_connection *conn); + NTSTATUS (*Bind)(struct ldapsrv_partition *partition, struct ldapsrv_connection *conn); NTSTATUS (*Search)(struct ldapsrv_partition *partition, struct ldapsrv_call *call, struct ldap_SearchRequest *r); NTSTATUS (*Modify)(struct ldapsrv_partition *partition, struct ldapsrv_call *call, struct ldap_ModifyRequest *r); NTSTATUS (*Add)(struct ldapsrv_partition *partition, struct ldapsrv_call *call, struct ldap_AddRequest *r); @@ -71,15 +75,12 @@ struct ldapsrv_partition_ops { struct ldapsrv_partition { struct ldapsrv_partition *prev,*next; - void *private_data; + void *private; const struct ldapsrv_partition_ops *ops; const char *base_dn; }; struct ldapsrv_service { - struct ldapsrv_partition *rootDSE; - struct ldapsrv_partition *default_partition; - struct ldapsrv_partition *partitions; struct tls_params *tls_params; }; diff --git a/source4/ldap_server/ldap_simple_ldb.c b/source4/ldap_server/ldap_simple_ldb.c index fbeec2f3ca..8a68004599 100644 --- a/source4/ldap_server/ldap_simple_ldb.c +++ b/source4/ldap_server/ldap_simple_ldb.c @@ -22,6 +22,7 @@ #include "includes.h" #include "ldap_server/ldap_server.h" #include "lib/ldb/include/ldb.h" +#include "auth/auth.h" #include "db_wrap.h" #define VALID_DN_SYNTAX(dn,i) do {\ @@ -34,8 +35,61 @@ }\ } while(0) +/* + connect to the sam database +*/ +NTSTATUS sldb_Init(struct ldapsrv_partition *partition, struct ldapsrv_connection *conn) +{ + TALLOC_CTX *mem_ctx = talloc_new(partition); + struct ldb_context *ldb; + const char *url; + url = lp_parm_string(-1, "ldapsrv", "samdb"); + if (url) { + + ldb = ldb_wrap_connect(mem_ctx, url, 0, NULL); + if (ldb == NULL) { + talloc_free(mem_ctx); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + if (ldb_set_opaque(ldb, "sessionInfo", conn->session_info)) { + talloc_free(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + talloc_steal(partition, ldb); + partition->private = ldb; + talloc_free(mem_ctx); + return NT_STATUS_OK; + } + + ldb = samdb_connect(mem_ctx, conn->session_info); + if (ldb == NULL) { + talloc_free(mem_ctx); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + talloc_steal(partition, ldb); + partition->private = ldb; + talloc_free(mem_ctx); + return NT_STATUS_OK; +} + +/* + Re-connect to the ldb after a bind (this does not handle the bind + itself, but just notes the change in credentials) +*/ +NTSTATUS sldb_Bind(struct ldapsrv_partition *partition, struct ldapsrv_connection *conn) +{ + struct ldb_context *samdb = partition->private; + NTSTATUS status; + status = sldb_Init(partition, conn); + if (NT_STATUS_IS_OK(status)) { + /* don't leak the old LDB */ + talloc_free(samdb); + } + return status; +} + static NTSTATUS sldb_Search(struct ldapsrv_partition *partition, struct ldapsrv_call *call, - struct ldap_SearchRequest *r) + struct ldap_SearchRequest *r) { void *local_ctx; struct ldb_dn *basedn; @@ -54,8 +108,7 @@ static NTSTATUS sldb_Search(struct ldapsrv_partition *partition, struct ldapsrv_ local_ctx = talloc_named(call, 0, "sldb_Search local memory context"); NT_STATUS_HAVE_NO_MEMORY(local_ctx); - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); + samdb = partition->private; basedn = ldb_dn_explode(local_ctx, r->basedn); VALID_DN_SYNTAX(basedn, 0); @@ -182,8 +235,7 @@ static NTSTATUS sldb_Add(struct ldapsrv_partition *partition, struct ldapsrv_cal local_ctx = talloc_named(call, 0, "sldb_Add local memory context"); NT_STATUS_HAVE_NO_MEMORY(local_ctx); - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); + samdb = partition->private; dn = ldb_dn_explode(local_ctx, r->dn); VALID_DN_SYNTAX(dn,1); @@ -280,8 +332,7 @@ static NTSTATUS sldb_Del(struct ldapsrv_partition *partition, struct ldapsrv_cal local_ctx = talloc_named(call, 0, "sldb_Del local memory context"); NT_STATUS_HAVE_NO_MEMORY(local_ctx); - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); + samdb = partition->private; dn = ldb_dn_explode(local_ctx, r->dn); VALID_DN_SYNTAX(dn,1); @@ -335,8 +386,7 @@ static NTSTATUS sldb_Modify(struct ldapsrv_partition *partition, struct ldapsrv_ local_ctx = talloc_named(call, 0, "sldb_Modify local memory context"); NT_STATUS_HAVE_NO_MEMORY(local_ctx); - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); + samdb = partition->private; dn = ldb_dn_explode(local_ctx, r->dn); VALID_DN_SYNTAX(dn, 1); @@ -447,8 +497,7 @@ static NTSTATUS sldb_Compare(struct ldapsrv_partition *partition, struct ldapsrv local_ctx = talloc_named(call, 0, "sldb_Compare local_memory_context"); NT_STATUS_HAVE_NO_MEMORY(local_ctx); - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); + samdb = partition->private; dn = ldb_dn_explode(local_ctx, r->dn); VALID_DN_SYNTAX(dn, 1); @@ -515,8 +564,7 @@ static NTSTATUS sldb_ModifyDN(struct ldapsrv_partition *partition, struct ldapsr local_ctx = talloc_named(call, 0, "sldb_ModifyDN local memory context"); NT_STATUS_HAVE_NO_MEMORY(local_ctx); - samdb = ldapsrv_sam_connect(call); - NT_STATUS_HAVE_NO_MEMORY(samdb); + samdb = partition->private; olddn = ldb_dn_explode(local_ctx, r->dn); VALID_DN_SYNTAX(olddn, 2); @@ -591,6 +639,8 @@ reply: } static const struct ldapsrv_partition_ops sldb_ops = { + .Init = sldb_Init, + .Bind = sldb_Bind, .Search = sldb_Search, .Add = sldb_Add, .Del = sldb_Del, |