efa338d82d58c23dc98067fba31be3bef1a12a03
[metze/samba/wip.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    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
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 "dsdb/samdb/samdb.h"
28 #include "dsdb/common/util.h"
29 #include "libcli/security/security.h"
30 #include "libcli/security/session.h"
31 #include "rpc_server/drsuapi/dcesrv_drsuapi.h"
32 #include "auth/auth.h"
33 #include "param/param.h"
34 #include "lib/messaging/irpc.h"
35
36 #define DRSUAPI_UNSUPPORTED(fname) do { \
37         DEBUG(1,(__location__ ": Unsupported DRS call %s\n", #fname)); \
38         if (DEBUGLVL(2)) NDR_PRINT_IN_DEBUG(fname, r); \
39         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); \
40 } while (0)
41
42 #define DCESRV_INTERFACE_DRSUAPI_BIND(call, iface) \
43         dcesrv_interface_drsuapi_bind(call, iface)
44 static NTSTATUS dcesrv_interface_drsuapi_bind(struct dcesrv_call_state *dce_call,
45                                               const struct dcesrv_interface *iface)
46 {
47         return dcesrv_interface_bind_require_privacy(dce_call, iface);
48 }
49
50 /* 
51   drsuapi_DsBind 
52 */
53 static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
54                        struct drsuapi_DsBind *r)
55 {
56         struct drsuapi_bind_state *b_state;
57         struct dcesrv_handle *handle;
58         struct drsuapi_DsBindInfoCtr *bind_info;
59         struct drsuapi_DsBindInfoCtr *local_info;
60         struct GUID site_guid, config_guid;
61         struct ldb_result *site_res, *config_res;
62         struct ldb_dn *server_site_dn, *config_dn;
63         static const char *site_attrs[] = { "objectGUID", NULL };
64         static const char *config_attrs[] = { "objectGUID", NULL };
65         struct ldb_result *ntds_res;
66         struct ldb_dn *ntds_dn;
67         static const char *ntds_attrs[] = { "ms-DS-ReplicationEpoch", NULL };
68         uint32_t pid;
69         uint32_t repl_epoch;
70         uint32_t supported_extensions;
71         uint32_t req_length;
72         int ret;
73         struct auth_session_info *auth_info;
74         WERROR werr;
75         bool connected_as_system = false;
76
77         r->out.bind_info = NULL;
78         ZERO_STRUCTP(r->out.bind_handle);
79
80         b_state = talloc_zero(mem_ctx, struct drsuapi_bind_state);
81         W_ERROR_HAVE_NO_MEMORY(b_state);
82
83         /* if this is a DC connecting, give them system level access */
84         werr = drs_security_level_check(dce_call, NULL, SECURITY_DOMAIN_CONTROLLER, NULL);
85         if (W_ERROR_IS_OK(werr)) {
86                 DEBUG(3,(__location__ ": doing DsBind with system_session\n"));
87                 auth_info = system_session(dce_call->conn->dce_ctx->lp_ctx);
88                 connected_as_system = true;
89         } else {
90                 auth_info = dce_call->conn->auth_state.session_info;
91         }
92
93         /*
94          * connect to the samdb
95          */
96         b_state->sam_ctx = samdb_connect(b_state, dce_call->event_ctx, 
97                                          dce_call->conn->dce_ctx->lp_ctx, auth_info, 0);
98         if (!b_state->sam_ctx) {
99                 return WERR_FOOBAR;
100         }
101
102         if (connected_as_system) {
103                 b_state->sam_ctx_system = b_state->sam_ctx;
104         } else {
105                 /* an RODC also needs system samdb access for secret
106                    attribute replication */
107                 werr = drs_security_level_check(dce_call, NULL, SECURITY_RO_DOMAIN_CONTROLLER,
108                                                 samdb_domain_sid(b_state->sam_ctx));
109                 if (W_ERROR_IS_OK(werr)) {
110                         b_state->sam_ctx_system = samdb_connect(b_state, dce_call->event_ctx,
111                                                                 dce_call->conn->dce_ctx->lp_ctx,
112                                                                 system_session(dce_call->conn->dce_ctx->lp_ctx), 0);
113                         if (!b_state->sam_ctx_system) {
114                                 return WERR_FOOBAR;
115                         }
116                 }
117         }
118
119         /*
120          * find out the guid of our own site
121          */
122         server_site_dn = samdb_server_site_dn(b_state->sam_ctx, mem_ctx);
123         W_ERROR_HAVE_NO_MEMORY(server_site_dn);
124
125         ret = ldb_search(b_state->sam_ctx, mem_ctx, &site_res,
126                                  server_site_dn, LDB_SCOPE_BASE, site_attrs,
127                                  "(objectClass=*)");
128         if (ret != LDB_SUCCESS) {
129                 return WERR_DS_DRA_INTERNAL_ERROR;
130         }
131         if (site_res->count != 1) {
132                 return WERR_DS_DRA_INTERNAL_ERROR;
133         }
134         site_guid = samdb_result_guid(site_res->msgs[0], "objectGUID");
135
136         /*
137          * lookup the local servers Replication Epoch
138          */
139         ntds_dn = samdb_ntds_settings_dn(b_state->sam_ctx, mem_ctx);
140         W_ERROR_HAVE_NO_MEMORY(ntds_dn);
141
142         ret = ldb_search(b_state->sam_ctx, mem_ctx, &ntds_res,
143                                  ntds_dn, LDB_SCOPE_BASE, ntds_attrs,
144                                  "(objectClass=*)");
145         if (ret != LDB_SUCCESS) {
146                 return WERR_DS_DRA_INTERNAL_ERROR;
147         }
148         if (ntds_res->count != 1) {
149                 return WERR_DS_DRA_INTERNAL_ERROR;
150         }
151         repl_epoch = ldb_msg_find_attr_as_uint(ntds_res->msgs[0],
152                                                "ms-DS-ReplicationEpoch", 0);
153
154         /*
155          * The "process identifier" of the client.
156          * According to the WSPP docs, sectin 5.35, this is
157          * for informational and debugging purposes only.
158          * The assignment is implementation specific.
159          */
160         pid = 0;
161
162         /*
163          * store the clients bind_guid
164          */
165         if (r->in.bind_guid) {
166                 b_state->remote_bind_guid = *r->in.bind_guid;
167         }
168
169         /*
170          * store the clients bind_info
171          */
172         if (r->in.bind_info) {
173                 b_state->remote_info = r->in.bind_info;
174         }
175
176         /*
177          * fill in our local bind info
178          */
179         local_info = talloc_zero(mem_ctx, struct drsuapi_DsBindInfoCtr);
180         W_ERROR_HAVE_NO_MEMORY(local_info);
181
182         /*
183          * Fill in supported extensions
184          */
185         supported_extensions = 0;
186         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_BASE;
187         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION;
188         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI;
189         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2;
190 #if 0 /* we don't support MSZIP compression (only decompression) */
191         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS;
192 #endif
193         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1;
194         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;
195         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;
196         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;
197         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;
198         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2;
199         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD;
200         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND;
201         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO;
202         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION;
203         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01;
204         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP;
205         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY;
206         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3;
207         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V5;
208         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2;
209         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6;
210         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS;
211         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8;
212         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5;
213         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6;
214         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
215         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7;
216         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT;
217 #if 0 /* we don't support XPRESS compression yet */
218         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
219 #endif
220         supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V10;
221
222         /*
223          * There is a chance for r->in.bind_info == NULL
224          * Currently we don't care, since it seems to be used nowhere else.
225          * But we need a request length. So use 28 as default.
226          */
227         req_length = 28;
228         if (r->in.bind_info) {
229                 req_length = r->in.bind_info->length;
230         }
231
232         /*
233          * fill 28 or 48 info, depends on request
234          */
235         if (req_length < 48) {
236                 local_info->length = 28;
237                 local_info->info.info28.supported_extensions = supported_extensions;
238                 local_info->info.info28.site_guid = site_guid;
239                 local_info->info.info28.pid = pid;
240                 local_info->info.info28.repl_epoch = repl_epoch;
241         } else {
242                 local_info->length = 48;
243                 local_info->info.info48.supported_extensions = supported_extensions;
244                 local_info->info.info48.site_guid = site_guid;
245                 local_info->info.info48.pid = pid;
246                 local_info->info.info48.repl_epoch = repl_epoch;
247
248                 local_info->info.info48.supported_extensions_ext = 0;
249                 local_info->info.info48.supported_extensions_ext |= DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2;
250
251                 /*
252                  * find out the guid of our own site
253                  */
254                 config_dn = ldb_get_config_basedn(b_state->sam_ctx);
255                 W_ERROR_HAVE_NO_MEMORY(config_dn);
256
257                 ret = ldb_search(b_state->sam_ctx, mem_ctx, &config_res,
258                              config_dn, LDB_SCOPE_BASE, config_attrs,
259                              "(objectClass=*)");
260                 if (ret != LDB_SUCCESS) {
261                         return WERR_DS_DRA_INTERNAL_ERROR;
262                 }
263                 if (config_res->count != 1) {
264                         return WERR_DS_DRA_INTERNAL_ERROR;
265                 }
266                 config_guid = samdb_result_guid(config_res->msgs[0], "objectGUID");
267                 local_info->info.info48.config_dn_guid = config_guid;
268         }
269
270         /*
271          * set local_info
272          */
273         b_state->local_info = local_info;
274
275         /*
276          * set bind_info
277          */
278         bind_info = local_info;
279
280         /*
281          * allocate a bind handle
282          */
283         handle = dcesrv_handle_new(dce_call->context, DRSUAPI_BIND_HANDLE);
284         W_ERROR_HAVE_NO_MEMORY(handle);
285         handle->data = talloc_steal(handle, b_state);
286
287         /*
288          * prepare reply
289          */
290         r->out.bind_info = bind_info;
291         *r->out.bind_handle = handle->wire_handle;
292
293         return WERR_OK;
294 }
295
296
297 /* 
298   drsuapi_DsUnbind 
299 */
300 static WERROR dcesrv_drsuapi_DsUnbind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
301                                struct drsuapi_DsUnbind *r)
302 {
303         struct dcesrv_handle *h;
304
305         *r->out.bind_handle = *r->in.bind_handle;
306
307         DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
308
309         talloc_free(h);
310
311         ZERO_STRUCTP(r->out.bind_handle);
312
313         return WERR_OK;
314 }
315
316
317 /* 
318   drsuapi_DsReplicaSync 
319 */
320 static WERROR dcesrv_drsuapi_DsReplicaSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
321                                            struct drsuapi_DsReplicaSync *r)
322 {
323         WERROR status;
324         uint32_t timeout;
325
326         status = drs_security_level_check(dce_call, "DsReplicaSync", SECURITY_DOMAIN_CONTROLLER, NULL);
327         if (!W_ERROR_IS_OK(status)) {
328                 return status;
329         }
330
331         if (r->in.level != 1) {
332                 DEBUG(0,("DsReplicaSync called with unsupported level %d\n", r->in.level));
333                 return WERR_DS_DRA_INVALID_PARAMETER;
334         }
335
336         if (r->in.req->req1.options & DRSUAPI_DRS_ASYNC_OP) {
337                 timeout = IRPC_CALL_TIMEOUT;
338         } else {
339                 /*
340                  * use Infinite time for timeout in case
341                  * the caller made a sync call
342                  */
343                 timeout = IRPC_CALL_TIMEOUT_INF;
344         }
345
346         dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx,
347                                      r, NDR_DRSUAPI_DSREPLICASYNC,
348                                      &ndr_table_drsuapi,
349                                      "dreplsrv", "DsReplicaSync",
350                                      timeout);
351
352         return WERR_OK;
353 }
354
355
356 /* 
357   drsuapi_DsReplicaAdd 
358 */
359 static WERROR dcesrv_drsuapi_DsReplicaAdd(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
360                                           struct drsuapi_DsReplicaAdd *r)
361 {
362         WERROR status;
363
364         status = drs_security_level_check(dce_call, "DsReplicaAdd", SECURITY_DOMAIN_CONTROLLER, NULL);
365         if (!W_ERROR_IS_OK(status)) {
366                 return status;
367         }
368
369         dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx,
370                                      r, NDR_DRSUAPI_DSREPLICAADD,
371                                      &ndr_table_drsuapi,
372                                      "dreplsrv", "DsReplicaAdd",
373                                      IRPC_CALL_TIMEOUT);
374
375         return WERR_OK;
376 }
377
378
379 /* 
380   drsuapi_DsReplicaDel 
381 */
382 static WERROR dcesrv_drsuapi_DsReplicaDel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
383                                           struct drsuapi_DsReplicaDel *r)
384 {
385         WERROR status;
386
387         status = drs_security_level_check(dce_call, "DsReplicaDel", SECURITY_DOMAIN_CONTROLLER, NULL);
388         if (!W_ERROR_IS_OK(status)) {
389                 return status;
390         }
391
392         dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx,
393                                      r, NDR_DRSUAPI_DSREPLICADEL,
394                                      &ndr_table_drsuapi,
395                                      "dreplsrv", "DsReplicaDel",
396                                      IRPC_CALL_TIMEOUT);
397
398         return WERR_OK;
399 }
400
401
402 /* 
403   drsuapi_DsReplicaModify 
404 */
405 static WERROR dcesrv_drsuapi_DsReplicaMod(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
406                                           struct drsuapi_DsReplicaMod *r)
407 {
408         WERROR status;
409
410         status = drs_security_level_check(dce_call, "DsReplicaMod", SECURITY_DOMAIN_CONTROLLER, NULL);
411         if (!W_ERROR_IS_OK(status)) {
412                 return status;
413         }
414
415         dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx,
416                                      r, NDR_DRSUAPI_DSREPLICAMOD,
417                                      &ndr_table_drsuapi,
418                                      "dreplsrv", "DsReplicaMod",
419                                      IRPC_CALL_TIMEOUT);
420
421         return WERR_OK;
422 }
423
424
425 /* 
426   DRSUAPI_VERIFY_NAMES 
427 */
428 static WERROR dcesrv_DRSUAPI_VERIFY_NAMES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
429                        struct DRSUAPI_VERIFY_NAMES *r)
430 {
431         DRSUAPI_UNSUPPORTED(DRSUAPI_VERIFY_NAMES);
432 }
433
434
435 /* 
436   drsuapi_DsGetMemberships 
437 */
438 static WERROR dcesrv_drsuapi_DsGetMemberships(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
439                        struct drsuapi_DsGetMemberships *r)
440 {
441         DRSUAPI_UNSUPPORTED(drsuapi_DsGetMemberships);
442 }
443
444
445 /* 
446   DRSUAPI_INTER_DOMAIN_MOVE 
447 */
448 static WERROR dcesrv_DRSUAPI_INTER_DOMAIN_MOVE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
449                        struct DRSUAPI_INTER_DOMAIN_MOVE *r)
450 {
451         DRSUAPI_UNSUPPORTED(DRSUAPI_INTER_DOMAIN_MOVE);
452 }
453
454
455 /* 
456   drsuapi_DsGetNT4ChangeLog 
457 */
458 static WERROR dcesrv_drsuapi_DsGetNT4ChangeLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
459                        struct drsuapi_DsGetNT4ChangeLog *r)
460 {
461         DRSUAPI_UNSUPPORTED(drsuapi_DsGetNT4ChangeLog);
462 }
463
464 /* 
465   drsuapi_DsCrackNames 
466 */
467 static WERROR dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
468                             struct drsuapi_DsCrackNames *r)
469 {
470         struct drsuapi_bind_state *b_state;
471         struct dcesrv_handle *h;
472
473         *r->out.level_out = r->in.level;
474
475         DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
476         b_state = h->data;
477
478         r->out.ctr = talloc_zero(mem_ctx, union drsuapi_DsNameCtr);
479         W_ERROR_HAVE_NO_MEMORY(r->out.ctr);
480
481         switch (r->in.level) {
482                 case 1: {
483                         switch(r->in.req->req1.format_offered){
484                         case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX:
485                         case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN:
486                         case DRSUAPI_DS_NAME_FORMAT_STRING_SID_NAME:
487                         case DRSUAPI_DS_NAME_FORMAT_ALT_SECURITY_IDENTITIES_NAME:
488                         case DRSUAPI_DS_NAME_FORMAT_MAP_SCHEMA_GUID:
489                         case DRSUAPI_DS_NAME_FORMAT_LIST_NCS:
490                         case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS:
491                         case DRSUAPI_DS_NAME_FORMAT_LIST_GLOBAL_CATALOG_SERVERS:
492                         case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_WITH_DCS_IN_SITE:
493                         case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_FOR_DOMAIN_IN_SITE:
494                         case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS_IN_SITE:
495                         case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_IN_SITE:
496                         case DRSUAPI_DS_NAME_FORMAT_LIST_SITES:
497                         case DRSUAPI_DS_NAME_FORMAT_UPN_AND_ALTSECID:
498                         case DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON:
499                                 DEBUG(0, ("DsCrackNames: Unsupported operation requested: %X",
500                                           r->in.req->req1.format_offered));
501                                 return WERR_OK;
502                         case DRSUAPI_DS_NAME_FORMAT_LIST_INFO_FOR_SERVER:
503                                 return dcesrv_drsuapi_ListInfoServer(b_state->sam_ctx, mem_ctx, &r->in.req->req1, &r->out.ctr->ctr1);
504                         case DRSUAPI_DS_NAME_FORMAT_LIST_ROLES:
505                                 return dcesrv_drsuapi_ListRoles(b_state->sam_ctx, mem_ctx,
506                                                                 &r->in.req->req1, &r->out.ctr->ctr1);
507                         default:/* format_offered is in the enum drsuapi_DsNameFormat*/
508                                 return dcesrv_drsuapi_CrackNamesByNameFormat(b_state->sam_ctx, mem_ctx,
509                                                                              &r->in.req->req1, &r->out.ctr->ctr1);
510                         }
511                 }
512         }
513         return WERR_UNKNOWN_LEVEL;
514 }
515
516
517 /* 
518   drsuapi_DsRemoveDSServer
519 */
520 static WERROR dcesrv_drsuapi_DsRemoveDSServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
521                                        struct drsuapi_DsRemoveDSServer *r)
522 {
523         struct drsuapi_bind_state *b_state;
524         struct dcesrv_handle *h;
525         struct ldb_dn *ntds_dn;
526         int ret;
527         bool ok;
528         WERROR status;
529
530         *r->out.level_out = 1;
531
532         status = drs_security_level_check(dce_call, "DsRemoveDSServer", SECURITY_DOMAIN_CONTROLLER, NULL);
533         if (!W_ERROR_IS_OK(status)) {
534                 return status;
535         }
536
537         DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
538         b_state = h->data;
539
540         switch (r->in.level) {
541         case 1:
542                 ntds_dn = ldb_dn_new(mem_ctx, b_state->sam_ctx, r->in.req->req1.server_dn);
543                 W_ERROR_HAVE_NO_MEMORY(ntds_dn);
544
545                 ok = ldb_dn_validate(ntds_dn);
546                 if (!ok) {
547                         return WERR_FOOBAR;
548                 }
549
550                 /* TODO: it's likely that we need more checks here */
551
552                 ok = ldb_dn_add_child_fmt(ntds_dn, "CN=NTDS Settings");
553                 if (!ok) {
554                         return WERR_FOOBAR;
555                 }
556
557                 if (r->in.req->req1.commit) {
558                         ret = dsdb_delete(b_state->sam_ctx, ntds_dn, DSDB_TREE_DELETE);
559                         if (ret != LDB_SUCCESS) {
560                                 return WERR_FOOBAR;
561                         }
562                 }
563
564                 return WERR_OK;
565         default:
566                 break;
567         }
568
569         return WERR_FOOBAR;
570 }
571
572
573 /* 
574   DRSUAPI_REMOVE_DS_DOMAIN 
575 */
576 static WERROR dcesrv_DRSUAPI_REMOVE_DS_DOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
577                        struct DRSUAPI_REMOVE_DS_DOMAIN *r)
578 {
579         DRSUAPI_UNSUPPORTED(DRSUAPI_REMOVE_DS_DOMAIN);
580 }
581
582 /* Obtain the site name from a server DN */
583 static const char *result_site_name(struct ldb_dn *server_dn)
584 {
585         /* Format is cn=<NETBIOS name>,cn=Servers,cn=<site>,cn=sites.... */
586         const struct ldb_val *val = ldb_dn_get_component_val(server_dn, 2);
587         const char *name = ldb_dn_get_component_name(server_dn, 2);
588
589         if (!name || (ldb_attr_cmp(name, "cn") != 0)) {
590                 /* Ensure this matches the format.  This gives us a
591                  * bit more confidence that a 'cn' value will be a
592                  * ascii string */
593                 return NULL;
594         }
595         if (val) {
596                 return (char *)val->data;
597         }
598         return NULL;
599 }
600
601 /* 
602   drsuapi_DsGetDomainControllerInfo 
603 */
604 static WERROR dcesrv_drsuapi_DsGetDomainControllerInfo_1(struct drsuapi_bind_state *b_state, 
605                                                 TALLOC_CTX *mem_ctx,
606                                                 struct drsuapi_DsGetDomainControllerInfo *r)
607 {
608         struct ldb_dn *sites_dn;
609         struct ldb_result *res;
610
611         const char *attrs_account_1[] = { "cn", "dnsHostName", NULL };
612         const char *attrs_account_2[] = { "cn", "dnsHostName", "objectGUID", NULL };
613
614         const char *attrs_none[] = { NULL };
615
616         const char *attrs_site[] = { "objectGUID", NULL };
617
618         const char *attrs_ntds[] = { "options", "objectGUID", NULL };
619
620         const char *attrs_1[] = { "serverReference", "cn", "dnsHostName", NULL };
621         const char *attrs_2[] = { "serverReference", "cn", "dnsHostName", "objectGUID", NULL };
622         const char **attrs;
623
624         struct drsuapi_DsGetDCInfoCtr1 *ctr1;
625         struct drsuapi_DsGetDCInfoCtr2 *ctr2;
626         struct drsuapi_DsGetDCInfoCtr3 *ctr3;
627
628         int ret;
629         unsigned int i;
630
631         *r->out.level_out = r->in.req->req1.level;
632         r->out.ctr = talloc_zero(mem_ctx, union drsuapi_DsGetDCInfoCtr);
633         W_ERROR_HAVE_NO_MEMORY(r->out.ctr);
634
635         switch (*r->out.level_out) {
636         case -1:
637                 /* this level is not like the others */
638                 return WERR_UNKNOWN_LEVEL;
639         case 1:
640                 attrs = attrs_1;
641                 break;
642         case 2:
643         case 3:
644                 attrs = attrs_2;
645                 break;
646         default:
647                 return WERR_UNKNOWN_LEVEL;
648         }
649
650         sites_dn = samdb_sites_dn(b_state->sam_ctx, mem_ctx);
651         if (!sites_dn) {
652                 return WERR_DS_OBJ_NOT_FOUND;
653         }
654
655         ret = ldb_search(b_state->sam_ctx, mem_ctx, &res, sites_dn, LDB_SCOPE_SUBTREE, attrs,
656                                  "(&(objectClass=server)(serverReference=*))");
657         
658         if (ret) {
659                 DEBUG(1, ("searching for servers in sites DN %s failed: %s\n", 
660                           ldb_dn_get_linearized(sites_dn), ldb_errstring(b_state->sam_ctx)));
661                 return WERR_GEN_FAILURE;
662         }
663
664         switch (*r->out.level_out) {
665         case 1:
666                 ctr1 = &r->out.ctr->ctr1;
667                 ctr1->count = res->count;
668                 ctr1->array = talloc_zero_array(mem_ctx, 
669                                                 struct drsuapi_DsGetDCInfo1, 
670                                                 res->count);
671                 for (i=0; i < res->count; i++) {
672                         struct ldb_dn *domain_dn;
673                         struct ldb_result *res_domain;
674                         struct ldb_result *res_account;
675                         struct ldb_dn *ntds_dn = ldb_dn_copy(mem_ctx, res->msgs[i]->dn);
676                         
677                         struct ldb_dn *ref_dn
678                                 = ldb_msg_find_attr_as_dn(b_state->sam_ctx, 
679                                                           mem_ctx, res->msgs[i], 
680                                                           "serverReference");
681
682                         if (!ntds_dn || !ldb_dn_add_child_fmt(ntds_dn, "CN=NTDS Settings")) {
683                                 return WERR_NOT_ENOUGH_MEMORY;
684                         }
685
686                         ret = ldb_search(b_state->sam_ctx, mem_ctx, &res_account, ref_dn,
687                                                  LDB_SCOPE_BASE, attrs_account_1,
688                                                 "(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=%u))",
689                                                 UF_SERVER_TRUST_ACCOUNT);
690                         if (ret == LDB_SUCCESS && res_account->count == 1) {
691                                 const char *errstr;
692                                 ctr1->array[i].dns_name
693                                         = ldb_msg_find_attr_as_string(res_account->msgs[0], "dNSHostName", NULL);
694                                 ctr1->array[i].netbios_name
695                                         = ldb_msg_find_attr_as_string(res_account->msgs[0], "cn", NULL);
696                                 ctr1->array[i].computer_dn
697                                         = ldb_dn_get_linearized(res_account->msgs[0]->dn);
698
699                                 /* Determine if this is the PDC */
700                                 ret = samdb_search_for_parent_domain(b_state->sam_ctx, 
701                                                                      mem_ctx, res_account->msgs[0]->dn,
702                                                                      &domain_dn, &errstr);
703                                 
704                                 if (ret == LDB_SUCCESS) {
705                                         ret = ldb_search(b_state->sam_ctx, mem_ctx, &res_domain, domain_dn,
706                                                                  LDB_SCOPE_BASE, attrs_none, "fSMORoleOwner=%s",
707                                                                  ldb_dn_get_linearized(ntds_dn));
708                                         if (ret) {
709                                                 return WERR_GEN_FAILURE;
710                                         }
711                                         if (res_domain->count == 1) {
712                                                 ctr1->array[i].is_pdc = true;
713                                         }
714                                 }
715                         }
716                         if ((ret != LDB_SUCCESS) && (ret != LDB_ERR_NO_SUCH_OBJECT)) {
717                                 DEBUG(5, ("warning: searching for computer DN %s failed: %s\n", 
718                                           ldb_dn_get_linearized(ref_dn), ldb_errstring(b_state->sam_ctx)));
719                         }
720
721                         /* Look at server DN and extract site component */
722                         ctr1->array[i].site_name = result_site_name(res->msgs[i]->dn);
723                         ctr1->array[i].server_dn = ldb_dn_get_linearized(res->msgs[i]->dn);
724
725
726                         ctr1->array[i].is_enabled = true;
727
728                 }
729                 break;
730         case 2:
731                 ctr2 = &r->out.ctr->ctr2;
732                 ctr2->count = res->count;
733                 ctr2->array = talloc_zero_array(mem_ctx, 
734                                                  struct drsuapi_DsGetDCInfo2, 
735                                                  res->count);
736                 for (i=0; i < res->count; i++) {
737                         struct ldb_dn *domain_dn;
738                         struct ldb_result *res_domain;
739                         struct ldb_result *res_account;
740                         struct ldb_dn *ntds_dn = ldb_dn_copy(mem_ctx, res->msgs[i]->dn);
741                         struct ldb_result *res_ntds;
742                         struct ldb_dn *site_dn = ldb_dn_copy(mem_ctx, res->msgs[i]->dn);
743                         struct ldb_result *res_site;
744                         struct ldb_dn *ref_dn
745                                 = ldb_msg_find_attr_as_dn(b_state->sam_ctx, 
746                                                           mem_ctx, res->msgs[i], 
747                                                           "serverReference");
748
749                         if (!ntds_dn || !ldb_dn_add_child_fmt(ntds_dn, "CN=NTDS Settings")) {
750                                 return WERR_NOT_ENOUGH_MEMORY;
751                         }
752
753                         /* Format is cn=<NETBIOS name>,cn=Servers,cn=<site>,cn=sites.... */
754                         if (!site_dn || !ldb_dn_remove_child_components(site_dn, 2)) {
755                                 return WERR_NOT_ENOUGH_MEMORY;
756                         }
757
758                         ret = ldb_search(b_state->sam_ctx, mem_ctx, &res_ntds, ntds_dn,
759                                                  LDB_SCOPE_BASE, attrs_ntds, "objectClass=nTDSDSA");
760                         if (ret == LDB_SUCCESS && res_ntds->count == 1) {
761                                 ctr2->array[i].is_gc
762                                         = (ldb_msg_find_attr_as_uint(res_ntds->msgs[0], "options", 0) & DS_NTDSDSA_OPT_IS_GC);
763                                 ctr2->array[i].ntds_guid 
764                                         = samdb_result_guid(res_ntds->msgs[0], "objectGUID");
765                                 ctr2->array[i].ntds_dn = ldb_dn_get_linearized(res_ntds->msgs[0]->dn);
766                         }
767                         if ((ret != LDB_SUCCESS) && (ret != LDB_ERR_NO_SUCH_OBJECT)) {
768                                 DEBUG(5, ("warning: searching for NTDS DN %s failed: %s\n", 
769                                           ldb_dn_get_linearized(ntds_dn), ldb_errstring(b_state->sam_ctx)));
770                         }
771
772                         ret = ldb_search(b_state->sam_ctx, mem_ctx, &res_site, site_dn,
773                                                  LDB_SCOPE_BASE, attrs_site, "objectClass=site");
774                         if (ret == LDB_SUCCESS && res_site->count == 1) {
775                                 ctr2->array[i].site_guid 
776                                         = samdb_result_guid(res_site->msgs[0], "objectGUID");
777                                 ctr2->array[i].site_dn = ldb_dn_get_linearized(res_site->msgs[0]->dn);
778                         }
779                         if ((ret != LDB_SUCCESS) && (ret != LDB_ERR_NO_SUCH_OBJECT)) {
780                                 DEBUG(5, ("warning: searching for site DN %s failed: %s\n", 
781                                           ldb_dn_get_linearized(site_dn), ldb_errstring(b_state->sam_ctx)));
782                         }
783
784                         ret = ldb_search(b_state->sam_ctx, mem_ctx, &res_account, ref_dn,
785                                                  LDB_SCOPE_BASE, attrs_account_2, "objectClass=computer");
786                         if (ret == LDB_SUCCESS && res_account->count == 1) {
787                                 const char *errstr;
788                                 ctr2->array[i].dns_name
789                                         = ldb_msg_find_attr_as_string(res_account->msgs[0], "dNSHostName", NULL);
790                                 ctr2->array[i].netbios_name
791                                         = ldb_msg_find_attr_as_string(res_account->msgs[0], "cn", NULL);
792                                 ctr2->array[i].computer_dn = ldb_dn_get_linearized(res_account->msgs[0]->dn);
793                                 ctr2->array[i].computer_guid 
794                                         = samdb_result_guid(res_account->msgs[0], "objectGUID");
795
796                                 /* Determine if this is the PDC */
797                                 ret = samdb_search_for_parent_domain(b_state->sam_ctx, 
798                                                                      mem_ctx, res_account->msgs[0]->dn,
799                                                                      &domain_dn, &errstr);
800                                 
801                                 if (ret == LDB_SUCCESS) {
802                                         ret = ldb_search(b_state->sam_ctx, mem_ctx, &res_domain, domain_dn,
803                                                                  LDB_SCOPE_BASE, attrs_none, "fSMORoleOwner=%s",
804                                                                  ldb_dn_get_linearized(ntds_dn));
805                                         if (ret == LDB_SUCCESS && res_domain->count == 1) {
806                                                 ctr2->array[i].is_pdc = true;
807                                         }
808                                         if ((ret != LDB_SUCCESS) && (ret != LDB_ERR_NO_SUCH_OBJECT)) {
809                                                 DEBUG(5, ("warning: searching for domain DN %s failed: %s\n", 
810                                                           ldb_dn_get_linearized(domain_dn), ldb_errstring(b_state->sam_ctx)));
811                                         }
812                                 }
813                         }
814                         if ((ret != LDB_SUCCESS) && (ret != LDB_ERR_NO_SUCH_OBJECT)) {
815                                 DEBUG(5, ("warning: searching for computer account DN %s failed: %s\n", 
816                                           ldb_dn_get_linearized(ref_dn), ldb_errstring(b_state->sam_ctx)));
817                         }
818
819                         /* Look at server DN and extract site component */
820                         ctr2->array[i].site_name = result_site_name(res->msgs[i]->dn);
821                         ctr2->array[i].server_dn = ldb_dn_get_linearized(res->msgs[i]->dn);
822                         ctr2->array[i].server_guid 
823                                 = samdb_result_guid(res->msgs[i], "objectGUID");
824
825                         ctr2->array[i].is_enabled = true;
826
827                 }
828                 break;
829         case 3:
830                 ctr3 = &r->out.ctr->ctr3;
831                 ctr3->count = res->count;
832                 ctr3->array = talloc_zero_array(mem_ctx,
833                                                  struct drsuapi_DsGetDCInfo3,
834                                                  res->count);
835                 for (i=0; i<res->count; i++) {
836                         struct ldb_dn *domain_dn;
837                         struct ldb_result *res_domain;
838                         struct ldb_result *res_account;
839                         struct ldb_dn *ntds_dn = ldb_dn_copy(mem_ctx, res->msgs[i]->dn);
840                         struct ldb_result *res_ntds;
841                         struct ldb_dn *site_dn = ldb_dn_copy(mem_ctx, res->msgs[i]->dn);
842                         struct ldb_result *res_site;
843                         bool is_rodc;
844                         struct ldb_dn *ref_dn
845                                 = ldb_msg_find_attr_as_dn(b_state->sam_ctx,
846                                                           mem_ctx, res->msgs[i],
847                                                           "serverReference");
848
849                         if (!ntds_dn || !ldb_dn_add_child_fmt(ntds_dn, "CN=NTDS Settings")) {
850                                 return WERR_NOT_ENOUGH_MEMORY;
851                         }
852
853                         /* Format is cn=<NETBIOS name>,cn=Servers,cn=<site>,cn=sites.... */
854                         if (!site_dn || !ldb_dn_remove_child_components(site_dn, 2)) {
855                                 return WERR_NOT_ENOUGH_MEMORY;
856                         }
857
858                         ret = ldb_search(b_state->sam_ctx, mem_ctx, &res_ntds, ntds_dn,
859                                                  LDB_SCOPE_BASE, attrs_ntds, "objectClass=nTDSDSA");
860                         if (ret == LDB_SUCCESS && res_ntds->count == 1) {
861                                 ctr3->array[i].is_gc
862                                         = (ldb_msg_find_attr_as_uint(res_ntds->msgs[0], "options", 0) & DS_NTDSDSA_OPT_IS_GC);
863                                 ctr3->array[i].ntds_guid
864                                         = samdb_result_guid(res_ntds->msgs[0], "objectGUID");
865                                 ctr3->array[i].ntds_dn = ldb_dn_get_linearized(res_ntds->msgs[0]->dn);
866                         }
867                         if ((ret != LDB_SUCCESS) && (ret != LDB_ERR_NO_SUCH_OBJECT)) {
868                                 DEBUG(5, ("warning: searching for NTDS DN %s failed: %s\n",
869                                           ldb_dn_get_linearized(ntds_dn), ldb_errstring(b_state->sam_ctx)));
870                         }
871
872                         ret = ldb_search(b_state->sam_ctx, mem_ctx, &res_site, site_dn,
873                                                  LDB_SCOPE_BASE, attrs_site, "objectClass=site");
874                         if (ret == LDB_SUCCESS && res_site->count == 1) {
875                                 ctr3->array[i].site_guid
876                                         = samdb_result_guid(res_site->msgs[0], "objectGUID");
877                                 ctr3->array[i].site_dn = ldb_dn_get_linearized(res_site->msgs[0]->dn);
878                         }
879                         if ((ret != LDB_SUCCESS) && (ret != LDB_ERR_NO_SUCH_OBJECT)) {
880                                 DEBUG(5, ("warning: searching for site DN %s failed: %s\n",
881                                           ldb_dn_get_linearized(site_dn), ldb_errstring(b_state->sam_ctx)));
882                         }
883
884                         ret = ldb_search(b_state->sam_ctx, mem_ctx, &res_account, ref_dn,
885                                                  LDB_SCOPE_BASE, attrs_account_2, "objectClass=computer");
886                         if (ret == LDB_SUCCESS && res_account->count == 1) {
887                                 const char *errstr;
888                                 ctr3->array[i].dns_name
889                                         = ldb_msg_find_attr_as_string(res_account->msgs[0], "dNSHostName", NULL);
890                                 ctr3->array[i].netbios_name
891                                         = ldb_msg_find_attr_as_string(res_account->msgs[0], "cn", NULL);
892                                 ctr3->array[i].computer_dn = ldb_dn_get_linearized(res_account->msgs[0]->dn);
893                                 ctr3->array[i].computer_guid
894                                         = samdb_result_guid(res_account->msgs[0], "objectGUID");
895
896                                 /* Determine if this is the PDC */
897                                 ret = samdb_search_for_parent_domain(b_state->sam_ctx,
898                                                                      mem_ctx, res_account->msgs[0]->dn,
899                                                                      &domain_dn, &errstr);
900
901                                 if (ret == LDB_SUCCESS) {
902                                         ret = ldb_search(b_state->sam_ctx, mem_ctx, &res_domain, domain_dn,
903                                                                  LDB_SCOPE_BASE, attrs_none, "fSMORoleOwner=%s",
904                                                                  ldb_dn_get_linearized(ntds_dn));
905                                         if (ret == LDB_SUCCESS && res_domain->count == 1) {
906                                                 ctr3->array[i].is_pdc = true;
907                                         }
908                                         if ((ret != LDB_SUCCESS) && (ret != LDB_ERR_NO_SUCH_OBJECT)) {
909                                                 DEBUG(5, ("warning: searching for domain DN %s failed: %s\n",
910                                                           ldb_dn_get_linearized(domain_dn), ldb_errstring(b_state->sam_ctx)));
911                                         }
912                                 }
913                         }
914                         if ((ret != LDB_SUCCESS) && (ret != LDB_ERR_NO_SUCH_OBJECT)) {
915                                 DEBUG(5, ("warning: searching for computer account DN %s failed: %s\n",
916                                           ldb_dn_get_linearized(ref_dn), ldb_errstring(b_state->sam_ctx)));
917                         }
918
919                         /* Look at server DN and extract site component */
920                         ctr3->array[i].site_name = result_site_name(res->msgs[i]->dn);
921                         ctr3->array[i].server_dn = ldb_dn_get_linearized(res->msgs[i]->dn);
922                         ctr3->array[i].server_guid
923                                 = samdb_result_guid(res->msgs[i], "objectGUID");
924
925                         ctr3->array[i].is_enabled = true;
926
927                         /* rodc? */
928                         ret = samdb_is_rodc(b_state->sam_ctx, &ctr3->array[i].server_guid, &is_rodc);
929                         if (ret == LDB_SUCCESS && is_rodc) {
930                                 ctr3->array[i].is_rodc = true;
931                         }
932                 }
933                 break;
934         default:
935                 return WERR_UNKNOWN_LEVEL;
936         }
937         return WERR_OK;
938 }
939
940 /* 
941   drsuapi_DsGetDomainControllerInfo 
942 */
943 static WERROR dcesrv_drsuapi_DsGetDomainControllerInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
944                                                 struct drsuapi_DsGetDomainControllerInfo *r)
945 {
946         struct dcesrv_handle *h;
947         struct drsuapi_bind_state *b_state;     
948         DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
949         b_state = h->data;
950
951         switch (r->in.level) {
952         case 1:
953                 return dcesrv_drsuapi_DsGetDomainControllerInfo_1(b_state, mem_ctx, r);
954         }
955
956         return WERR_UNKNOWN_LEVEL;
957 }
958
959
960
961 /* 
962   drsuapi_DsExecuteKCC 
963 */
964 static WERROR dcesrv_drsuapi_DsExecuteKCC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
965                                   struct drsuapi_DsExecuteKCC *r)
966 {
967         WERROR status;
968         uint32_t timeout;
969         status = drs_security_level_check(dce_call, "DsExecuteKCC", SECURITY_DOMAIN_CONTROLLER, NULL);
970
971         if (!W_ERROR_IS_OK(status)) {
972                 return status;
973         }
974         if (r->in.req->ctr1.taskID != 0) {
975                 return WERR_INVALID_PARAMETER;
976         }
977         if (r->in.req->ctr1.flags & DRSUAPI_DS_EXECUTE_KCC_ASYNCHRONOUS_OPERATION) {
978                 timeout = IRPC_CALL_TIMEOUT;
979         } else {
980                 /*
981                  * use Infinite time for timeout in case
982                  * the caller made a sync call
983                  */
984                 timeout = IRPC_CALL_TIMEOUT_INF;
985         }
986
987         dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSEXECUTEKCC,
988                                      &ndr_table_drsuapi, "kccsrv", "DsExecuteKCC",
989                                      timeout);
990         DEBUG(10, ("Forwarded the call to execute the KCC\n"));
991         return WERR_OK;
992 }
993
994
995 /* 
996   drsuapi_DsReplicaGetInfo 
997 */
998 static WERROR dcesrv_drsuapi_DsReplicaGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
999                        struct drsuapi_DsReplicaGetInfo *r)
1000 {
1001         enum security_user_level level;
1002
1003         if (!lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL,
1004                          "drs", "disable_sec_check", false)) {
1005                 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
1006                 if (level < SECURITY_DOMAIN_CONTROLLER) {
1007                         DEBUG(1,(__location__ ": Administrator access required for DsReplicaGetInfo\n"));
1008                         security_token_debug(0, 2, dce_call->conn->auth_state.session_info->security_token);
1009                         return WERR_DS_DRA_ACCESS_DENIED;
1010                 }
1011         }
1012
1013         dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSREPLICAGETINFO,
1014                                      &ndr_table_drsuapi, "kccsrv", "DsReplicaGetInfo",
1015                                      IRPC_CALL_TIMEOUT);
1016
1017         return WERR_OK;
1018 }
1019
1020
1021 /* 
1022   DRSUAPI_ADD_SID_HISTORY 
1023 */
1024 static WERROR dcesrv_DRSUAPI_ADD_SID_HISTORY(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1025                        struct DRSUAPI_ADD_SID_HISTORY *r)
1026 {
1027         DRSUAPI_UNSUPPORTED(DRSUAPI_ADD_SID_HISTORY);
1028 }
1029
1030 /* 
1031   drsuapi_DsGetMemberships2 
1032 */
1033 static WERROR dcesrv_drsuapi_DsGetMemberships2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1034                        struct drsuapi_DsGetMemberships2 *r)
1035 {
1036         DRSUAPI_UNSUPPORTED(drsuapi_DsGetMemberships2);
1037 }
1038
1039 /* 
1040   DRSUAPI_REPLICA_VERIFY_OBJECTS 
1041 */
1042 static WERROR dcesrv_DRSUAPI_REPLICA_VERIFY_OBJECTS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1043                        struct DRSUAPI_REPLICA_VERIFY_OBJECTS *r)
1044 {
1045         DRSUAPI_UNSUPPORTED(DRSUAPI_REPLICA_VERIFY_OBJECTS);
1046 }
1047
1048
1049 /* 
1050   DRSUAPI_GET_OBJECT_EXISTENCE 
1051 */
1052 static WERROR dcesrv_DRSUAPI_GET_OBJECT_EXISTENCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1053                        struct DRSUAPI_GET_OBJECT_EXISTENCE *r)
1054 {
1055         DRSUAPI_UNSUPPORTED(DRSUAPI_GET_OBJECT_EXISTENCE);
1056 }
1057
1058
1059 /* 
1060   drsuapi_QuerySitesByCost 
1061 */
1062 static WERROR dcesrv_drsuapi_QuerySitesByCost(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1063                        struct drsuapi_QuerySitesByCost *r)
1064 {
1065         DRSUAPI_UNSUPPORTED(drsuapi_QuerySitesByCost);
1066 }
1067
1068
1069 /* include the generated boilerplate */
1070 #include "librpc/gen_ndr/ndr_drsuapi_s.c"