2 Unix SMB/CIFS implementation.
3 LDAP server SIMPLE LDB implementation
4 Copyright (C) Stefan Metzmacher 2004
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /* TODO: samdb_context is not a pulblic struct */
24 struct samdb_context {
25 struct ldb_context *ldb;
26 struct samdb_context **static_ptr;
30 #define ALLOC_CHECK(ptr) do {\
32 return NT_STATUS_NO_MEMORY;\
36 static NTSTATUS sldb_Search(struct ldapsrv_partition *partition, struct ldapsrv_call *call,
37 struct ldap_SearchRequest *r)
40 struct ldap_Result *done;
41 struct ldap_SearchResEntry *ent;
42 struct ldapsrv_reply *ent_r, *done_r;
44 struct samdb_context *samdb;
45 struct ldb_message **res;
47 struct ldb_context *ldb;
48 enum ldb_scope scope = LDB_SCOPE_DEFAULT;
49 const char **attrs = NULL;
51 DEBUG(0, ("sldb_Search: %s\n", r->filter));
53 samdb = samdb_connect(call);
57 case LDAP_SEARCH_SCOPE_BASE:
58 scope = LDB_SCOPE_BASE;
60 case LDAP_SEARCH_SCOPE_SINGLE:
61 scope = LDB_SCOPE_ONELEVEL;
63 case LDAP_SEARCH_SCOPE_SUB:
64 scope = LDB_SCOPE_SUBTREE;
68 if (r->num_attributes >= 1) {
69 attrs = talloc_array_p(samdb, const char *, r->num_attributes+1);
72 for (i=0; i < r->num_attributes; i++) {
73 attrs[i] = r->attributes[i];
78 ldb_set_alloc(ldb, talloc_ldb_alloc, samdb);
79 count = ldb_search(ldb, r->basedn, scope, r->filter, attrs, &res);
83 } else if (count == 0) {
85 } else if (count == -1) {
89 for (i=0; i < count; i++) {
90 ent_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultEntry);
93 ent = &ent_r->msg.r.SearchResultEntry;
94 ent->dn = talloc_steal(ent_r, res[i]->dn);
95 ent->num_attributes = 0;
96 ent->attributes = NULL;
97 if (res[i]->num_elements == 0) {
100 ent->num_attributes = res[i]->num_elements;
101 ent->attributes = talloc_array_p(ent_r, struct ldap_attribute, ent->num_attributes);
102 ALLOC_CHECK(ent->attributes);
103 for (j=0; j < ent->num_attributes; j++) {
104 ent->attributes[j].name = talloc_steal(ent->attributes, res[i]->elements[j].name);
105 ent->attributes[j].num_values = 0;
106 ent->attributes[j].values = NULL;
107 if (r->attributesonly && (res[i]->elements[j].num_values == 0)) {
110 ent->attributes[j].num_values = res[i]->elements[j].num_values;
111 ent->attributes[j].values = talloc_array_p(ent->attributes,
112 DATA_BLOB, ent->attributes[j].num_values);
113 ALLOC_CHECK(ent->attributes[j].values);
114 for (y=0; y < ent->attributes[j].num_values; y++) {
115 ent->attributes[j].values[y].length = res[i]->elements[j].values[y].length;
116 ent->attributes[j].values[y].data = talloc_steal(ent->attributes[j].values,
117 res[i]->elements[j].values[y].data);
121 status = ldapsrv_queue_reply(call, ent_r);
122 if (!NT_STATUS_IS_OK(status)) {
129 done_r = ldapsrv_init_reply(call, LDAP_TAG_SearchResultDone);
132 done = &done_r->msg.r.SearchResultDone;
133 done->resultcode = result;
135 done->errormessage = NULL;
136 done->referral = NULL;
138 return ldapsrv_queue_reply(call, done_r);
141 static const struct ldapsrv_partition_ops sldb_ops = {
142 .Search = sldb_Search
145 const struct ldapsrv_partition_ops *ldapsrv_get_sldb_partition_ops(void)