r4682: A LDB-based secrets implementation in Samba4.
[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 "librpc/gen_ndr/ndr_lsa.h"
26 #include "librpc/gen_ndr/ndr_samr.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/common/common.h"
29 #include "lib/ldb/include/ldb.h"
30 #include "auth/auth.h"
31 #include "system/time.h"
32
33 /*
34   this type allows us to distinguish handle types
35 */
36 enum lsa_handle {
37         LSA_HANDLE_POLICY,
38         LSA_HANDLE_ACCOUNT,
39         LSA_HANDLE_SECRET
40 };
41
42 /*
43   state associated with a lsa_OpenPolicy() operation
44 */
45 struct lsa_policy_state {
46         struct dcesrv_handle *handle;
47         struct ldb_wrap *sam_ctx;
48         struct sidmap_context *sidmap;
49         uint32_t access_mask;
50         const char *domain_dn;
51         const char *builtin_dn;
52         const char *system_dn;
53         const char *domain_name;
54         struct dom_sid *domain_sid;
55         struct dom_sid *builtin_sid;
56 };
57
58
59 /*
60   state associated with a lsa_OpenAccount() operation
61 */
62 struct lsa_account_state {
63         struct lsa_policy_state *policy;
64         uint32_t access_mask;
65         struct dom_sid *account_sid;
66         const char *account_sid_str;
67         const char *account_dn;
68 };
69
70
71 /*
72   state associated with a lsa_OpenSecret() operation
73 */
74 struct lsa_secret_state {
75         struct lsa_policy_state *policy;
76         uint32_t access_mask;
77         const char *secret_dn;
78         struct ldb_wrap *sam_ctx;
79 };
80
81 /* 
82   lsa_Close 
83 */
84 static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
85                           struct lsa_Close *r)
86 {
87         struct dcesrv_handle *h;
88
89         *r->out.handle = *r->in.handle;
90
91         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
92
93         talloc_free(h);
94
95         ZERO_STRUCTP(r->out.handle);
96
97         return NT_STATUS_OK;
98 }
99
100
101 /* 
102   lsa_Delete 
103 */
104 static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
105                            struct lsa_Delete *r)
106 {
107         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
108 }
109
110
111 /* 
112   lsa_EnumPrivs 
113 */
114 static NTSTATUS lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
115                               struct lsa_EnumPrivs *r)
116 {
117         struct dcesrv_handle *h;
118         struct lsa_policy_state *state;
119         int i;
120         const char *privname;
121
122         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
123
124         state = h->data;
125
126         i = *r->in.resume_handle;
127         if (i == 0) i = 1;
128
129         while ((privname = sec_privilege_name(i)) &&
130                r->out.privs->count < r->in.max_count) {
131                 struct lsa_PrivEntry *e;
132
133                 r->out.privs->privs = talloc_realloc_p(r->out.privs,
134                                                        r->out.privs->privs, 
135                                                        struct lsa_PrivEntry, 
136                                                        r->out.privs->count+1);
137                 if (r->out.privs->privs == NULL) {
138                         return NT_STATUS_NO_MEMORY;
139                 }
140                 e = &r->out.privs->privs[r->out.privs->count];
141                 e->luid.low = i;
142                 e->luid.high = 0;
143                 e->name.string = privname;
144                 r->out.privs->count++;
145                 i++;
146         }
147
148         *r->out.resume_handle = i;
149
150         return NT_STATUS_OK;
151 }
152
153
154 /* 
155   lsa_QuerySecObj 
156 */
157 static NTSTATUS lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
158                                   struct lsa_QuerySecurity *r)
159 {
160         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
161 }
162
163
164 /* 
165   lsa_SetSecObj 
166 */
167 static NTSTATUS lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
168                               struct lsa_SetSecObj *r)
169 {
170         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
171 }
172
173
174 /* 
175   lsa_ChangePassword 
176 */
177 static NTSTATUS lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
178                                    struct lsa_ChangePassword *r)
179 {
180         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
181 }
182
183 static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
184                                      struct lsa_policy_state **_state)
185 {
186         struct lsa_policy_state *state;
187         const char *sid_str;
188
189         state = talloc_p(mem_ctx, struct lsa_policy_state);
190         if (!state) {
191                 return NT_STATUS_NO_MEMORY;
192         }
193
194         /* make sure the sam database is accessible */
195         state->sam_ctx = samdb_connect(state);
196         if (state->sam_ctx == NULL) {
197                 talloc_free(state);
198                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
199         }
200
201         state->sidmap = sidmap_open(state);
202         if (state->sidmap == NULL) {
203                 talloc_free(state);
204                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
205         }
206
207         /* work out the domain_dn - useful for so many calls its worth
208            fetching here */
209         state->domain_dn = samdb_search_string(state->sam_ctx, state, NULL,
210                                                "dn", "(&(objectClass=domain)(!(objectclass=builtinDomain)))");
211         if (!state->domain_dn) {
212                 talloc_free(state);
213                 return NT_STATUS_NO_SUCH_DOMAIN;                
214         }
215
216         /* work out the builtin_dn - useful for so many calls its worth
217            fetching here */
218         state->builtin_dn = samdb_search_string(state->sam_ctx, state, NULL,
219                                                 "dn", "objectClass=builtinDomain");
220         if (!state->builtin_dn) {
221                 talloc_free(state);
222                 return NT_STATUS_NO_SUCH_DOMAIN;                
223         }
224
225         /* work out the system_dn - useful for so many calls its worth
226            fetching here */
227         state->system_dn = samdb_search_string(state->sam_ctx, state, state->domain_dn,
228                                                "dn", "(&(objectClass=container)(cn=System))");
229         if (!state->system_dn) {
230                 talloc_free(state);
231                 return NT_STATUS_NO_SUCH_DOMAIN;                
232         }
233
234         sid_str = samdb_search_string(state->sam_ctx, state, NULL,
235                                       "objectSid", "dn=%s", state->domain_dn);
236         if (!sid_str) {
237                 talloc_free(state);
238                 return NT_STATUS_NO_SUCH_DOMAIN;                
239         }
240
241         state->domain_sid = dom_sid_parse_talloc(state, sid_str);
242         if (!state->domain_sid) {
243                 talloc_free(state);
244                 return NT_STATUS_NO_SUCH_DOMAIN;                
245         }
246
247         state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
248         if (!state->builtin_sid) {
249                 talloc_free(state);
250                 return NT_STATUS_NO_SUCH_DOMAIN;                
251         }
252
253         state->domain_name = samdb_search_string(state->sam_ctx, state, NULL,
254                                                  "name", "dn=%s", state->domain_dn);
255         if (!state->domain_name) {
256                 talloc_free(state);
257                 return NT_STATUS_NO_SUCH_DOMAIN;                
258         }
259
260         *_state = state;
261
262         return NT_STATUS_OK;
263 }
264
265 /* 
266   lsa_OpenPolicy2
267 */
268 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
269                                struct lsa_OpenPolicy2 *r)
270 {
271         NTSTATUS status;
272         struct lsa_policy_state *state;
273         struct dcesrv_handle *handle;
274
275         ZERO_STRUCTP(r->out.handle);
276
277         status = lsa_get_policy_state(dce_call, mem_ctx, &state);
278         if (!NT_STATUS_IS_OK(status)) {
279                 return status;
280         }
281
282         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
283         if (!handle) {
284                 return NT_STATUS_NO_MEMORY;
285         }
286
287         handle->data = talloc_steal(handle, state);
288
289         state->access_mask = r->in.access_mask;
290         state->handle = handle;
291         *r->out.handle = handle->wire_handle;
292
293         /* note that we have completely ignored the attr element of
294            the OpenPolicy. As far as I can tell, this is what w2k3
295            does */
296
297         return NT_STATUS_OK;
298 }
299
300 /* 
301   lsa_OpenPolicy
302   a wrapper around lsa_OpenPolicy2
303 */
304 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
305                                 struct lsa_OpenPolicy *r)
306 {
307         struct lsa_OpenPolicy2 r2;
308
309         r2.in.system_name = NULL;
310         r2.in.attr = r->in.attr;
311         r2.in.access_mask = r->in.access_mask;
312         r2.out.handle = r->out.handle;
313
314         return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
315 }
316
317
318
319
320 /*
321   fill in the AccountDomain info
322 */
323 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
324                                        struct lsa_DomainInfo *info)
325 {
326         const char * const attrs[] = { "objectSid", "name", NULL};
327         int ret;
328         struct ldb_message **res;
329
330         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
331                            "dn=%s", state->domain_dn);
332         if (ret != 1) {
333                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
334         }
335
336         info->name.string = samdb_result_string(res[0], "name", NULL);
337         info->sid         = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
338
339         return NT_STATUS_OK;
340 }
341
342 /*
343   fill in the DNS domain info
344 */
345 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
346                              struct lsa_DnsDomainInfo *info)
347 {
348         const char * const attrs[] = { "name", "dnsDomain", "objectGUID", "objectSid", NULL };
349         int ret;
350         struct ldb_message **res;
351
352         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
353                            "dn=%s", state->domain_dn);
354         if (ret != 1) {
355                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
356         }
357
358         info->name.string       = samdb_result_string(res[0],           "name", NULL);
359         info->dns_domain.string = samdb_result_string(res[0],           "dnsDomain", NULL);
360         info->dns_forest.string = samdb_result_string(res[0],           "dnsDomain", NULL);
361         info->domain_guid       = samdb_result_guid(res[0],             "objectGUID");
362         info->sid               = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
363
364         return NT_STATUS_OK;
365 }
366
367 /* 
368   lsa_QueryInfoPolicy2
369 */
370 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
371                                      struct lsa_QueryInfoPolicy2 *r)
372 {
373         struct lsa_policy_state *state;
374         struct dcesrv_handle *h;
375
376         r->out.info = NULL;
377
378         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
379
380         state = h->data;
381
382         r->out.info = talloc_p(mem_ctx, union lsa_PolicyInformation);
383         if (!r->out.info) {
384                 return NT_STATUS_NO_MEMORY;
385         }
386
387         ZERO_STRUCTP(r->out.info);
388
389         switch (r->in.level) {
390         case LSA_POLICY_INFO_DOMAIN:
391         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
392                 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
393
394         case LSA_POLICY_INFO_DNS:
395                 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
396         }
397
398         return NT_STATUS_INVALID_INFO_CLASS;
399 }
400
401 /* 
402   lsa_QueryInfoPolicy 
403 */
404 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
405                                     struct lsa_QueryInfoPolicy *r)
406 {
407         struct lsa_QueryInfoPolicy2 r2;
408         NTSTATUS status;
409
410         r2.in.handle = r->in.handle;
411         r2.in.level = r->in.level;
412         
413         status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
414
415         r->out.info = r2.out.info;
416
417         return status;
418 }
419
420 /* 
421   lsa_SetInfoPolicy 
422 */
423 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
424                                   struct lsa_SetInfoPolicy *r)
425 {
426         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
427 }
428
429
430 /* 
431   lsa_ClearAuditLog 
432 */
433 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
434                                   struct lsa_ClearAuditLog *r)
435 {
436         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
437 }
438
439
440 /* 
441   lsa_CreateAccount 
442 */
443 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
444                                   struct lsa_CreateAccount *r)
445 {
446         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
447 }
448
449
450 /* 
451   lsa_EnumAccounts 
452 */
453 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
454                                  struct lsa_EnumAccounts *r)
455 {
456         struct dcesrv_handle *h;
457         struct lsa_policy_state *state;
458         int ret, i;
459         struct ldb_message **res;
460         const char * const attrs[] = { "objectSid", NULL};
461         uint32_t count;
462
463         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
464
465         state = h->data;
466
467         ret = samdb_search(state->sam_ctx, mem_ctx, state->builtin_dn, &res, attrs, 
468                            "privilege=*");
469         if (ret <= 0) {
470                 return NT_STATUS_NO_SUCH_USER;
471         }
472
473         if (*r->in.resume_handle >= ret) {
474                 return NT_STATUS_NO_MORE_ENTRIES;
475         }
476
477         count = ret - *r->in.resume_handle;
478         if (count > r->in.num_entries) {
479                 count = r->in.num_entries;
480         }
481
482         if (count == 0) {
483                 return NT_STATUS_NO_MORE_ENTRIES;
484         }
485
486         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_SidPtr, count);
487         if (r->out.sids->sids == NULL) {
488                 return NT_STATUS_NO_MEMORY;
489         }
490
491         for (i=0;i<count;i++) {
492                 const char *sidstr;
493
494                 sidstr = samdb_result_string(res[i + *r->in.resume_handle], "objectSid", NULL);
495                 if (sidstr == NULL) {
496                         return NT_STATUS_NO_MEMORY;
497                 }
498                 r->out.sids->sids[i].sid = dom_sid_parse_talloc(r->out.sids->sids, sidstr);
499                 if (r->out.sids->sids[i].sid == NULL) {
500                         return NT_STATUS_NO_MEMORY;
501                 }
502         }
503
504         r->out.sids->num_sids = count;
505         *r->out.resume_handle = count + *r->in.resume_handle;
506
507         return NT_STATUS_OK;
508         
509 }
510
511
512 /* 
513   lsa_CreateTrustedDomain 
514 */
515 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
516                                         struct lsa_CreateTrustedDomain *r)
517 {
518         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
519 }
520
521
522 /* 
523   lsa_EnumTrustDom 
524 */
525 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
526                        struct lsa_EnumTrustDom *r)
527 {
528         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
529 }
530
531
532 /*
533   return the authority name and authority sid, given a sid
534 */
535 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
536                                    TALLOC_CTX *mem_ctx, struct dom_sid *sid,
537                                    const char **authority_name,
538                                    struct dom_sid **authority_sid)
539 {
540         if (dom_sid_in_domain(state->domain_sid, sid)) {
541                 *authority_name = state->domain_name;
542                 *authority_sid = state->domain_sid;
543                 return NT_STATUS_OK;
544         }
545
546         if (dom_sid_in_domain(state->builtin_sid, sid)) {
547                 *authority_name = "BUILTIN";
548                 *authority_sid = state->builtin_sid;
549                 return NT_STATUS_OK;
550         }
551
552         *authority_sid = dom_sid_dup(mem_ctx, sid);
553         if (*authority_sid == NULL) {
554                 return NT_STATUS_NO_MEMORY;
555         }
556         (*authority_sid)->num_auths = 0;
557         *authority_name = dom_sid_string(mem_ctx, *authority_sid);
558         if (*authority_name == NULL) {
559                 return NT_STATUS_NO_MEMORY;
560         }
561
562         return NT_STATUS_OK;
563 }
564
565 /*
566   add to the lsa_RefDomainList for LookupSids and LookupNames
567 */
568 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, 
569                                    struct dom_sid *sid, 
570                                    struct lsa_RefDomainList *domains,
571                                    uint32_t *sid_index)
572 {
573         NTSTATUS status;
574         const char *authority_name;
575         struct dom_sid *authority_sid;
576         int i;
577
578         /* work out the authority name */
579         status = lsa_authority_name(state, mem_ctx, sid, 
580                                     &authority_name, &authority_sid);
581         if (!NT_STATUS_IS_OK(status)) {
582                 return status;
583         }
584         
585         /* see if we've already done this authority name */
586         for (i=0;i<domains->count;i++) {
587                 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
588                         *sid_index = i;
589                         return NT_STATUS_OK;
590                 }
591         }
592
593         domains->domains = talloc_realloc_p(domains, 
594                                             domains->domains,
595                                             struct lsa_TrustInformation,
596                                             domains->count+1);
597         if (domains->domains == NULL) {
598                 return NT_STATUS_NO_MEMORY;
599         }
600         domains->domains[i].name.string = authority_name;
601         domains->domains[i].sid         = authority_sid;
602         domains->count++;
603         *sid_index = i;
604         
605         return NT_STATUS_OK;
606 }
607
608 /*
609   lookup a name for 1 SID
610 */
611 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
612                                struct dom_sid *sid, const char *sid_str,
613                                const char **name, uint32_t *atype)
614 {
615         int ret;
616         struct ldb_message **res;
617         const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
618         NTSTATUS status;
619
620         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
621                            "objectSid=%s", sid_str);
622         if (ret == 1) {
623                 *name = ldb_msg_find_string(res[0], "sAMAccountName", NULL);
624                 if (!*name) {
625                         *name = ldb_msg_find_string(res[0], "name", NULL);
626                         if (!*name) {
627                                 *name = talloc_strdup(mem_ctx, sid_str);
628                                 NTSTATUS_TALLOC_CHECK(*name);
629                         }
630                 }
631
632                 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
633
634                 return NT_STATUS_OK;
635         }
636
637         status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
638
639         return status;
640 }
641
642
643 /*
644   lsa_LookupSids3
645 */
646 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
647                                 TALLOC_CTX *mem_ctx,
648                                 struct lsa_LookupSids3 *r)
649 {
650         struct lsa_policy_state *state;
651         int i;
652         NTSTATUS status = NT_STATUS_OK;
653
654         r->out.domains = NULL;
655
656         status = lsa_get_policy_state(dce_call, mem_ctx, &state);
657         if (!NT_STATUS_IS_OK(status)) {
658                 return status;
659         }
660
661         r->out.domains = talloc_zero_p(mem_ctx,  struct lsa_RefDomainList);
662         if (r->out.domains == NULL) {
663                 return NT_STATUS_NO_MEMORY;
664         }
665
666         r->out.names = talloc_zero_p(mem_ctx,  struct lsa_TransNameArray2);
667         if (r->out.names == NULL) {
668                 return NT_STATUS_NO_MEMORY;
669         }
670
671         *r->out.count = 0;
672
673         r->out.names->names = talloc_array_p(r->out.names, struct lsa_TranslatedName2, 
674                                              r->in.sids->num_sids);
675         if (r->out.names->names == NULL) {
676                 return NT_STATUS_NO_MEMORY;
677         }
678
679         for (i=0;i<r->in.sids->num_sids;i++) {
680                 struct dom_sid *sid = r->in.sids->sids[i].sid;
681                 char *sid_str = dom_sid_string(mem_ctx, sid);
682                 const char *name;
683                 uint32_t atype, rtype, sid_index;
684                 NTSTATUS status2;
685
686                 r->out.names->count++;
687                 (*r->out.count)++;
688
689                 r->out.names->names[i].sid_type    = SID_NAME_UNKNOWN;
690                 r->out.names->names[i].name.string = sid_str;
691                 r->out.names->names[i].sid_index   = 0xFFFFFFFF;
692                 r->out.names->names[i].unknown     = 0;
693
694                 if (sid_str == NULL) {
695                         r->out.names->names[i].name.string = "(SIDERROR)";
696                         status = STATUS_SOME_UNMAPPED;
697                         continue;
698                 }
699
700                 /* work out the authority name */
701                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
702                 if (!NT_STATUS_IS_OK(status2)) {
703                         return status2;
704                 }
705
706                 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str, 
707                                          &name, &atype);
708                 if (!NT_STATUS_IS_OK(status2)) {
709                         status = STATUS_SOME_UNMAPPED;
710                         continue;
711                 }
712
713                 rtype = samdb_atype_map(atype);
714                 if (rtype == SID_NAME_UNKNOWN) {
715                         status = STATUS_SOME_UNMAPPED;
716                         continue;
717                 }
718
719                 r->out.names->names[i].sid_type    = rtype;
720                 r->out.names->names[i].name.string = name;
721                 r->out.names->names[i].sid_index   = sid_index;
722                 r->out.names->names[i].unknown     = 0;
723         }
724         
725         return status;
726 }
727
728
729 /*
730   lsa_LookupSids2
731 */
732 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
733                                 TALLOC_CTX *mem_ctx,
734                                 struct lsa_LookupSids2 *r)
735 {
736         struct lsa_LookupSids3 r3;
737         NTSTATUS status;
738
739         r3.in.sids     = r->in.sids;
740         r3.in.names    = r->in.names;
741         r3.in.level    = r->in.level;
742         r3.in.count    = r->in.count;
743         r3.in.unknown1 = r->in.unknown1;
744         r3.in.unknown2 = r->in.unknown2;
745         r3.out.count   = r->out.count;
746         r3.out.names   = r->out.names;
747
748         status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
749         if (dce_call->fault_code != 0) {
750                 return status;
751         }
752
753         r->out.domains = r3.out.domains;
754         r->out.names   = r3.out.names;
755         r->out.count   = r3.out.count;
756
757         return status;
758 }
759
760
761 /* 
762   lsa_LookupSids 
763 */
764 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
765                                struct lsa_LookupSids *r)
766 {
767         struct lsa_LookupSids3 r3;
768         NTSTATUS status;
769         int i;
770
771         r3.in.sids     = r->in.sids;
772         r3.in.names    = NULL;
773         r3.in.level    = r->in.level;
774         r3.in.count    = r->in.count;
775         r3.in.unknown1 = 0;
776         r3.in.unknown2 = 0;
777         r3.out.count   = r->out.count;
778
779         status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
780         if (dce_call->fault_code != 0) {
781                 return status;
782         }
783
784         r->out.domains = r3.out.domains;
785         r->out.names = talloc_p(mem_ctx, struct lsa_TransNameArray);
786         if (r->out.names == NULL) {
787                 return NT_STATUS_NO_MEMORY;
788         }
789         r->out.names->count = r3.out.names->count;
790         r->out.names->names = talloc_array_p(r->out.names, struct lsa_TranslatedName, 
791                                              r->out.names->count);
792         if (r->out.names->names == NULL) {
793                 return NT_STATUS_NO_MEMORY;
794         }
795         for (i=0;i<r->out.names->count;i++) {
796                 r->out.names->names[i].sid_type    = r3.out.names->names[i].sid_type;
797                 r->out.names->names[i].name.string = r3.out.names->names[i].name.string;
798                 r->out.names->names[i].sid_index   = r3.out.names->names[i].sid_index;
799         }
800
801         return status;
802 }
803
804
805 /* 
806   lsa_OpenAccount 
807 */
808 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
809                                 struct lsa_OpenAccount *r)
810 {
811         struct dcesrv_handle *h, *ah;
812         struct lsa_policy_state *state;
813         struct lsa_account_state *astate;
814
815         ZERO_STRUCTP(r->out.acct_handle);
816
817         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
818
819         state = h->data;
820
821         astate = talloc_p(dce_call->conn, struct lsa_account_state);
822         if (astate == NULL) {
823                 return NT_STATUS_NO_MEMORY;
824         }
825
826         astate->account_sid = dom_sid_dup(astate, r->in.sid);
827         if (astate->account_sid == NULL) {
828                 talloc_free(astate);
829                 return NT_STATUS_NO_MEMORY;
830         }
831         
832         astate->account_sid_str = dom_sid_string(astate, astate->account_sid);
833         if (astate->account_sid_str == NULL) {
834                 talloc_free(astate);
835                 return NT_STATUS_NO_MEMORY;
836         }
837
838         /* check it really exists */
839         astate->account_dn = samdb_search_string(state->sam_ctx, astate,
840                                                  NULL, "dn", 
841                                                  "(&(objectSid=%s)(objectClass=group))", 
842                                                  astate->account_sid_str);
843         if (astate->account_dn == NULL) {
844                 talloc_free(astate);
845                 return NT_STATUS_NO_SUCH_USER;
846         }
847         
848         astate->policy = talloc_reference(astate, state);
849         astate->access_mask = r->in.access_mask;
850
851         ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
852         if (!ah) {
853                 talloc_free(astate);
854                 return NT_STATUS_NO_MEMORY;
855         }
856
857         ah->data = talloc_steal(ah, astate);
858
859         *r->out.acct_handle = ah->wire_handle;
860
861         return NT_STATUS_OK;
862 }
863
864
865 /* 
866   lsa_EnumPrivsAccount 
867 */
868 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 
869                                      TALLOC_CTX *mem_ctx,
870                                      struct lsa_EnumPrivsAccount *r)
871 {
872         struct dcesrv_handle *h;
873         struct lsa_account_state *astate;
874         int ret, i;
875         struct ldb_message **res;
876         const char * const attrs[] = { "privilege", NULL};
877         struct ldb_message_element *el;
878
879         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
880
881         astate = h->data;
882
883         r->out.privs = talloc_p(mem_ctx, struct lsa_PrivilegeSet);
884         r->out.privs->count = 0;
885         r->out.privs->unknown = 0;
886         r->out.privs->set = NULL;
887
888         ret = samdb_search(astate->policy->sam_ctx, mem_ctx, NULL, &res, attrs, 
889                            "dn=%s", astate->account_dn);
890         if (ret != 1) {
891                 return NT_STATUS_OK;
892         }
893
894         el = ldb_msg_find_element(res[0], "privilege");
895         if (el == NULL || el->num_values == 0) {
896                 return NT_STATUS_OK;
897         }
898
899         r->out.privs->set = talloc_array_p(r->out.privs, 
900                                            struct lsa_LUIDAttribute, el->num_values);
901         if (r->out.privs->set == NULL) {
902                 return NT_STATUS_NO_MEMORY;
903         }
904
905         for (i=0;i<el->num_values;i++) {
906                 int id = sec_privilege_id(el->values[i].data);
907                 if (id == -1) {
908                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
909                 }
910                 r->out.privs->set[i].attribute = 0;
911                 r->out.privs->set[i].luid.low = id;
912                 r->out.privs->set[i].luid.high = 0;
913         }
914
915         r->out.privs->count = el->num_values;
916
917         return NT_STATUS_OK;
918 }
919
920 /* 
921   lsa_EnumAccountRights 
922 */
923 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
924                                       TALLOC_CTX *mem_ctx,
925                                       struct lsa_EnumAccountRights *r)
926 {
927         struct dcesrv_handle *h;
928         struct lsa_policy_state *state;
929         int ret, i;
930         struct ldb_message **res;
931         const char * const attrs[] = { "privilege", NULL};
932         const char *sidstr;
933         struct ldb_message_element *el;
934
935         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
936
937         state = h->data;
938
939         sidstr = dom_sid_string(mem_ctx, r->in.sid);
940         if (sidstr == NULL) {
941                 return NT_STATUS_NO_MEMORY;
942         }
943
944         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
945                            "objectSid=%s", sidstr);
946         if (ret != 1) {
947                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
948         }
949
950         el = ldb_msg_find_element(res[0], "privilege");
951         if (el == NULL || el->num_values == 0) {
952                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
953         }
954
955         r->out.rights->count = el->num_values;
956         r->out.rights->names = talloc_array_p(r->out.rights, 
957                                               struct lsa_String, r->out.rights->count);
958         if (r->out.rights->names == NULL) {
959                 return NT_STATUS_NO_MEMORY;
960         }
961
962         for (i=0;i<el->num_values;i++) {
963                 r->out.rights->names[i].string = el->values[i].data;
964         }
965
966         return NT_STATUS_OK;
967 }
968
969
970
971 /* 
972   helper for lsa_AddAccountRights and lsa_RemoveAccountRights
973 */
974 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
975                                            TALLOC_CTX *mem_ctx,
976                                            struct lsa_policy_state *state,
977                                            int ldb_flag,
978                                            struct dom_sid *sid,
979                                            const struct lsa_RightSet *rights)
980 {
981         const char *sidstr;
982         struct ldb_message msg;
983         struct ldb_message_element el;
984         int i, ret;
985         const char *dn;
986         struct lsa_EnumAccountRights r2;
987
988         sidstr = dom_sid_string(mem_ctx, sid);
989         if (sidstr == NULL) {
990                 return NT_STATUS_NO_MEMORY;
991         }
992
993         dn = samdb_search_string(state->sam_ctx, mem_ctx, NULL, "dn", 
994                                  "objectSid=%s", sidstr);
995         if (dn == NULL) {
996                 return NT_STATUS_NO_SUCH_USER;
997         }
998
999         msg.dn = talloc_strdup(mem_ctx, dn);
1000         if (msg.dn == NULL) {
1001                 return NT_STATUS_NO_MEMORY;
1002         }
1003         msg.num_elements = 1;
1004         msg.elements = &el;
1005         el.flags = ldb_flag;
1006         el.name = talloc_strdup(mem_ctx, "privilege");
1007         if (el.name == NULL) {
1008                 return NT_STATUS_NO_MEMORY;
1009         }
1010
1011         if (ldb_flag == LDB_FLAG_MOD_ADD) {
1012                 NTSTATUS status;
1013
1014                 r2.in.handle = &state->handle->wire_handle;
1015                 r2.in.sid = sid;
1016                 r2.out.rights = talloc_p(mem_ctx, struct lsa_RightSet);
1017
1018                 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1019                 if (!NT_STATUS_IS_OK(status)) {
1020                         ZERO_STRUCTP(r2.out.rights);
1021                 }
1022         }
1023
1024         el.num_values = 0;
1025         el.values = talloc_array_p(mem_ctx, struct ldb_val, rights->count);
1026         if (el.values == NULL) {
1027                 return NT_STATUS_NO_MEMORY;
1028         }
1029         for (i=0;i<rights->count;i++) {
1030                 if (sec_privilege_id(rights->names[i].string) == -1) {
1031                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1032                 }
1033
1034                 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1035                         int j;
1036                         for (j=0;j<r2.out.rights->count;j++) {
1037                                 if (StrCaseCmp(r2.out.rights->names[j].string, 
1038                                                rights->names[i].string) == 0) {
1039                                         break;
1040                                 }
1041                         }
1042                         if (j != r2.out.rights->count) continue;
1043                 }
1044
1045
1046                 el.values[el.num_values].length = strlen(rights->names[i].string);
1047                 el.values[el.num_values].data = talloc_strdup(mem_ctx, rights->names[i].string);
1048                 if (el.values[el.num_values].data == NULL) {
1049                         return NT_STATUS_NO_MEMORY;
1050                 }
1051                 el.num_values++;
1052         }
1053
1054         if (el.num_values == 0) {
1055                 return NT_STATUS_OK;
1056         }
1057
1058         ret = samdb_modify(state->sam_ctx, mem_ctx, &msg);
1059         if (ret != 0) {
1060                 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1061                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1062                 }
1063                 return NT_STATUS_UNEXPECTED_IO_ERROR;
1064         }
1065
1066         return NT_STATUS_OK;
1067 }
1068
1069 /* 
1070   lsa_AddPrivilegesToAccount
1071 */
1072 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1073                                            struct lsa_AddPrivilegesToAccount *r)
1074 {
1075         struct lsa_RightSet rights;
1076         struct dcesrv_handle *h;
1077         struct lsa_account_state *astate;
1078         int i;
1079
1080         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1081
1082         astate = h->data;
1083
1084         rights.count = r->in.privs->count;
1085         rights.names = talloc_array_p(mem_ctx, struct lsa_String, rights.count);
1086         if (rights.names == NULL) {
1087                 return NT_STATUS_NO_MEMORY;
1088         }
1089         for (i=0;i<rights.count;i++) {
1090                 int id = r->in.privs->set[i].luid.low;
1091                 if (r->in.privs->set[i].luid.high) {
1092                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1093                 }
1094                 rights.names[i].string = sec_privilege_name(id);
1095                 if (rights.names[i].string == NULL) {
1096                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1097                 }
1098         }
1099
1100         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1101                                           LDB_FLAG_MOD_ADD, astate->account_sid,
1102                                           &rights);
1103 }
1104
1105
1106 /* 
1107   lsa_RemovePrivilegesFromAccount
1108 */
1109 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1110                                                 struct lsa_RemovePrivilegesFromAccount *r)
1111 {
1112         struct lsa_RightSet *rights;
1113         struct dcesrv_handle *h;
1114         struct lsa_account_state *astate;
1115         int i;
1116
1117         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1118
1119         astate = h->data;
1120
1121         rights = talloc_p(mem_ctx, struct lsa_RightSet);
1122
1123         if (r->in.remove_all == 1 && 
1124             r->in.privs == NULL) {
1125                 struct lsa_EnumAccountRights r2;
1126                 NTSTATUS status;
1127
1128                 r2.in.handle = &astate->policy->handle->wire_handle;
1129                 r2.in.sid = astate->account_sid;
1130                 r2.out.rights = rights;
1131
1132                 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1133                 if (!NT_STATUS_IS_OK(status)) {
1134                         return status;
1135                 }
1136
1137                 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1138                                                   LDB_FLAG_MOD_DELETE, astate->account_sid,
1139                                                   r2.out.rights);
1140         }
1141
1142         if (r->in.remove_all != 0) {
1143                 return NT_STATUS_INVALID_PARAMETER;
1144         }
1145
1146         rights->count = r->in.privs->count;
1147         rights->names = talloc_array_p(mem_ctx, struct lsa_String, rights->count);
1148         if (rights->names == NULL) {
1149                 return NT_STATUS_NO_MEMORY;
1150         }
1151         for (i=0;i<rights->count;i++) {
1152                 int id = r->in.privs->set[i].luid.low;
1153                 if (r->in.privs->set[i].luid.high) {
1154                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1155                 }
1156                 rights->names[i].string = sec_privilege_name(id);
1157                 if (rights->names[i].string == NULL) {
1158                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1159                 }
1160         }
1161
1162         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1163                                           LDB_FLAG_MOD_DELETE, astate->account_sid,
1164                                           rights);
1165 }
1166
1167
1168 /* 
1169   lsa_GetQuotasForAccount
1170 */
1171 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1172                        struct lsa_GetQuotasForAccount *r)
1173 {
1174         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1175 }
1176
1177
1178 /* 
1179   lsa_SetQuotasForAccount
1180 */
1181 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1182                        struct lsa_SetQuotasForAccount *r)
1183 {
1184         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1185 }
1186
1187
1188 /* 
1189   lsa_GetSystemAccessAccount
1190 */
1191 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1192                        struct lsa_GetSystemAccessAccount *r)
1193 {
1194         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1195 }
1196
1197
1198 /* 
1199   lsa_SetSystemAccessAccount
1200 */
1201 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1202                        struct lsa_SetSystemAccessAccount *r)
1203 {
1204         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1205 }
1206
1207
1208 /* 
1209   lsa_OpenTrustedDomain
1210 */
1211 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1212                        struct lsa_OpenTrustedDomain *r)
1213 {
1214         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1215 }
1216
1217
1218 /* 
1219   lsa_QueryTrustedDomainInfo
1220 */
1221 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1222                        struct lsa_QueryTrustedDomainInfo *r)
1223 {
1224         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1225 }
1226
1227
1228 /* 
1229   lsa_SetInformationTrustedDomain
1230 */
1231 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1232                        struct lsa_SetInformationTrustedDomain *r)
1233 {
1234         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1235 }
1236
1237
1238 /* 
1239   lsa_CreateSecret 
1240 */
1241 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1242                                  struct lsa_CreateSecret *r)
1243 {
1244         struct dcesrv_handle *policy_handle;
1245         struct lsa_policy_state *policy_state;
1246         struct lsa_secret_state *secret_state;
1247         struct dcesrv_handle *handle;
1248         struct ldb_message **msgs, *msg;
1249         const char *attrs[] = {
1250                 NULL
1251         };
1252
1253         const char *name;
1254
1255         int ret;
1256
1257         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1258         ZERO_STRUCTP(r->out.sec_handle);
1259         
1260         policy_state = policy_handle->data;
1261
1262         if (!r->in.name.string) {
1263                 return NT_STATUS_INVALID_PARAMETER;
1264         }
1265         
1266         secret_state = talloc(mem_ctx, struct lsa_secret_state);
1267         if (!secret_state) {
1268                 return NT_STATUS_NO_MEMORY;
1269         }
1270
1271         msg = ldb_msg_new(mem_ctx);
1272         if (msg == NULL) {
1273                 return NT_STATUS_NO_MEMORY;
1274         }
1275
1276         if (strncmp("G$", r->in.name.string, 2) == 0) {
1277                 const char *name2;
1278                 name = &r->in.name.string[2];
1279                 secret_state->sam_ctx = talloc_reference(secret_state, policy_state->sam_ctx);
1280
1281                 if (strlen(name) < 1) {
1282                         return NT_STATUS_INVALID_PARAMETER;
1283                 }
1284
1285                 name2 = talloc_asprintf(mem_ctx, "%s Secret", name);
1286                 /* search for the secret record */
1287                 ret = samdb_search(secret_state->sam_ctx,
1288                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
1289                                    "(&(cn=%s)(objectclass=secret))", 
1290                                    name2);
1291                 if (ret > 0) {
1292                         return NT_STATUS_OBJECT_NAME_COLLISION;
1293                 }
1294                 
1295                 if (ret < 0 || ret > 1) {
1296                         DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1297                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1298                 }
1299
1300                 msg->dn = talloc_asprintf(mem_ctx, "cn=%s,%s", name2, policy_state->system_dn);
1301                 if (!name2 || !msg->dn) {
1302                         return NT_STATUS_NO_MEMORY;
1303                 }
1304                 
1305                 samdb_msg_add_string(secret_state->sam_ctx, mem_ctx, msg, "cn", name2);
1306         
1307         } else {
1308                 name = r->in.name.string;
1309                 if (strlen(name) < 1) {
1310                         return NT_STATUS_INVALID_PARAMETER;
1311                 }
1312
1313                 secret_state->sam_ctx = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1314                 /* search for the secret record */
1315                 ret = samdb_search(secret_state->sam_ctx,
1316                                    mem_ctx, "cn=LSA Secrets", &msgs, attrs,
1317                                    "(&(cn=%s)(objectclass=secret))", 
1318                                    name);
1319                 if (ret > 0) {
1320                         return NT_STATUS_OBJECT_NAME_COLLISION;
1321                 }
1322                 
1323                 if (ret < 0 || ret > 1) {
1324                         DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1325                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1326                 }
1327
1328                 msg->dn = talloc_asprintf(mem_ctx, "cn=%s,cn=LSA Secrets", name);
1329                 samdb_msg_add_string(secret_state->sam_ctx, mem_ctx, msg, "cn", name);
1330         } 
1331         samdb_msg_add_string(secret_state->sam_ctx, mem_ctx, msg, "objectClass", "secret");
1332         
1333         secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1334
1335         /* create the secret */
1336         ret = samdb_add(secret_state->sam_ctx, mem_ctx, msg);
1337         if (ret != 0) {
1338                 DEBUG(0,("Failed to create secret record %s\n", msg->dn));
1339                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1340         }
1341
1342         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1343         if (!handle) {
1344                 return NT_STATUS_NO_MEMORY;
1345         }
1346         
1347         handle->data = talloc_steal(handle, secret_state);
1348         
1349         secret_state->access_mask = r->in.access_mask;
1350         secret_state->policy = talloc_reference(secret_state, policy_state);
1351         
1352         *r->out.sec_handle = handle->wire_handle;
1353         
1354         return NT_STATUS_OK;
1355 }
1356
1357
1358 /* 
1359   lsa_OpenSecret 
1360 */
1361 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1362                                struct lsa_OpenSecret *r)
1363 {
1364         struct dcesrv_handle *policy_handle;
1365         
1366         struct lsa_policy_state *policy_state;
1367         struct lsa_secret_state *secret_state;
1368         struct dcesrv_handle *handle;
1369         struct ldb_message **msgs;
1370         const char *attrs[] = {
1371                 NULL
1372         };
1373
1374         const char *name;
1375
1376         int ret;
1377
1378         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1379         ZERO_STRUCTP(r->out.sec_handle);
1380         policy_state = policy_handle->data;
1381
1382         if (!r->in.name.string) {
1383                 return NT_STATUS_INVALID_PARAMETER;
1384         }
1385         
1386         secret_state = talloc(mem_ctx, struct lsa_secret_state);
1387         if (!secret_state) {
1388                 return NT_STATUS_NO_MEMORY;
1389         }
1390
1391         if (strncmp("G$", r->in.name.string, 2) == 0) {
1392                 name = &r->in.name.string[2];
1393                 secret_state->sam_ctx = talloc_reference(secret_state, policy_state->sam_ctx);
1394
1395                 if (strlen(name) < 1) {
1396                         return NT_STATUS_INVALID_PARAMETER;
1397                 }
1398
1399                 /* search for the secret record */
1400                 ret = samdb_search(secret_state->sam_ctx,
1401                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
1402                                    "(&(cn=%s Secret)(objectclass=secret))", 
1403                                    name);
1404                 if (ret == 0) {
1405                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1406                 }
1407                 
1408                 if (ret != 1) {
1409                         DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1410                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1411                 }
1412         
1413         } else {
1414                 name = r->in.name.string;
1415                 if (strlen(name) < 1) {
1416                         return NT_STATUS_INVALID_PARAMETER;
1417                 }
1418
1419                 secret_state->sam_ctx = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1420                 /* search for the secret record */
1421                 ret = samdb_search(secret_state->sam_ctx,
1422                                    mem_ctx, "cn=LSA Secrets", &msgs, attrs,
1423                                    "(&(cn=%s)(objectclass=secret))", 
1424                                    name);
1425                 if (ret == 0) {
1426                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1427                 }
1428                 
1429                 if (ret != 1) {
1430                         DEBUG(0,("Found %d records matching DN %s\n", ret, policy_state->system_dn));
1431                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1432                 }
1433         } 
1434
1435         secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1436         
1437         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1438         if (!handle) {
1439                 return NT_STATUS_NO_MEMORY;
1440         }
1441         
1442         handle->data = talloc_steal(handle, secret_state);
1443         
1444         secret_state->access_mask = r->in.access_mask;
1445         secret_state->policy = talloc_reference(secret_state, policy_state);
1446         
1447         *r->out.sec_handle = handle->wire_handle;
1448         
1449         return NT_STATUS_OK;
1450 }
1451
1452
1453 /* 
1454   lsa_SetSecret 
1455 */
1456 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1457                               struct lsa_SetSecret *r)
1458 {
1459
1460         struct dcesrv_handle *h;
1461         struct lsa_secret_state *secret_state;
1462         struct ldb_message *msg;
1463         DATA_BLOB session_key;
1464         DATA_BLOB crypt_secret, secret;
1465         struct ldb_val val;
1466         int ret;
1467         NTSTATUS status = NT_STATUS_OK;
1468
1469         struct timeval now = timeval_current();
1470         NTTIME nt_now = timeval_to_nttime(&now);
1471
1472         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1473
1474         secret_state = h->data;
1475
1476         msg = ldb_msg_new(mem_ctx);
1477         if (msg == NULL) {
1478                 return NT_STATUS_NO_MEMORY;
1479         }
1480
1481         msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1482         if (!msg->dn) {
1483                 return NT_STATUS_NO_MEMORY;
1484         }
1485         status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1486         if (!NT_STATUS_IS_OK(status)) {
1487                 return status;
1488         }
1489
1490         if (r->in.old_val) {
1491                 /* Decrypt */
1492                 crypt_secret.data = r->in.old_val->data;
1493                 crypt_secret.length = r->in.old_val->size;
1494                 
1495                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1496                 if (!NT_STATUS_IS_OK(status)) {
1497                         return status;
1498                 }
1499                 
1500                 val.data = secret.data;
1501                 val.length = secret.length;
1502                 
1503                 /* set value */
1504                 if (samdb_msg_add_value(secret_state->sam_ctx, 
1505                                         mem_ctx, msg, "priorSecret", &val) != 0) {
1506                         return NT_STATUS_NO_MEMORY; 
1507                 }
1508                 
1509                 /* set old value mtime */
1510                 if (samdb_msg_add_uint64(secret_state->sam_ctx, 
1511                                          mem_ctx, msg, "priorSetTime", nt_now) != 0) { 
1512                         return NT_STATUS_NO_MEMORY; 
1513                 }
1514         }
1515
1516         if (r->in.new_val) {
1517                 /* Decrypt */
1518                 crypt_secret.data = r->in.new_val->data;
1519                 crypt_secret.length = r->in.new_val->size;
1520                 
1521                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1522                 if (!NT_STATUS_IS_OK(status)) {
1523                         return status;
1524                 }
1525                 
1526                 val.data = secret.data;
1527                 val.length = secret.length;
1528                 
1529                 /* set value */
1530                 if (samdb_msg_add_value(secret_state->sam_ctx, 
1531                                         mem_ctx, msg, "secret", &val) != 0) {
1532                         return NT_STATUS_NO_MEMORY; 
1533                 }
1534                 
1535                 /* set new value mtime */
1536                 if (samdb_msg_add_uint64(secret_state->sam_ctx, 
1537                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
1538                         return NT_STATUS_NO_MEMORY; 
1539                 }
1540                 
1541                 /* If the old value is not set, then migrate the
1542                  * current value to the old value */
1543                 if (!r->in.old_val) {
1544                         const struct ldb_val *new_val;
1545                         NTTIME last_set_time;
1546                         struct ldb_message **res;
1547                         const char *attrs[] = {
1548                                 "secret",
1549                                 "lastSetTime",
1550                                 NULL
1551                         };
1552                         
1553                         /* search for the secret record */
1554                         ret = samdb_search(secret_state->sam_ctx,
1555                                            mem_ctx, NULL, &res, attrs,
1556                                            "(dn=%s)", secret_state->secret_dn);
1557                         if (ret == 0) {
1558                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1559                         }
1560                         
1561                         if (ret != 1) {
1562                                 DEBUG(0,("Found %d records matching dn=%s\n", ret, secret_state->secret_dn));
1563                                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1564                         }
1565
1566                         new_val = ldb_msg_find_ldb_val(res[0], "secret");
1567                         last_set_time = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
1568                         
1569                         if (new_val) {
1570                                 /* set value */
1571                                 if (samdb_msg_add_value(secret_state->sam_ctx, 
1572                                                         mem_ctx, msg, "priorSecret", 
1573                                                         new_val) != 0) {
1574                                         return NT_STATUS_NO_MEMORY; 
1575                                 }
1576                         }
1577                         
1578                         /* set new value mtime */
1579                         if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
1580                                 if (samdb_msg_add_uint64(secret_state->sam_ctx, 
1581                                                          mem_ctx, msg, "priorSetTime", last_set_time) != 0) { 
1582                                         return NT_STATUS_NO_MEMORY; 
1583                                 }
1584                         }
1585                 }
1586         }
1587
1588         /* modify the samdb record */
1589         ret = samdb_replace(secret_state->sam_ctx, mem_ctx, msg);
1590         if (ret != 0) {
1591                 /* we really need samdb.c to return NTSTATUS */
1592                 return NT_STATUS_UNSUCCESSFUL;
1593         }
1594
1595         return NT_STATUS_OK;
1596 }
1597
1598
1599 /* 
1600   lsa_QuerySecret 
1601 */
1602 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1603                                 struct lsa_QuerySecret *r)
1604 {
1605         struct dcesrv_handle *h;
1606         struct lsa_secret_state *secret_state;
1607         struct ldb_message *msg;
1608         DATA_BLOB session_key;
1609         DATA_BLOB crypt_secret, secret;
1610         int ret;
1611         struct ldb_message **res;
1612         const char *attrs[] = {
1613                 "secret",
1614                 "priorSecret",
1615                 "lastSetTime",
1616                 "priorSetTime", 
1617                 NULL
1618         };
1619
1620         NTSTATUS nt_status;
1621
1622         time_t now = time(NULL);
1623         NTTIME now_nt;
1624         unix_to_nt_time(&now_nt, now);
1625
1626         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1627
1628         secret_state = h->data;
1629
1630         /* pull all the user attributes */
1631         ret = samdb_search(secret_state->sam_ctx, mem_ctx, NULL, &res, attrs,
1632                            "dn=%s", secret_state->secret_dn);
1633         if (ret != 1) {
1634                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1635         }
1636         msg = res[0];
1637         
1638         nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1639         if (!NT_STATUS_IS_OK(nt_status)) {
1640                 return nt_status;
1641         }
1642         
1643         if (r->in.old_val) {
1644                 const struct ldb_val *prior_val;
1645                 /* Decrypt */
1646                 prior_val = ldb_msg_find_ldb_val(res[0], "priorSecret");
1647                 
1648                 if (prior_val && prior_val->length) {
1649                         secret.data = prior_val->data;
1650                         secret.length = prior_val->length;
1651                 
1652                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
1653                         if (!crypt_secret.length) {
1654                                 return NT_STATUS_NO_MEMORY;
1655                         }
1656                         r->out.old_val = talloc(mem_ctx, struct lsa_DATA_BUF_PTR);
1657                         r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
1658                         r->out.old_val->buf->size = crypt_secret.length;
1659                         r->out.old_val->buf->length = crypt_secret.length;
1660                         r->out.old_val->buf->data = crypt_secret.data;
1661                 }
1662         }
1663         
1664         if (r->in.old_mtime) {
1665                 r->out.old_mtime = talloc(mem_ctx, NTTIME_hyper);
1666                 if (!r->out.old_mtime) {
1667                         return NT_STATUS_NO_MEMORY;
1668                 }
1669                 *r->out.old_mtime = ldb_msg_find_uint64(res[0], "priorSetTime", 0);
1670         }
1671         
1672         if (r->in.new_val) {
1673                 const struct ldb_val *new_val;
1674                 /* Decrypt */
1675                 new_val = ldb_msg_find_ldb_val(res[0], "secret");
1676                 
1677                 if (new_val && new_val->length) {
1678                         secret.data = new_val->data;
1679                         secret.length = new_val->length;
1680                 
1681                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
1682                         if (!crypt_secret.length) {
1683                                 return NT_STATUS_NO_MEMORY;
1684                         }
1685                         r->out.new_val = talloc(mem_ctx, struct lsa_DATA_BUF_PTR);
1686                         r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
1687                         r->out.new_val->buf->length = crypt_secret.length;
1688                         r->out.new_val->buf->size = crypt_secret.length;
1689                         r->out.new_val->buf->data = crypt_secret.data;
1690                 }
1691         }
1692         
1693         if (r->in.new_mtime) {
1694                 r->out.new_mtime = talloc(mem_ctx, NTTIME_hyper);
1695                 if (!r->out.new_mtime) {
1696                         return NT_STATUS_NO_MEMORY;
1697                 }
1698                 *r->out.new_mtime = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
1699         }
1700         
1701         return NT_STATUS_OK;
1702 }
1703
1704
1705 /* 
1706   lsa_LookupPrivValue
1707 */
1708 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
1709                                     TALLOC_CTX *mem_ctx,
1710                                     struct lsa_LookupPrivValue *r)
1711 {
1712         struct dcesrv_handle *h;
1713         struct lsa_policy_state *state;
1714         int id;
1715
1716         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1717
1718         state = h->data;
1719
1720         id = sec_privilege_id(r->in.name->string);
1721         if (id == -1) {
1722                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1723         }
1724
1725         r->out.luid->low = id;
1726         r->out.luid->high = 0;
1727
1728         return NT_STATUS_OK;    
1729 }
1730
1731
1732 /* 
1733   lsa_LookupPrivName 
1734 */
1735 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
1736                                    TALLOC_CTX *mem_ctx,
1737                                    struct lsa_LookupPrivName *r)
1738 {
1739         struct dcesrv_handle *h;
1740         struct lsa_policy_state *state;
1741         const char *privname;
1742
1743         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1744
1745         state = h->data;
1746
1747         if (r->in.luid->high != 0) {
1748                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1749         }
1750
1751         privname = sec_privilege_name(r->in.luid->low);
1752         if (privname == NULL) {
1753                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1754         }
1755
1756         r->out.name = talloc_p(mem_ctx, struct lsa_String);
1757         if (r->out.name == NULL) {
1758                 return NT_STATUS_NO_MEMORY;
1759         }
1760         r->out.name->string = privname;
1761
1762         return NT_STATUS_OK;    
1763 }
1764
1765
1766 /* 
1767   lsa_LookupPrivDisplayName
1768 */
1769 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
1770                                           TALLOC_CTX *mem_ctx,
1771                                           struct lsa_LookupPrivDisplayName *r)
1772 {
1773         struct dcesrv_handle *h;
1774         struct lsa_policy_state *state;
1775         int id;
1776
1777         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1778
1779         state = h->data;
1780
1781         id = sec_privilege_id(r->in.name->string);
1782         if (id == -1) {
1783                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1784         }
1785         
1786         r->out.disp_name = talloc_p(mem_ctx, struct lsa_String);
1787         if (r->out.disp_name == NULL) {
1788                 return NT_STATUS_NO_MEMORY;
1789         }
1790
1791         r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
1792         if (r->out.disp_name->string == NULL) {
1793                 return NT_STATUS_INTERNAL_ERROR;
1794         }
1795
1796         return NT_STATUS_OK;
1797 }
1798
1799
1800 /* 
1801   lsa_DeleteObject
1802 */
1803 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1804                        struct lsa_DeleteObject *r)
1805 {
1806         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1807 }
1808
1809
1810 /* 
1811   lsa_EnumAccountsWithUserRight
1812 */
1813 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
1814                                               TALLOC_CTX *mem_ctx,
1815                                               struct lsa_EnumAccountsWithUserRight *r)
1816 {
1817         struct dcesrv_handle *h;
1818         struct lsa_policy_state *state;
1819         int ret, i;
1820         struct ldb_message **res;
1821         const char * const attrs[] = { "objectSid", NULL};
1822         const char *privname;
1823
1824         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1825
1826         state = h->data;
1827
1828         if (r->in.name == NULL) {
1829                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1830         } 
1831
1832         privname = r->in.name->string;
1833         if (sec_privilege_id(privname) == -1) {
1834                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1835         }
1836
1837         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
1838                            "privilege=%s", privname);
1839         if (ret <= 0) {
1840                 return NT_STATUS_NO_SUCH_USER;
1841         }
1842
1843         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_SidPtr, ret);
1844         if (r->out.sids->sids == NULL) {
1845                 return NT_STATUS_NO_MEMORY;
1846         }
1847         for (i=0;i<ret;i++) {
1848                 const char *sidstr;
1849                 sidstr = samdb_result_string(res[i], "objectSid", NULL);
1850                 if (sidstr == NULL) {
1851                         return NT_STATUS_NO_MEMORY;
1852                 }
1853                 r->out.sids->sids[i].sid = dom_sid_parse_talloc(r->out.sids->sids,
1854                                                                 sidstr);
1855                 if (r->out.sids->sids[i].sid == NULL) {
1856                         return NT_STATUS_NO_MEMORY;
1857                 }
1858         }
1859         r->out.sids->num_sids = ret;
1860
1861         return NT_STATUS_OK;
1862 }
1863
1864
1865 /* 
1866   lsa_AddAccountRights
1867 */
1868 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
1869                                      TALLOC_CTX *mem_ctx,
1870                                      struct lsa_AddAccountRights *r)
1871 {
1872         struct dcesrv_handle *h;
1873         struct lsa_policy_state *state;
1874
1875         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1876
1877         state = h->data;
1878
1879         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
1880                                           LDB_FLAG_MOD_ADD,
1881                                           r->in.sid, r->in.rights);
1882 }
1883
1884
1885 /* 
1886   lsa_RemoveAccountRights
1887 */
1888 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
1889                                         TALLOC_CTX *mem_ctx,
1890                                         struct lsa_RemoveAccountRights *r)
1891 {
1892         struct dcesrv_handle *h;
1893         struct lsa_policy_state *state;
1894
1895         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1896
1897         state = h->data;
1898
1899         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
1900                                           LDB_FLAG_MOD_DELETE,
1901                                           r->in.sid, r->in.rights);
1902 }
1903
1904
1905 /* 
1906   lsa_QueryTrustedDomainInfoBySid
1907 */
1908 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1909                                                 struct lsa_QueryTrustedDomainInfoBySid *r)
1910 {
1911         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1912 }
1913
1914
1915 /* 
1916   lsa_SetTrustDomainInfo
1917 */
1918 static NTSTATUS lsa_SetTrustDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1919                        struct lsa_SetTrustDomainInfo *r)
1920 {
1921         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1922 }
1923
1924
1925 /* 
1926   lsa_DeleteTrustDomain
1927 */
1928 static NTSTATUS lsa_DeleteTrustDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1929                        struct lsa_DeleteTrustDomain *r)
1930 {
1931         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1932 }
1933
1934
1935 /* 
1936   lsa_StorePrivateData
1937 */
1938 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1939                        struct lsa_StorePrivateData *r)
1940 {
1941         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1942 }
1943
1944
1945 /* 
1946   lsa_RetrievePrivateData
1947 */
1948 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1949                        struct lsa_RetrievePrivateData *r)
1950 {
1951         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1952 }
1953
1954
1955 /* 
1956   lsa_GetUserName
1957 */
1958 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1959                        struct lsa_GetUserName *r)
1960 {
1961         NTSTATUS status = NT_STATUS_OK;
1962         const char *account_name;
1963         const char *authority_name;
1964         struct lsa_String *_account_name;
1965         struct lsa_StringPointer *_authority_name = NULL;
1966
1967         /* this is what w2k3 does */
1968         r->out.account_name = r->in.account_name;
1969         r->out.authority_name = r->in.authority_name;
1970
1971         if (r->in.account_name && r->in.account_name->string) {
1972                 return NT_STATUS_INVALID_PARAMETER;
1973         }
1974
1975         if (r->in.authority_name &&
1976             r->in.authority_name->string &&
1977             r->in.authority_name->string->string) {
1978                 return NT_STATUS_INVALID_PARAMETER;
1979         }
1980
1981         /* TODO: this check should go and we should rely on the calling code that this is valid */
1982         if (!dce_call->conn->auth_state.session_info ||
1983             !dce_call->conn->auth_state.session_info->server_info ||
1984             !dce_call->conn->auth_state.session_info->server_info->account_name ||
1985             !dce_call->conn->auth_state.session_info->server_info->domain_name) {
1986                 return NT_STATUS_INTERNAL_ERROR;
1987         }
1988
1989         account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
1990         authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
1991
1992         _account_name = talloc_p(mem_ctx, struct lsa_String);
1993         NTSTATUS_TALLOC_CHECK(_account_name);
1994         _account_name->string = account_name;
1995
1996         if (r->in.authority_name) {
1997                 _authority_name = talloc_p(mem_ctx, struct lsa_StringPointer);
1998                 NTSTATUS_TALLOC_CHECK(_authority_name);
1999                 _authority_name->string = talloc_p(mem_ctx, struct lsa_String);
2000                 NTSTATUS_TALLOC_CHECK(_authority_name->string);
2001                 _authority_name->string->string = authority_name;
2002         }
2003
2004         r->out.account_name = _account_name;
2005         r->out.authority_name = _authority_name;
2006
2007         return status;
2008 }
2009
2010 /*
2011   lsa_SetInfoPolicy2
2012 */
2013 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2014                                    TALLOC_CTX *mem_ctx,
2015                                    struct lsa_SetInfoPolicy2 *r)
2016 {
2017         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2018 }
2019
2020 /*
2021   lsa_QueryTrustedDomainInfoByName
2022 */
2023 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2024                                                  TALLOC_CTX *mem_ctx,
2025                                                  struct lsa_QueryTrustedDomainInfoByName *r)
2026 {
2027         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2028 }
2029
2030 /*
2031   lsa_SetTrustedDomainInfoByName
2032 */
2033 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2034                                                TALLOC_CTX *mem_ctx,
2035                                                struct lsa_SetTrustedDomainInfoByName *r)
2036 {
2037         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2038 }
2039
2040 /*
2041   lsa_EnumTrustedDomainsEx
2042 */
2043 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call,
2044                                          TALLOC_CTX *mem_ctx,
2045                                          struct lsa_EnumTrustedDomainsEx *r)
2046 {
2047         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2048 }
2049
2050 /*
2051   lsa_CreateTrustedDomainEx
2052 */
2053 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
2054                                           TALLOC_CTX *mem_ctx,
2055                                           struct lsa_CreateTrustedDomainEx *r)
2056 {
2057         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2058 }
2059
2060 /*
2061   lsa_CloseTrustedDomainEx
2062 */
2063 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
2064                                          TALLOC_CTX *mem_ctx,
2065                                          struct lsa_CloseTrustedDomainEx *r)
2066 {
2067         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2068 }
2069
2070 /*
2071   lsa_QueryDomainInformationPolicy
2072 */
2073 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2074                                                  TALLOC_CTX *mem_ctx,
2075                                                  struct lsa_QueryDomainInformationPolicy *r)
2076 {
2077         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2078 }
2079
2080 /*
2081   lsa_SetDomInfoPolicy
2082 */
2083 static NTSTATUS lsa_SetDomInfoPolicy(struct dcesrv_call_state *dce_call,
2084                                      TALLOC_CTX *mem_ctx,
2085                                      struct lsa_SetDomInfoPolicy *r)
2086 {
2087         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2088 }
2089
2090 /*
2091   lsa_OpenTrustedDomainByName
2092 */
2093 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
2094                                             TALLOC_CTX *mem_ctx,
2095                                             struct lsa_OpenTrustedDomainByName *r)
2096 {
2097         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2098 }
2099
2100 /*
2101   lsa_TestCall
2102 */
2103 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2104                              TALLOC_CTX *mem_ctx,
2105                              struct lsa_TestCall *r)
2106 {
2107         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2108 }
2109
2110 /*
2111   lookup a SID for 1 name
2112 */
2113 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2114                                 const char *name, struct dom_sid **sid, uint32_t *atype)
2115 {
2116         int ret;
2117         struct ldb_message **res;
2118         const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2119         const char *p;
2120
2121         p = strchr_m(name, '\\');
2122         if (p != NULL) {
2123                 /* TODO: properly parse the domain prefix here, and use it to 
2124                    limit the search */
2125                 name = p + 1;
2126         }
2127
2128         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", name);
2129         if (ret == 1) {
2130                 const char *sid_str = ldb_msg_find_string(res[0], "objectSid", NULL);
2131                 if (sid_str == NULL) {
2132                         return NT_STATUS_INVALID_SID;
2133                 }
2134
2135                 *sid = dom_sid_parse_talloc(mem_ctx, sid_str);
2136                 if (*sid == NULL) {
2137                         return NT_STATUS_INVALID_SID;
2138                 }
2139
2140                 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
2141
2142                 return NT_STATUS_OK;
2143         }
2144
2145         /* need to add a call into sidmap to check for a allocated sid */
2146
2147         return NT_STATUS_INVALID_SID;
2148 }
2149
2150
2151 /*
2152   lsa_LookupNames3
2153 */
2154 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call,
2155                                  TALLOC_CTX *mem_ctx,
2156                                  struct lsa_LookupNames3 *r)
2157 {
2158         struct lsa_policy_state *state;
2159         struct dcesrv_handle *h;
2160         int i;
2161         NTSTATUS status = NT_STATUS_OK;
2162
2163         r->out.domains = NULL;
2164
2165         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2166
2167         state = h->data;
2168
2169         r->out.domains = talloc_zero_p(mem_ctx,  struct lsa_RefDomainList);
2170         if (r->out.domains == NULL) {
2171                 return NT_STATUS_NO_MEMORY;
2172         }
2173
2174         r->out.sids = talloc_zero_p(mem_ctx,  struct lsa_TransSidArray3);
2175         if (r->out.sids == NULL) {
2176                 return NT_STATUS_NO_MEMORY;
2177         }
2178
2179         *r->out.count = 0;
2180
2181         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid3, 
2182                                            r->in.num_names);
2183         if (r->out.sids->sids == NULL) {
2184                 return NT_STATUS_NO_MEMORY;
2185         }
2186
2187         for (i=0;i<r->in.num_names;i++) {
2188                 const char *name = r->in.names[i].string;
2189                 struct dom_sid *sid;
2190                 uint32_t atype, rtype, sid_index;
2191                 NTSTATUS status2;
2192
2193                 r->out.sids->count++;
2194                 (*r->out.count)++;
2195
2196                 r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
2197                 r->out.sids->sids[i].sid         = NULL;
2198                 r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
2199                 r->out.sids->sids[i].unknown     = 0;
2200
2201                 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2202                 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2203                         status = STATUS_SOME_UNMAPPED;
2204                         continue;
2205                 }
2206
2207                 rtype = samdb_atype_map(atype);
2208                 if (rtype == SID_NAME_UNKNOWN) {
2209                         status = STATUS_SOME_UNMAPPED;
2210                         continue;
2211                 }
2212
2213                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2214                 if (!NT_STATUS_IS_OK(status2)) {
2215                         return status2;
2216                 }
2217
2218                 r->out.sids->sids[i].sid_type    = rtype;
2219                 r->out.sids->sids[i].sid         = sid;
2220                 r->out.sids->sids[i].sid_index   = sid_index;
2221                 r->out.sids->sids[i].unknown     = 0;
2222         }
2223         
2224         return status;
2225 }
2226
2227 /*
2228   lsa_LookupNames2
2229 */
2230 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
2231                                  TALLOC_CTX *mem_ctx,
2232                                  struct lsa_LookupNames2 *r)
2233 {
2234         struct lsa_policy_state *state;
2235         struct dcesrv_handle *h;
2236         int i;
2237         NTSTATUS status = NT_STATUS_OK;
2238
2239         r->out.domains = NULL;
2240
2241         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2242
2243         state = h->data;
2244
2245         r->out.domains = talloc_zero_p(mem_ctx,  struct lsa_RefDomainList);
2246         if (r->out.domains == NULL) {
2247                 return NT_STATUS_NO_MEMORY;
2248         }
2249
2250         r->out.sids = talloc_zero_p(mem_ctx,  struct lsa_TransSidArray2);
2251         if (r->out.sids == NULL) {
2252                 return NT_STATUS_NO_MEMORY;
2253         }
2254
2255         *r->out.count = 0;
2256
2257         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid2, 
2258                                            r->in.num_names);
2259         if (r->out.sids->sids == NULL) {
2260                 return NT_STATUS_NO_MEMORY;
2261         }
2262
2263         for (i=0;i<r->in.num_names;i++) {
2264                 const char *name = r->in.names[i].string;
2265                 struct dom_sid *sid;
2266                 uint32_t atype, rtype, sid_index;
2267                 NTSTATUS status2;
2268
2269                 r->out.sids->count++;
2270                 (*r->out.count)++;
2271
2272                 r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
2273                 r->out.sids->sids[i].rid         = 0xFFFFFFFF;
2274                 r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
2275                 r->out.sids->sids[i].unknown     = 0;
2276
2277                 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2278                 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2279                         status = STATUS_SOME_UNMAPPED;
2280                         continue;
2281                 }
2282
2283                 rtype = samdb_atype_map(atype);
2284                 if (rtype == SID_NAME_UNKNOWN) {
2285                         status = STATUS_SOME_UNMAPPED;
2286                         continue;
2287                 }
2288
2289                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2290                 if (!NT_STATUS_IS_OK(status2)) {
2291                         return status2;
2292                 }
2293
2294                 r->out.sids->sids[i].sid_type    = rtype;
2295                 r->out.sids->sids[i].rid         = sid->sub_auths[sid->num_auths-1];
2296                 r->out.sids->sids[i].sid_index   = sid_index;
2297                 r->out.sids->sids[i].unknown     = 0;
2298         }
2299         
2300         return status;
2301 }
2302
2303 /* 
2304   lsa_LookupNames 
2305 */
2306 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2307                        struct lsa_LookupNames *r)
2308 {
2309         struct lsa_LookupNames2 r2;
2310         NTSTATUS status;
2311         int i;
2312
2313         r2.in.handle    = r->in.handle;
2314         r2.in.num_names = r->in.num_names;
2315         r2.in.names     = r->in.names;
2316         r2.in.sids      = NULL;
2317         r2.in.level     = r->in.level;
2318         r2.in.count     = r->in.count;
2319         r2.in.unknown1  = 0;
2320         r2.in.unknown2  = 0;
2321         r2.out.count    = r->out.count;
2322
2323         status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
2324         if (dce_call->fault_code != 0) {
2325                 return status;
2326         }
2327
2328         r->out.domains = r2.out.domains;
2329         r->out.sids = talloc_p(mem_ctx, struct lsa_TransSidArray);
2330         if (r->out.sids == NULL) {
2331                 return NT_STATUS_NO_MEMORY;
2332         }
2333         r->out.sids->count = r2.out.sids->count;
2334         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid, 
2335                                            r->out.sids->count);
2336         if (r->out.sids->sids == NULL) {
2337                 return NT_STATUS_NO_MEMORY;
2338         }
2339         for (i=0;i<r->out.sids->count;i++) {
2340                 r->out.sids->sids[i].sid_type    = r2.out.sids->sids[i].sid_type;
2341                 r->out.sids->sids[i].rid         = r2.out.sids->sids[i].rid;
2342                 r->out.sids->sids[i].sid_index   = r2.out.sids->sids[i].sid_index;
2343         }
2344
2345         return status;
2346 }
2347
2348
2349
2350 /*
2351   lsa_CreateTrustedDomainEx2
2352 */
2353 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
2354                                            TALLOC_CTX *mem_ctx,
2355                                            struct lsa_CreateTrustedDomainEx2 *r)
2356 {
2357         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2358 }
2359
2360 /* 
2361   lsa_CREDRWRITE 
2362 */
2363 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2364                        struct lsa_CREDRWRITE *r)
2365 {
2366         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2367 }
2368
2369
2370 /* 
2371   lsa_CREDRREAD 
2372 */
2373 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2374                        struct lsa_CREDRREAD *r)
2375 {
2376         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2377 }
2378
2379
2380 /* 
2381   lsa_CREDRENUMERATE 
2382 */
2383 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2384                        struct lsa_CREDRENUMERATE *r)
2385 {
2386         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2387 }
2388
2389
2390 /* 
2391   lsa_CREDRWRITEDOMAINCREDENTIALS 
2392 */
2393 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2394                        struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2395 {
2396         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2397 }
2398
2399
2400 /* 
2401   lsa_CREDRREADDOMAINCREDENTIALS 
2402 */
2403 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2404                        struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2405 {
2406         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2407 }
2408
2409
2410 /* 
2411   lsa_CREDRDELETE 
2412 */
2413 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2414                        struct lsa_CREDRDELETE *r)
2415 {
2416         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2417 }
2418
2419
2420 /* 
2421   lsa_CREDRGETTARGETINFO 
2422 */
2423 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2424                        struct lsa_CREDRGETTARGETINFO *r)
2425 {
2426         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2427 }
2428
2429
2430 /* 
2431   lsa_CREDRPROFILELOADED 
2432 */
2433 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2434                        struct lsa_CREDRPROFILELOADED *r)
2435 {
2436         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2437 }
2438
2439
2440 /* 
2441   lsa_CREDRGETSESSIONTYPES 
2442 */
2443 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2444                        struct lsa_CREDRGETSESSIONTYPES *r)
2445 {
2446         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2447 }
2448
2449
2450 /* 
2451   lsa_LSARREGISTERAUDITEVENT 
2452 */
2453 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2454                        struct lsa_LSARREGISTERAUDITEVENT *r)
2455 {
2456         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2457 }
2458
2459
2460 /* 
2461   lsa_LSARGENAUDITEVENT 
2462 */
2463 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2464                        struct lsa_LSARGENAUDITEVENT *r)
2465 {
2466         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2467 }
2468
2469
2470 /* 
2471   lsa_LSARUNREGISTERAUDITEVENT 
2472 */
2473 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2474                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
2475 {
2476         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2477 }
2478
2479
2480 /* 
2481   lsa_LSARQUERYFORESTTRUSTINFORMATION 
2482 */
2483 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2484                        struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
2485 {
2486         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2487 }
2488
2489
2490 /* 
2491   lsa_LSARSETFORESTTRUSTINFORMATION 
2492 */
2493 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2494                        struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2495 {
2496         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2497 }
2498
2499
2500 /* 
2501   lsa_CREDRRENAME 
2502 */
2503 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2504                        struct lsa_CREDRRENAME *r)
2505 {
2506         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2507 }
2508
2509
2510 /* 
2511   lsa_LSARLOOKUPNAMES4 
2512 */
2513 static NTSTATUS lsa_LSARLOOKUPNAMES4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2514                        struct lsa_LSARLOOKUPNAMES4 *r)
2515 {
2516         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2517 }
2518
2519
2520 /* 
2521   lsa_LSAROPENPOLICYSCE 
2522 */
2523 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2524                        struct lsa_LSAROPENPOLICYSCE *r)
2525 {
2526         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2527 }
2528
2529
2530 /* 
2531   lsa_LSARADTREGISTERSECURITYEVENTSOURCE 
2532 */
2533 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2534                        struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2535 {
2536         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2537 }
2538
2539
2540 /* 
2541   lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE 
2542 */
2543 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2544                        struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2545 {
2546         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2547 }
2548
2549
2550 /* 
2551   lsa_LSARADTREPORTSECURITYEVENT 
2552 */
2553 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2554                        struct lsa_LSARADTREPORTSECURITYEVENT *r)
2555 {
2556         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2557 }
2558
2559
2560 /* include the generated boilerplate */
2561 #include "librpc/gen_ndr/ndr_lsa_s.c"