r17956: LSA Cleanup!
[kai/samba-autobuild/.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-2005
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 2 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, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25 #include "rpc_server/dcerpc_server.h"
26 #include "rpc_server/common/common.h"
27 #include "auth/auth.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "libcli/ldap/ldap.h"
30 #include "lib/ldb/include/ldb_errors.h"
31 #include "libcli/security/security.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "passdb/secrets.h"
34 #include "db_wrap.h"
35
36 /*
37   this type allows us to distinguish handle types
38 */
39 enum lsa_handle {
40         LSA_HANDLE_POLICY,
41         LSA_HANDLE_ACCOUNT,
42         LSA_HANDLE_SECRET,
43         LSA_HANDLE_TRUSTED_DOMAIN
44 };
45
46 /*
47   state associated with a lsa_OpenPolicy() operation
48 */
49 struct lsa_policy_state {
50         struct dcesrv_handle *handle;
51         struct ldb_context *sam_ldb;
52         struct sidmap_context *sidmap;
53         uint32_t access_mask;
54         const struct ldb_dn *domain_dn;
55         const struct ldb_dn *builtin_dn;
56         const struct ldb_dn *system_dn;
57         const char *domain_name;
58         const char *domain_dns;
59         struct dom_sid *domain_sid;
60         struct GUID domain_guid;
61         struct dom_sid *builtin_sid;
62 };
63
64
65 /*
66   state associated with a lsa_OpenAccount() operation
67 */
68 struct lsa_account_state {
69         struct lsa_policy_state *policy;
70         uint32_t access_mask;
71         struct dom_sid *account_sid;
72 };
73
74
75 /*
76   state associated with a lsa_OpenSecret() operation
77 */
78 struct lsa_secret_state {
79         struct lsa_policy_state *policy;
80         uint32_t access_mask;
81         struct ldb_dn *secret_dn;
82         struct ldb_context *sam_ldb;
83         BOOL global;
84 };
85
86 /*
87   state associated with a lsa_OpenTrustedDomain() operation
88 */
89 struct lsa_trusted_domain_state {
90         struct lsa_policy_state *policy;
91         uint32_t access_mask;
92         const struct ldb_dn *trusted_domain_dn;
93 };
94
95 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
96                                       TALLOC_CTX *mem_ctx,
97                                       struct lsa_EnumAccountRights *r);
98
99 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
100                                            TALLOC_CTX *mem_ctx,
101                                            struct lsa_policy_state *state,
102                                            int ldb_flag,
103                                            struct dom_sid *sid,
104                                            const struct lsa_RightSet *rights);
105
106 /* 
107   lsa_Close 
108 */
109 static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
110                           struct lsa_Close *r)
111 {
112         struct dcesrv_handle *h;
113
114         *r->out.handle = *r->in.handle;
115
116         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
117
118         talloc_free(h);
119
120         ZERO_STRUCTP(r->out.handle);
121
122         return NT_STATUS_OK;
123 }
124
125
126 /* 
127   lsa_Delete 
128 */
129 static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
130                            struct lsa_Delete *r)
131 {
132         struct dcesrv_handle *h;
133         int ret;
134
135         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
136         if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
137                 struct lsa_secret_state *secret_state = h->data;
138                 ret = samdb_delete(secret_state->sam_ldb, mem_ctx, secret_state->secret_dn);
139                 talloc_free(h);
140                 if (ret != 0) {
141                         return NT_STATUS_INVALID_HANDLE;
142                 }
143
144                 return NT_STATUS_OK;
145         } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
146                 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
147                 ret = samdb_delete(trusted_domain_state->policy->sam_ldb, mem_ctx, 
148                                    trusted_domain_state->trusted_domain_dn);
149                 talloc_free(h);
150                 if (ret != 0) {
151                         return NT_STATUS_INVALID_HANDLE;
152                 }
153
154                 return NT_STATUS_OK;
155         } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
156                 struct lsa_RightSet *rights;
157                 struct lsa_account_state *astate;
158                 struct lsa_EnumAccountRights r2;
159                 NTSTATUS status;
160
161                 rights = talloc(mem_ctx, struct lsa_RightSet);
162
163                 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
164                 
165                 astate = h->data;
166
167                 r2.in.handle = &astate->policy->handle->wire_handle;
168                 r2.in.sid = astate->account_sid;
169                 r2.out.rights = rights;
170
171                 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
172                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
173                         return NT_STATUS_OK;
174                 }
175
176                 if (!NT_STATUS_IS_OK(status)) {
177                         return status;
178                 }
179
180                 status = lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
181                                                     LDB_FLAG_MOD_DELETE, astate->account_sid,
182                                                     r2.out.rights);
183                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
184                         return NT_STATUS_OK;
185                 }
186
187                 if (!NT_STATUS_IS_OK(status)) {
188                         return status;
189                 }
190         } 
191         
192         return NT_STATUS_INVALID_HANDLE;
193 }
194
195
196 /* 
197   lsa_EnumPrivs 
198 */
199 static NTSTATUS lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
200                               struct lsa_EnumPrivs *r)
201 {
202         struct dcesrv_handle *h;
203         struct lsa_policy_state *state;
204         int i;
205         const char *privname;
206
207         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
208
209         state = h->data;
210
211         i = *r->in.resume_handle;
212         if (i == 0) i = 1;
213
214         while ((privname = sec_privilege_name(i)) &&
215                r->out.privs->count < r->in.max_count) {
216                 struct lsa_PrivEntry *e;
217
218                 r->out.privs->privs = talloc_realloc(r->out.privs,
219                                                        r->out.privs->privs, 
220                                                        struct lsa_PrivEntry, 
221                                                        r->out.privs->count+1);
222                 if (r->out.privs->privs == NULL) {
223                         return NT_STATUS_NO_MEMORY;
224                 }
225                 e = &r->out.privs->privs[r->out.privs->count];
226                 e->luid.low = i;
227                 e->luid.high = 0;
228                 e->name.string = privname;
229                 r->out.privs->count++;
230                 i++;
231         }
232
233         *r->out.resume_handle = i;
234
235         return NT_STATUS_OK;
236 }
237
238
239 /* 
240   lsa_QuerySecObj 
241 */
242 static NTSTATUS lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
243                                   struct lsa_QuerySecurity *r)
244 {
245         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
246 }
247
248
249 /* 
250   lsa_SetSecObj 
251 */
252 static NTSTATUS lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
253                               struct lsa_SetSecObj *r)
254 {
255         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
256 }
257
258
259 /* 
260   lsa_ChangePassword 
261 */
262 static NTSTATUS lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
263                                    struct lsa_ChangePassword *r)
264 {
265         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
266 }
267
268 static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
269                                      struct lsa_policy_state **_state)
270 {
271         struct lsa_policy_state *state;
272         const struct ldb_dn *partitions_basedn;
273         struct ldb_result *dom_res;
274         const char *dom_attrs[] = {
275                 "objectSid", 
276                 "objectGUID", 
277                 NULL
278         };
279         struct ldb_result *ref_res;
280         const char *ref_attrs[] = {
281                 "nETBIOSName",
282                 "dnsRoot",
283                 NULL
284         };
285         char *ref_filter;
286         int ret;
287
288         state = talloc(mem_ctx, struct lsa_policy_state);
289         if (!state) {
290                 return NT_STATUS_NO_MEMORY;
291         }
292
293         /* make sure the sam database is accessible */
294         state->sam_ldb = samdb_connect(state, dce_call->conn->auth_state.session_info); 
295         if (state->sam_ldb == NULL) {
296                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
297         }
298
299         partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
300
301         state->sidmap = sidmap_open(state);
302         if (state->sidmap == NULL) {
303                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
304         }
305
306         /* work out the domain_dn - useful for so many calls its worth
307            fetching here */
308         state->domain_dn = samdb_base_dn(state->sam_ldb);
309         if (!state->domain_dn) {
310                 return NT_STATUS_NO_MEMORY;             
311         }
312
313         ret = ldb_search(state->sam_ldb, state->domain_dn, LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
314         
315         if (ret != LDB_SUCCESS) {
316                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
317         }
318         talloc_steal(state, dom_res);
319         if (dom_res->count != 1) {
320                 return NT_STATUS_NO_SUCH_DOMAIN;                
321         }
322
323         state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
324         if (!state->domain_sid) {
325                 return NT_STATUS_NO_SUCH_DOMAIN;                
326         }
327
328         state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
329         if (!state->domain_sid) {
330                 return NT_STATUS_NO_SUCH_DOMAIN;                
331         }
332
333         talloc_free(dom_res);
334
335         ref_filter = talloc_asprintf(state, "(&(objectclass=crossRef)(ncName=%s))", 
336                                      ldb_dn_linearize(mem_ctx, state->domain_dn)); 
337         if (!ref_filter) {
338                 return NT_STATUS_NO_MEMORY;
339         }
340
341         ret = ldb_search(state->sam_ldb, partitions_basedn, LDB_SCOPE_SUBTREE, ref_filter, ref_attrs, &ref_res);
342         talloc_steal(state, ref_res);
343         talloc_free(ref_filter);
344         
345         if (ret != LDB_SUCCESS) {
346                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
347         }
348         if (ref_res->count != 1) {
349                 return NT_STATUS_NO_SUCH_DOMAIN;                
350         }
351
352         state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
353         if (!state->domain_name) {
354                 return NT_STATUS_NO_SUCH_DOMAIN;                
355         }
356         talloc_steal(state, state->domain_name);
357
358         state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
359         if (!state->domain_dns) {
360                 return NT_STATUS_NO_SUCH_DOMAIN;                
361         }
362         talloc_steal(state, state->domain_dns);
363
364         talloc_free(ref_res);
365
366         /* work out the builtin_dn - useful for so many calls its worth
367            fetching here */
368         state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
369         if (!state->builtin_dn) {
370                 return NT_STATUS_NO_SUCH_DOMAIN;                
371         }
372
373         /* work out the system_dn - useful for so many calls its worth
374            fetching here */
375         state->system_dn = samdb_search_dn(state->sam_ldb, state,
376                                            state->domain_dn, "(&(objectClass=container)(cn=System))");
377         if (!state->system_dn) {
378                 return NT_STATUS_NO_SUCH_DOMAIN;                
379         }
380
381         state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
382         if (!state->builtin_sid) {
383                 return NT_STATUS_NO_SUCH_DOMAIN;                
384         }
385
386         *_state = state;
387
388         return NT_STATUS_OK;
389 }
390
391 /* 
392   lsa_OpenPolicy2
393 */
394 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
395                                struct lsa_OpenPolicy2 *r)
396 {
397         NTSTATUS status;
398         struct lsa_policy_state *state;
399         struct dcesrv_handle *handle;
400
401         ZERO_STRUCTP(r->out.handle);
402
403         status = lsa_get_policy_state(dce_call, mem_ctx, &state);
404         if (!NT_STATUS_IS_OK(status)) {
405                 return status;
406         }
407
408         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
409         if (!handle) {
410                 return NT_STATUS_NO_MEMORY;
411         }
412
413         handle->data = talloc_steal(handle, state);
414
415         state->access_mask = r->in.access_mask;
416         state->handle = handle;
417         *r->out.handle = handle->wire_handle;
418
419         /* note that we have completely ignored the attr element of
420            the OpenPolicy. As far as I can tell, this is what w2k3
421            does */
422
423         return NT_STATUS_OK;
424 }
425
426 /* 
427   lsa_OpenPolicy
428   a wrapper around lsa_OpenPolicy2
429 */
430 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
431                                 struct lsa_OpenPolicy *r)
432 {
433         struct lsa_OpenPolicy2 r2;
434
435         r2.in.system_name = NULL;
436         r2.in.attr = r->in.attr;
437         r2.in.access_mask = r->in.access_mask;
438         r2.out.handle = r->out.handle;
439
440         return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
441 }
442
443
444
445
446 /*
447   fill in the AccountDomain info
448 */
449 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
450                                        struct lsa_DomainInfo *info)
451 {
452         info->name.string = state->domain_name;
453         info->sid         = state->domain_sid;
454
455         return NT_STATUS_OK;
456 }
457
458 /*
459   fill in the DNS domain info
460 */
461 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
462                              struct lsa_DnsDomainInfo *info)
463 {
464         info->name.string = state->domain_name;
465         info->sid         = state->domain_sid;
466         info->dns_domain.string = state->domain_dns;
467         info->dns_forest.string = state->domain_dns;
468         info->domain_guid       = state->domain_guid;
469
470         return NT_STATUS_OK;
471 }
472
473 /* 
474   lsa_QueryInfoPolicy2
475 */
476 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
477                                      struct lsa_QueryInfoPolicy2 *r)
478 {
479         struct lsa_policy_state *state;
480         struct dcesrv_handle *h;
481
482         r->out.info = NULL;
483
484         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
485
486         state = h->data;
487
488         r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
489         if (!r->out.info) {
490                 return NT_STATUS_NO_MEMORY;
491         }
492
493         ZERO_STRUCTP(r->out.info);
494
495         switch (r->in.level) {
496         case LSA_POLICY_INFO_DOMAIN:
497         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
498                 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
499
500         case LSA_POLICY_INFO_DNS:
501                 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
502         }
503
504         return NT_STATUS_INVALID_INFO_CLASS;
505 }
506
507 /* 
508   lsa_QueryInfoPolicy 
509 */
510 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
511                                     struct lsa_QueryInfoPolicy *r)
512 {
513         struct lsa_QueryInfoPolicy2 r2;
514         NTSTATUS status;
515
516         r2.in.handle = r->in.handle;
517         r2.in.level = r->in.level;
518         
519         status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
520
521         r->out.info = r2.out.info;
522
523         return status;
524 }
525
526 /* 
527   lsa_SetInfoPolicy 
528 */
529 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
530                                   struct lsa_SetInfoPolicy *r)
531 {
532         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
533 }
534
535
536 /* 
537   lsa_ClearAuditLog 
538 */
539 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
540                                   struct lsa_ClearAuditLog *r)
541 {
542         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
543 }
544
545
546 /* 
547   lsa_CreateAccount 
548 */
549 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
550                                   struct lsa_CreateAccount *r)
551 {
552         struct lsa_account_state *astate;
553
554         struct lsa_policy_state *state;
555         struct dcesrv_handle *h, *ah;
556
557         ZERO_STRUCTP(r->out.acct_handle);
558
559         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
560
561         state = h->data;
562
563         astate = talloc(dce_call->conn, struct lsa_account_state);
564         if (astate == NULL) {
565                 return NT_STATUS_NO_MEMORY;
566         }
567
568         astate->account_sid = dom_sid_dup(astate, r->in.sid);
569         if (astate->account_sid == NULL) {
570                 talloc_free(astate);
571                 return NT_STATUS_NO_MEMORY;
572         }
573         
574         astate->policy = talloc_reference(astate, state);
575         astate->access_mask = r->in.access_mask;
576
577         ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
578         if (!ah) {
579                 talloc_free(astate);
580                 return NT_STATUS_NO_MEMORY;
581         }
582
583         ah->data = talloc_steal(ah, astate);
584
585         *r->out.acct_handle = ah->wire_handle;
586
587         return NT_STATUS_OK;
588 }
589
590
591 /* 
592   lsa_EnumAccounts 
593 */
594 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
595                                  struct lsa_EnumAccounts *r)
596 {
597         struct dcesrv_handle *h;
598         struct lsa_policy_state *state;
599         int ret, i;
600         struct ldb_message **res;
601         const char * const attrs[] = { "objectSid", NULL};
602         uint32_t count;
603
604         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
605
606         state = h->data;
607
608         /* NOTE: This call must only return accounts that have at least
609            one privilege set 
610         */
611         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
612                            "(&(objectSid=*)(privilege=*))");
613         if (ret < 0) {
614                 return NT_STATUS_NO_SUCH_USER;
615         }
616
617         if (*r->in.resume_handle >= ret) {
618                 return NT_STATUS_NO_MORE_ENTRIES;
619         }
620
621         count = ret - *r->in.resume_handle;
622         if (count > r->in.num_entries) {
623                 count = r->in.num_entries;
624         }
625
626         if (count == 0) {
627                 return NT_STATUS_NO_MORE_ENTRIES;
628         }
629
630         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
631         if (r->out.sids->sids == NULL) {
632                 return NT_STATUS_NO_MEMORY;
633         }
634
635         for (i=0;i<count;i++) {
636                 r->out.sids->sids[i].sid = 
637                         samdb_result_dom_sid(r->out.sids->sids, 
638                                              res[i + *r->in.resume_handle],
639                                              "objectSid");
640                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
641         }
642
643         r->out.sids->num_sids = count;
644         *r->out.resume_handle = count + *r->in.resume_handle;
645
646         return NT_STATUS_OK;
647         
648 }
649
650
651 /*
652   lsa_CreateTrustedDomainEx2
653 */
654 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
655                                            TALLOC_CTX *mem_ctx,
656                                            struct lsa_CreateTrustedDomainEx2 *r)
657 {
658         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
659 }
660
661 /*
662   lsa_CreateTrustedDomainEx
663 */
664 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
665                                           TALLOC_CTX *mem_ctx,
666                                           struct lsa_CreateTrustedDomainEx *r)
667 {
668         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
669 }
670
671 /* 
672   lsa_CreateTrustedDomain 
673 */
674 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
675                                         struct lsa_CreateTrustedDomain *r)
676 {
677         struct dcesrv_handle *policy_handle;
678         struct lsa_policy_state *policy_state;
679         struct lsa_trusted_domain_state *trusted_domain_state;
680         struct dcesrv_handle *handle;
681         struct ldb_message **msgs, *msg;
682         const char *attrs[] = {
683                 NULL
684         };
685         const char *name;
686         int ret;
687
688         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
689         ZERO_STRUCTP(r->out.trustdom_handle);
690         
691         policy_state = policy_handle->data;
692
693         if (!r->in.info->name.string) {
694                 return NT_STATUS_INVALID_PARAMETER;
695         }
696         name = r->in.info->name.string;
697         
698         trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
699         if (!trusted_domain_state) {
700                 return NT_STATUS_NO_MEMORY;
701         }
702         trusted_domain_state->policy = policy_state;
703
704         msg = ldb_msg_new(mem_ctx);
705         if (msg == NULL) {
706                 return NT_STATUS_NO_MEMORY;
707         }
708
709         /* search for the trusted_domain record */
710         ret = gendb_search(trusted_domain_state->policy->sam_ldb,
711                            mem_ctx, policy_state->system_dn, &msgs, attrs,
712                            "(&(cn=%s)(objectclass=trustedDomain))", 
713                            ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
714         if (ret > 0) {
715                 return NT_STATUS_OBJECT_NAME_COLLISION;
716         }
717         
718         if (ret < 0 || ret > 1) {
719                 DEBUG(0,("Found %d records matching DN %s\n", ret,
720                          ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
721                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
722         }
723         
724         msg->dn = ldb_dn_build_child(mem_ctx, "cn",
725                                      r->in.info->name.string, 
726                                      policy_state->system_dn);
727         if (!msg->dn) {
728                 return NT_STATUS_NO_MEMORY;
729         }
730         
731         samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "cn", name);
732         samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
733
734         if (r->in.info->sid) {
735                 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
736                 if (!sid_string) {
737                         return NT_STATUS_NO_MEMORY;
738                 }
739                         
740                 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
741         }
742
743         samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
744         
745         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
746
747         /* create the trusted_domain */
748         ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
749         if (ret != LDB_SUCCESS) {
750                 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
751                          ldb_dn_linearize(mem_ctx, msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
752                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
753         }
754
755         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
756         if (!handle) {
757                 return NT_STATUS_NO_MEMORY;
758         }
759         
760         handle->data = talloc_steal(handle, trusted_domain_state);
761         
762         trusted_domain_state->access_mask = r->in.access_mask;
763         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
764         
765         *r->out.trustdom_handle = handle->wire_handle;
766         
767         return NT_STATUS_OK;
768 }
769
770 /* 
771   lsa_OpenTrustedDomain
772 */
773 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
774                                       struct lsa_OpenTrustedDomain *r)
775 {
776         struct dcesrv_handle *policy_handle;
777         
778         struct lsa_policy_state *policy_state;
779         struct lsa_trusted_domain_state *trusted_domain_state;
780         struct dcesrv_handle *handle;
781         struct ldb_message **msgs;
782         const char *attrs[] = {
783                 NULL
784         };
785
786         const char *sid_string;
787         int ret;
788
789         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
790         ZERO_STRUCTP(r->out.trustdom_handle);
791         policy_state = policy_handle->data;
792
793         trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
794         if (!trusted_domain_state) {
795                 return NT_STATUS_NO_MEMORY;
796         }
797         trusted_domain_state->policy = policy_state;
798
799         sid_string = dom_sid_string(mem_ctx, r->in.sid);
800         if (!sid_string) {
801                 return NT_STATUS_NO_MEMORY;
802         }
803
804         /* search for the trusted_domain record */
805         ret = gendb_search(trusted_domain_state->policy->sam_ldb,
806                            mem_ctx, policy_state->system_dn, &msgs, attrs,
807                            "(&(securityIdentifier=%s)(objectclass=trustedDomain))", 
808                            sid_string);
809         if (ret == 0) {
810                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
811         }
812         
813         if (ret != 1) {
814                 DEBUG(0,("Found %d records matching DN %s\n", ret,
815                          ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
816                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
817         }
818
819         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
820         
821         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
822         if (!handle) {
823                 return NT_STATUS_NO_MEMORY;
824         }
825         
826         handle->data = talloc_steal(handle, trusted_domain_state);
827         
828         trusted_domain_state->access_mask = r->in.access_mask;
829         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
830         
831         *r->out.trustdom_handle = handle->wire_handle;
832         
833         return NT_STATUS_OK;
834 }
835
836
837 /*
838   lsa_OpenTrustedDomainByName
839 */
840 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
841                                             TALLOC_CTX *mem_ctx,
842                                             struct lsa_OpenTrustedDomainByName *r)
843 {
844         struct dcesrv_handle *policy_handle;
845         
846         struct lsa_policy_state *policy_state;
847         struct lsa_trusted_domain_state *trusted_domain_state;
848         struct dcesrv_handle *handle;
849         struct ldb_message **msgs;
850         const char *attrs[] = {
851                 NULL
852         };
853
854         int ret;
855
856         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
857         ZERO_STRUCTP(r->out.trustdom_handle);
858         policy_state = policy_handle->data;
859
860         if (!r->in.name.string) {
861                 return NT_STATUS_INVALID_PARAMETER;
862         }
863         
864         trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
865         if (!trusted_domain_state) {
866                 return NT_STATUS_NO_MEMORY;
867         }
868         trusted_domain_state->policy = policy_state;
869
870         /* search for the trusted_domain record */
871         ret = gendb_search(trusted_domain_state->policy->sam_ldb,
872                            mem_ctx, policy_state->system_dn, &msgs, attrs,
873                            "(&(flatname=%s)(objectclass=trustedDomain))", 
874                            ldb_binary_encode_string(mem_ctx, r->in.name.string));
875         if (ret == 0) {
876                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
877         }
878         
879         if (ret != 1) {
880                 DEBUG(0,("Found %d records matching DN %s\n", ret,
881                          ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
882                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
883         }
884
885         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
886         
887         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
888         if (!handle) {
889                 return NT_STATUS_NO_MEMORY;
890         }
891         
892         handle->data = talloc_steal(handle, trusted_domain_state);
893         
894         trusted_domain_state->access_mask = r->in.access_mask;
895         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
896         
897         *r->out.trustdom_handle = handle->wire_handle;
898         
899         return NT_STATUS_OK;
900 }
901
902
903
904 /* 
905   lsa_SetTrustedDomainInfo
906 */
907 static NTSTATUS lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
908                                          struct lsa_SetTrustedDomainInfo *r)
909 {
910         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
911 }
912
913
914
915 /* 
916   lsa_SetInfomrationTrustedDomain
917 */
918 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, 
919                                                 TALLOC_CTX *mem_ctx,
920                                                 struct lsa_SetInformationTrustedDomain *r)
921 {
922         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
923 }
924
925
926 /* 
927   lsa_DeleteTrustedDomain
928 */
929 static NTSTATUS lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
930                                       struct lsa_DeleteTrustedDomain *r)
931 {
932         NTSTATUS status;
933         struct lsa_OpenTrustedDomain open;
934         struct lsa_Delete delete;
935         struct dcesrv_handle *h;
936
937         open.in.handle = r->in.handle;
938         open.in.sid = r->in.dom_sid;
939         open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
940         open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
941         if (!open.out.trustdom_handle) {
942                 return NT_STATUS_NO_MEMORY;
943         }
944         status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
945         if (!NT_STATUS_IS_OK(status)) {
946                 return status;
947         }
948
949         DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
950         talloc_steal(mem_ctx, h);
951
952         delete.in.handle = open.out.trustdom_handle;
953         status = lsa_Delete(dce_call, mem_ctx, &delete);
954         if (!NT_STATUS_IS_OK(status)) {
955                 return status;
956         }
957         return NT_STATUS_OK;
958 }
959
960 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx, 
961                                      struct ldb_message *msg, 
962                                      struct lsa_TrustDomainInfoInfoEx *info_ex) 
963 {
964         info_ex->domain_name.string
965                 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
966         info_ex->netbios_name.string
967                 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
968         info_ex->sid 
969                 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
970         info_ex->trust_direction
971                 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
972         info_ex->trust_type
973                 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
974         info_ex->trust_attributes
975                 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);  
976         return NT_STATUS_OK;
977 }
978
979 /* 
980   lsa_QueryTrustedDomainInfo
981 */
982 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
983                                            struct lsa_QueryTrustedDomainInfo *r)
984 {
985         struct dcesrv_handle *h;
986         struct lsa_trusted_domain_state *trusted_domain_state;
987         struct ldb_message *msg;
988         int ret;
989         struct ldb_message **res;
990         const char *attrs[] = {
991                 "flatname", 
992                 "trustPartner",
993                 "securityIdentifier",
994                 "trustDirection",
995                 "trustType",
996                 "trustAttributes", 
997                 NULL
998         };
999
1000         DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1001
1002         trusted_domain_state = h->data;
1003
1004         /* pull all the user attributes */
1005         ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1006                               trusted_domain_state->trusted_domain_dn, &res, attrs);
1007         if (ret != 1) {
1008                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1009         }
1010         msg = res[0];
1011         
1012         r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
1013         if (!r->out.info) {
1014                 return NT_STATUS_NO_MEMORY;
1015         }
1016         switch (r->in.level) {
1017         case LSA_TRUSTED_DOMAIN_INFO_NAME:
1018                 r->out.info->name.netbios_name.string
1019                         = samdb_result_string(msg, "flatname", NULL);                                      
1020                 break;
1021         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1022                 r->out.info->posix_offset.posix_offset
1023                         = samdb_result_uint(msg, "posixOffset", 0);                                        
1024                 break;
1025 #if 0  /* Win2k3 doesn't implement this */
1026         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1027                 r->out.info->info_basic.netbios_name.string 
1028                         = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1029                 r->out.info->info_basic.sid
1030                         = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1031                 break;
1032 #endif
1033         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1034                 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
1035
1036         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1037                 ZERO_STRUCT(r->out.info->full_info);
1038                 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
1039
1040         case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
1041                 ZERO_STRUCT(r->out.info->info_all);
1042                 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
1043
1044         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
1045         case LSA_TRUSTED_DOMAIN_INFO_11:
1046                 /* oops, we don't want to return the info after all */
1047                 talloc_free(r->out.info);
1048                 r->out.info = NULL;
1049                 return NT_STATUS_INVALID_PARAMETER;
1050         default:
1051                 /* oops, we don't want to return the info after all */
1052                 talloc_free(r->out.info);
1053                 r->out.info = NULL;
1054                 return NT_STATUS_INVALID_INFO_CLASS;
1055         }
1056
1057         return NT_STATUS_OK;
1058 }
1059
1060
1061 /* 
1062   lsa_QueryTrustedDomainInfoBySid
1063 */
1064 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1065                                                 struct lsa_QueryTrustedDomainInfoBySid *r)
1066 {
1067         NTSTATUS status;
1068         struct lsa_OpenTrustedDomain open;
1069         struct lsa_QueryTrustedDomainInfo query;
1070         struct dcesrv_handle *h;
1071         open.in.handle = r->in.handle;
1072         open.in.sid = r->in.dom_sid;
1073         open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1074         open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1075         if (!open.out.trustdom_handle) {
1076                 return NT_STATUS_NO_MEMORY;
1077         }
1078         status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1079         if (!NT_STATUS_IS_OK(status)) {
1080                 return status;
1081         }
1082
1083         /* Ensure this handle goes away at the end of this call */
1084         DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1085         talloc_steal(mem_ctx, h);
1086         
1087         query.in.trustdom_handle = open.out.trustdom_handle;
1088         query.in.level = r->in.level;
1089         status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1090         if (!NT_STATUS_IS_OK(status)) {
1091                 return status;
1092         }
1093         
1094         r->out.info = query.out.info;
1095         return NT_STATUS_OK;
1096 }
1097
1098 /*
1099   lsa_SetTrustedDomainInfoByName
1100 */
1101 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1102                                                TALLOC_CTX *mem_ctx,
1103                                                struct lsa_SetTrustedDomainInfoByName *r)
1104 {
1105         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1106 }
1107
1108 /* 
1109    lsa_QueryTrustedDomainInfoByName
1110 */
1111 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1112                                                  TALLOC_CTX *mem_ctx,
1113                                                  struct lsa_QueryTrustedDomainInfoByName *r)
1114 {
1115         NTSTATUS status;
1116         struct lsa_OpenTrustedDomainByName open;
1117         struct lsa_QueryTrustedDomainInfo query;
1118         struct dcesrv_handle *h;
1119         open.in.handle = r->in.handle;
1120         open.in.name = r->in.trusted_domain;
1121         open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1122         open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1123         if (!open.out.trustdom_handle) {
1124                 return NT_STATUS_NO_MEMORY;
1125         }
1126         status = lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1127         if (!NT_STATUS_IS_OK(status)) {
1128                 return status;
1129         }
1130         
1131         /* Ensure this handle goes away at the end of this call */
1132         DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1133         talloc_steal(mem_ctx, h);
1134
1135         query.in.trustdom_handle = open.out.trustdom_handle;
1136         query.in.level = r->in.level;
1137         status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1138         if (!NT_STATUS_IS_OK(status)) {
1139                 return status;
1140         }
1141         
1142         r->out.info = query.out.info;
1143         return NT_STATUS_OK;
1144 }
1145
1146 /*
1147   lsa_CloseTrustedDomainEx 
1148 */
1149 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1150                                          TALLOC_CTX *mem_ctx,
1151                                          struct lsa_CloseTrustedDomainEx *r)
1152 {
1153         /* The result of a bad hair day from an IDL programmer?  Not
1154          * implmented in Win2k3.  You should always just lsa_Close
1155          * anyway. */
1156         return NT_STATUS_NOT_IMPLEMENTED;
1157 }
1158
1159
1160 /*
1161   comparison function for sorting lsa_DomainInformation array
1162 */
1163 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1164 {
1165         return strcasecmp(e1->name.string, e2->name.string);
1166 }
1167
1168 /* 
1169   lsa_EnumTrustDom 
1170 */
1171 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1172                                  struct lsa_EnumTrustDom *r)
1173 {
1174         struct dcesrv_handle *policy_handle;
1175         struct lsa_DomainInfo *entries;
1176         struct lsa_policy_state *policy_state;
1177         struct ldb_message **domains;
1178         const char *attrs[] = {
1179                 "flatname", 
1180                 "securityIdentifier",
1181                 NULL
1182         };
1183
1184
1185         int count, i;
1186
1187         *r->out.resume_handle = 0;
1188
1189         r->out.domains->domains = NULL;
1190         r->out.domains->count = 0;
1191
1192         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1193
1194         policy_state = policy_handle->data;
1195
1196         /* search for all users in this domain. This could possibly be cached and 
1197            resumed based on resume_key */
1198         count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 
1199                              "objectclass=trustedDomain");
1200         if (count == -1) {
1201                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1202         }
1203         if (count == 0 || r->in.max_size == 0) {
1204                 return NT_STATUS_OK;
1205         }
1206
1207         /* convert to lsa_TrustInformation format */
1208         entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1209         if (!entries) {
1210                 return NT_STATUS_NO_MEMORY;
1211         }
1212         for (i=0;i<count;i++) {
1213                 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1214                 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1215         }
1216
1217         /* sort the results by name */
1218         qsort(entries, count, sizeof(*entries), 
1219               (comparison_fn_t)compare_DomainInfo);
1220
1221         if (*r->in.resume_handle >= count) {
1222                 *r->out.resume_handle = -1;
1223
1224                 return NT_STATUS_NO_MORE_ENTRIES;
1225         }
1226
1227         /* return the rest, limit by max_size. Note that we 
1228            use the w2k3 element size value of 60 */
1229         r->out.domains->count = count - *r->in.resume_handle;
1230         r->out.domains->count = MIN(r->out.domains->count, 
1231                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1232
1233         r->out.domains->domains = entries + *r->in.resume_handle;
1234         r->out.domains->count = r->out.domains->count;
1235
1236         if (r->out.domains->count < count - *r->in.resume_handle) {
1237                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1238                 return STATUS_MORE_ENTRIES;
1239         }
1240
1241         return NT_STATUS_OK;
1242 }
1243
1244 /*
1245   comparison function for sorting lsa_DomainInformation array
1246 */
1247 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1248 {
1249         return strcasecmp(e1->domain_name.string, e2->domain_name.string);
1250 }
1251
1252 /* 
1253   lsa_EnumTrustedDomainsEx 
1254 */
1255 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1256                                         struct lsa_EnumTrustedDomainsEx *r)
1257 {
1258         struct dcesrv_handle *policy_handle;
1259         struct lsa_TrustDomainInfoInfoEx *entries;
1260         struct lsa_policy_state *policy_state;
1261         struct ldb_message **domains;
1262         const char *attrs[] = {
1263                 "flatname", 
1264                 "trustPartner",
1265                 "securityIdentifier",
1266                 "trustDirection",
1267                 "trustType",
1268                 "trustAttributes", 
1269                 NULL
1270         };
1271         NTSTATUS nt_status;
1272
1273         int count, i;
1274
1275         *r->out.resume_handle = 0;
1276
1277         r->out.domains->domains = NULL;
1278         r->out.domains->count = 0;
1279
1280         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1281
1282         policy_state = policy_handle->data;
1283
1284         /* search for all users in this domain. This could possibly be cached and 
1285            resumed based on resume_key */
1286         count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 
1287                              "objectclass=trustedDomain");
1288         if (count == -1) {
1289                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1290         }
1291         if (count == 0 || r->in.max_size == 0) {
1292                 return NT_STATUS_OK;
1293         }
1294
1295         /* convert to lsa_DomainInformation format */
1296         entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1297         if (!entries) {
1298                 return NT_STATUS_NO_MEMORY;
1299         }
1300         for (i=0;i<count;i++) {
1301                 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1302                 if (!NT_STATUS_IS_OK(nt_status)) {
1303                         return nt_status;
1304                 }
1305         }
1306
1307         /* sort the results by name */
1308         qsort(entries, count, sizeof(*entries), 
1309               (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1310
1311         if (*r->in.resume_handle >= count) {
1312                 *r->out.resume_handle = -1;
1313
1314                 return NT_STATUS_NO_MORE_ENTRIES;
1315         }
1316
1317         /* return the rest, limit by max_size. Note that we 
1318            use the w2k3 element size value of 60 */
1319         r->out.domains->count = count - *r->in.resume_handle;
1320         r->out.domains->count = MIN(r->out.domains->count, 
1321                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1322
1323         r->out.domains->domains = entries + *r->in.resume_handle;
1324         r->out.domains->count = r->out.domains->count;
1325
1326         if (r->out.domains->count < count - *r->in.resume_handle) {
1327                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1328                 return STATUS_MORE_ENTRIES;
1329         }
1330
1331         return NT_STATUS_OK;
1332 }
1333
1334
1335 /*
1336   return the authority name and authority sid, given a sid
1337 */
1338 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
1339                                    TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1340                                    const char **authority_name,
1341                                    struct dom_sid **authority_sid)
1342 {
1343         if (dom_sid_in_domain(state->domain_sid, sid)) {
1344                 *authority_name = state->domain_name;
1345                 *authority_sid = state->domain_sid;
1346                 return NT_STATUS_OK;
1347         }
1348
1349         if (dom_sid_in_domain(state->builtin_sid, sid)) {
1350                 *authority_name = "BUILTIN";
1351                 *authority_sid = state->builtin_sid;
1352                 return NT_STATUS_OK;
1353         }
1354
1355         *authority_sid = dom_sid_dup(mem_ctx, sid);
1356         if (*authority_sid == NULL) {
1357                 return NT_STATUS_NO_MEMORY;
1358         }
1359         (*authority_sid)->num_auths = 0;
1360         *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1361         if (*authority_name == NULL) {
1362                 return NT_STATUS_NO_MEMORY;
1363         }
1364
1365         return NT_STATUS_OK;
1366 }
1367
1368 /*
1369   add to the lsa_RefDomainList for LookupSids and LookupNames
1370 */
1371 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, 
1372                                    struct dom_sid *sid, 
1373                                    struct lsa_RefDomainList *domains,
1374                                    uint32_t *sid_index)
1375 {
1376         NTSTATUS status;
1377         const char *authority_name;
1378         struct dom_sid *authority_sid;
1379         int i;
1380
1381         /* work out the authority name */
1382         status = lsa_authority_name(state, mem_ctx, sid, 
1383                                     &authority_name, &authority_sid);
1384         if (!NT_STATUS_IS_OK(status)) {
1385                 return status;
1386         }
1387         
1388         /* see if we've already done this authority name */
1389         for (i=0;i<domains->count;i++) {
1390                 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1391                         *sid_index = i;
1392                         return NT_STATUS_OK;
1393                 }
1394         }
1395
1396         domains->domains = talloc_realloc(domains, 
1397                                           domains->domains,
1398                                           struct lsa_DomainInfo,
1399                                           domains->count+1);
1400         if (domains->domains == NULL) {
1401                 return NT_STATUS_NO_MEMORY;
1402         }
1403         domains->domains[i].name.string = authority_name;
1404         domains->domains[i].sid         = authority_sid;
1405         domains->count++;
1406         domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
1407         *sid_index = i;
1408         
1409         return NT_STATUS_OK;
1410 }
1411
1412 /*
1413   lookup a name for 1 SID
1414 */
1415 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1416                                struct dom_sid *sid, const char *sid_str,
1417                                const char **name, uint32_t *atype)
1418 {
1419         int ret;
1420         struct ldb_message **res;
1421         const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1422         NTSTATUS status;
1423
1424         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
1425                            "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1426         if (ret == 1) {
1427                 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
1428                 if (!*name) {
1429                         *name = ldb_msg_find_attr_as_string(res[0], "name", NULL);
1430                         if (!*name) {
1431                                 *name = talloc_strdup(mem_ctx, sid_str);
1432                                 NT_STATUS_HAVE_NO_MEMORY(*name);
1433                         }
1434                 }
1435
1436                 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1437
1438                 return NT_STATUS_OK;
1439         }
1440
1441         status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1442
1443         return status;
1444 }
1445
1446
1447 /*
1448   lsa_LookupSids3
1449 */
1450 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1451                                 TALLOC_CTX *mem_ctx,
1452                                 struct lsa_LookupSids3 *r)
1453 {
1454         struct lsa_policy_state *state;
1455         int i;
1456         NTSTATUS status = NT_STATUS_OK;
1457
1458         r->out.domains = NULL;
1459
1460         status = lsa_get_policy_state(dce_call, mem_ctx, &state);
1461         if (!NT_STATUS_IS_OK(status)) {
1462                 return status;
1463         }
1464
1465         r->out.domains = talloc_zero(mem_ctx,  struct lsa_RefDomainList);
1466         if (r->out.domains == NULL) {
1467                 return NT_STATUS_NO_MEMORY;
1468         }
1469
1470         r->out.names = talloc_zero(mem_ctx,  struct lsa_TransNameArray2);
1471         if (r->out.names == NULL) {
1472                 return NT_STATUS_NO_MEMORY;
1473         }
1474
1475         *r->out.count = 0;
1476
1477         r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2, 
1478                                              r->in.sids->num_sids);
1479         if (r->out.names->names == NULL) {
1480                 return NT_STATUS_NO_MEMORY;
1481         }
1482
1483         for (i=0;i<r->in.sids->num_sids;i++) {
1484                 struct dom_sid *sid = r->in.sids->sids[i].sid;
1485                 char *sid_str = dom_sid_string(mem_ctx, sid);
1486                 const char *name;
1487                 uint32_t atype, rtype, sid_index;
1488                 NTSTATUS status2;
1489
1490                 r->out.names->count++;
1491                 (*r->out.count)++;
1492
1493                 r->out.names->names[i].sid_type    = SID_NAME_UNKNOWN;
1494                 r->out.names->names[i].name.string = sid_str;
1495                 r->out.names->names[i].sid_index   = 0xFFFFFFFF;
1496                 r->out.names->names[i].unknown     = 0;
1497
1498                 if (sid_str == NULL) {
1499                         r->out.names->names[i].name.string = "(SIDERROR)";
1500                         status = STATUS_SOME_UNMAPPED;
1501                         continue;
1502                 }
1503
1504                 /* work out the authority name */
1505                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1506                 if (!NT_STATUS_IS_OK(status2)) {
1507                         return status2;
1508                 }
1509
1510                 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str, 
1511                                          &name, &atype);
1512                 if (!NT_STATUS_IS_OK(status2)) {
1513                         status = STATUS_SOME_UNMAPPED;
1514                         continue;
1515                 }
1516
1517                 rtype = samdb_atype_map(atype);
1518                 if (rtype == SID_NAME_UNKNOWN) {
1519                         status = STATUS_SOME_UNMAPPED;
1520                         continue;
1521                 }
1522
1523                 r->out.names->names[i].sid_type    = rtype;
1524                 r->out.names->names[i].name.string = name;
1525                 r->out.names->names[i].sid_index   = sid_index;
1526                 r->out.names->names[i].unknown     = 0;
1527         }
1528         
1529         return status;
1530 }
1531
1532
1533 /*
1534   lsa_LookupSids2
1535 */
1536 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1537                                 TALLOC_CTX *mem_ctx,
1538                                 struct lsa_LookupSids2 *r)
1539 {
1540         struct lsa_LookupSids3 r3;
1541         NTSTATUS status;
1542
1543         r3.in.sids     = r->in.sids;
1544         r3.in.names    = r->in.names;
1545         r3.in.level    = r->in.level;
1546         r3.in.count    = r->in.count;
1547         r3.in.unknown1 = r->in.unknown1;
1548         r3.in.unknown2 = r->in.unknown2;
1549         r3.out.count   = r->out.count;
1550         r3.out.names   = r->out.names;
1551
1552         status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1553         if (dce_call->fault_code != 0) {
1554                 return status;
1555         }
1556
1557         r->out.domains = r3.out.domains;
1558         r->out.names   = r3.out.names;
1559         r->out.count   = r3.out.count;
1560
1561         return status;
1562 }
1563
1564
1565 /* 
1566   lsa_LookupSids 
1567 */
1568 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1569                                struct lsa_LookupSids *r)
1570 {
1571         struct lsa_LookupSids3 r3;
1572         NTSTATUS status;
1573         int i;
1574
1575         r3.in.sids     = r->in.sids;
1576         r3.in.names    = NULL;
1577         r3.in.level    = r->in.level;
1578         r3.in.count    = r->in.count;
1579         r3.in.unknown1 = 0;
1580         r3.in.unknown2 = 0;
1581         r3.out.count   = r->out.count;
1582         r3.out.names   = NULL;
1583
1584         status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1585         if (dce_call->fault_code != 0) {
1586                 return status;
1587         }
1588
1589         r->out.domains = r3.out.domains;
1590         if (!r3.out.names) {
1591                 r->out.names = NULL;
1592                 return status;
1593         }
1594
1595         r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1596         if (r->out.names == NULL) {
1597                 return NT_STATUS_NO_MEMORY;
1598         }
1599         r->out.names->count = r3.out.names->count;
1600         r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName, 
1601                                              r->out.names->count);
1602         if (r->out.names->names == NULL) {
1603                 return NT_STATUS_NO_MEMORY;
1604         }
1605         for (i=0;i<r->out.names->count;i++) {
1606                 r->out.names->names[i].sid_type    = r3.out.names->names[i].sid_type;
1607                 r->out.names->names[i].name.string = r3.out.names->names[i].name.string;
1608                 r->out.names->names[i].sid_index   = r3.out.names->names[i].sid_index;
1609         }
1610
1611         return status;
1612 }
1613
1614
1615 /* 
1616   lsa_OpenAccount 
1617 */
1618 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1619                                 struct lsa_OpenAccount *r)
1620 {
1621         struct dcesrv_handle *h, *ah;
1622         struct lsa_policy_state *state;
1623         struct lsa_account_state *astate;
1624
1625         ZERO_STRUCTP(r->out.acct_handle);
1626
1627         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1628
1629         state = h->data;
1630
1631         astate = talloc(dce_call->conn, struct lsa_account_state);
1632         if (astate == NULL) {
1633                 return NT_STATUS_NO_MEMORY;
1634         }
1635
1636         astate->account_sid = dom_sid_dup(astate, r->in.sid);
1637         if (astate->account_sid == NULL) {
1638                 talloc_free(astate);
1639                 return NT_STATUS_NO_MEMORY;
1640         }
1641         
1642         astate->policy = talloc_reference(astate, state);
1643         astate->access_mask = r->in.access_mask;
1644
1645         ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1646         if (!ah) {
1647                 talloc_free(astate);
1648                 return NT_STATUS_NO_MEMORY;
1649         }
1650
1651         ah->data = talloc_steal(ah, astate);
1652
1653         *r->out.acct_handle = ah->wire_handle;
1654
1655         return NT_STATUS_OK;
1656 }
1657
1658
1659 /* 
1660   lsa_EnumPrivsAccount 
1661 */
1662 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 
1663                                      TALLOC_CTX *mem_ctx,
1664                                      struct lsa_EnumPrivsAccount *r)
1665 {
1666         struct dcesrv_handle *h;
1667         struct lsa_account_state *astate;
1668         int ret, i;
1669         struct ldb_message **res;
1670         const char * const attrs[] = { "privilege", NULL};
1671         struct ldb_message_element *el;
1672         const char *sidstr;
1673
1674         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1675
1676         astate = h->data;
1677
1678         r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1679         r->out.privs->count = 0;
1680         r->out.privs->unknown = 0;
1681         r->out.privs->set = NULL;
1682
1683         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1684         if (sidstr == NULL) {
1685                 return NT_STATUS_NO_MEMORY;
1686         }
1687
1688         ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs, 
1689                            "objectSid=%s", sidstr);
1690         if (ret != 1) {
1691                 return NT_STATUS_OK;
1692         }
1693
1694         el = ldb_msg_find_element(res[0], "privilege");
1695         if (el == NULL || el->num_values == 0) {
1696                 return NT_STATUS_OK;
1697         }
1698
1699         r->out.privs->set = talloc_array(r->out.privs, 
1700                                          struct lsa_LUIDAttribute, el->num_values);
1701         if (r->out.privs->set == NULL) {
1702                 return NT_STATUS_NO_MEMORY;
1703         }
1704
1705         for (i=0;i<el->num_values;i++) {
1706                 int id = sec_privilege_id((const char *)el->values[i].data);
1707                 if (id == -1) {
1708                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1709                 }
1710                 r->out.privs->set[i].attribute = 0;
1711                 r->out.privs->set[i].luid.low = id;
1712                 r->out.privs->set[i].luid.high = 0;
1713         }
1714
1715         r->out.privs->count = el->num_values;
1716
1717         return NT_STATUS_OK;
1718 }
1719
1720 /* 
1721   lsa_EnumAccountRights 
1722 */
1723 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
1724                                       TALLOC_CTX *mem_ctx,
1725                                       struct lsa_EnumAccountRights *r)
1726 {
1727         struct dcesrv_handle *h;
1728         struct lsa_policy_state *state;
1729         int ret, i;
1730         struct ldb_message **res;
1731         const char * const attrs[] = { "privilege", NULL};
1732         const char *sidstr;
1733         struct ldb_message_element *el;
1734
1735         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1736
1737         state = h->data;
1738
1739         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1740         if (sidstr == NULL) {
1741                 return NT_STATUS_NO_MEMORY;
1742         }
1743
1744         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
1745                            "(&(objectSid=%s)(privilege=*))", sidstr);
1746         if (ret == 0) {
1747                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1748         }
1749         if (ret > 1) {
1750                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1751         }
1752         if (ret == -1) {
1753                 DEBUG(3, ("searching for account rights for SID: %s failed: %s", 
1754                           dom_sid_string(mem_ctx, r->in.sid),
1755                           ldb_errstring(state->sam_ldb)));
1756                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1757         }
1758
1759         el = ldb_msg_find_element(res[0], "privilege");
1760         if (el == NULL || el->num_values == 0) {
1761                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1762         }
1763
1764         r->out.rights->count = el->num_values;
1765         r->out.rights->names = talloc_array(r->out.rights, 
1766                                             struct lsa_StringLarge, r->out.rights->count);
1767         if (r->out.rights->names == NULL) {
1768                 return NT_STATUS_NO_MEMORY;
1769         }
1770
1771         for (i=0;i<el->num_values;i++) {
1772                 r->out.rights->names[i].string = (const char *)el->values[i].data;
1773         }
1774
1775         return NT_STATUS_OK;
1776 }
1777
1778
1779
1780 /* 
1781   helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1782 */
1783 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
1784                                            TALLOC_CTX *mem_ctx,
1785                                            struct lsa_policy_state *state,
1786                                            int ldb_flag,
1787                                            struct dom_sid *sid,
1788                                            const struct lsa_RightSet *rights)
1789 {
1790         const char *sidstr;
1791         struct ldb_message *msg;
1792         struct ldb_message_element *el;
1793         int i, ret;
1794         struct lsa_EnumAccountRights r2;
1795
1796         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1797         if (sidstr == NULL) {
1798                 return NT_STATUS_NO_MEMORY;
1799         }
1800
1801         msg = ldb_msg_new(mem_ctx);
1802         if (msg == NULL) {
1803                 return NT_STATUS_NO_MEMORY;
1804         }
1805
1806         msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx, 
1807                                   NULL, "objectSid=%s", sidstr);
1808         if (msg->dn == NULL) {
1809                 NTSTATUS status;
1810                 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1811                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1812                 }
1813                 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx, 
1814                                                                  sid, &msg->dn);
1815                 if (!NT_STATUS_IS_OK(status)) {
1816                         return status;
1817                 }
1818                 return NT_STATUS_NO_SUCH_USER;
1819         }
1820
1821         if (ldb_msg_add_empty(msg, "privilege", ldb_flag)) {
1822                 return NT_STATUS_NO_MEMORY;
1823         }
1824
1825         if (ldb_flag == LDB_FLAG_MOD_ADD) {
1826                 NTSTATUS status;
1827
1828                 r2.in.handle = &state->handle->wire_handle;
1829                 r2.in.sid = sid;
1830                 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1831
1832                 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1833                 if (!NT_STATUS_IS_OK(status)) {
1834                         ZERO_STRUCTP(r2.out.rights);
1835                 }
1836         }
1837
1838         for (i=0;i<rights->count;i++) {
1839                 if (sec_privilege_id(rights->names[i].string) == -1) {
1840                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1841                 }
1842
1843                 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1844                         int j;
1845                         for (j=0;j<r2.out.rights->count;j++) {
1846                                 if (strcasecmp_m(r2.out.rights->names[j].string, 
1847                                                rights->names[i].string) == 0) {
1848                                         break;
1849                                 }
1850                         }
1851                         if (j != r2.out.rights->count) continue;
1852                 }
1853
1854                 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1855                 if (ret != LDB_SUCCESS) {
1856                         return NT_STATUS_NO_MEMORY;
1857                 }
1858         }
1859
1860         el = ldb_msg_find_element(msg, "privilege");
1861         if (!el) {
1862                 return NT_STATUS_OK;
1863         }
1864
1865         ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
1866         if (ret != 0) {
1867                 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1868                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1869                 }
1870                 DEBUG(3, ("Could not %s attributes from %s: %s", 
1871                           ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
1872                           ldb_dn_linearize(mem_ctx, msg->dn), ldb_errstring(state->sam_ldb)));
1873                 return NT_STATUS_UNEXPECTED_IO_ERROR;
1874         }
1875
1876         return NT_STATUS_OK;
1877 }
1878
1879 /* 
1880   lsa_AddPrivilegesToAccount
1881 */
1882 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1883                                            struct lsa_AddPrivilegesToAccount *r)
1884 {
1885         struct lsa_RightSet rights;
1886         struct dcesrv_handle *h;
1887         struct lsa_account_state *astate;
1888         int i;
1889
1890         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1891
1892         astate = h->data;
1893
1894         rights.count = r->in.privs->count;
1895         rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1896         if (rights.names == NULL) {
1897                 return NT_STATUS_NO_MEMORY;
1898         }
1899         for (i=0;i<rights.count;i++) {
1900                 int id = r->in.privs->set[i].luid.low;
1901                 if (r->in.privs->set[i].luid.high) {
1902                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1903                 }
1904                 rights.names[i].string = sec_privilege_name(id);
1905                 if (rights.names[i].string == NULL) {
1906                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1907                 }
1908         }
1909
1910         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1911                                           LDB_FLAG_MOD_ADD, astate->account_sid,
1912                                           &rights);
1913 }
1914
1915
1916 /* 
1917   lsa_RemovePrivilegesFromAccount
1918 */
1919 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1920                                                 struct lsa_RemovePrivilegesFromAccount *r)
1921 {
1922         struct lsa_RightSet *rights;
1923         struct dcesrv_handle *h;
1924         struct lsa_account_state *astate;
1925         int i;
1926
1927         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1928
1929         astate = h->data;
1930
1931         rights = talloc(mem_ctx, struct lsa_RightSet);
1932
1933         if (r->in.remove_all == 1 && 
1934             r->in.privs == NULL) {
1935                 struct lsa_EnumAccountRights r2;
1936                 NTSTATUS status;
1937
1938                 r2.in.handle = &astate->policy->handle->wire_handle;
1939                 r2.in.sid = astate->account_sid;
1940                 r2.out.rights = rights;
1941
1942                 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1943                 if (!NT_STATUS_IS_OK(status)) {
1944                         return status;
1945                 }
1946
1947                 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1948                                                   LDB_FLAG_MOD_DELETE, astate->account_sid,
1949                                                   r2.out.rights);
1950         }
1951
1952         if (r->in.remove_all != 0) {
1953                 return NT_STATUS_INVALID_PARAMETER;
1954         }
1955
1956         rights->count = r->in.privs->count;
1957         rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1958         if (rights->names == NULL) {
1959                 return NT_STATUS_NO_MEMORY;
1960         }
1961         for (i=0;i<rights->count;i++) {
1962                 int id = r->in.privs->set[i].luid.low;
1963                 if (r->in.privs->set[i].luid.high) {
1964                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1965                 }
1966                 rights->names[i].string = sec_privilege_name(id);
1967                 if (rights->names[i].string == NULL) {
1968                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1969                 }
1970         }
1971
1972         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1973                                           LDB_FLAG_MOD_DELETE, astate->account_sid,
1974                                           rights);
1975 }
1976
1977
1978 /* 
1979   lsa_GetQuotasForAccount
1980 */
1981 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1982                        struct lsa_GetQuotasForAccount *r)
1983 {
1984         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1985 }
1986
1987
1988 /* 
1989   lsa_SetQuotasForAccount
1990 */
1991 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1992                        struct lsa_SetQuotasForAccount *r)
1993 {
1994         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1995 }
1996
1997
1998 /* 
1999   lsa_GetSystemAccessAccount
2000 */
2001 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2002                        struct lsa_GetSystemAccessAccount *r)
2003 {
2004         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2005 }
2006
2007
2008 /* 
2009   lsa_SetSystemAccessAccount
2010 */
2011 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2012                        struct lsa_SetSystemAccessAccount *r)
2013 {
2014         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2015 }
2016
2017
2018 /* 
2019   lsa_CreateSecret 
2020 */
2021 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2022                                  struct lsa_CreateSecret *r)
2023 {
2024         struct dcesrv_handle *policy_handle;
2025         struct lsa_policy_state *policy_state;
2026         struct lsa_secret_state *secret_state;
2027         struct dcesrv_handle *handle;
2028         struct ldb_message **msgs, *msg;
2029         const char *errstr;
2030         const char *attrs[] = {
2031                 NULL
2032         };
2033
2034         const char *name;
2035
2036         int ret;
2037
2038         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2039         ZERO_STRUCTP(r->out.sec_handle);
2040         
2041         policy_state = policy_handle->data;
2042
2043         if (!r->in.name.string) {
2044                 return NT_STATUS_INVALID_PARAMETER;
2045         }
2046         
2047         secret_state = talloc(mem_ctx, struct lsa_secret_state);
2048         if (!secret_state) {
2049                 return NT_STATUS_NO_MEMORY;
2050         }
2051         secret_state->policy = policy_state;
2052
2053         msg = ldb_msg_new(mem_ctx);
2054         if (msg == NULL) {
2055                 return NT_STATUS_NO_MEMORY;
2056         }
2057
2058         if (strncmp("G$", r->in.name.string, 2) == 0) {
2059                 const char *name2;
2060                 name = &r->in.name.string[2];
2061                 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2062                 secret_state->global = True;
2063
2064                 if (strlen(name) < 1) {
2065                         return NT_STATUS_INVALID_PARAMETER;
2066                 }
2067
2068                 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2069                 /* search for the secret record */
2070                 ret = gendb_search(secret_state->sam_ldb,
2071                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
2072                                    "(&(cn=%s)(objectclass=secret))", 
2073                                    name2);
2074                 if (ret > 0) {
2075                         return NT_STATUS_OBJECT_NAME_COLLISION;
2076                 }
2077                 
2078                 if (ret == -1) {
2079                         DEBUG(0,("Failure searching for CN=%s: %s\n", 
2080                                  name2, ldb_errstring(secret_state->sam_ldb)));
2081                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2082                 }
2083
2084                 msg->dn = ldb_dn_build_child(mem_ctx, "cn", name2, policy_state->system_dn);
2085                 if (!name2 || !msg->dn) {
2086                         return NT_STATUS_NO_MEMORY;
2087                 }
2088                 
2089                 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2090         
2091         } else {
2092                 secret_state->global = False;
2093
2094                 name = r->in.name.string;
2095                 if (strlen(name) < 1) {
2096                         return NT_STATUS_INVALID_PARAMETER;
2097                 }
2098
2099                 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2100                 /* search for the secret record */
2101                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2102                                    ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
2103                                    &msgs, attrs,
2104                                    "(&(cn=%s)(objectclass=secret))", 
2105                                    ldb_binary_encode_string(mem_ctx, name));
2106                 if (ret > 0) {
2107                         return NT_STATUS_OBJECT_NAME_COLLISION;
2108                 }
2109                 
2110                 if (ret == -1) {
2111                         DEBUG(0,("Failure searching for CN=%s: %s\n", 
2112                                  name, ldb_errstring(secret_state->sam_ldb)));
2113                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2114                 }
2115
2116                 msg->dn = ldb_dn_string_compose(mem_ctx, NULL, "cn=%s,cn=LSA Secrets", name);
2117                 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2118         } 
2119
2120         /* pull in all the template attributes.  Note this is always from the global samdb */
2121         ret = samdb_copy_template(secret_state->policy->sam_ldb, msg, 
2122                                   "(&(cn=TemplateSecret)(objectclass=secretTemplate))", &errstr);
2123         if (ret != 0) {
2124                 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2125                          errstr));
2126                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2127         }
2128
2129         samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2130         
2131         secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2132
2133         /* create the secret */
2134         ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
2135         if (ret != 0) {
2136                 DEBUG(0,("Failed to create secret record %s: %s\n",
2137                          ldb_dn_linearize(mem_ctx, msg->dn), 
2138                          ldb_errstring(secret_state->sam_ldb)));
2139                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2140         }
2141
2142         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2143         if (!handle) {
2144                 return NT_STATUS_NO_MEMORY;
2145         }
2146         
2147         handle->data = talloc_steal(handle, secret_state);
2148         
2149         secret_state->access_mask = r->in.access_mask;
2150         secret_state->policy = talloc_reference(secret_state, policy_state);
2151         
2152         *r->out.sec_handle = handle->wire_handle;
2153         
2154         return NT_STATUS_OK;
2155 }
2156
2157
2158 /* 
2159   lsa_OpenSecret 
2160 */
2161 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2162                                struct lsa_OpenSecret *r)
2163 {
2164         struct dcesrv_handle *policy_handle;
2165         
2166         struct lsa_policy_state *policy_state;
2167         struct lsa_secret_state *secret_state;
2168         struct dcesrv_handle *handle;
2169         struct ldb_message **msgs;
2170         const char *attrs[] = {
2171                 NULL
2172         };
2173
2174         const char *name;
2175
2176         int ret;
2177
2178         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2179         ZERO_STRUCTP(r->out.sec_handle);
2180         policy_state = policy_handle->data;
2181
2182         if (!r->in.name.string) {
2183                 return NT_STATUS_INVALID_PARAMETER;
2184         }
2185         
2186         secret_state = talloc(mem_ctx, struct lsa_secret_state);
2187         if (!secret_state) {
2188                 return NT_STATUS_NO_MEMORY;
2189         }
2190         secret_state->policy = policy_state;
2191
2192         if (strncmp("G$", r->in.name.string, 2) == 0) {
2193                 name = &r->in.name.string[2];
2194                 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2195                 secret_state->global = True;
2196
2197                 if (strlen(name) < 1) {
2198                         return NT_STATUS_INVALID_PARAMETER;
2199                 }
2200
2201                 /* search for the secret record */
2202                 ret = gendb_search(secret_state->sam_ldb,
2203                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
2204                                    "(&(cn=%s Secret)(objectclass=secret))", 
2205                                    ldb_binary_encode_string(mem_ctx, name));
2206                 if (ret == 0) {
2207                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2208                 }
2209                 
2210                 if (ret != 1) {
2211                         DEBUG(0,("Found %d records matching DN %s\n", ret,
2212                                  ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
2213                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2214                 }
2215         
2216         } else {
2217                 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2218
2219                 secret_state->global = False;
2220                 name = r->in.name.string;
2221                 if (strlen(name) < 1) {
2222                         return NT_STATUS_INVALID_PARAMETER;
2223                 }
2224
2225                 /* search for the secret record */
2226                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2227                                    ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
2228                                    &msgs, attrs,
2229                                    "(&(cn=%s)(objectclass=secret))", 
2230                                    ldb_binary_encode_string(mem_ctx, name));
2231                 if (ret == 0) {
2232                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2233                 }
2234                 
2235                 if (ret != 1) {
2236                         DEBUG(0,("Found %d records matching DN %s\n", ret,
2237                                  ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
2238                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2239                 }
2240         } 
2241
2242         secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2243         
2244         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2245         if (!handle) {
2246                 return NT_STATUS_NO_MEMORY;
2247         }
2248         
2249         handle->data = talloc_steal(handle, secret_state);
2250         
2251         secret_state->access_mask = r->in.access_mask;
2252         secret_state->policy = talloc_reference(secret_state, policy_state);
2253         
2254         *r->out.sec_handle = handle->wire_handle;
2255         
2256         return NT_STATUS_OK;
2257 }
2258
2259
2260 /* 
2261   lsa_SetSecret 
2262 */
2263 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2264                               struct lsa_SetSecret *r)
2265 {
2266
2267         struct dcesrv_handle *h;
2268         struct lsa_secret_state *secret_state;
2269         struct ldb_message *msg;
2270         DATA_BLOB session_key;
2271         DATA_BLOB crypt_secret, secret;
2272         struct ldb_val val;
2273         int ret;
2274         NTSTATUS status = NT_STATUS_OK;
2275
2276         struct timeval now = timeval_current();
2277         NTTIME nt_now = timeval_to_nttime(&now);
2278
2279         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2280
2281         secret_state = h->data;
2282
2283         msg = ldb_msg_new(mem_ctx);
2284         if (msg == NULL) {
2285                 return NT_STATUS_NO_MEMORY;
2286         }
2287
2288         msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2289         if (!msg->dn) {
2290                 return NT_STATUS_NO_MEMORY;
2291         }
2292         status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2293         if (!NT_STATUS_IS_OK(status)) {
2294                 return status;
2295         }
2296
2297         if (r->in.old_val) {
2298                 /* Decrypt */
2299                 crypt_secret.data = r->in.old_val->data;
2300                 crypt_secret.length = r->in.old_val->size;
2301                 
2302                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2303                 if (!NT_STATUS_IS_OK(status)) {
2304                         return status;
2305                 }
2306                 
2307                 val.data = secret.data;
2308                 val.length = secret.length;
2309                 
2310                 /* set value */
2311                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2312                                         mem_ctx, msg, "priorSecret", &val) != 0) {
2313                         return NT_STATUS_NO_MEMORY; 
2314                 }
2315                 
2316                 /* set old value mtime */
2317                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2318                                          mem_ctx, msg, "priorSetTime", nt_now) != 0) { 
2319                         return NT_STATUS_NO_MEMORY; 
2320                 }
2321
2322                 if (!r->in.new_val) {
2323                         /* This behaviour varies depending of if this is a local, or a global secret... */
2324                         if (secret_state->global) {
2325                                 /* set old value mtime */
2326                                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2327                                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
2328                                         return NT_STATUS_NO_MEMORY; 
2329                                 }
2330                         } else {
2331                                 if (samdb_msg_add_delete(secret_state->sam_ldb, 
2332                                                          mem_ctx, msg, "secret")) {
2333                                         return NT_STATUS_NO_MEMORY;
2334                                 }
2335                                 if (samdb_msg_add_delete(secret_state->sam_ldb, 
2336                                                          mem_ctx, msg, "lastSetTime")) {
2337                                         return NT_STATUS_NO_MEMORY;
2338                                 }
2339                         }
2340                 }
2341         }
2342
2343         if (r->in.new_val) {
2344                 /* Decrypt */
2345                 crypt_secret.data = r->in.new_val->data;
2346                 crypt_secret.length = r->in.new_val->size;
2347                 
2348                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2349                 if (!NT_STATUS_IS_OK(status)) {
2350                         return status;
2351                 }
2352                 
2353                 val.data = secret.data;
2354                 val.length = secret.length;
2355                 
2356                 /* set value */
2357                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2358                                         mem_ctx, msg, "secret", &val) != 0) {
2359                         return NT_STATUS_NO_MEMORY; 
2360                 }
2361                 
2362                 /* set new value mtime */
2363                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2364                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
2365                         return NT_STATUS_NO_MEMORY; 
2366                 }
2367                 
2368                 /* If the old value is not set, then migrate the
2369                  * current value to the old value */
2370                 if (!r->in.old_val) {
2371                         const struct ldb_val *new_val;
2372                         NTTIME last_set_time;
2373                         struct ldb_message **res;
2374                         const char *attrs[] = {
2375                                 "secret",
2376                                 "lastSetTime",
2377                                 NULL
2378                         };
2379                         
2380                         /* search for the secret record */
2381                         ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2382                                               secret_state->secret_dn, &res, attrs);
2383                         if (ret == 0) {
2384                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2385                         }
2386                         
2387                         if (ret != 1) {
2388                                 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2389                                          ldb_dn_linearize(mem_ctx, secret_state->secret_dn)));
2390                                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2391                         }
2392
2393                         new_val = ldb_msg_find_ldb_val(res[0], "secret");
2394                         last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2395                         
2396                         if (new_val) {
2397                                 /* set value */
2398                                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2399                                                         mem_ctx, msg, "priorSecret", 
2400                                                         new_val) != 0) {
2401                                         return NT_STATUS_NO_MEMORY; 
2402                                 }
2403                         }
2404                         
2405                         /* set new value mtime */
2406                         if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2407                                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2408                                                          mem_ctx, msg, "priorSetTime", last_set_time) != 0) { 
2409                                         return NT_STATUS_NO_MEMORY; 
2410                                 }
2411                         }
2412                 }
2413         }
2414
2415         /* modify the samdb record */
2416         ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2417         if (ret != 0) {
2418                 /* we really need samdb.c to return NTSTATUS */
2419                 return NT_STATUS_UNSUCCESSFUL;
2420         }
2421
2422         return NT_STATUS_OK;
2423 }
2424
2425
2426 /* 
2427   lsa_QuerySecret 
2428 */
2429 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2430                                 struct lsa_QuerySecret *r)
2431 {
2432         struct dcesrv_handle *h;
2433         struct lsa_secret_state *secret_state;
2434         struct ldb_message *msg;
2435         DATA_BLOB session_key;
2436         DATA_BLOB crypt_secret, secret;
2437         int ret;
2438         struct ldb_message **res;
2439         const char *attrs[] = {
2440                 "secret",
2441                 "priorSecret",
2442                 "lastSetTime",
2443                 "priorSetTime", 
2444                 NULL
2445         };
2446
2447         NTSTATUS nt_status;
2448
2449         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2450
2451         secret_state = h->data;
2452
2453         /* pull all the user attributes */
2454         ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2455                               secret_state->secret_dn, &res, attrs);
2456         if (ret != 1) {
2457                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2458         }
2459         msg = res[0];
2460         
2461         nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2462         if (!NT_STATUS_IS_OK(nt_status)) {
2463                 return nt_status;
2464         }
2465         
2466         if (r->in.old_val) {
2467                 const struct ldb_val *prior_val;
2468                 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2469                 if (!r->out.old_val) {
2470                         return NT_STATUS_NO_MEMORY;
2471                 }
2472                 /* Decrypt */
2473                 prior_val = ldb_msg_find_ldb_val(res[0], "priorSecret");
2474                 
2475                 if (prior_val && prior_val->length) {
2476                         secret.data = prior_val->data;
2477                         secret.length = prior_val->length;
2478                 
2479                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2480                         if (!crypt_secret.length) {
2481                                 return NT_STATUS_NO_MEMORY;
2482                         }
2483                         r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2484                         if (!r->out.old_val->buf) {
2485                                 return NT_STATUS_NO_MEMORY;
2486                         }
2487                         r->out.old_val->buf->size = crypt_secret.length;
2488                         r->out.old_val->buf->length = crypt_secret.length;
2489                         r->out.old_val->buf->data = crypt_secret.data;
2490                 }
2491         }
2492         
2493         if (r->in.old_mtime) {
2494                 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2495                 if (!r->out.old_mtime) {
2496                         return NT_STATUS_NO_MEMORY;
2497                 }
2498                 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2499         }
2500         
2501         if (r->in.new_val) {
2502                 const struct ldb_val *new_val;
2503                 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2504                 if (!r->out.new_val) {
2505                         return NT_STATUS_NO_MEMORY;
2506                 }
2507
2508                 /* Decrypt */
2509                 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2510                 
2511                 if (new_val && new_val->length) {
2512                         secret.data = new_val->data;
2513                         secret.length = new_val->length;
2514                 
2515                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2516                         if (!crypt_secret.length) {
2517                                 return NT_STATUS_NO_MEMORY;
2518                         }
2519                         r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2520                         if (!r->out.new_val->buf) {
2521                                 return NT_STATUS_NO_MEMORY;
2522                         }
2523                         r->out.new_val->buf->length = crypt_secret.length;
2524                         r->out.new_val->buf->size = crypt_secret.length;
2525                         r->out.new_val->buf->data = crypt_secret.data;
2526                 }
2527         }
2528         
2529         if (r->in.new_mtime) {
2530                 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2531                 if (!r->out.new_mtime) {
2532                         return NT_STATUS_NO_MEMORY;
2533                 }
2534                 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2535         }
2536         
2537         return NT_STATUS_OK;
2538 }
2539
2540
2541 /* 
2542   lsa_LookupPrivValue
2543 */
2544 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
2545                                     TALLOC_CTX *mem_ctx,
2546                                     struct lsa_LookupPrivValue *r)
2547 {
2548         struct dcesrv_handle *h;
2549         struct lsa_policy_state *state;
2550         int id;
2551
2552         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2553
2554         state = h->data;
2555
2556         id = sec_privilege_id(r->in.name->string);
2557         if (id == -1) {
2558                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2559         }
2560
2561         r->out.luid->low = id;
2562         r->out.luid->high = 0;
2563
2564         return NT_STATUS_OK;    
2565 }
2566
2567
2568 /* 
2569   lsa_LookupPrivName 
2570 */
2571 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
2572                                    TALLOC_CTX *mem_ctx,
2573                                    struct lsa_LookupPrivName *r)
2574 {
2575         struct dcesrv_handle *h;
2576         struct lsa_policy_state *state;
2577         const char *privname;
2578
2579         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2580
2581         state = h->data;
2582
2583         if (r->in.luid->high != 0) {
2584                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2585         }
2586
2587         privname = sec_privilege_name(r->in.luid->low);
2588         if (privname == NULL) {
2589                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2590         }
2591
2592         r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2593         if (r->out.name == NULL) {
2594                 return NT_STATUS_NO_MEMORY;
2595         }
2596         r->out.name->string = privname;
2597
2598         return NT_STATUS_OK;    
2599 }
2600
2601
2602 /* 
2603   lsa_LookupPrivDisplayName
2604 */
2605 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
2606                                           TALLOC_CTX *mem_ctx,
2607                                           struct lsa_LookupPrivDisplayName *r)
2608 {
2609         struct dcesrv_handle *h;
2610         struct lsa_policy_state *state;
2611         int id;
2612
2613         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2614
2615         state = h->data;
2616
2617         id = sec_privilege_id(r->in.name->string);
2618         if (id == -1) {
2619                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2620         }
2621         
2622         r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2623         if (r->out.disp_name == NULL) {
2624                 return NT_STATUS_NO_MEMORY;
2625         }
2626
2627         r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2628         if (r->out.disp_name->string == NULL) {
2629                 return NT_STATUS_INTERNAL_ERROR;
2630         }
2631
2632         return NT_STATUS_OK;
2633 }
2634
2635
2636 /* 
2637   lsa_DeleteObject
2638 */
2639 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2640                        struct lsa_DeleteObject *r)
2641 {
2642         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2643 }
2644
2645
2646 /* 
2647   lsa_EnumAccountsWithUserRight
2648 */
2649 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
2650                                               TALLOC_CTX *mem_ctx,
2651                                               struct lsa_EnumAccountsWithUserRight *r)
2652 {
2653         struct dcesrv_handle *h;
2654         struct lsa_policy_state *state;
2655         int ret, i;
2656         struct ldb_message **res;
2657         const char * const attrs[] = { "objectSid", NULL};
2658         const char *privname;
2659
2660         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2661
2662         state = h->data;
2663
2664         if (r->in.name == NULL) {
2665                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2666         } 
2667
2668         privname = r->in.name->string;
2669         if (sec_privilege_id(privname) == -1) {
2670                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2671         }
2672
2673         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
2674                            "privilege=%s", privname);
2675         if (ret == -1) {
2676                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2677         }
2678         if (ret == 0) {
2679                 return NT_STATUS_NO_MORE_ENTRIES;
2680         }
2681
2682         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2683         if (r->out.sids->sids == NULL) {
2684                 return NT_STATUS_NO_MEMORY;
2685         }
2686         for (i=0;i<ret;i++) {
2687                 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2688                                                                 res[i], "objectSid");
2689                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2690         }
2691         r->out.sids->num_sids = ret;
2692
2693         return NT_STATUS_OK;
2694 }
2695
2696
2697 /* 
2698   lsa_AddAccountRights
2699 */
2700 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
2701                                      TALLOC_CTX *mem_ctx,
2702                                      struct lsa_AddAccountRights *r)
2703 {
2704         struct dcesrv_handle *h;
2705         struct lsa_policy_state *state;
2706
2707         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2708
2709         state = h->data;
2710
2711         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2712                                           LDB_FLAG_MOD_ADD,
2713                                           r->in.sid, r->in.rights);
2714 }
2715
2716
2717 /* 
2718   lsa_RemoveAccountRights
2719 */
2720 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
2721                                         TALLOC_CTX *mem_ctx,
2722                                         struct lsa_RemoveAccountRights *r)
2723 {
2724         struct dcesrv_handle *h;
2725         struct lsa_policy_state *state;
2726
2727         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2728
2729         state = h->data;
2730
2731         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2732                                           LDB_FLAG_MOD_DELETE,
2733                                           r->in.sid, r->in.rights);
2734 }
2735
2736
2737 /* 
2738   lsa_StorePrivateData
2739 */
2740 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2741                        struct lsa_StorePrivateData *r)
2742 {
2743         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2744 }
2745
2746
2747 /* 
2748   lsa_RetrievePrivateData
2749 */
2750 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2751                        struct lsa_RetrievePrivateData *r)
2752 {
2753         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2754 }
2755
2756
2757 /* 
2758   lsa_GetUserName
2759 */
2760 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2761                                 struct lsa_GetUserName *r)
2762 {
2763         NTSTATUS status = NT_STATUS_OK;
2764         const char *account_name;
2765         const char *authority_name;
2766         struct lsa_String *_account_name;
2767         struct lsa_StringPointer *_authority_name = NULL;
2768
2769         /* this is what w2k3 does */
2770         r->out.account_name = r->in.account_name;
2771         r->out.authority_name = r->in.authority_name;
2772
2773         if (r->in.account_name && r->in.account_name->string) {
2774                 return NT_STATUS_INVALID_PARAMETER;
2775         }
2776
2777         if (r->in.authority_name &&
2778             r->in.authority_name->string &&
2779             r->in.authority_name->string->string) {
2780                 return NT_STATUS_INVALID_PARAMETER;
2781         }
2782
2783         account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2784         authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2785
2786         _account_name = talloc(mem_ctx, struct lsa_String);
2787         NT_STATUS_HAVE_NO_MEMORY(_account_name);
2788         _account_name->string = account_name;
2789
2790         if (r->in.authority_name) {
2791                 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2792                 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2793                 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2794                 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2795                 _authority_name->string->string = authority_name;
2796         }
2797
2798         r->out.account_name = _account_name;
2799         r->out.authority_name = _authority_name;
2800
2801         return status;
2802 }
2803
2804 /*
2805   lsa_SetInfoPolicy2
2806 */
2807 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2808                                    TALLOC_CTX *mem_ctx,
2809                                    struct lsa_SetInfoPolicy2 *r)
2810 {
2811         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2812 }
2813
2814 /*
2815   lsa_QueryDomainInformationPolicy
2816 */
2817 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2818                                                  TALLOC_CTX *mem_ctx,
2819                                                  struct lsa_QueryDomainInformationPolicy *r)
2820 {
2821         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2822 }
2823
2824 /*
2825   lsa_SetDomInfoPolicy
2826 */
2827 static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2828                                               TALLOC_CTX *mem_ctx,
2829                                               struct lsa_SetDomainInformationPolicy *r)
2830 {
2831         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2832 }
2833
2834 /*
2835   lsa_TestCall
2836 */
2837 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2838                              TALLOC_CTX *mem_ctx,
2839                              struct lsa_TestCall *r)
2840 {
2841         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2842 }
2843
2844 /*
2845   lookup a SID for 1 name
2846 */
2847 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2848                                 const char *name, struct dom_sid **sid, uint32_t *atype)
2849 {
2850         int ret;
2851         struct ldb_message **res;
2852         const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2853         const char *p;
2854
2855         p = strchr_m(name, '\\');
2856         if (p != NULL) {
2857                 /* TODO: properly parse the domain prefix here, and use it to 
2858                    limit the search */
2859                 name = p + 1;
2860         }
2861
2862         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
2863         if (ret == 1) {
2864                 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
2865                 if (*sid == NULL) {
2866                         return NT_STATUS_INVALID_SID;
2867                 }
2868
2869                 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
2870
2871                 return NT_STATUS_OK;
2872         }
2873
2874         /* need to add a call into sidmap to check for a allocated sid */
2875
2876         return NT_STATUS_INVALID_SID;
2877 }
2878
2879
2880 /*
2881   lsa_LookupNames4
2882 */
2883 static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call,
2884                                  TALLOC_CTX *mem_ctx,
2885                                  struct lsa_LookupNames4 *r)
2886 {
2887         struct lsa_policy_state *state;
2888         int i;
2889         NTSTATUS status = NT_STATUS_OK;
2890
2891         status = lsa_get_policy_state(dce_call, mem_ctx, &state);
2892         if (!NT_STATUS_IS_OK(status)) {
2893                 return status;
2894         }
2895
2896         r->out.domains = NULL;
2897
2898         r->out.domains = talloc_zero(mem_ctx,  struct lsa_RefDomainList);
2899         if (r->out.domains == NULL) {
2900                 return NT_STATUS_NO_MEMORY;
2901         }
2902
2903         r->out.sids = talloc_zero(mem_ctx,  struct lsa_TransSidArray3);
2904         if (r->out.sids == NULL) {
2905                 return NT_STATUS_NO_MEMORY;
2906         }
2907
2908         *r->out.count = 0;
2909
2910         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3, 
2911                                            r->in.num_names);
2912         if (r->out.sids->sids == NULL) {
2913                 return NT_STATUS_NO_MEMORY;
2914         }
2915
2916         for (i=0;i<r->in.num_names;i++) {
2917                 const char *name = r->in.names[i].string;
2918                 struct dom_sid *sid;
2919                 uint32_t atype, rtype, sid_index;
2920                 NTSTATUS status2;
2921
2922                 r->out.sids->count++;
2923                 (*r->out.count)++;
2924
2925                 r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
2926                 r->out.sids->sids[i].sid         = NULL;
2927                 r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
2928                 r->out.sids->sids[i].unknown     = 0;
2929
2930                 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2931                 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2932                         status = STATUS_SOME_UNMAPPED;
2933                         continue;
2934                 }
2935
2936                 rtype = samdb_atype_map(atype);
2937                 if (rtype == SID_NAME_UNKNOWN) {
2938                         status = STATUS_SOME_UNMAPPED;
2939                         continue;
2940                 }
2941
2942                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2943                 if (!NT_STATUS_IS_OK(status2)) {
2944                         return status2;
2945                 }
2946
2947                 r->out.sids->sids[i].sid_type    = rtype;
2948                 r->out.sids->sids[i].sid         = sid;
2949                 r->out.sids->sids[i].sid_index   = sid_index;
2950                 r->out.sids->sids[i].unknown     = 0;
2951         }
2952         
2953         return status;
2954 }
2955
2956 /* 
2957   lsa_LookupNames3
2958 */
2959 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2960                                  struct lsa_LookupNames3 *r)
2961 {
2962         struct lsa_LookupNames4 r2;
2963         NTSTATUS status;
2964         struct dcesrv_handle *h;
2965         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2966         
2967         r2.in.num_names = r->in.num_names;
2968         r2.in.names = r->in.names;
2969         r2.in.sids = r->in.sids;
2970         r2.in.count = r->in.count;
2971         r2.in.unknown1 = r->in.unknown1;
2972         r2.in.unknown2 = r->in.unknown2;
2973         r2.out.domains = r->out.domains;
2974         r2.out.sids = r->out.sids;
2975         r2.out.count = r->out.count;
2976         
2977         status = lsa_LookupNames4(dce_call, mem_ctx, &r2);
2978         if (dce_call->fault_code != 0) {
2979                 return status;
2980         }
2981         
2982         r->out.domains = r2.out.domains;
2983         r->out.sids = r2.out.sids;
2984         r->out.count = r2.out.count;
2985         return status;
2986 }
2987
2988 /*
2989   lsa_LookupNames2
2990 */
2991 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
2992                                  TALLOC_CTX *mem_ctx,
2993                                  struct lsa_LookupNames2 *r)
2994 {
2995         struct lsa_policy_state *state;
2996         struct dcesrv_handle *h;
2997         int i;
2998         NTSTATUS status = NT_STATUS_OK;
2999
3000         r->out.domains = NULL;
3001
3002         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3003
3004         state = h->data;
3005
3006         r->out.domains = talloc_zero(mem_ctx,  struct lsa_RefDomainList);
3007         if (r->out.domains == NULL) {
3008                 return NT_STATUS_NO_MEMORY;
3009         }
3010
3011         r->out.sids = talloc_zero(mem_ctx,  struct lsa_TransSidArray2);
3012         if (r->out.sids == NULL) {
3013                 return NT_STATUS_NO_MEMORY;
3014         }
3015
3016         *r->out.count = 0;
3017
3018         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2, 
3019                                            r->in.num_names);
3020         if (r->out.sids->sids == NULL) {
3021                 return NT_STATUS_NO_MEMORY;
3022         }
3023
3024         for (i=0;i<r->in.num_names;i++) {
3025                 const char *name = r->in.names[i].string;
3026                 struct dom_sid *sid;
3027                 uint32_t atype, rtype, sid_index;
3028                 NTSTATUS status2;
3029
3030                 r->out.sids->count++;
3031                 (*r->out.count)++;
3032
3033                 r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
3034                 r->out.sids->sids[i].rid         = 0xFFFFFFFF;
3035                 r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
3036                 r->out.sids->sids[i].unknown     = 0;
3037
3038                 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
3039                 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3040                         status = STATUS_SOME_UNMAPPED;
3041                         continue;
3042                 }
3043
3044                 rtype = samdb_atype_map(atype);
3045                 if (rtype == SID_NAME_UNKNOWN) {
3046                         status = STATUS_SOME_UNMAPPED;
3047                         continue;
3048                 }
3049
3050                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
3051                 if (!NT_STATUS_IS_OK(status2)) {
3052                         return status2;
3053                 }
3054
3055                 r->out.sids->sids[i].sid_type    = rtype;
3056                 r->out.sids->sids[i].rid         = sid->sub_auths[sid->num_auths-1];
3057                 r->out.sids->sids[i].sid_index   = sid_index;
3058                 r->out.sids->sids[i].unknown     = 0;
3059         }
3060         
3061         return status;
3062 }
3063
3064 /* 
3065   lsa_LookupNames 
3066 */
3067 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3068                        struct lsa_LookupNames *r)
3069 {
3070         struct lsa_LookupNames2 r2;
3071         NTSTATUS status;
3072         int i;
3073
3074         r2.in.handle    = r->in.handle;
3075         r2.in.num_names = r->in.num_names;
3076         r2.in.names     = r->in.names;
3077         r2.in.sids      = NULL;
3078         r2.in.level     = r->in.level;
3079         r2.in.count     = r->in.count;
3080         r2.in.unknown1  = 0;
3081         r2.in.unknown2  = 0;
3082         r2.out.count    = r->out.count;
3083
3084         status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
3085         if (dce_call->fault_code != 0) {
3086                 return status;
3087         }
3088
3089         r->out.domains = r2.out.domains;
3090         r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
3091         if (r->out.sids == NULL) {
3092                 return NT_STATUS_NO_MEMORY;
3093         }
3094         r->out.sids->count = r2.out.sids->count;
3095         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid, 
3096                                            r->out.sids->count);
3097         if (r->out.sids->sids == NULL) {
3098                 return NT_STATUS_NO_MEMORY;
3099         }
3100         for (i=0;i<r->out.sids->count;i++) {
3101                 r->out.sids->sids[i].sid_type    = r2.out.sids->sids[i].sid_type;
3102                 r->out.sids->sids[i].rid         = r2.out.sids->sids[i].rid;
3103                 r->out.sids->sids[i].sid_index   = r2.out.sids->sids[i].sid_index;
3104         }
3105
3106         return status;
3107 }
3108
3109 /* 
3110   lsa_CREDRWRITE 
3111 */
3112 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3113                        struct lsa_CREDRWRITE *r)
3114 {
3115         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3116 }
3117
3118
3119 /* 
3120   lsa_CREDRREAD 
3121 */
3122 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3123                        struct lsa_CREDRREAD *r)
3124 {
3125         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3126 }
3127
3128
3129 /* 
3130   lsa_CREDRENUMERATE 
3131 */
3132 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3133                        struct lsa_CREDRENUMERATE *r)
3134 {
3135         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3136 }
3137
3138
3139 /* 
3140   lsa_CREDRWRITEDOMAINCREDENTIALS 
3141 */
3142 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3143                        struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3144 {
3145         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3146 }
3147
3148
3149 /* 
3150   lsa_CREDRREADDOMAINCREDENTIALS 
3151 */
3152 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3153                        struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3154 {
3155         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3156 }
3157
3158
3159 /* 
3160   lsa_CREDRDELETE 
3161 */
3162 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3163                        struct lsa_CREDRDELETE *r)
3164 {
3165         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3166 }
3167
3168
3169 /* 
3170   lsa_CREDRGETTARGETINFO 
3171 */
3172 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3173                        struct lsa_CREDRGETTARGETINFO *r)
3174 {
3175         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3176 }
3177
3178
3179 /* 
3180   lsa_CREDRPROFILELOADED 
3181 */
3182 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3183                        struct lsa_CREDRPROFILELOADED *r)
3184 {
3185         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3186 }
3187
3188
3189 /* 
3190   lsa_CREDRGETSESSIONTYPES 
3191 */
3192 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3193                        struct lsa_CREDRGETSESSIONTYPES *r)
3194 {
3195         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3196 }
3197
3198
3199 /* 
3200   lsa_LSARREGISTERAUDITEVENT 
3201 */
3202 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3203                        struct lsa_LSARREGISTERAUDITEVENT *r)
3204 {
3205         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3206 }
3207
3208
3209 /* 
3210   lsa_LSARGENAUDITEVENT 
3211 */
3212 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3213                        struct lsa_LSARGENAUDITEVENT *r)
3214 {
3215         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3216 }
3217
3218
3219 /* 
3220   lsa_LSARUNREGISTERAUDITEVENT 
3221 */
3222 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3223                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
3224 {
3225         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3226 }
3227
3228
3229 /* 
3230   lsa_LSARQUERYFORESTTRUSTINFORMATION 
3231 */
3232 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3233                        struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
3234 {
3235         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3236 }
3237
3238
3239 /* 
3240   lsa_LSARSETFORESTTRUSTINFORMATION 
3241 */
3242 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3243                        struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3244 {
3245         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3246 }
3247
3248
3249 /* 
3250   lsa_CREDRRENAME 
3251 */
3252 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3253                        struct lsa_CREDRRENAME *r)
3254 {
3255         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3256 }
3257
3258
3259
3260 /* 
3261   lsa_LSAROPENPOLICYSCE 
3262 */
3263 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3264                        struct lsa_LSAROPENPOLICYSCE *r)
3265 {
3266         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3267 }
3268
3269
3270 /* 
3271   lsa_LSARADTREGISTERSECURITYEVENTSOURCE 
3272 */
3273 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3274                        struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3275 {
3276         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3277 }
3278
3279
3280 /* 
3281   lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE 
3282 */
3283 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3284                        struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3285 {
3286         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3287 }
3288
3289
3290 /* 
3291   lsa_LSARADTREPORTSECURITYEVENT 
3292 */
3293 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3294                        struct lsa_LSARADTREPORTSECURITYEVENT *r)
3295 {
3296         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3297 }
3298
3299
3300 /* include the generated boilerplate */
3301 #include "librpc/gen_ndr/ndr_lsa_s.c"