b7a5b2d24265b3afd962c9a3eb8b05ecf3913bf8
[kamenim/samba.git] / source4 / rpc_server / drsuapi / dcesrv_drsuapi.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the drsuapi pipe
5
6    Copyright (C) Stefan Metzmacher 2004
7    
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 2 of the License, or
11    (at your option) any later version.
12    
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.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "librpc/gen_ndr/ndr_drsuapi.h"
25 #include "rpc_server/dcerpc_server.h"
26 #include "rpc_server/common/common.h"
27 #include "rpc_server/drsuapi/dcesrv_drsuapi.h"
28 #include "dsdb/samdb/samdb.h"
29
30 /* 
31   drsuapi_DsBind 
32 */
33 static WERROR drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
34                        struct drsuapi_DsBind *r)
35 {
36         struct drsuapi_bind_state *b_state;
37         struct dcesrv_handle *handle;
38         struct drsuapi_DsBindInfoCtr *bind_info;
39         struct GUID site_guid;
40
41         r->out.bind_info = NULL;
42         ZERO_STRUCTP(r->out.bind_handle);
43
44         b_state = talloc(dce_call->conn, struct drsuapi_bind_state);
45         W_ERROR_HAVE_NO_MEMORY(b_state);
46
47         b_state->sam_ctx = samdb_connect(b_state, dce_call->conn->auth_state.session_info); 
48         if (!b_state->sam_ctx) {
49                 talloc_free(b_state);
50                 return WERR_FOOBAR;
51         }
52
53         handle = dcesrv_handle_new(dce_call->context, DRSUAPI_BIND_HANDLE);
54         if (!handle) {
55                 talloc_free(b_state);
56                 return WERR_NOMEM;
57         }
58
59         handle->data = talloc_steal(handle, b_state);
60
61         bind_info = talloc(mem_ctx, struct drsuapi_DsBindInfoCtr);
62         W_ERROR_HAVE_NO_MEMORY(bind_info);
63
64         ZERO_STRUCT(site_guid);
65
66         bind_info->length                               = 28;
67         bind_info->info.info28.supported_extensions     = 0;
68         bind_info->info.info28.site_guid                = site_guid;
69         bind_info->info.info28.u1                       = 0;
70         bind_info->info.info28.repl_epoch               = 0;
71
72         r->out.bind_info = bind_info;
73         *r->out.bind_handle = handle->wire_handle;
74
75         return WERR_OK;
76 }
77
78
79 /* 
80   drsuapi_DsUnbind 
81 */
82 static WERROR drsuapi_DsUnbind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
83                                struct drsuapi_DsUnbind *r)
84 {
85         struct dcesrv_handle *h;
86
87         *r->out.bind_handle = *r->in.bind_handle;
88
89         DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
90
91         talloc_free(h);
92
93         ZERO_STRUCTP(r->out.bind_handle);
94
95         return WERR_OK;
96 }
97
98
99 /* 
100   drsuapi_DsReplicaSync 
101 */
102 static WERROR drsuapi_DsReplicaSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
103                        struct drsuapi_DsReplicaSync *r)
104 {
105         /* TODO: implement this call correct!
106          *       for now we just say yes,
107          *       because we have no output parameter
108          */
109         return WERR_OK;
110 }
111
112
113 /* 
114   drsuapi_DsGetNCChanges
115 */
116 static WERROR drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
117                        struct drsuapi_DsGetNCChanges *r)
118 {
119         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
120 }
121
122
123 /* 
124   drsuapi_DsReplicaUpdateRefs
125 */
126 static WERROR drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
127                        struct drsuapi_DsReplicaUpdateRefs *r)
128 {
129         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
130 }
131
132
133 /* 
134   DRSUAPI_REPLICA_ADD 
135 */
136 static WERROR DRSUAPI_REPLICA_ADD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
137                        struct DRSUAPI_REPLICA_ADD *r)
138 {
139         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
140 }
141
142
143 /* 
144   DRSUAPI_REPLICA_DEL 
145 */
146 static WERROR DRSUAPI_REPLICA_DEL(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
147                        struct DRSUAPI_REPLICA_DEL *r)
148 {
149         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
150 }
151
152
153 /* 
154   DRSUAPI_REPLICA_MODIFY 
155 */
156 static WERROR DRSUAPI_REPLICA_MODIFY(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
157                        struct DRSUAPI_REPLICA_MODIFY *r)
158 {
159         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
160 }
161
162
163 /* 
164   DRSUAPI_VERIFY_NAMES 
165 */
166 static WERROR DRSUAPI_VERIFY_NAMES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
167                        struct DRSUAPI_VERIFY_NAMES *r)
168 {
169         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
170 }
171
172
173 /* 
174   drsuapi_DsGetMemberships 
175 */
176 static WERROR drsuapi_DsGetMemberships(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
177                        struct drsuapi_DsGetMemberships *r)
178 {
179         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
180 }
181
182
183 /* 
184   DRSUAPI_INTER_DOMAIN_MOVE 
185 */
186 static WERROR DRSUAPI_INTER_DOMAIN_MOVE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
187                        struct DRSUAPI_INTER_DOMAIN_MOVE *r)
188 {
189         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
190 }
191
192
193 /* 
194   DRSUAPI_GET_NT4_CHANGELOG 
195 */
196 static WERROR DRSUAPI_GET_NT4_CHANGELOG(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
197                        struct DRSUAPI_GET_NT4_CHANGELOG *r)
198 {
199         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
200 }
201
202
203 /* 
204   drsuapi_DsCrackNames 
205 */
206 WERROR drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
207                             struct drsuapi_DsCrackNames *r)
208 {
209         WERROR status;
210         struct drsuapi_bind_state *b_state;
211         struct dcesrv_handle *h;
212
213         r->out.level = r->in.level;
214         ZERO_STRUCT(r->out.ctr);
215
216         DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
217         b_state = h->data;
218
219         switch (r->in.level) {
220                 case 1: {
221                         struct drsuapi_DsNameCtr1 *ctr1;
222                         struct drsuapi_DsNameInfo1 *names;
223                         int count;
224                         int i;
225
226                         ctr1 = talloc(mem_ctx, struct drsuapi_DsNameCtr1);
227                         W_ERROR_HAVE_NO_MEMORY(ctr1);
228
229                         count = r->in.req.req1.count;
230                         names = talloc_array(mem_ctx, struct drsuapi_DsNameInfo1, count);
231                         W_ERROR_HAVE_NO_MEMORY(names);
232
233                         for (i=0; i < count; i++) {
234                                 status = DsCrackNameOneName(b_state->sam_ctx, mem_ctx,
235                                                             r->in.req.req1.format_flags,
236                                                             r->in.req.req1.format_offered,
237                                                             r->in.req.req1.format_desired,
238                                                             r->in.req.req1.names[i].str,
239                                                             &names[i]);
240                                 if (!W_ERROR_IS_OK(status)) {
241                                         return status;
242                                 }
243                         }
244
245                         ctr1->count = count;
246                         ctr1->array = names;
247                         r->out.ctr.ctr1 = ctr1;
248
249                         return WERR_OK;
250                 }
251         }
252         
253         return WERR_UNKNOWN_LEVEL;
254 }
255
256 /* 
257   drsuapi_DsWriteAccountSpn 
258 */
259 static WERROR drsuapi_DsWriteAccountSpn(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
260                        struct drsuapi_DsWriteAccountSpn *r)
261 {
262         struct drsuapi_bind_state *b_state;
263         struct dcesrv_handle *h;
264
265         r->out.level = r->in.level;
266
267         DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
268         b_state = h->data;
269
270         switch (r->in.level) {
271                 case 1: {
272                         struct drsuapi_DsWriteAccountSpnRequest1 *req;
273                         struct ldb_message *msg;
274                         int count, i, ret;
275                         req = &r->in.req.req1;
276                         count = req->count;
277
278                         msg = ldb_msg_new(mem_ctx);
279                         if (msg == NULL) {
280                                 return WERR_NOMEM;
281                         }
282
283                         msg->dn = ldb_dn_new(msg, b_state->sam_ctx, req->object_dn);
284                         if ( ! ldb_dn_validate(msg->dn)) {
285                                 r->out.res.res1.status = WERR_OK;
286                                 return WERR_OK;
287                         }
288                         
289                         /* construct mods */
290                         for (i = 0; i < count; i++) {
291                                 samdb_msg_add_string(b_state->sam_ctx, 
292                                                      msg, msg, "servicePrincipalName",
293                                                      req->spn_names[i].str);
294                         }
295                         for (i=0;i<msg->num_elements;i++) {
296                                 switch (req->operation) {
297                                 case DRSUAPI_DS_SPN_OPERATION_ADD:
298                                         msg->elements[i].flags = LDB_FLAG_MOD_ADD;
299                                         break;
300                                 case DRSUAPI_DS_SPN_OPERATION_REPLACE:
301                                         msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
302                                         break;
303                                 case DRSUAPI_DS_SPN_OPERATION_DELETE:
304                                         msg->elements[i].flags = LDB_FLAG_MOD_DELETE;
305                                         break;
306                                 }
307                         }
308    
309                         /* Apply to database */
310
311                         ret = samdb_modify(b_state->sam_ctx, mem_ctx, msg);
312                         if (ret != 0) {
313                                 DEBUG(0,("Failed to modify SPNs on %s: %s\n",
314                                          ldb_dn_linearize(mem_ctx, msg->dn), 
315                                          ldb_errstring(b_state->sam_ctx)));
316                                 r->out.res.res1.status = WERR_ACCESS_DENIED;
317                         } else {
318                                 r->out.res.res1.status = WERR_OK;
319                         }
320
321                         return WERR_OK;
322                 }
323         }
324         
325         return WERR_UNKNOWN_LEVEL;
326 }
327
328
329 /* 
330   DRSUAPI_REMOVE_DS_SERVER 
331 */
332 static WERROR DRSUAPI_REMOVE_DS_SERVER(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
333                        struct DRSUAPI_REMOVE_DS_SERVER *r)
334 {
335         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
336 }
337
338
339 /* 
340   DRSUAPI_REMOVE_DS_DOMAIN 
341 */
342 static WERROR DRSUAPI_REMOVE_DS_DOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
343                        struct DRSUAPI_REMOVE_DS_DOMAIN *r)
344 {
345         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
346 }
347
348
349 /* 
350   drsuapi_DsGetDomainControllerInfo 
351 */
352 static WERROR drsuapi_DsGetDomainControllerInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
353                                                 struct drsuapi_DsGetDomainControllerInfo *r)
354 {
355         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
356 }
357
358
359 /* 
360   drsuapi_DsAddEntry
361 */
362 static WERROR drsuapi_DsAddEntry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
363                        struct drsuapi_DsAddEntry *r)
364 {
365         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
366 }
367
368
369 /* 
370   DRSUAPI_EXECUTE_KCC 
371 */
372 static WERROR DRSUAPI_EXECUTE_KCC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
373                        struct DRSUAPI_EXECUTE_KCC *r)
374 {
375         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
376 }
377
378
379 /* 
380   drsuapi_DsReplicaGetInfo 
381 */
382 static WERROR drsuapi_DsReplicaGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
383                        struct drsuapi_DsReplicaGetInfo *r)
384 {
385         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
386 }
387
388
389 /* 
390   DRSUAPI_ADD_SID_HISTORY 
391 */
392 static WERROR DRSUAPI_ADD_SID_HISTORY(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
393                        struct DRSUAPI_ADD_SID_HISTORY *r)
394 {
395         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
396 }
397
398 /* 
399   drsuapi_DsGetMemberships2 
400 */
401 static WERROR drsuapi_DsGetMemberships2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
402                        struct drsuapi_DsGetMemberships2 *r)
403 {
404         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
405 }
406
407 /* 
408   DRSUAPI_REPLICA_VERIFY_OBJECTS 
409 */
410 static WERROR DRSUAPI_REPLICA_VERIFY_OBJECTS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
411                        struct DRSUAPI_REPLICA_VERIFY_OBJECTS *r)
412 {
413         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
414 }
415
416
417 /* 
418   DRSUAPI_GET_OBJECT_EXISTENCE 
419 */
420 static WERROR DRSUAPI_GET_OBJECT_EXISTENCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
421                        struct DRSUAPI_GET_OBJECT_EXISTENCE *r)
422 {
423         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
424 }
425
426
427 /* 
428   DRSUAPI_QUERY_SITES_BY_COST 
429 */
430 static WERROR DRSUAPI_QUERY_SITES_BY_COST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
431                        struct DRSUAPI_QUERY_SITES_BY_COST *r)
432 {
433         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
434 }
435
436
437 /* include the generated boilerplate */
438 #include "librpc/gen_ndr/ndr_drsuapi_s.c"