2 Unix SMB/CIFS implementation.
4 CLDAP server - rootdse handling
6 Copyright (C) Stefan Metzmacher 2006
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "lib/ldb/include/ldb.h"
25 #include "lib/ldb/include/ldb_errors.h"
26 #include "smbd/service_task.h"
27 #include "cldap_server/cldap_server.h"
28 #include "librpc/gen_ndr/ndr_misc.h"
29 #include "dsdb/samdb/samdb.h"
32 static void cldapd_rootdse_fill(struct cldapd_server
*cldapd
,
34 struct ldap_SearchRequest
*search
,
35 struct ldap_SearchResEntry
**response
,
36 struct ldap_Result
*result
)
38 struct ldap_SearchResEntry
*ent
= NULL
;
39 struct ldb_dn
*basedn
;
40 struct ldb_result
*res
= NULL
;
41 struct ldb_request
*lreq
;
42 enum ldb_scope scope
= LDB_SCOPE_DEFAULT
;
43 const char **attrs
= NULL
;
44 const char *errstr
= NULL
;
48 basedn
= ldb_dn_new(mem_ctx
, cldapd
->samctx
, NULL
);
49 if (basedn
== NULL
) goto nomem
;
50 scope
= LDB_SCOPE_BASE
;
52 if (search
->num_attributes
>= 1) {
55 attrs
= talloc_array(mem_ctx
, const char *, search
->num_attributes
+1);
56 if (attrs
== NULL
) goto nomem
;
58 for (i
=0; i
< search
->num_attributes
; i
++) {
59 attrs
[i
] = search
->attributes
[i
];
64 res
= talloc_zero(mem_ctx
, struct ldb_result
);
65 if (res
== NULL
) goto nomem
;
67 ldb_ret
= ldb_build_search_req_ex(&lreq
, cldapd
->samctx
, mem_ctx
,
71 res
, ldb_search_default_callback
,
74 if (ldb_ret
!= LDB_SUCCESS
) {
78 /* Copy the timeout from the incoming call */
79 ldb_set_timeout(cldapd
->samctx
, lreq
, search
->timelimit
);
81 ldb_ret
= ldb_request(cldapd
->samctx
, lreq
);
82 if (ldb_ret
!= LDB_SUCCESS
) {
86 ldb_ret
= ldb_wait(lreq
->handle
, LDB_WAIT_ALL
);
87 if (ldb_ret
!= LDB_SUCCESS
) {
92 errstr
= "Internal error: to much replies";
93 ldb_ret
= LDB_ERR_OTHER
;
95 } else if (res
->count
== 1) {
98 ent
= talloc(mem_ctx
, struct ldap_SearchResEntry
);
99 if (ent
== NULL
) goto nomem
;
101 ent
->dn
= ldb_dn_alloc_linearized(ent
, res
->msgs
[0]->dn
);
102 if (ent
->dn
== NULL
) goto nomem
;
103 ent
->num_attributes
= 0;
104 ent
->attributes
= NULL
;
105 if (res
->msgs
[0]->num_elements
== 0) {
108 ent
->num_attributes
= res
->msgs
[0]->num_elements
;
109 ent
->attributes
= talloc_array(ent
, struct ldb_message_element
, ent
->num_attributes
);
110 if (ent
->attributes
== NULL
) goto nomem
;
111 for (j
=0; j
< ent
->num_attributes
; j
++) {
112 ent
->attributes
[j
].name
= talloc_steal(ent
->attributes
, res
->msgs
[0]->elements
[j
].name
);
113 ent
->attributes
[j
].num_values
= 0;
114 ent
->attributes
[j
].values
= NULL
;
115 if (search
->attributesonly
&& (res
->msgs
[0]->elements
[j
].num_values
== 0)) {
118 ent
->attributes
[j
].num_values
= res
->msgs
[0]->elements
[j
].num_values
;
119 ent
->attributes
[j
].values
= res
->msgs
[0]->elements
[j
].values
;
120 talloc_steal(ent
->attributes
, res
->msgs
[0]->elements
[j
].values
);
127 } else if (ldb_ret
== LDB_SUCCESS
) {
132 errstr
= ldb_errstring(cldapd
->samctx
);
137 ret
= LDAP_OPERATIONS_ERROR
;
138 errstr
= "No memory";
141 result
->resultcode
= ret
;
142 result
->errormessage
= (errstr
?talloc_strdup(mem_ctx
, errstr
):NULL
);
146 handle incoming cldap requests
148 void cldapd_rootdse_request(struct cldap_socket
*cldap
,
149 struct cldapd_server
*cldapd
,
152 struct ldap_SearchRequest
*search
,
153 struct tsocket_address
*src
)
156 struct cldap_reply reply
;
157 struct ldap_Result result
;
161 reply
.messageid
= message_id
;
163 reply
.response
= NULL
;
164 reply
.result
= &result
;
166 cldapd_rootdse_fill(cldapd
, tmp_ctx
, search
, &reply
.response
, reply
.result
);
168 status
= cldap_reply_send(cldap
, &reply
);
169 if (!NT_STATUS_IS_OK(status
)) {
170 DEBUG(2,("cldap rootdse query failed '%s' - %s\n",
171 ldb_filter_from_tree(tmp_ctx
, search
->tree
), nt_errstr(status
)));