2 Unix SMB/CIFS 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.
22 #include "ldap_server/ldap_server.h"
23 #include "dlinklist.h"
24 #include "libcli/ldap/ldap.h"
27 struct ldapsrv_reply
*ldapsrv_init_reply(struct ldapsrv_call
*call
, uint8_t type
)
29 struct ldapsrv_reply
*reply
;
31 reply
= talloc(call
, struct ldapsrv_reply
);
36 reply
->prev
= reply
->next
= NULL
;
37 reply
->state
= LDAPSRV_REPLY_STATE_NEW
;
38 reply
->msg
.messageid
= call
->request
.messageid
;
39 reply
->msg
.type
= type
;
40 reply
->msg
.mem_ctx
= reply
;
45 NTSTATUS
ldapsrv_queue_reply(struct ldapsrv_call
*call
, struct ldapsrv_reply
*reply
)
47 DLIST_ADD_END(call
->replies
, reply
, struct ldapsrv_reply
*);
51 struct ldapsrv_partition
*ldapsrv_get_partition(struct ldapsrv_connection
*conn
, const char *dn
, uint8_t scope
)
53 if (scope
== LDAP_SEARCH_SCOPE_BASE
54 && strcasecmp("", dn
) == 0) {
55 return conn
->service
->rootDSE
;
58 return conn
->service
->default_partition
;
61 NTSTATUS
ldapsrv_unwilling(struct ldapsrv_call
*call
, int error
)
63 struct ldapsrv_reply
*reply
;
64 struct ldap_ExtendedResponse
*r
;
66 DEBUG(10,("Unwilling type[%d] id[%d]\n", call
->request
.type
, call
->request
.messageid
));
68 reply
= ldapsrv_init_reply(call
, LDAP_TAG_ExtendedResponse
);
70 return NT_STATUS_NO_MEMORY
;
73 r
= &reply
->msg
.r
.ExtendedResponse
;
74 r
->response
.resultcode
= error
;
75 r
->response
.dn
= NULL
;
76 r
->response
.errormessage
= NULL
;
77 r
->response
.referral
= NULL
;
82 return ldapsrv_queue_reply(call
, reply
);
85 static NTSTATUS
ldapsrv_SearchRequest(struct ldapsrv_call
*call
)
87 struct ldap_SearchRequest
*req
= &call
->request
.r
.SearchRequest
;
88 struct ldapsrv_partition
*part
;
90 DEBUG(10, ("SearchRequest"));
91 DEBUGADD(10, (" basedn: %s", req
->basedn
));
92 DEBUGADD(10, (" filter: %s\n", req
->filter
));
94 part
= ldapsrv_get_partition(call
->conn
, req
->basedn
, req
->scope
);
96 if (!part
->ops
->Search
) {
97 struct ldap_Result
*done
;
98 struct ldapsrv_reply
*done_r
;
100 done_r
= ldapsrv_init_reply(call
, LDAP_TAG_SearchResultDone
);
102 return NT_STATUS_NO_MEMORY
;
105 done
= &done_r
->msg
.r
.SearchResultDone
;
106 done
->resultcode
= 53;
108 done
->errormessage
= NULL
;
109 done
->referral
= NULL
;
111 return ldapsrv_queue_reply(call
, done_r
);
114 return part
->ops
->Search(part
, call
, req
);
117 static NTSTATUS
ldapsrv_ModifyRequest(struct ldapsrv_call
*call
)
119 struct ldap_ModifyRequest
*req
= &call
->request
.r
.ModifyRequest
;
120 struct ldapsrv_partition
*part
;
122 DEBUG(10, ("ModifyRequest"));
123 DEBUGADD(10, (" dn: %s", req
->dn
));
125 part
= ldapsrv_get_partition(call
->conn
, req
->dn
, LDAP_SEARCH_SCOPE_SUB
);
127 if (!part
->ops
->Modify
) {
128 return ldapsrv_unwilling(call
, 53);
131 return part
->ops
->Modify(part
, call
, req
);
134 static NTSTATUS
ldapsrv_AddRequest(struct ldapsrv_call
*call
)
136 struct ldap_AddRequest
*req
= &call
->request
.r
.AddRequest
;
137 struct ldapsrv_partition
*part
;
139 DEBUG(10, ("AddRequest"));
140 DEBUGADD(10, (" dn: %s", req
->dn
));
142 part
= ldapsrv_get_partition(call
->conn
, req
->dn
, LDAP_SEARCH_SCOPE_SUB
);
144 if (!part
->ops
->Add
) {
145 return ldapsrv_unwilling(call
, 53);
148 return part
->ops
->Add(part
, call
, req
);
151 static NTSTATUS
ldapsrv_DelRequest(struct ldapsrv_call
*call
)
153 struct ldap_DelRequest
*req
= &call
->request
.r
.DelRequest
;
154 struct ldapsrv_partition
*part
;
156 DEBUG(10, ("DelRequest"));
157 DEBUGADD(10, (" dn: %s", req
->dn
));
159 part
= ldapsrv_get_partition(call
->conn
, req
->dn
, LDAP_SEARCH_SCOPE_SUB
);
161 if (!part
->ops
->Del
) {
162 return ldapsrv_unwilling(call
, 53);
165 return part
->ops
->Del(part
, call
, req
);
168 static NTSTATUS
ldapsrv_ModifyDNRequest(struct ldapsrv_call
*call
)
170 struct ldap_ModifyDNRequest
*req
= &call
->request
.r
.ModifyDNRequest
;
171 struct ldapsrv_partition
*part
;
173 DEBUG(10, ("ModifyDNRequrest"));
174 DEBUGADD(10, (" dn: %s", req
->dn
));
175 DEBUGADD(10, (" newrdn: %s", req
->newrdn
));
177 part
= ldapsrv_get_partition(call
->conn
, req
->dn
, LDAP_SEARCH_SCOPE_SUB
);
179 if (!part
->ops
->ModifyDN
) {
180 return ldapsrv_unwilling(call
, 53);
183 return part
->ops
->ModifyDN(part
, call
, req
);
186 static NTSTATUS
ldapsrv_CompareRequest(struct ldapsrv_call
*call
)
188 struct ldap_CompareRequest
*req
= &call
->request
.r
.CompareRequest
;
189 struct ldapsrv_partition
*part
;
191 DEBUG(10, ("CompareRequest"));
192 DEBUGADD(10, (" dn: %s", req
->dn
));
194 part
= ldapsrv_get_partition(call
->conn
, req
->dn
, LDAP_SEARCH_SCOPE_SUB
);
196 if (!part
->ops
->Compare
) {
197 return ldapsrv_unwilling(call
, 53);
200 return part
->ops
->Compare(part
, call
, req
);
203 static NTSTATUS
ldapsrv_AbandonRequest(struct ldapsrv_call
*call
)
205 /* struct ldap_AbandonRequest *req = &call->request.r.AbandonRequest;*/
206 DEBUG(10, ("AbandonRequest\n"));
210 static NTSTATUS
ldapsrv_ExtendedRequest(struct ldapsrv_call
*call
)
212 /* struct ldap_ExtendedRequest *req = &call->request.r.ExtendedRequest;*/
213 struct ldapsrv_reply
*reply
;
215 DEBUG(10, ("Extended\n"));
217 reply
= ldapsrv_init_reply(call
, LDAP_TAG_ExtendedResponse
);
219 return NT_STATUS_NO_MEMORY
;
222 ZERO_STRUCT(reply
->msg
.r
);
224 return ldapsrv_queue_reply(call
, reply
);
227 NTSTATUS
ldapsrv_do_call(struct ldapsrv_call
*call
)
229 switch(call
->request
.type
) {
230 case LDAP_TAG_BindRequest
:
231 return ldapsrv_BindRequest(call
);
232 case LDAP_TAG_UnbindRequest
:
233 return ldapsrv_UnbindRequest(call
);
234 case LDAP_TAG_SearchRequest
:
235 return ldapsrv_SearchRequest(call
);
236 case LDAP_TAG_ModifyRequest
:
237 return ldapsrv_ModifyRequest(call
);
238 case LDAP_TAG_AddRequest
:
239 return ldapsrv_AddRequest(call
);
240 case LDAP_TAG_DelRequest
:
241 return ldapsrv_DelRequest(call
);
242 case LDAP_TAG_ModifyDNRequest
:
243 return ldapsrv_ModifyDNRequest(call
);
244 case LDAP_TAG_CompareRequest
:
245 return ldapsrv_CompareRequest(call
);
246 case LDAP_TAG_AbandonRequest
:
247 return ldapsrv_AbandonRequest(call
);
248 case LDAP_TAG_ExtendedRequest
:
249 return ldapsrv_ExtendedRequest(call
);
251 return ldapsrv_unwilling(call
, 2);