Show why a LookupName fails (help debugging)
[samba.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the lsarpc pipe
5
6    Copyright (C) Andrew Tridgell 2004
7    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2007
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 "rpc_server/lsa/lsa.h"
24 #include "util/util_ldb.h"
25 #include "libcli/ldap/ldap_ndr.h"
26
27 /*
28   this type allows us to distinguish handle types
29 */
30
31 /*
32   state associated with a lsa_OpenAccount() operation
33 */
34 struct lsa_account_state {
35         struct lsa_policy_state *policy;
36         uint32_t access_mask;
37         struct dom_sid *account_sid;
38 };
39
40
41 /*
42   state associated with a lsa_OpenSecret() operation
43 */
44 struct lsa_secret_state {
45         struct lsa_policy_state *policy;
46         uint32_t access_mask;
47         struct ldb_dn *secret_dn;
48         struct ldb_context *sam_ldb;
49         bool global;
50 };
51
52 /*
53   state associated with a lsa_OpenTrustedDomain() operation
54 */
55 struct lsa_trusted_domain_state {
56         struct lsa_policy_state *policy;
57         uint32_t access_mask;
58         struct ldb_dn *trusted_domain_dn;
59 };
60
61 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
62                                       TALLOC_CTX *mem_ctx,
63                                       struct lsa_EnumAccountRights *r);
64
65 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
66                                            TALLOC_CTX *mem_ctx,
67                                            struct lsa_policy_state *state,
68                                            int ldb_flag,
69                                            struct dom_sid *sid,
70                                            const struct lsa_RightSet *rights);
71
72 /* 
73   lsa_Close 
74 */
75 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
76                           struct lsa_Close *r)
77 {
78         struct dcesrv_handle *h;
79
80         *r->out.handle = *r->in.handle;
81
82         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
83
84         talloc_free(h);
85
86         ZERO_STRUCTP(r->out.handle);
87
88         return NT_STATUS_OK;
89 }
90
91
92 /* 
93   lsa_Delete 
94 */
95 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
96                            struct lsa_Delete *r)
97 {
98         struct dcesrv_handle *h;
99         int ret;
100
101         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
102         if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
103                 struct lsa_secret_state *secret_state = h->data;
104                 ret = ldb_delete(secret_state->sam_ldb, 
105                                  secret_state->secret_dn);
106                 talloc_free(h);
107                 if (ret != 0) {
108                         return NT_STATUS_INVALID_HANDLE;
109                 }
110
111                 return NT_STATUS_OK;
112         } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
113                 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
114                 ret = ldb_delete(trusted_domain_state->policy->sam_ldb, 
115                                  trusted_domain_state->trusted_domain_dn);
116                 talloc_free(h);
117                 if (ret != 0) {
118                         return NT_STATUS_INVALID_HANDLE;
119                 }
120
121                 return NT_STATUS_OK;
122         } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
123                 struct lsa_RightSet *rights;
124                 struct lsa_account_state *astate;
125                 struct lsa_EnumAccountRights r2;
126                 NTSTATUS status;
127
128                 rights = talloc(mem_ctx, struct lsa_RightSet);
129
130                 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
131                 
132                 astate = h->data;
133
134                 r2.in.handle = &astate->policy->handle->wire_handle;
135                 r2.in.sid = astate->account_sid;
136                 r2.out.rights = rights;
137
138                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
139                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
140                         return NT_STATUS_OK;
141                 }
142
143                 if (!NT_STATUS_IS_OK(status)) {
144                         return status;
145                 }
146
147                 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
148                                                     LDB_FLAG_MOD_DELETE, astate->account_sid,
149                                                     r2.out.rights);
150                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
151                         return NT_STATUS_OK;
152                 }
153
154                 if (!NT_STATUS_IS_OK(status)) {
155                         return status;
156                 }
157         } 
158         
159         return NT_STATUS_INVALID_HANDLE;
160 }
161
162
163 /* 
164   lsa_EnumPrivs 
165 */
166 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
167                               struct lsa_EnumPrivs *r)
168 {
169         struct dcesrv_handle *h;
170         struct lsa_policy_state *state;
171         int i;
172         const char *privname;
173
174         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
175
176         state = h->data;
177
178         i = *r->in.resume_handle;
179         if (i == 0) i = 1;
180
181         while ((privname = sec_privilege_name(i)) &&
182                r->out.privs->count < r->in.max_count) {
183                 struct lsa_PrivEntry *e;
184
185                 r->out.privs->privs = talloc_realloc(r->out.privs,
186                                                        r->out.privs->privs, 
187                                                        struct lsa_PrivEntry, 
188                                                        r->out.privs->count+1);
189                 if (r->out.privs->privs == NULL) {
190                         return NT_STATUS_NO_MEMORY;
191                 }
192                 e = &r->out.privs->privs[r->out.privs->count];
193                 e->luid.low = i;
194                 e->luid.high = 0;
195                 e->name.string = privname;
196                 r->out.privs->count++;
197                 i++;
198         }
199
200         *r->out.resume_handle = i;
201
202         return NT_STATUS_OK;
203 }
204
205
206 /* 
207   lsa_QuerySecObj 
208 */
209 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
210                                   struct lsa_QuerySecurity *r)
211 {
212         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
213 }
214
215
216 /* 
217   lsa_SetSecObj 
218 */
219 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
220                               struct lsa_SetSecObj *r)
221 {
222         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
223 }
224
225
226 /* 
227   lsa_ChangePassword 
228 */
229 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
230                                    struct lsa_ChangePassword *r)
231 {
232         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
233 }
234
235 /* 
236   dssetup_DsRoleGetPrimaryDomainInformation 
237
238   This is not an LSA call, but is the only call left on the DSSETUP
239   pipe (after the pipe was truncated), and needs lsa_get_policy_state
240 */
241 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call, 
242                                                  TALLOC_CTX *mem_ctx,
243                                                  struct dssetup_DsRoleGetPrimaryDomainInformation *r)
244 {
245         union dssetup_DsRoleInfo *info;
246
247         info = talloc(mem_ctx, union dssetup_DsRoleInfo);
248         W_ERROR_HAVE_NO_MEMORY(info);
249
250         switch (r->in.level) {
251         case DS_ROLE_BASIC_INFORMATION:
252         {
253                 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
254                 uint32_t flags = 0;
255                 const char *domain = NULL;
256                 const char *dns_domain = NULL;
257                 const char *forest = NULL;
258                 struct GUID domain_guid;
259                 struct lsa_policy_state *state;
260
261                 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
262                 if (!NT_STATUS_IS_OK(status)) {
263                         return ntstatus_to_werror(status);
264                 }
265
266                 ZERO_STRUCT(domain_guid);
267
268                 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
269                 case ROLE_STANDALONE:
270                         role            = DS_ROLE_STANDALONE_SERVER;
271                         break;
272                 case ROLE_DOMAIN_MEMBER:
273                         role            = DS_ROLE_MEMBER_SERVER;
274                         break;
275                 case ROLE_DOMAIN_CONTROLLER:
276                         if (samdb_is_pdc(state->sam_ldb)) {
277                                 role    = DS_ROLE_PRIMARY_DC;
278                         } else {
279                                 role    = DS_ROLE_BACKUP_DC;
280                         }
281                         break;
282                 }
283
284                 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
285                 case ROLE_STANDALONE:
286                         domain          = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
287                         W_ERROR_HAVE_NO_MEMORY(domain);
288                         break;
289                 case ROLE_DOMAIN_MEMBER:
290                         domain          = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
291                         W_ERROR_HAVE_NO_MEMORY(domain);
292                         /* TODO: what is with dns_domain and forest and guid? */
293                         break;
294                 case ROLE_DOMAIN_CONTROLLER:
295                         flags           = DS_ROLE_PRIMARY_DS_RUNNING;
296
297                         if (state->mixed_domain == 1) {
298                                 flags   |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
299                         }
300                         
301                         domain          = state->domain_name;
302                         dns_domain      = state->domain_dns;
303                         forest          = state->forest_dns;
304
305                         domain_guid     = state->domain_guid;
306                         flags   |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
307                         break;
308                 }
309
310                 info->basic.role        = role; 
311                 info->basic.flags       = flags;
312                 info->basic.domain      = domain;
313                 info->basic.dns_domain  = dns_domain;
314                 info->basic.forest      = forest;
315                 info->basic.domain_guid = domain_guid;
316
317                 r->out.info = info;
318                 return WERR_OK;
319         }
320         case DS_ROLE_UPGRADE_STATUS:
321         {
322                 info->upgrade.upgrading     = DS_ROLE_NOT_UPGRADING;
323                 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
324
325                 r->out.info = info;
326                 return WERR_OK;
327         }
328         case DS_ROLE_OP_STATUS:
329         {
330                 info->opstatus.status = DS_ROLE_OP_IDLE;
331
332                 r->out.info = info;
333                 return WERR_OK;
334         }
335         default:
336                 return WERR_INVALID_PARAM;
337         }
338
339         return WERR_INVALID_PARAM;
340 }
341
342
343 /*
344   fill in the AccountDomain info
345 */
346 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
347                                        struct lsa_DomainInfo *info)
348 {
349         info->name.string = state->domain_name;
350         info->sid         = state->domain_sid;
351
352         return NT_STATUS_OK;
353 }
354
355 /*
356   fill in the DNS domain info
357 */
358 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
359                              struct lsa_DnsDomainInfo *info)
360 {
361         info->name.string = state->domain_name;
362         info->sid         = state->domain_sid;
363         info->dns_domain.string = state->domain_dns;
364         info->dns_forest.string = state->forest_dns;
365         info->domain_guid       = state->domain_guid;
366
367         return NT_STATUS_OK;
368 }
369
370 /* 
371   lsa_QueryInfoPolicy2
372 */
373 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
374                                      struct lsa_QueryInfoPolicy2 *r)
375 {
376         struct lsa_policy_state *state;
377         struct dcesrv_handle *h;
378
379         r->out.info = NULL;
380
381         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
382
383         state = h->data;
384
385         r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
386         if (!r->out.info) {
387                 return NT_STATUS_NO_MEMORY;
388         }
389
390         ZERO_STRUCTP(r->out.info);
391
392         switch (r->in.level) {
393         case LSA_POLICY_INFO_DOMAIN:
394         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
395                 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
396
397         case LSA_POLICY_INFO_DNS:
398                 return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
399         case LSA_POLICY_INFO_DB:
400         case LSA_POLICY_INFO_AUDIT_FULL_SET:
401         case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
402                 return NT_STATUS_INVALID_PARAMETER;
403         }
404
405         return NT_STATUS_INVALID_INFO_CLASS;
406 }
407
408 /* 
409   lsa_QueryInfoPolicy 
410 */
411 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
412                                     struct lsa_QueryInfoPolicy *r)
413 {
414         struct lsa_QueryInfoPolicy2 r2;
415         NTSTATUS status;
416
417         r2.in.handle = r->in.handle;
418         r2.in.level = r->in.level;
419         
420         status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
421
422         r->out.info = r2.out.info;
423
424         return status;
425 }
426
427 /* 
428   lsa_SetInfoPolicy 
429 */
430 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
431                                   struct lsa_SetInfoPolicy *r)
432 {
433         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
434 }
435
436
437 /* 
438   lsa_ClearAuditLog 
439 */
440 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
441                                   struct lsa_ClearAuditLog *r)
442 {
443         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
444 }
445
446
447 /* 
448   lsa_CreateAccount 
449 */
450 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
451                                   struct lsa_CreateAccount *r)
452 {
453         struct lsa_account_state *astate;
454
455         struct lsa_policy_state *state;
456         struct dcesrv_handle *h, *ah;
457
458         ZERO_STRUCTP(r->out.acct_handle);
459
460         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
461
462         state = h->data;
463
464         astate = talloc(dce_call->conn, struct lsa_account_state);
465         if (astate == NULL) {
466                 return NT_STATUS_NO_MEMORY;
467         }
468
469         astate->account_sid = dom_sid_dup(astate, r->in.sid);
470         if (astate->account_sid == NULL) {
471                 talloc_free(astate);
472                 return NT_STATUS_NO_MEMORY;
473         }
474         
475         astate->policy = talloc_reference(astate, state);
476         astate->access_mask = r->in.access_mask;
477
478         ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
479         if (!ah) {
480                 talloc_free(astate);
481                 return NT_STATUS_NO_MEMORY;
482         }
483
484         ah->data = talloc_steal(ah, astate);
485
486         *r->out.acct_handle = ah->wire_handle;
487
488         return NT_STATUS_OK;
489 }
490
491
492 /* 
493   lsa_EnumAccounts 
494 */
495 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
496                                  struct lsa_EnumAccounts *r)
497 {
498         struct dcesrv_handle *h;
499         struct lsa_policy_state *state;
500         int ret, i;
501         struct ldb_message **res;
502         const char * const attrs[] = { "objectSid", NULL};
503         uint32_t count;
504
505         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
506
507         state = h->data;
508
509         /* NOTE: This call must only return accounts that have at least
510            one privilege set 
511         */
512         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
513                            "(&(objectSid=*)(privilege=*))");
514         if (ret < 0) {
515                 return NT_STATUS_NO_SUCH_USER;
516         }
517
518         if (*r->in.resume_handle >= ret) {
519                 return NT_STATUS_NO_MORE_ENTRIES;
520         }
521
522         count = ret - *r->in.resume_handle;
523         if (count > r->in.num_entries) {
524                 count = r->in.num_entries;
525         }
526
527         if (count == 0) {
528                 return NT_STATUS_NO_MORE_ENTRIES;
529         }
530
531         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
532         if (r->out.sids->sids == NULL) {
533                 return NT_STATUS_NO_MEMORY;
534         }
535
536         for (i=0;i<count;i++) {
537                 r->out.sids->sids[i].sid = 
538                         samdb_result_dom_sid(r->out.sids->sids, 
539                                              res[i + *r->in.resume_handle],
540                                              "objectSid");
541                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
542         }
543
544         r->out.sids->num_sids = count;
545         *r->out.resume_handle = count + *r->in.resume_handle;
546
547         return NT_STATUS_OK;
548         
549 }
550
551
552 /*
553   lsa_CreateTrustedDomainEx2
554 */
555 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
556                                            TALLOC_CTX *mem_ctx,
557                                            struct lsa_CreateTrustedDomainEx2 *r)
558 {
559         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
560 }
561
562 /*
563   lsa_CreateTrustedDomainEx
564 */
565 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
566                                           TALLOC_CTX *mem_ctx,
567                                           struct lsa_CreateTrustedDomainEx *r)
568 {
569         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
570 }
571
572 /* 
573   lsa_CreateTrustedDomain 
574 */
575 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
576                                         struct lsa_CreateTrustedDomain *r)
577 {
578         struct dcesrv_handle *policy_handle;
579         struct lsa_policy_state *policy_state;
580         struct lsa_trusted_domain_state *trusted_domain_state;
581         struct dcesrv_handle *handle;
582         struct ldb_message **msgs, *msg;
583         const char *attrs[] = {
584                 NULL
585         };
586         const char *name;
587         int ret;
588
589         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
590         ZERO_STRUCTP(r->out.trustdom_handle);
591         
592         policy_state = policy_handle->data;
593
594         if (!r->in.info->name.string) {
595                 return NT_STATUS_INVALID_PARAMETER;
596         }
597         name = r->in.info->name.string;
598         
599         trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
600         if (!trusted_domain_state) {
601                 return NT_STATUS_NO_MEMORY;
602         }
603         trusted_domain_state->policy = policy_state;
604
605         msg = ldb_msg_new(mem_ctx);
606         if (msg == NULL) {
607                 return NT_STATUS_NO_MEMORY;
608         }
609
610         /* search for the trusted_domain record */
611         ret = gendb_search(trusted_domain_state->policy->sam_ldb,
612                            mem_ctx, policy_state->system_dn, &msgs, attrs,
613                            "(&(cn=%s)(objectclass=trustedDomain))", 
614                            ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
615         if (ret > 0) {
616                 return NT_STATUS_OBJECT_NAME_COLLISION;
617         }
618         
619         if (ret < 0 || ret > 1) {
620                 DEBUG(0,("Found %d records matching DN %s\n", ret,
621                          ldb_dn_get_linearized(policy_state->system_dn)));
622                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
623         }
624         
625         msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
626         if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
627                 return NT_STATUS_NO_MEMORY;
628         }
629         
630         samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
631
632         if (r->in.info->sid) {
633                 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
634                 if (!sid_string) {
635                         return NT_STATUS_NO_MEMORY;
636                 }
637                         
638                 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
639         }
640
641         samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
642         
643         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
644
645         /* create the trusted_domain */
646         ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
647         switch (ret) {
648         case  LDB_SUCCESS:
649                 break;
650         case  LDB_ERR_ENTRY_ALREADY_EXISTS:
651                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
652                 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
653                          ldb_dn_get_linearized(msg->dn),
654                          ldb_errstring(trusted_domain_state->policy->sam_ldb)));
655                 return NT_STATUS_DOMAIN_EXISTS;
656         case  LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
657                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
658                 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
659                          ldb_dn_get_linearized(msg->dn),
660                          ldb_errstring(trusted_domain_state->policy->sam_ldb)));
661                 return NT_STATUS_ACCESS_DENIED;
662         default:
663                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
664                 DEBUG(0,("Failed to create user record %s: %s\n",
665                          ldb_dn_get_linearized(msg->dn),
666                          ldb_errstring(trusted_domain_state->policy->sam_ldb)));
667                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
668         }
669
670         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
671         if (!handle) {
672                 return NT_STATUS_NO_MEMORY;
673         }
674         
675         handle->data = talloc_steal(handle, trusted_domain_state);
676         
677         trusted_domain_state->access_mask = r->in.access_mask;
678         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
679         
680         *r->out.trustdom_handle = handle->wire_handle;
681         
682         return NT_STATUS_OK;
683 }
684
685 /* 
686   lsa_OpenTrustedDomain
687 */
688 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
689                                       struct lsa_OpenTrustedDomain *r)
690 {
691         struct dcesrv_handle *policy_handle;
692         
693         struct lsa_policy_state *policy_state;
694         struct lsa_trusted_domain_state *trusted_domain_state;
695         struct dcesrv_handle *handle;
696         struct ldb_message **msgs;
697         const char *attrs[] = {
698                 NULL
699         };
700
701         const char *sid_string;
702         int ret;
703
704         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
705         ZERO_STRUCTP(r->out.trustdom_handle);
706         policy_state = policy_handle->data;
707
708         trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
709         if (!trusted_domain_state) {
710                 return NT_STATUS_NO_MEMORY;
711         }
712         trusted_domain_state->policy = policy_state;
713
714         sid_string = dom_sid_string(mem_ctx, r->in.sid);
715         if (!sid_string) {
716                 return NT_STATUS_NO_MEMORY;
717         }
718
719         /* search for the trusted_domain record */
720         ret = gendb_search(trusted_domain_state->policy->sam_ldb,
721                            mem_ctx, policy_state->system_dn, &msgs, attrs,
722                            "(&(securityIdentifier=%s)(objectclass=trustedDomain))", 
723                            sid_string);
724         if (ret == 0) {
725                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
726         }
727         
728         if (ret != 1) {
729                 DEBUG(0,("Found %d records matching DN %s\n", ret,
730                          ldb_dn_get_linearized(policy_state->system_dn)));
731                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
732         }
733
734         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
735         
736         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
737         if (!handle) {
738                 return NT_STATUS_NO_MEMORY;
739         }
740         
741         handle->data = talloc_steal(handle, trusted_domain_state);
742         
743         trusted_domain_state->access_mask = r->in.access_mask;
744         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
745         
746         *r->out.trustdom_handle = handle->wire_handle;
747         
748         return NT_STATUS_OK;
749 }
750
751
752 /*
753   lsa_OpenTrustedDomainByName
754 */
755 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
756                                             TALLOC_CTX *mem_ctx,
757                                             struct lsa_OpenTrustedDomainByName *r)
758 {
759         struct dcesrv_handle *policy_handle;
760         
761         struct lsa_policy_state *policy_state;
762         struct lsa_trusted_domain_state *trusted_domain_state;
763         struct dcesrv_handle *handle;
764         struct ldb_message **msgs;
765         const char *attrs[] = {
766                 NULL
767         };
768
769         int ret;
770
771         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
772         ZERO_STRUCTP(r->out.trustdom_handle);
773         policy_state = policy_handle->data;
774
775         if (!r->in.name.string) {
776                 return NT_STATUS_INVALID_PARAMETER;
777         }
778         
779         trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
780         if (!trusted_domain_state) {
781                 return NT_STATUS_NO_MEMORY;
782         }
783         trusted_domain_state->policy = policy_state;
784
785         /* search for the trusted_domain record */
786         ret = gendb_search(trusted_domain_state->policy->sam_ldb,
787                            mem_ctx, policy_state->system_dn, &msgs, attrs,
788                            "(&(flatname=%s)(objectclass=trustedDomain))", 
789                            ldb_binary_encode_string(mem_ctx, r->in.name.string));
790         if (ret == 0) {
791                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
792         }
793         
794         if (ret != 1) {
795                 DEBUG(0,("Found %d records matching DN %s\n", ret,
796                          ldb_dn_get_linearized(policy_state->system_dn)));
797                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
798         }
799
800         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
801         
802         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
803         if (!handle) {
804                 return NT_STATUS_NO_MEMORY;
805         }
806         
807         handle->data = talloc_steal(handle, trusted_domain_state);
808         
809         trusted_domain_state->access_mask = r->in.access_mask;
810         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
811         
812         *r->out.trustdom_handle = handle->wire_handle;
813         
814         return NT_STATUS_OK;
815 }
816
817
818
819 /* 
820   lsa_SetTrustedDomainInfo
821 */
822 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
823                                          struct lsa_SetTrustedDomainInfo *r)
824 {
825         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
826 }
827
828
829
830 /* 
831   lsa_SetInfomrationTrustedDomain
832 */
833 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, 
834                                                 TALLOC_CTX *mem_ctx,
835                                                 struct lsa_SetInformationTrustedDomain *r)
836 {
837         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
838 }
839
840
841 /* 
842   lsa_DeleteTrustedDomain
843 */
844 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
845                                       struct lsa_DeleteTrustedDomain *r)
846 {
847         NTSTATUS status;
848         struct lsa_OpenTrustedDomain open;
849         struct lsa_Delete delete;
850         struct dcesrv_handle *h;
851
852         open.in.handle = r->in.handle;
853         open.in.sid = r->in.dom_sid;
854         open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
855         open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
856         if (!open.out.trustdom_handle) {
857                 return NT_STATUS_NO_MEMORY;
858         }
859         status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
860         if (!NT_STATUS_IS_OK(status)) {
861                 return status;
862         }
863
864         DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
865         talloc_steal(mem_ctx, h);
866
867         delete.in.handle = open.out.trustdom_handle;
868         status = dcesrv_lsa_Delete(dce_call, mem_ctx, &delete);
869         if (!NT_STATUS_IS_OK(status)) {
870                 return status;
871         }
872         return NT_STATUS_OK;
873 }
874
875 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx, 
876                                      struct ldb_message *msg, 
877                                      struct lsa_TrustDomainInfoInfoEx *info_ex) 
878 {
879         info_ex->domain_name.string
880                 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
881         info_ex->netbios_name.string
882                 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
883         info_ex->sid 
884                 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
885         info_ex->trust_direction
886                 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
887         info_ex->trust_type
888                 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
889         info_ex->trust_attributes
890                 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);  
891         return NT_STATUS_OK;
892 }
893
894 /* 
895   lsa_QueryTrustedDomainInfo
896 */
897 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
898                                            struct lsa_QueryTrustedDomainInfo *r)
899 {
900         struct dcesrv_handle *h;
901         struct lsa_trusted_domain_state *trusted_domain_state;
902         struct ldb_message *msg;
903         int ret;
904         struct ldb_message **res;
905         const char *attrs[] = {
906                 "flatname", 
907                 "trustPartner",
908                 "securityIdentifier",
909                 "trustDirection",
910                 "trustType",
911                 "trustAttributes", 
912                 NULL
913         };
914
915         DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
916
917         trusted_domain_state = h->data;
918
919         /* pull all the user attributes */
920         ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
921                               trusted_domain_state->trusted_domain_dn, &res, attrs);
922         if (ret != 1) {
923                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
924         }
925         msg = res[0];
926         
927         r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
928         if (!r->out.info) {
929                 return NT_STATUS_NO_MEMORY;
930         }
931         switch (r->in.level) {
932         case LSA_TRUSTED_DOMAIN_INFO_NAME:
933                 r->out.info->name.netbios_name.string
934                         = samdb_result_string(msg, "flatname", NULL);                                      
935                 break;
936         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
937                 r->out.info->posix_offset.posix_offset
938                         = samdb_result_uint(msg, "posixOffset", 0);                                        
939                 break;
940 #if 0  /* Win2k3 doesn't implement this */
941         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
942                 r->out.info->info_basic.netbios_name.string 
943                         = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
944                 r->out.info->info_basic.sid
945                         = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
946                 break;
947 #endif
948         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
949                 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
950
951         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
952                 ZERO_STRUCT(r->out.info->full_info);
953                 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
954
955         case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
956                 ZERO_STRUCT(r->out.info->info_all);
957                 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
958
959         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
960         case LSA_TRUSTED_DOMAIN_INFO_11:
961                 /* oops, we don't want to return the info after all */
962                 talloc_free(r->out.info);
963                 r->out.info = NULL;
964                 return NT_STATUS_INVALID_PARAMETER;
965         default:
966                 /* oops, we don't want to return the info after all */
967                 talloc_free(r->out.info);
968                 r->out.info = NULL;
969                 return NT_STATUS_INVALID_INFO_CLASS;
970         }
971
972         return NT_STATUS_OK;
973 }
974
975
976 /* 
977   lsa_QueryTrustedDomainInfoBySid
978 */
979 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
980                                                 struct lsa_QueryTrustedDomainInfoBySid *r)
981 {
982         NTSTATUS status;
983         struct lsa_OpenTrustedDomain open;
984         struct lsa_QueryTrustedDomainInfo query;
985         struct dcesrv_handle *h;
986         open.in.handle = r->in.handle;
987         open.in.sid = r->in.dom_sid;
988         open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
989         open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
990         if (!open.out.trustdom_handle) {
991                 return NT_STATUS_NO_MEMORY;
992         }
993         status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
994         if (!NT_STATUS_IS_OK(status)) {
995                 return status;
996         }
997
998         /* Ensure this handle goes away at the end of this call */
999         DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1000         talloc_steal(mem_ctx, h);
1001         
1002         query.in.trustdom_handle = open.out.trustdom_handle;
1003         query.in.level = r->in.level;
1004         status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1005         if (!NT_STATUS_IS_OK(status)) {
1006                 return status;
1007         }
1008         
1009         r->out.info = query.out.info;
1010         return NT_STATUS_OK;
1011 }
1012
1013 /*
1014   lsa_SetTrustedDomainInfoByName
1015 */
1016 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1017                                                TALLOC_CTX *mem_ctx,
1018                                                struct lsa_SetTrustedDomainInfoByName *r)
1019 {
1020         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1021 }
1022
1023 /* 
1024    lsa_QueryTrustedDomainInfoByName
1025 */
1026 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1027                                                  TALLOC_CTX *mem_ctx,
1028                                                  struct lsa_QueryTrustedDomainInfoByName *r)
1029 {
1030         NTSTATUS status;
1031         struct lsa_OpenTrustedDomainByName open;
1032         struct lsa_QueryTrustedDomainInfo query;
1033         struct dcesrv_handle *h;
1034         open.in.handle = r->in.handle;
1035         open.in.name = r->in.trusted_domain;
1036         open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1037         open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1038         if (!open.out.trustdom_handle) {
1039                 return NT_STATUS_NO_MEMORY;
1040         }
1041         status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1042         if (!NT_STATUS_IS_OK(status)) {
1043                 return status;
1044         }
1045         
1046         /* Ensure this handle goes away at the end of this call */
1047         DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1048         talloc_steal(mem_ctx, h);
1049
1050         query.in.trustdom_handle = open.out.trustdom_handle;
1051         query.in.level = r->in.level;
1052         status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1053         if (!NT_STATUS_IS_OK(status)) {
1054                 return status;
1055         }
1056         
1057         r->out.info = query.out.info;
1058         return NT_STATUS_OK;
1059 }
1060
1061 /*
1062   lsa_CloseTrustedDomainEx 
1063 */
1064 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1065                                          TALLOC_CTX *mem_ctx,
1066                                          struct lsa_CloseTrustedDomainEx *r)
1067 {
1068         /* The result of a bad hair day from an IDL programmer?  Not
1069          * implmented in Win2k3.  You should always just lsa_Close
1070          * anyway. */
1071         return NT_STATUS_NOT_IMPLEMENTED;
1072 }
1073
1074
1075 /*
1076   comparison function for sorting lsa_DomainInformation array
1077 */
1078 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1079 {
1080         return strcasecmp_m(e1->name.string, e2->name.string);
1081 }
1082
1083 /* 
1084   lsa_EnumTrustDom 
1085 */
1086 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1087                                  struct lsa_EnumTrustDom *r)
1088 {
1089         struct dcesrv_handle *policy_handle;
1090         struct lsa_DomainInfo *entries;
1091         struct lsa_policy_state *policy_state;
1092         struct ldb_message **domains;
1093         const char *attrs[] = {
1094                 "flatname", 
1095                 "securityIdentifier",
1096                 NULL
1097         };
1098
1099
1100         int count, i;
1101
1102         *r->out.resume_handle = 0;
1103
1104         r->out.domains->domains = NULL;
1105         r->out.domains->count = 0;
1106
1107         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1108
1109         policy_state = policy_handle->data;
1110
1111         /* search for all users in this domain. This could possibly be cached and 
1112            resumed based on resume_key */
1113         count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 
1114                              "objectclass=trustedDomain");
1115         if (count == -1) {
1116                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1117         }
1118         if (count == 0 || r->in.max_size == 0) {
1119                 return NT_STATUS_OK;
1120         }
1121
1122         /* convert to lsa_TrustInformation format */
1123         entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1124         if (!entries) {
1125                 return NT_STATUS_NO_MEMORY;
1126         }
1127         for (i=0;i<count;i++) {
1128                 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1129                 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1130         }
1131
1132         /* sort the results by name */
1133         qsort(entries, count, sizeof(*entries), 
1134               (comparison_fn_t)compare_DomainInfo);
1135
1136         if (*r->in.resume_handle >= count) {
1137                 *r->out.resume_handle = -1;
1138
1139                 return NT_STATUS_NO_MORE_ENTRIES;
1140         }
1141
1142         /* return the rest, limit by max_size. Note that we 
1143            use the w2k3 element size value of 60 */
1144         r->out.domains->count = count - *r->in.resume_handle;
1145         r->out.domains->count = MIN(r->out.domains->count, 
1146                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1147
1148         r->out.domains->domains = entries + *r->in.resume_handle;
1149         r->out.domains->count = r->out.domains->count;
1150
1151         if (r->out.domains->count < count - *r->in.resume_handle) {
1152                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1153                 return STATUS_MORE_ENTRIES;
1154         }
1155
1156         return NT_STATUS_OK;
1157 }
1158
1159 /*
1160   comparison function for sorting lsa_DomainInformation array
1161 */
1162 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1163 {
1164         return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1165 }
1166
1167 /* 
1168   lsa_EnumTrustedDomainsEx 
1169 */
1170 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1171                                         struct lsa_EnumTrustedDomainsEx *r)
1172 {
1173         struct dcesrv_handle *policy_handle;
1174         struct lsa_TrustDomainInfoInfoEx *entries;
1175         struct lsa_policy_state *policy_state;
1176         struct ldb_message **domains;
1177         const char *attrs[] = {
1178                 "flatname", 
1179                 "trustPartner",
1180                 "securityIdentifier",
1181                 "trustDirection",
1182                 "trustType",
1183                 "trustAttributes", 
1184                 NULL
1185         };
1186         NTSTATUS nt_status;
1187
1188         int count, i;
1189
1190         *r->out.resume_handle = 0;
1191
1192         r->out.domains->domains = NULL;
1193         r->out.domains->count = 0;
1194
1195         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1196
1197         policy_state = policy_handle->data;
1198
1199         /* search for all users in this domain. This could possibly be cached and 
1200            resumed based on resume_key */
1201         count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 
1202                              "objectclass=trustedDomain");
1203         if (count == -1) {
1204                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1205         }
1206         if (count == 0 || r->in.max_size == 0) {
1207                 return NT_STATUS_OK;
1208         }
1209
1210         /* convert to lsa_DomainInformation format */
1211         entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1212         if (!entries) {
1213                 return NT_STATUS_NO_MEMORY;
1214         }
1215         for (i=0;i<count;i++) {
1216                 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1217                 if (!NT_STATUS_IS_OK(nt_status)) {
1218                         return nt_status;
1219                 }
1220         }
1221
1222         /* sort the results by name */
1223         qsort(entries, count, sizeof(*entries), 
1224               (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1225
1226         if (*r->in.resume_handle >= count) {
1227                 *r->out.resume_handle = -1;
1228
1229                 return NT_STATUS_NO_MORE_ENTRIES;
1230         }
1231
1232         /* return the rest, limit by max_size. Note that we 
1233            use the w2k3 element size value of 60 */
1234         r->out.domains->count = count - *r->in.resume_handle;
1235         r->out.domains->count = MIN(r->out.domains->count, 
1236                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1237
1238         r->out.domains->domains = entries + *r->in.resume_handle;
1239         r->out.domains->count = r->out.domains->count;
1240
1241         if (r->out.domains->count < count - *r->in.resume_handle) {
1242                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1243                 return STATUS_MORE_ENTRIES;
1244         }
1245
1246         return NT_STATUS_OK;
1247 }
1248
1249
1250 /* 
1251   lsa_OpenAccount 
1252 */
1253 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1254                                 struct lsa_OpenAccount *r)
1255 {
1256         struct dcesrv_handle *h, *ah;
1257         struct lsa_policy_state *state;
1258         struct lsa_account_state *astate;
1259
1260         ZERO_STRUCTP(r->out.acct_handle);
1261
1262         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1263
1264         state = h->data;
1265
1266         astate = talloc(dce_call->conn, struct lsa_account_state);
1267         if (astate == NULL) {
1268                 return NT_STATUS_NO_MEMORY;
1269         }
1270
1271         astate->account_sid = dom_sid_dup(astate, r->in.sid);
1272         if (astate->account_sid == NULL) {
1273                 talloc_free(astate);
1274                 return NT_STATUS_NO_MEMORY;
1275         }
1276         
1277         astate->policy = talloc_reference(astate, state);
1278         astate->access_mask = r->in.access_mask;
1279
1280         ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1281         if (!ah) {
1282                 talloc_free(astate);
1283                 return NT_STATUS_NO_MEMORY;
1284         }
1285
1286         ah->data = talloc_steal(ah, astate);
1287
1288         *r->out.acct_handle = ah->wire_handle;
1289
1290         return NT_STATUS_OK;
1291 }
1292
1293
1294 /* 
1295   lsa_EnumPrivsAccount 
1296 */
1297 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 
1298                                      TALLOC_CTX *mem_ctx,
1299                                      struct lsa_EnumPrivsAccount *r)
1300 {
1301         struct dcesrv_handle *h;
1302         struct lsa_account_state *astate;
1303         int ret, i;
1304         struct ldb_message **res;
1305         const char * const attrs[] = { "privilege", NULL};
1306         struct ldb_message_element *el;
1307         const char *sidstr;
1308
1309         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1310
1311         astate = h->data;
1312
1313         r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1314         r->out.privs->count = 0;
1315         r->out.privs->unknown = 0;
1316         r->out.privs->set = NULL;
1317
1318         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1319         if (sidstr == NULL) {
1320                 return NT_STATUS_NO_MEMORY;
1321         }
1322
1323         ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs, 
1324                            "objectSid=%s", sidstr);
1325         if (ret != 1) {
1326                 return NT_STATUS_OK;
1327         }
1328
1329         el = ldb_msg_find_element(res[0], "privilege");
1330         if (el == NULL || el->num_values == 0) {
1331                 return NT_STATUS_OK;
1332         }
1333
1334         r->out.privs->set = talloc_array(r->out.privs, 
1335                                          struct lsa_LUIDAttribute, el->num_values);
1336         if (r->out.privs->set == NULL) {
1337                 return NT_STATUS_NO_MEMORY;
1338         }
1339
1340         for (i=0;i<el->num_values;i++) {
1341                 int id = sec_privilege_id((const char *)el->values[i].data);
1342                 if (id == -1) {
1343                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1344                 }
1345                 r->out.privs->set[i].attribute = 0;
1346                 r->out.privs->set[i].luid.low = id;
1347                 r->out.privs->set[i].luid.high = 0;
1348         }
1349
1350         r->out.privs->count = el->num_values;
1351
1352         return NT_STATUS_OK;
1353 }
1354
1355 /* 
1356   lsa_EnumAccountRights 
1357 */
1358 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
1359                                       TALLOC_CTX *mem_ctx,
1360                                       struct lsa_EnumAccountRights *r)
1361 {
1362         struct dcesrv_handle *h;
1363         struct lsa_policy_state *state;
1364         int ret, i;
1365         struct ldb_message **res;
1366         const char * const attrs[] = { "privilege", NULL};
1367         const char *sidstr;
1368         struct ldb_message_element *el;
1369
1370         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1371
1372         state = h->data;
1373
1374         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1375         if (sidstr == NULL) {
1376                 return NT_STATUS_NO_MEMORY;
1377         }
1378
1379         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
1380                            "(&(objectSid=%s)(privilege=*))", sidstr);
1381         if (ret == 0) {
1382                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1383         }
1384         if (ret > 1) {
1385                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1386         }
1387         if (ret == -1) {
1388                 DEBUG(3, ("searching for account rights for SID: %s failed: %s", 
1389                           dom_sid_string(mem_ctx, r->in.sid),
1390                           ldb_errstring(state->sam_ldb)));
1391                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1392         }
1393
1394         el = ldb_msg_find_element(res[0], "privilege");
1395         if (el == NULL || el->num_values == 0) {
1396                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1397         }
1398
1399         r->out.rights->count = el->num_values;
1400         r->out.rights->names = talloc_array(r->out.rights, 
1401                                             struct lsa_StringLarge, r->out.rights->count);
1402         if (r->out.rights->names == NULL) {
1403                 return NT_STATUS_NO_MEMORY;
1404         }
1405
1406         for (i=0;i<el->num_values;i++) {
1407                 r->out.rights->names[i].string = (const char *)el->values[i].data;
1408         }
1409
1410         return NT_STATUS_OK;
1411 }
1412
1413
1414
1415 /* 
1416   helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1417 */
1418 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
1419                                            TALLOC_CTX *mem_ctx,
1420                                            struct lsa_policy_state *state,
1421                                            int ldb_flag,
1422                                            struct dom_sid *sid,
1423                                            const struct lsa_RightSet *rights)
1424 {
1425         const char *sidstr;
1426         struct ldb_message *msg;
1427         struct ldb_message_element *el;
1428         int i, ret;
1429         struct lsa_EnumAccountRights r2;
1430
1431         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1432         if (sidstr == NULL) {
1433                 return NT_STATUS_NO_MEMORY;
1434         }
1435
1436         msg = ldb_msg_new(mem_ctx);
1437         if (msg == NULL) {
1438                 return NT_STATUS_NO_MEMORY;
1439         }
1440
1441         msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx, 
1442                                   NULL, "objectSid=%s", sidstr);
1443         if (msg->dn == NULL) {
1444                 NTSTATUS status;
1445                 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1446                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1447                 }
1448                 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx, 
1449                                                                  sid, &msg->dn);
1450                 if (!NT_STATUS_IS_OK(status)) {
1451                         return status;
1452                 }
1453                 return NT_STATUS_NO_SUCH_USER;
1454         }
1455
1456         if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1457                 return NT_STATUS_NO_MEMORY;
1458         }
1459
1460         if (ldb_flag == LDB_FLAG_MOD_ADD) {
1461                 NTSTATUS status;
1462
1463                 r2.in.handle = &state->handle->wire_handle;
1464                 r2.in.sid = sid;
1465                 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1466
1467                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1468                 if (!NT_STATUS_IS_OK(status)) {
1469                         ZERO_STRUCTP(r2.out.rights);
1470                 }
1471         }
1472
1473         for (i=0;i<rights->count;i++) {
1474                 if (sec_privilege_id(rights->names[i].string) == -1) {
1475                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1476                 }
1477
1478                 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1479                         int j;
1480                         for (j=0;j<r2.out.rights->count;j++) {
1481                                 if (strcasecmp_m(r2.out.rights->names[j].string, 
1482                                                rights->names[i].string) == 0) {
1483                                         break;
1484                                 }
1485                         }
1486                         if (j != r2.out.rights->count) continue;
1487                 }
1488
1489                 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1490                 if (ret != LDB_SUCCESS) {
1491                         return NT_STATUS_NO_MEMORY;
1492                 }
1493         }
1494
1495         el = ldb_msg_find_element(msg, "privilege");
1496         if (!el) {
1497                 return NT_STATUS_OK;
1498         }
1499
1500         ret = ldb_modify(state->sam_ldb, msg);
1501         if (ret != 0) {
1502                 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1503                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1504                 }
1505                 DEBUG(3, ("Could not %s attributes from %s: %s", 
1506                           ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1507                           ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
1508                 return NT_STATUS_UNEXPECTED_IO_ERROR;
1509         }
1510
1511         return NT_STATUS_OK;
1512 }
1513
1514 /* 
1515   lsa_AddPrivilegesToAccount
1516 */
1517 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1518                                            struct lsa_AddPrivilegesToAccount *r)
1519 {
1520         struct lsa_RightSet rights;
1521         struct dcesrv_handle *h;
1522         struct lsa_account_state *astate;
1523         int i;
1524
1525         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1526
1527         astate = h->data;
1528
1529         rights.count = r->in.privs->count;
1530         rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1531         if (rights.names == NULL) {
1532                 return NT_STATUS_NO_MEMORY;
1533         }
1534         for (i=0;i<rights.count;i++) {
1535                 int id = r->in.privs->set[i].luid.low;
1536                 if (r->in.privs->set[i].luid.high) {
1537                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1538                 }
1539                 rights.names[i].string = sec_privilege_name(id);
1540                 if (rights.names[i].string == NULL) {
1541                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1542                 }
1543         }
1544
1545         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1546                                           LDB_FLAG_MOD_ADD, astate->account_sid,
1547                                           &rights);
1548 }
1549
1550
1551 /* 
1552   lsa_RemovePrivilegesFromAccount
1553 */
1554 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1555                                                 struct lsa_RemovePrivilegesFromAccount *r)
1556 {
1557         struct lsa_RightSet *rights;
1558         struct dcesrv_handle *h;
1559         struct lsa_account_state *astate;
1560         int i;
1561
1562         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1563
1564         astate = h->data;
1565
1566         rights = talloc(mem_ctx, struct lsa_RightSet);
1567
1568         if (r->in.remove_all == 1 && 
1569             r->in.privs == NULL) {
1570                 struct lsa_EnumAccountRights r2;
1571                 NTSTATUS status;
1572
1573                 r2.in.handle = &astate->policy->handle->wire_handle;
1574                 r2.in.sid = astate->account_sid;
1575                 r2.out.rights = rights;
1576
1577                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1578                 if (!NT_STATUS_IS_OK(status)) {
1579                         return status;
1580                 }
1581
1582                 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1583                                                   LDB_FLAG_MOD_DELETE, astate->account_sid,
1584                                                   r2.out.rights);
1585         }
1586
1587         if (r->in.remove_all != 0) {
1588                 return NT_STATUS_INVALID_PARAMETER;
1589         }
1590
1591         rights->count = r->in.privs->count;
1592         rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1593         if (rights->names == NULL) {
1594                 return NT_STATUS_NO_MEMORY;
1595         }
1596         for (i=0;i<rights->count;i++) {
1597                 int id = r->in.privs->set[i].luid.low;
1598                 if (r->in.privs->set[i].luid.high) {
1599                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1600                 }
1601                 rights->names[i].string = sec_privilege_name(id);
1602                 if (rights->names[i].string == NULL) {
1603                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1604                 }
1605         }
1606
1607         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1608                                           LDB_FLAG_MOD_DELETE, astate->account_sid,
1609                                           rights);
1610 }
1611
1612
1613 /* 
1614   lsa_GetQuotasForAccount
1615 */
1616 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1617                        struct lsa_GetQuotasForAccount *r)
1618 {
1619         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1620 }
1621
1622
1623 /* 
1624   lsa_SetQuotasForAccount
1625 */
1626 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1627                        struct lsa_SetQuotasForAccount *r)
1628 {
1629         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1630 }
1631
1632
1633 /* 
1634   lsa_GetSystemAccessAccount
1635 */
1636 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1637                        struct lsa_GetSystemAccessAccount *r)
1638 {
1639         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1640 }
1641
1642
1643 /* 
1644   lsa_SetSystemAccessAccount
1645 */
1646 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1647                        struct lsa_SetSystemAccessAccount *r)
1648 {
1649         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1650 }
1651
1652
1653 /* 
1654   lsa_CreateSecret 
1655 */
1656 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1657                                  struct lsa_CreateSecret *r)
1658 {
1659         struct dcesrv_handle *policy_handle;
1660         struct lsa_policy_state *policy_state;
1661         struct lsa_secret_state *secret_state;
1662         struct dcesrv_handle *handle;
1663         struct ldb_message **msgs, *msg;
1664         const char *errstr;
1665         const char *attrs[] = {
1666                 NULL
1667         };
1668
1669         const char *name;
1670
1671         int ret;
1672
1673         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1674         ZERO_STRUCTP(r->out.sec_handle);
1675         
1676         policy_state = policy_handle->data;
1677
1678         if (!r->in.name.string) {
1679                 return NT_STATUS_INVALID_PARAMETER;
1680         }
1681         
1682         secret_state = talloc(mem_ctx, struct lsa_secret_state);
1683         if (!secret_state) {
1684                 return NT_STATUS_NO_MEMORY;
1685         }
1686         secret_state->policy = policy_state;
1687
1688         msg = ldb_msg_new(mem_ctx);
1689         if (msg == NULL) {
1690                 return NT_STATUS_NO_MEMORY;
1691         }
1692
1693         if (strncmp("G$", r->in.name.string, 2) == 0) {
1694                 const char *name2;
1695                 name = &r->in.name.string[2];
1696                 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1697                 secret_state->global = true;
1698
1699                 if (strlen(name) < 1) {
1700                         return NT_STATUS_INVALID_PARAMETER;
1701                 }
1702
1703                 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1704                 /* search for the secret record */
1705                 ret = gendb_search(secret_state->sam_ldb,
1706                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
1707                                    "(&(cn=%s)(objectclass=secret))", 
1708                                    name2);
1709                 if (ret > 0) {
1710                         return NT_STATUS_OBJECT_NAME_COLLISION;
1711                 }
1712                 
1713                 if (ret == -1) {
1714                         DEBUG(0,("Failure searching for CN=%s: %s\n", 
1715                                  name2, ldb_errstring(secret_state->sam_ldb)));
1716                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1717                 }
1718
1719                 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1720                 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
1721                         return NT_STATUS_NO_MEMORY;
1722                 }
1723                 
1724                 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1725         
1726         } else {
1727                 secret_state->global = false;
1728
1729                 name = r->in.name.string;
1730                 if (strlen(name) < 1) {
1731                         return NT_STATUS_INVALID_PARAMETER;
1732                 }
1733
1734                 secret_state->sam_ldb = talloc_reference(secret_state, 
1735                                                          secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
1736                 /* search for the secret record */
1737                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1738                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1739                                    &msgs, attrs,
1740                                    "(&(cn=%s)(objectclass=secret))", 
1741                                    ldb_binary_encode_string(mem_ctx, name));
1742                 if (ret > 0) {
1743                         return NT_STATUS_OBJECT_NAME_COLLISION;
1744                 }
1745                 
1746                 if (ret == -1) {
1747                         DEBUG(0,("Failure searching for CN=%s: %s\n", 
1748                                  name, ldb_errstring(secret_state->sam_ldb)));
1749                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1750                 }
1751
1752                 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
1753                 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1754         } 
1755
1756         /* pull in all the template attributes.  Note this is always from the global samdb */
1757         ret = samdb_copy_template(secret_state->policy->sam_ldb, msg, 
1758                                   "secret", &errstr);
1759         if (ret != 0) {
1760                 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1761                          errstr));
1762                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1763         }
1764
1765         samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1766         
1767         secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1768
1769         /* create the secret */
1770         ret = ldb_add(secret_state->sam_ldb, msg);
1771         if (ret != 0) {
1772                 DEBUG(0,("Failed to create secret record %s: %s\n",
1773                          ldb_dn_get_linearized(msg->dn), 
1774                          ldb_errstring(secret_state->sam_ldb)));
1775                 return NT_STATUS_ACCESS_DENIED;
1776         }
1777
1778         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1779         if (!handle) {
1780                 return NT_STATUS_NO_MEMORY;
1781         }
1782         
1783         handle->data = talloc_steal(handle, secret_state);
1784         
1785         secret_state->access_mask = r->in.access_mask;
1786         secret_state->policy = talloc_reference(secret_state, policy_state);
1787         
1788         *r->out.sec_handle = handle->wire_handle;
1789         
1790         return NT_STATUS_OK;
1791 }
1792
1793
1794 /* 
1795   lsa_OpenSecret 
1796 */
1797 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1798                                struct lsa_OpenSecret *r)
1799 {
1800         struct dcesrv_handle *policy_handle;
1801         
1802         struct lsa_policy_state *policy_state;
1803         struct lsa_secret_state *secret_state;
1804         struct dcesrv_handle *handle;
1805         struct ldb_message **msgs;
1806         const char *attrs[] = {
1807                 NULL
1808         };
1809
1810         const char *name;
1811
1812         int ret;
1813
1814         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1815         ZERO_STRUCTP(r->out.sec_handle);
1816         policy_state = policy_handle->data;
1817
1818         if (!r->in.name.string) {
1819                 return NT_STATUS_INVALID_PARAMETER;
1820         }
1821         
1822         secret_state = talloc(mem_ctx, struct lsa_secret_state);
1823         if (!secret_state) {
1824                 return NT_STATUS_NO_MEMORY;
1825         }
1826         secret_state->policy = policy_state;
1827
1828         if (strncmp("G$", r->in.name.string, 2) == 0) {
1829                 name = &r->in.name.string[2];
1830                 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1831                 secret_state->global = true;
1832
1833                 if (strlen(name) < 1) {
1834                         return NT_STATUS_INVALID_PARAMETER;
1835                 }
1836
1837                 /* search for the secret record */
1838                 ret = gendb_search(secret_state->sam_ldb,
1839                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
1840                                    "(&(cn=%s Secret)(objectclass=secret))", 
1841                                    ldb_binary_encode_string(mem_ctx, name));
1842                 if (ret == 0) {
1843                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1844                 }
1845                 
1846                 if (ret != 1) {
1847                         DEBUG(0,("Found %d records matching DN %s\n", ret,
1848                                  ldb_dn_get_linearized(policy_state->system_dn)));
1849                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1850                 }
1851         
1852         } else {
1853                 secret_state->sam_ldb = talloc_reference(secret_state, 
1854                                  secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
1855
1856                 secret_state->global = false;
1857                 name = r->in.name.string;
1858                 if (strlen(name) < 1) {
1859                         return NT_STATUS_INVALID_PARAMETER;
1860                 }
1861
1862                 /* search for the secret record */
1863                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1864                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1865                                    &msgs, attrs,
1866                                    "(&(cn=%s)(objectclass=secret))", 
1867                                    ldb_binary_encode_string(mem_ctx, name));
1868                 if (ret == 0) {
1869                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1870                 }
1871                 
1872                 if (ret != 1) {
1873                         DEBUG(0,("Found %d records matching CN=%s\n", 
1874                                  ret, ldb_binary_encode_string(mem_ctx, name)));
1875                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1876                 }
1877         } 
1878
1879         secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1880         
1881         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1882         if (!handle) {
1883                 return NT_STATUS_NO_MEMORY;
1884         }
1885         
1886         handle->data = talloc_steal(handle, secret_state);
1887         
1888         secret_state->access_mask = r->in.access_mask;
1889         secret_state->policy = talloc_reference(secret_state, policy_state);
1890         
1891         *r->out.sec_handle = handle->wire_handle;
1892         
1893         return NT_STATUS_OK;
1894 }
1895
1896
1897 /* 
1898   lsa_SetSecret 
1899 */
1900 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1901                               struct lsa_SetSecret *r)
1902 {
1903
1904         struct dcesrv_handle *h;
1905         struct lsa_secret_state *secret_state;
1906         struct ldb_message *msg;
1907         DATA_BLOB session_key;
1908         DATA_BLOB crypt_secret, secret;
1909         struct ldb_val val;
1910         int ret;
1911         NTSTATUS status = NT_STATUS_OK;
1912
1913         struct timeval now = timeval_current();
1914         NTTIME nt_now = timeval_to_nttime(&now);
1915
1916         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1917
1918         secret_state = h->data;
1919
1920         msg = ldb_msg_new(mem_ctx);
1921         if (msg == NULL) {
1922                 return NT_STATUS_NO_MEMORY;
1923         }
1924
1925         msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1926         if (!msg->dn) {
1927                 return NT_STATUS_NO_MEMORY;
1928         }
1929         status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1930         if (!NT_STATUS_IS_OK(status)) {
1931                 return status;
1932         }
1933
1934         if (r->in.old_val) {
1935                 /* Decrypt */
1936                 crypt_secret.data = r->in.old_val->data;
1937                 crypt_secret.length = r->in.old_val->size;
1938                 
1939                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1940                 if (!NT_STATUS_IS_OK(status)) {
1941                         return status;
1942                 }
1943                 
1944                 val.data = secret.data;
1945                 val.length = secret.length;
1946                 
1947                 /* set value */
1948                 if (samdb_msg_add_value(secret_state->sam_ldb, 
1949                                         mem_ctx, msg, "priorValue", &val) != 0) {
1950                         return NT_STATUS_NO_MEMORY; 
1951                 }
1952                 
1953                 /* set old value mtime */
1954                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
1955                                          mem_ctx, msg, "priorSetTime", nt_now) != 0) { 
1956                         return NT_STATUS_NO_MEMORY; 
1957                 }
1958
1959                 if (!r->in.new_val) {
1960                         /* This behaviour varies depending of if this is a local, or a global secret... */
1961                         if (secret_state->global) {
1962                                 /* set old value mtime */
1963                                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
1964                                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
1965                                         return NT_STATUS_NO_MEMORY; 
1966                                 }
1967                         } else {
1968                                 if (samdb_msg_add_delete(secret_state->sam_ldb, 
1969                                                          mem_ctx, msg, "currentValue")) {
1970                                         return NT_STATUS_NO_MEMORY;
1971                                 }
1972                                 if (samdb_msg_add_delete(secret_state->sam_ldb, 
1973                                                          mem_ctx, msg, "lastSetTime")) {
1974                                         return NT_STATUS_NO_MEMORY;
1975                                 }
1976                         }
1977                 }
1978         }
1979
1980         if (r->in.new_val) {
1981                 /* Decrypt */
1982                 crypt_secret.data = r->in.new_val->data;
1983                 crypt_secret.length = r->in.new_val->size;
1984                 
1985                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1986                 if (!NT_STATUS_IS_OK(status)) {
1987                         return status;
1988                 }
1989                 
1990                 val.data = secret.data;
1991                 val.length = secret.length;
1992                 
1993                 /* set value */
1994                 if (samdb_msg_add_value(secret_state->sam_ldb, 
1995                                         mem_ctx, msg, "currentValue", &val) != 0) {
1996                         return NT_STATUS_NO_MEMORY; 
1997                 }
1998                 
1999                 /* set new value mtime */
2000                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2001                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
2002                         return NT_STATUS_NO_MEMORY; 
2003                 }
2004                 
2005                 /* If the old value is not set, then migrate the
2006                  * current value to the old value */
2007                 if (!r->in.old_val) {
2008                         const struct ldb_val *new_val;
2009                         NTTIME last_set_time;
2010                         struct ldb_message **res;
2011                         const char *attrs[] = {
2012                                 "currentValue",
2013                                 "lastSetTime",
2014                                 NULL
2015                         };
2016                         
2017                         /* search for the secret record */
2018                         ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2019                                               secret_state->secret_dn, &res, attrs);
2020                         if (ret == 0) {
2021                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2022                         }
2023                         
2024                         if (ret != 1) {
2025                                 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2026                                          ldb_dn_get_linearized(secret_state->secret_dn)));
2027                                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2028                         }
2029
2030                         new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2031                         last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2032                         
2033                         if (new_val) {
2034                                 /* set value */
2035                                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2036                                                         mem_ctx, msg, "priorValue", 
2037                                                         new_val) != 0) {
2038                                         return NT_STATUS_NO_MEMORY; 
2039                                 }
2040                         }
2041                         
2042                         /* set new value mtime */
2043                         if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2044                                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2045                                                          mem_ctx, msg, "priorSetTime", last_set_time) != 0) { 
2046                                         return NT_STATUS_NO_MEMORY; 
2047                                 }
2048                         }
2049                 }
2050         }
2051
2052         /* modify the samdb record */
2053         ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2054         if (ret != 0) {
2055                 /* we really need samdb.c to return NTSTATUS */
2056                 return NT_STATUS_UNSUCCESSFUL;
2057         }
2058
2059         return NT_STATUS_OK;
2060 }
2061
2062
2063 /* 
2064   lsa_QuerySecret 
2065 */
2066 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2067                                 struct lsa_QuerySecret *r)
2068 {
2069         struct dcesrv_handle *h;
2070         struct lsa_secret_state *secret_state;
2071         struct ldb_message *msg;
2072         DATA_BLOB session_key;
2073         DATA_BLOB crypt_secret, secret;
2074         int ret;
2075         struct ldb_message **res;
2076         const char *attrs[] = {
2077                 "currentValue",
2078                 "priorValue",
2079                 "lastSetTime",
2080                 "priorSetTime", 
2081                 NULL
2082         };
2083
2084         NTSTATUS nt_status;
2085
2086         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2087
2088         secret_state = h->data;
2089
2090         /* pull all the user attributes */
2091         ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2092                               secret_state->secret_dn, &res, attrs);
2093         if (ret != 1) {
2094                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2095         }
2096         msg = res[0];
2097         
2098         nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2099         if (!NT_STATUS_IS_OK(nt_status)) {
2100                 return nt_status;
2101         }
2102         
2103         if (r->in.old_val) {
2104                 const struct ldb_val *prior_val;
2105                 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2106                 if (!r->out.old_val) {
2107                         return NT_STATUS_NO_MEMORY;
2108                 }
2109                 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2110                 
2111                 if (prior_val && prior_val->length) {
2112                         secret.data = prior_val->data;
2113                         secret.length = prior_val->length;
2114                 
2115                         /* Encrypt */
2116                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2117                         if (!crypt_secret.length) {
2118                                 return NT_STATUS_NO_MEMORY;
2119                         }
2120                         r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2121                         if (!r->out.old_val->buf) {
2122                                 return NT_STATUS_NO_MEMORY;
2123                         }
2124                         r->out.old_val->buf->size = crypt_secret.length;
2125                         r->out.old_val->buf->length = crypt_secret.length;
2126                         r->out.old_val->buf->data = crypt_secret.data;
2127                 }
2128         }
2129         
2130         if (r->in.old_mtime) {
2131                 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2132                 if (!r->out.old_mtime) {
2133                         return NT_STATUS_NO_MEMORY;
2134                 }
2135                 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2136         }
2137         
2138         if (r->in.new_val) {
2139                 const struct ldb_val *new_val;
2140                 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2141                 if (!r->out.new_val) {
2142                         return NT_STATUS_NO_MEMORY;
2143                 }
2144
2145                 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2146                 
2147                 if (new_val && new_val->length) {
2148                         secret.data = new_val->data;
2149                         secret.length = new_val->length;
2150                 
2151                         /* Encrypt */
2152                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2153                         if (!crypt_secret.length) {
2154                                 return NT_STATUS_NO_MEMORY;
2155                         }
2156                         r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2157                         if (!r->out.new_val->buf) {
2158                                 return NT_STATUS_NO_MEMORY;
2159                         }
2160                         r->out.new_val->buf->length = crypt_secret.length;
2161                         r->out.new_val->buf->size = crypt_secret.length;
2162                         r->out.new_val->buf->data = crypt_secret.data;
2163                 }
2164         }
2165         
2166         if (r->in.new_mtime) {
2167                 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2168                 if (!r->out.new_mtime) {
2169                         return NT_STATUS_NO_MEMORY;
2170                 }
2171                 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2172         }
2173         
2174         return NT_STATUS_OK;
2175 }
2176
2177
2178 /* 
2179   lsa_LookupPrivValue
2180 */
2181 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
2182                                     TALLOC_CTX *mem_ctx,
2183                                     struct lsa_LookupPrivValue *r)
2184 {
2185         struct dcesrv_handle *h;
2186         struct lsa_policy_state *state;
2187         int id;
2188
2189         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2190
2191         state = h->data;
2192
2193         id = sec_privilege_id(r->in.name->string);
2194         if (id == -1) {
2195                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2196         }
2197
2198         r->out.luid->low = id;
2199         r->out.luid->high = 0;
2200
2201         return NT_STATUS_OK;    
2202 }
2203
2204
2205 /* 
2206   lsa_LookupPrivName 
2207 */
2208 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
2209                                    TALLOC_CTX *mem_ctx,
2210                                    struct lsa_LookupPrivName *r)
2211 {
2212         struct dcesrv_handle *h;
2213         struct lsa_policy_state *state;
2214         const char *privname;
2215
2216         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2217
2218         state = h->data;
2219
2220         if (r->in.luid->high != 0) {
2221                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2222         }
2223
2224         privname = sec_privilege_name(r->in.luid->low);
2225         if (privname == NULL) {
2226                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2227         }
2228
2229         r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2230         if (r->out.name == NULL) {
2231                 return NT_STATUS_NO_MEMORY;
2232         }
2233         r->out.name->string = privname;
2234
2235         return NT_STATUS_OK;    
2236 }
2237
2238
2239 /* 
2240   lsa_LookupPrivDisplayName
2241 */
2242 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
2243                                           TALLOC_CTX *mem_ctx,
2244                                           struct lsa_LookupPrivDisplayName *r)
2245 {
2246         struct dcesrv_handle *h;
2247         struct lsa_policy_state *state;
2248         int id;
2249
2250         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2251
2252         state = h->data;
2253
2254         id = sec_privilege_id(r->in.name->string);
2255         if (id == -1) {
2256                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2257         }
2258         
2259         r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2260         if (r->out.disp_name == NULL) {
2261                 return NT_STATUS_NO_MEMORY;
2262         }
2263
2264         r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2265         if (r->out.disp_name->string == NULL) {
2266                 return NT_STATUS_INTERNAL_ERROR;
2267         }
2268
2269         return NT_STATUS_OK;
2270 }
2271
2272
2273 /* 
2274   lsa_DeleteObject
2275 */
2276 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2277                        struct lsa_DeleteObject *r)
2278 {
2279         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2280 }
2281
2282
2283 /* 
2284   lsa_EnumAccountsWithUserRight
2285 */
2286 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
2287                                               TALLOC_CTX *mem_ctx,
2288                                               struct lsa_EnumAccountsWithUserRight *r)
2289 {
2290         struct dcesrv_handle *h;
2291         struct lsa_policy_state *state;
2292         int ret, i;
2293         struct ldb_message **res;
2294         const char * const attrs[] = { "objectSid", NULL};
2295         const char *privname;
2296
2297         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2298
2299         state = h->data;
2300
2301         if (r->in.name == NULL) {
2302                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2303         } 
2304
2305         privname = r->in.name->string;
2306         if (sec_privilege_id(privname) == -1) {
2307                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2308         }
2309
2310         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
2311                            "privilege=%s", privname);
2312         if (ret == -1) {
2313                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2314         }
2315         if (ret == 0) {
2316                 return NT_STATUS_NO_MORE_ENTRIES;
2317         }
2318
2319         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2320         if (r->out.sids->sids == NULL) {
2321                 return NT_STATUS_NO_MEMORY;
2322         }
2323         for (i=0;i<ret;i++) {
2324                 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2325                                                                 res[i], "objectSid");
2326                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2327         }
2328         r->out.sids->num_sids = ret;
2329
2330         return NT_STATUS_OK;
2331 }
2332
2333
2334 /* 
2335   lsa_AddAccountRights
2336 */
2337 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
2338                                      TALLOC_CTX *mem_ctx,
2339                                      struct lsa_AddAccountRights *r)
2340 {
2341         struct dcesrv_handle *h;
2342         struct lsa_policy_state *state;
2343
2344         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2345
2346         state = h->data;
2347
2348         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2349                                           LDB_FLAG_MOD_ADD,
2350                                           r->in.sid, r->in.rights);
2351 }
2352
2353
2354 /* 
2355   lsa_RemoveAccountRights
2356 */
2357 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
2358                                         TALLOC_CTX *mem_ctx,
2359                                         struct lsa_RemoveAccountRights *r)
2360 {
2361         struct dcesrv_handle *h;
2362         struct lsa_policy_state *state;
2363
2364         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2365
2366         state = h->data;
2367
2368         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2369                                           LDB_FLAG_MOD_DELETE,
2370                                           r->in.sid, r->in.rights);
2371 }
2372
2373
2374 /* 
2375   lsa_StorePrivateData
2376 */
2377 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2378                        struct lsa_StorePrivateData *r)
2379 {
2380         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2381 }
2382
2383
2384 /* 
2385   lsa_RetrievePrivateData
2386 */
2387 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2388                        struct lsa_RetrievePrivateData *r)
2389 {
2390         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2391 }
2392
2393
2394 /* 
2395   lsa_GetUserName
2396 */
2397 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2398                                 struct lsa_GetUserName *r)
2399 {
2400         NTSTATUS status = NT_STATUS_OK;
2401         const char *account_name;
2402         const char *authority_name;
2403         struct lsa_String *_account_name;
2404         struct lsa_StringPointer *_authority_name = NULL;
2405
2406         /* this is what w2k3 does */
2407         r->out.account_name = r->in.account_name;
2408         r->out.authority_name = r->in.authority_name;
2409
2410         if (r->in.account_name && r->in.account_name->string) {
2411                 return NT_STATUS_INVALID_PARAMETER;
2412         }
2413
2414         if (r->in.authority_name &&
2415             r->in.authority_name->string &&
2416             r->in.authority_name->string->string) {
2417                 return NT_STATUS_INVALID_PARAMETER;
2418         }
2419
2420         account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2421         authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2422
2423         _account_name = talloc(mem_ctx, struct lsa_String);
2424         NT_STATUS_HAVE_NO_MEMORY(_account_name);
2425         _account_name->string = account_name;
2426
2427         if (r->in.authority_name) {
2428                 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2429                 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2430                 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2431                 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2432                 _authority_name->string->string = authority_name;
2433         }
2434
2435         r->out.account_name = _account_name;
2436         r->out.authority_name = _authority_name;
2437
2438         return status;
2439 }
2440
2441 /*
2442   lsa_SetInfoPolicy2
2443 */
2444 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2445                                    TALLOC_CTX *mem_ctx,
2446                                    struct lsa_SetInfoPolicy2 *r)
2447 {
2448         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2449 }
2450
2451 /*
2452   lsa_QueryDomainInformationPolicy
2453 */
2454 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2455                                                  TALLOC_CTX *mem_ctx,
2456                                                  struct lsa_QueryDomainInformationPolicy *r)
2457 {
2458         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2459 }
2460
2461 /*
2462   lsa_SetDomInfoPolicy
2463 */
2464 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2465                                               TALLOC_CTX *mem_ctx,
2466                                               struct lsa_SetDomainInformationPolicy *r)
2467 {
2468         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2469 }
2470
2471 /*
2472   lsa_TestCall
2473 */
2474 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2475                              TALLOC_CTX *mem_ctx,
2476                              struct lsa_TestCall *r)
2477 {
2478         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2479 }
2480
2481 /* 
2482   lsa_CREDRWRITE 
2483 */
2484 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2485                        struct lsa_CREDRWRITE *r)
2486 {
2487         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2488 }
2489
2490
2491 /* 
2492   lsa_CREDRREAD 
2493 */
2494 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2495                        struct lsa_CREDRREAD *r)
2496 {
2497         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2498 }
2499
2500
2501 /* 
2502   lsa_CREDRENUMERATE 
2503 */
2504 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2505                        struct lsa_CREDRENUMERATE *r)
2506 {
2507         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2508 }
2509
2510
2511 /* 
2512   lsa_CREDRWRITEDOMAINCREDENTIALS 
2513 */
2514 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2515                        struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2516 {
2517         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2518 }
2519
2520
2521 /* 
2522   lsa_CREDRREADDOMAINCREDENTIALS 
2523 */
2524 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2525                        struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2526 {
2527         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2528 }
2529
2530
2531 /* 
2532   lsa_CREDRDELETE 
2533 */
2534 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2535                        struct lsa_CREDRDELETE *r)
2536 {
2537         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2538 }
2539
2540
2541 /* 
2542   lsa_CREDRGETTARGETINFO 
2543 */
2544 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2545                        struct lsa_CREDRGETTARGETINFO *r)
2546 {
2547         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2548 }
2549
2550
2551 /* 
2552   lsa_CREDRPROFILELOADED 
2553 */
2554 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2555                        struct lsa_CREDRPROFILELOADED *r)
2556 {
2557         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2558 }
2559
2560
2561 /* 
2562   lsa_CREDRGETSESSIONTYPES 
2563 */
2564 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2565                        struct lsa_CREDRGETSESSIONTYPES *r)
2566 {
2567         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2568 }
2569
2570
2571 /* 
2572   lsa_LSARREGISTERAUDITEVENT 
2573 */
2574 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2575                        struct lsa_LSARREGISTERAUDITEVENT *r)
2576 {
2577         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2578 }
2579
2580
2581 /* 
2582   lsa_LSARGENAUDITEVENT 
2583 */
2584 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2585                        struct lsa_LSARGENAUDITEVENT *r)
2586 {
2587         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2588 }
2589
2590
2591 /* 
2592   lsa_LSARUNREGISTERAUDITEVENT 
2593 */
2594 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2595                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
2596 {
2597         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2598 }
2599
2600
2601 /* 
2602   lsa_lsaRQueryForestTrustInformation 
2603 */
2604 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2605                        struct lsa_lsaRQueryForestTrustInformation *r)
2606 {
2607         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2608 }
2609
2610
2611 /* 
2612   lsa_LSARSETFORESTTRUSTINFORMATION 
2613 */
2614 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2615                        struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2616 {
2617         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2618 }
2619
2620
2621 /* 
2622   lsa_CREDRRENAME 
2623 */
2624 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2625                        struct lsa_CREDRRENAME *r)
2626 {
2627         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2628 }
2629
2630
2631
2632 /* 
2633   lsa_LSAROPENPOLICYSCE 
2634 */
2635 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2636                        struct lsa_LSAROPENPOLICYSCE *r)
2637 {
2638         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2639 }
2640
2641
2642 /* 
2643   lsa_LSARADTREGISTERSECURITYEVENTSOURCE 
2644 */
2645 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2646                        struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2647 {
2648         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2649 }
2650
2651
2652 /* 
2653   lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE 
2654 */
2655 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2656                        struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2657 {
2658         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2659 }
2660
2661
2662 /* 
2663   lsa_LSARADTREPORTSECURITYEVENT 
2664 */
2665 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2666                        struct lsa_LSARADTREPORTSECURITYEVENT *r)
2667 {
2668         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2669 }
2670
2671
2672 /* include the generated boilerplate */
2673 #include "librpc/gen_ndr/ndr_lsa_s.c"
2674
2675
2676
2677 /*****************************************
2678 NOTE! The remaining calls below were
2679 removed in w2k3, so the DCESRV_FAULT()
2680 replies are the correct implementation. Do
2681 not try and fill these in with anything else
2682 ******************************************/
2683
2684 /* 
2685   dssetup_DsRoleDnsNameToFlatName 
2686 */
2687 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2688                                         struct dssetup_DsRoleDnsNameToFlatName *r)
2689 {
2690         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2691 }
2692
2693
2694 /* 
2695   dssetup_DsRoleDcAsDc 
2696 */
2697 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2698                              struct dssetup_DsRoleDcAsDc *r)
2699 {
2700         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2701 }
2702
2703
2704 /* 
2705   dssetup_DsRoleDcAsReplica 
2706 */
2707 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2708                                   struct dssetup_DsRoleDcAsReplica *r)
2709 {
2710         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2711 }
2712
2713
2714 /* 
2715   dssetup_DsRoleDemoteDc 
2716 */
2717 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2718                                struct dssetup_DsRoleDemoteDc *r)
2719 {
2720         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2721 }
2722
2723
2724 /* 
2725   dssetup_DsRoleGetDcOperationProgress 
2726 */
2727 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2728                                              struct dssetup_DsRoleGetDcOperationProgress *r)
2729 {
2730         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2731 }
2732
2733
2734 /* 
2735   dssetup_DsRoleGetDcOperationResults 
2736 */
2737 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2738                                             struct dssetup_DsRoleGetDcOperationResults *r)
2739 {
2740         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2741 }
2742
2743
2744 /* 
2745   dssetup_DsRoleCancel 
2746 */
2747 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2748                              struct dssetup_DsRoleCancel *r)
2749 {
2750         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2751 }
2752
2753
2754 /* 
2755   dssetup_DsRoleServerSaveStateForUpgrade 
2756 */
2757 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2758                                                 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
2759 {
2760         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2761 }
2762
2763
2764 /* 
2765   dssetup_DsRoleUpgradeDownlevelServer 
2766 */
2767 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2768                                              struct dssetup_DsRoleUpgradeDownlevelServer *r)
2769 {
2770         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2771 }
2772
2773
2774 /* 
2775   dssetup_DsRoleAbortDownlevelServerUpgrade 
2776 */
2777 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2778                                                   struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
2779 {
2780         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2781 }
2782
2783
2784 /* include the generated boilerplate */
2785 #include "librpc/gen_ndr/ndr_dssetup_s.c"
2786
2787 NTSTATUS dcerpc_server_lsa_init(void)
2788 {
2789         NTSTATUS ret;
2790         
2791         ret = dcerpc_server_dssetup_init();
2792         if (!NT_STATUS_IS_OK(ret)) {
2793                 return ret;
2794         }
2795         ret = dcerpc_server_lsarpc_init();
2796         if (!NT_STATUS_IS_OK(ret)) {
2797                 return ret;
2798         }
2799         return ret;
2800 }