9f205d6ef029f0ba6be2f7dbae76fca276fb275b
[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    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "librpc/gen_ndr/ndr_lsa.h"
25 #include "librpc/gen_ndr/ndr_samr.h"
26 #include "rpc_server/dcerpc_server.h"
27 #include "rpc_server/common/common.h"
28 #include "lib/ldb/include/ldb.h"
29
30 /*
31   this type allows us to distinguish handle types
32 */
33 enum lsa_handle {
34         LSA_HANDLE_POLICY,
35         LSA_HANDLE_ACCOUNT,
36         LSA_HANDLE_SECRET
37 };
38
39 /*
40   state associated with a lsa_OpenPolicy() operation
41 */
42 struct lsa_policy_state {
43         void *sam_ctx;
44         struct sidmap_context *sidmap;
45         uint32_t access_mask;
46         const char *domain_dn;
47         const char *domain_name;
48         struct dom_sid *domain_sid;
49         struct dom_sid *builtin_sid;
50 };
51
52
53 /*
54   destroy an open policy. This closes the database connection
55 */
56 static void lsa_Policy_destroy(struct dcesrv_connection *conn, struct dcesrv_handle *h)
57 {
58         struct lsa_policy_state *state = h->data;
59         talloc_free(state);
60 }
61
62 /* 
63   lsa_Close 
64 */
65 static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
66                           struct lsa_Close *r)
67 {
68         struct dcesrv_handle *h;
69
70         *r->out.handle = *r->in.handle;
71
72         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
73
74         /* this causes the callback samr_XXX_destroy() to be called by
75            the handle destroy code which destroys the state associated
76            with the handle */
77         dcesrv_handle_destroy(dce_call->conn, h);
78
79         ZERO_STRUCTP(r->out.handle);
80
81         return NT_STATUS_OK;
82 }
83
84
85 /* 
86   lsa_Delete 
87 */
88 static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
89                            struct lsa_Delete *r)
90 {
91         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
92 }
93
94
95 /* 
96   lsa_EnumPrivs 
97 */
98 static NTSTATUS lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
99                               struct lsa_EnumPrivs *r)
100 {
101         struct dcesrv_handle *h;
102         struct lsa_policy_state *state;
103         int i;
104         const char *privname;
105
106         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
107
108         state = h->data;
109
110         i = *r->in.resume_handle;
111         if (i == 0) i = 1;
112
113         while ((privname = sec_privilege_name(i)) &&
114                r->out.privs->count < r->in.max_count) {
115                 struct lsa_PrivEntry *e;
116
117                 r->out.privs->privs = talloc_realloc_p(r->out.privs,
118                                                        r->out.privs->privs, 
119                                                        struct lsa_PrivEntry, 
120                                                        r->out.privs->count+1);
121                 if (r->out.privs->privs == NULL) {
122                         return NT_STATUS_NO_MEMORY;
123                 }
124                 e = &r->out.privs->privs[r->out.privs->count];
125                 e->luid.low = i;
126                 e->luid.high = 0;
127                 e->name.string = privname;
128                 r->out.privs->count++;
129                 i++;
130         }
131
132         *r->in.resume_handle = i;
133
134         return NT_STATUS_OK;
135 }
136
137
138 /* 
139   lsa_QuerySecObj 
140 */
141 static NTSTATUS lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
142                                   struct lsa_QuerySecurity *r)
143 {
144         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
145 }
146
147
148 /* 
149   lsa_SetSecObj 
150 */
151 static NTSTATUS lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
152                               struct lsa_SetSecObj *r)
153 {
154         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
155 }
156
157
158 /* 
159   lsa_ChangePassword 
160 */
161 static NTSTATUS lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
162                                    struct lsa_ChangePassword *r)
163 {
164         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
165 }
166
167
168 /* 
169   lsa_OpenPolicy2
170 */
171 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
172                                struct lsa_OpenPolicy2 *r)
173 {
174         struct lsa_policy_state *state;
175         struct dcesrv_handle *handle;
176         const char *sid_str;
177
178         ZERO_STRUCTP(r->out.handle);
179
180         state = talloc_p(dce_call->conn, struct lsa_policy_state);
181         if (!state) {
182                 return NT_STATUS_NO_MEMORY;
183         }
184
185         /* make sure the sam database is accessible */
186         state->sam_ctx = samdb_connect(state);
187         if (state->sam_ctx == NULL) {
188                 talloc_free(state);
189                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
190         }
191
192         state->sidmap = sidmap_open(state);
193         if (state->sidmap == NULL) {
194                 talloc_free(state);
195                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
196         }
197
198         /* work out the domain_dn - useful for so many calls its worth
199            fetching here */
200         state->domain_dn = samdb_search_string(state->sam_ctx, state, NULL,
201                                                "dn", "(&(objectClass=domain)(!(objectclass=builtinDomain)))");
202         if (!state->domain_dn) {
203                 talloc_free(state);
204                 return NT_STATUS_NO_SUCH_DOMAIN;                
205         }
206
207         sid_str = samdb_search_string(state->sam_ctx, state, NULL,
208                                       "objectSid", "dn=%s", state->domain_dn);
209         if (!sid_str) {
210                 talloc_free(state);
211                 return NT_STATUS_NO_SUCH_DOMAIN;                
212         }
213
214         state->domain_sid = dom_sid_parse_talloc(state, sid_str);
215         if (!state->domain_sid) {
216                 talloc_free(state);
217                 return NT_STATUS_NO_SUCH_DOMAIN;                
218         }
219
220         state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
221         if (!state->builtin_sid) {
222                 talloc_free(state);
223                 return NT_STATUS_NO_SUCH_DOMAIN;                
224         }
225
226         state->domain_name = samdb_search_string(state->sam_ctx, state, NULL,
227                                                  "name", "dn=%s", state->domain_dn);
228         if (!state->domain_name) {
229                 talloc_free(state);
230                 return NT_STATUS_NO_SUCH_DOMAIN;                
231         }
232         
233
234         handle = dcesrv_handle_new(dce_call->conn, LSA_HANDLE_POLICY);
235         if (!handle) {
236                 talloc_free(state);
237                 return NT_STATUS_NO_MEMORY;
238         }
239
240         handle->data = state;
241         handle->destroy = lsa_Policy_destroy;
242
243         state->access_mask = r->in.access_mask;
244         *r->out.handle = handle->wire_handle;
245
246         /* note that we have completely ignored the attr element of
247            the OpenPolicy. As far as I can tell, this is what w2k3
248            does */
249
250         return NT_STATUS_OK;
251 }
252
253 /* 
254   lsa_OpenPolicy
255   a wrapper around lsa_OpenPolicy2
256 */
257 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
258                                 struct lsa_OpenPolicy *r)
259 {
260         struct lsa_OpenPolicy2 r2;
261
262         r2.in.system_name = NULL;
263         r2.in.attr = r->in.attr;
264         r2.in.access_mask = r->in.access_mask;
265         r2.out.handle = r->out.handle;
266
267         return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
268 }
269
270
271
272
273 /*
274   fill in the AccountDomain info
275 */
276 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
277                                        struct lsa_DomainInfo *info)
278 {
279         const char * const attrs[] = { "objectSid", "name", NULL};
280         int ret;
281         struct ldb_message **res;
282
283         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
284                            "dn=%s", state->domain_dn);
285         if (ret != 1) {
286                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
287         }
288
289         info->name.string = samdb_result_string(res[0], "name", NULL);
290         info->sid         = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
291
292         return NT_STATUS_OK;
293 }
294
295 /*
296   fill in the DNS domain info
297 */
298 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
299                              struct lsa_DnsDomainInfo *info)
300 {
301         const char * const attrs[] = { "name", "dnsDomain", "objectGUID", "objectSid", NULL };
302         int ret;
303         struct ldb_message **res;
304
305         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
306                            "dn=%s", state->domain_dn);
307         if (ret != 1) {
308                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
309         }
310
311         info->name.string       = samdb_result_string(res[0],           "name", NULL);
312         info->dns_domain.string = samdb_result_string(res[0],           "dnsDomain", NULL);
313         info->dns_forest.string = samdb_result_string(res[0],           "dnsDomain", NULL);
314         info->domain_guid       = samdb_result_guid(res[0],             "objectGUID");
315         info->sid               = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
316
317         return NT_STATUS_OK;
318 }
319
320 /* 
321   lsa_QueryInfoPolicy2
322 */
323 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
324                                      struct lsa_QueryInfoPolicy2 *r)
325 {
326         struct lsa_policy_state *state;
327         struct dcesrv_handle *h;
328
329         r->out.info = NULL;
330
331         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
332
333         state = h->data;
334
335         r->out.info = talloc_p(mem_ctx, union lsa_PolicyInformation);
336         if (!r->out.info) {
337                 return NT_STATUS_NO_MEMORY;
338         }
339
340         ZERO_STRUCTP(r->out.info);
341
342         switch (r->in.level) {
343         case LSA_POLICY_INFO_DOMAIN:
344         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
345                 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
346
347         case LSA_POLICY_INFO_DNS:
348                 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
349         }
350
351         return NT_STATUS_INVALID_INFO_CLASS;
352 }
353
354 /* 
355   lsa_QueryInfoPolicy 
356 */
357 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
358                                     struct lsa_QueryInfoPolicy *r)
359 {
360         struct lsa_QueryInfoPolicy2 r2;
361         NTSTATUS status;
362
363         r2.in.handle = r->in.handle;
364         r2.in.level = r->in.level;
365         
366         status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
367
368         r->out.info = r2.out.info;
369
370         return status;
371 }
372
373 /* 
374   lsa_SetInfoPolicy 
375 */
376 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
377                                   struct lsa_SetInfoPolicy *r)
378 {
379         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
380 }
381
382
383 /* 
384   lsa_ClearAuditLog 
385 */
386 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
387                                   struct lsa_ClearAuditLog *r)
388 {
389         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
390 }
391
392
393 /* 
394   lsa_CreateAccount 
395 */
396 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
397                                   struct lsa_CreateAccount *r)
398 {
399         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
400 }
401
402
403 /* 
404   lsa_EnumAccounts 
405 */
406 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
407                                  struct lsa_EnumAccounts *r)
408 {
409         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
410 }
411
412
413 /* 
414   lsa_CreateTrustedDomain 
415 */
416 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
417                                         struct lsa_CreateTrustedDomain *r)
418 {
419         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
420 }
421
422
423 /* 
424   lsa_EnumTrustDom 
425 */
426 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
427                        struct lsa_EnumTrustDom *r)
428 {
429         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
430 }
431
432
433 /*
434   return the authority name and authority sid, given a sid
435 */
436 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
437                                    TALLOC_CTX *mem_ctx, struct dom_sid *sid,
438                                    const char **authority_name,
439                                    struct dom_sid **authority_sid)
440 {
441         if (dom_sid_in_domain(state->domain_sid, sid)) {
442                 *authority_name = state->domain_name;
443                 *authority_sid = state->domain_sid;
444                 return NT_STATUS_OK;
445         }
446
447         if (dom_sid_in_domain(state->builtin_sid, sid)) {
448                 *authority_name = "BUILTIN";
449                 *authority_sid = state->builtin_sid;
450                 return NT_STATUS_OK;
451         }
452
453         *authority_sid = dom_sid_dup(mem_ctx, sid);
454         if (*authority_sid == NULL) {
455                 return NT_STATUS_NO_MEMORY;
456         }
457         (*authority_sid)->num_auths = 0;
458         *authority_name = dom_sid_string(mem_ctx, *authority_sid);
459         if (*authority_name == NULL) {
460                 return NT_STATUS_NO_MEMORY;
461         }
462
463         return NT_STATUS_OK;
464 }
465
466 /*
467   add to the lsa_RefDomainList for LookupSids and LookupNames
468 */
469 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, 
470                                    struct dom_sid *sid, 
471                                    struct lsa_RefDomainList *domains,
472                                    uint32_t *sid_index)
473 {
474         NTSTATUS status;
475         const char *authority_name;
476         struct dom_sid *authority_sid;
477         int i;
478
479         /* work out the authority name */
480         status = lsa_authority_name(state, mem_ctx, sid, 
481                                     &authority_name, &authority_sid);
482         if (!NT_STATUS_IS_OK(status)) {
483                 return status;
484         }
485         
486         /* see if we've already done this authority name */
487         for (i=0;i<domains->count;i++) {
488                 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
489                         *sid_index = i;
490                         return NT_STATUS_OK;
491                 }
492         }
493
494         domains->domains = talloc_realloc_p(domains, 
495                                             domains->domains,
496                                             struct lsa_TrustInformation,
497                                             domains->count+1);
498         if (domains->domains == NULL) {
499                 return NT_STATUS_NO_MEMORY;
500         }
501         domains->domains[i].name.string = authority_name;
502         domains->domains[i].sid         = authority_sid;
503         domains->count++;
504         *sid_index = i;
505         
506         return NT_STATUS_OK;
507 }
508
509 /*
510   lookup a name for 1 SID
511 */
512 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
513                                struct dom_sid *sid, const char *sid_str,
514                                const char **name, uint32_t *atype)
515 {
516         int ret;
517         struct ldb_message **res;
518         const char * const attrs[] = { "sAMAccountName", "sAMAccountType", NULL};
519         NTSTATUS status;
520
521         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
522                            "objectSid=%s", sid_str);
523         if (ret == 1) {
524                 *name = ldb_msg_find_string(res[0], "sAMAccountName", NULL);
525                 if (*name == NULL) {
526                         return NT_STATUS_NO_MEMORY;
527                 }
528         
529                 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
530
531                 return NT_STATUS_OK;
532         }
533
534         status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
535
536         return status;
537 }
538
539
540 /*
541   lsa_LookupSids2
542 */
543 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
544                                 TALLOC_CTX *mem_ctx,
545                                 struct lsa_LookupSids2 *r)
546 {
547         struct lsa_policy_state *state;
548         struct dcesrv_handle *h;
549         int i;
550         NTSTATUS status = NT_STATUS_OK;
551
552         r->out.domains = NULL;
553
554         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
555
556         state = h->data;
557
558         r->out.domains = talloc_zero_p(mem_ctx,  struct lsa_RefDomainList);
559         if (r->out.domains == NULL) {
560                 return NT_STATUS_NO_MEMORY;
561         }
562
563         r->out.names = talloc_zero_p(mem_ctx,  struct lsa_TransNameArray2);
564         if (r->out.names == NULL) {
565                 return NT_STATUS_NO_MEMORY;
566         }
567
568         *r->out.count = 0;
569
570         r->out.names->names = talloc_array_p(r->out.names, struct lsa_TranslatedName2, 
571                                              r->in.sids->num_sids);
572         if (r->out.names->names == NULL) {
573                 return NT_STATUS_NO_MEMORY;
574         }
575
576         for (i=0;i<r->in.sids->num_sids;i++) {
577                 struct dom_sid *sid = r->in.sids->sids[i].sid;
578                 char *sid_str = dom_sid_string(mem_ctx, sid);
579                 const char *name;
580                 uint32_t atype, rtype, sid_index;
581                 NTSTATUS status2;
582
583                 r->out.names->count++;
584                 (*r->out.count)++;
585
586                 r->out.names->names[i].sid_type    = SID_NAME_UNKNOWN;
587                 r->out.names->names[i].name.string = sid_str;
588                 r->out.names->names[i].sid_index   = 0xFFFFFFFF;
589                 r->out.names->names[i].unknown     = 0;
590
591                 if (sid_str == NULL) {
592                         r->out.names->names[i].name.string = "(SIDERROR)";
593                         status = STATUS_SOME_UNMAPPED;
594                         continue;
595                 }
596
597                 /* work out the authority name */
598                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
599                 if (!NT_STATUS_IS_OK(status2)) {
600                         return status2;
601                 }
602
603                 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str, 
604                                          &name, &atype);
605                 if (!NT_STATUS_IS_OK(status2)) {
606                         status = STATUS_SOME_UNMAPPED;
607                         continue;
608                 }
609
610                 rtype = samdb_atype_map(atype);
611                 if (rtype == SID_NAME_UNKNOWN) {
612                         status = STATUS_SOME_UNMAPPED;
613                         continue;
614                 }
615
616                 r->out.names->names[i].sid_type    = rtype;
617                 r->out.names->names[i].name.string = name;
618                 r->out.names->names[i].sid_index   = sid_index;
619                 r->out.names->names[i].unknown     = 0;
620         }
621         
622         return status;
623 }
624
625
626 /* 
627   lsa_LookupSids 
628 */
629 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
630                                struct lsa_LookupSids *r)
631 {
632         struct lsa_LookupSids2 r2;
633         NTSTATUS status;
634         int i;
635
636         r2.in.handle   = r->in.handle;
637         r2.in.sids     = r->in.sids;
638         r2.in.names    = NULL;
639         r2.in.level    = r->in.level;
640         r2.in.count    = r->in.count;
641         r2.in.unknown1 = 0;
642         r2.in.unknown2 = 0;
643         r2.out.count   = r->out.count;
644
645         status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
646         if (dce_call->fault_code != 0) {
647                 return status;
648         }
649
650         r->out.domains = r2.out.domains;
651         r->out.names = talloc_p(mem_ctx, struct lsa_TransNameArray);
652         if (r->out.names == NULL) {
653                 return NT_STATUS_NO_MEMORY;
654         }
655         r->out.names->count = r2.out.names->count;
656         r->out.names->names = talloc_array_p(r->out.names, struct lsa_TranslatedName, 
657                                              r->out.names->count);
658         if (r->out.names->names == NULL) {
659                 return NT_STATUS_NO_MEMORY;
660         }
661         for (i=0;i<r->out.names->count;i++) {
662                 r->out.names->names[i].sid_type    = r2.out.names->names[i].sid_type;
663                 r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
664                 r->out.names->names[i].sid_index   = r2.out.names->names[i].sid_index;
665         }
666
667         return status;
668 }
669
670
671 /* 
672   lsa_CreateSecret 
673 */
674 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
675                        struct lsa_CreateSecret *r)
676 {
677         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
678 }
679
680
681 /* 
682   lsa_OpenAccount 
683 */
684 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
685                        struct lsa_OpenAccount *r)
686 {
687         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
688 }
689
690
691 /* 
692   lsa_EnumPrivsAccount 
693 */
694 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
695                        struct lsa_EnumPrivsAccount *r)
696 {
697         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
698 }
699
700
701 /* 
702   lsa_AddPrivilegesToAccount
703 */
704 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
705                        struct lsa_AddPrivilegesToAccount *r)
706 {
707         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
708 }
709
710
711 /* 
712   lsa_RemovePrivilegesFromAccount
713 */
714 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
715                        struct lsa_RemovePrivilegesFromAccount *r)
716 {
717         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
718 }
719
720
721 /* 
722   lsa_GetQuotasForAccount
723 */
724 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
725                        struct lsa_GetQuotasForAccount *r)
726 {
727         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
728 }
729
730
731 /* 
732   lsa_SetQuotasForAccount
733 */
734 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
735                        struct lsa_SetQuotasForAccount *r)
736 {
737         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
738 }
739
740
741 /* 
742   lsa_GetSystemAccessAccount
743 */
744 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
745                        struct lsa_GetSystemAccessAccount *r)
746 {
747         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
748 }
749
750
751 /* 
752   lsa_SetSystemAccessAccount
753 */
754 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
755                        struct lsa_SetSystemAccessAccount *r)
756 {
757         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
758 }
759
760
761 /* 
762   lsa_OpenTrustedDomain
763 */
764 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
765                        struct lsa_OpenTrustedDomain *r)
766 {
767         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
768 }
769
770
771 /* 
772   lsa_QueryTrustedDomainInfo
773 */
774 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
775                        struct lsa_QueryTrustedDomainInfo *r)
776 {
777         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
778 }
779
780
781 /* 
782   lsa_SetInformationTrustedDomain
783 */
784 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
785                        struct lsa_SetInformationTrustedDomain *r)
786 {
787         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
788 }
789
790
791 /* 
792   lsa_OpenSecret 
793 */
794 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
795                        struct lsa_OpenSecret *r)
796 {
797         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
798 }
799
800
801 /* 
802   lsa_SetSecret 
803 */
804 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
805                        struct lsa_SetSecret *r)
806 {
807         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
808 }
809
810
811 /* 
812   lsa_QuerySecret 
813 */
814 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
815                        struct lsa_QuerySecret *r)
816 {
817         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
818 }
819
820
821 /* 
822   lsa_LookupPrivValue
823 */
824 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
825                                     TALLOC_CTX *mem_ctx,
826                                     struct lsa_LookupPrivValue *r)
827 {
828         struct dcesrv_handle *h;
829         struct lsa_policy_state *state;
830         int id;
831
832         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
833
834         state = h->data;
835
836         id = sec_privilege_id(r->in.name->string);
837         if (id == -1) {
838                 return NT_STATUS_NO_SUCH_PRIVILEGE;
839         }
840
841         r->out.luid->low = id;
842         r->out.luid->high = 0;
843
844         return NT_STATUS_OK;    
845 }
846
847
848 /* 
849   lsa_LookupPrivName 
850 */
851 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
852                                    TALLOC_CTX *mem_ctx,
853                                    struct lsa_LookupPrivName *r)
854 {
855         struct dcesrv_handle *h;
856         struct lsa_policy_state *state;
857         const char *privname;
858
859         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
860
861         state = h->data;
862
863         if (r->in.luid->high != 0) {
864                 return NT_STATUS_NO_SUCH_PRIVILEGE;
865         }
866
867         privname = sec_privilege_name(r->in.luid->low);
868         if (privname == NULL) {
869                 return NT_STATUS_NO_SUCH_PRIVILEGE;
870         }
871
872         r->out.name = talloc_p(mem_ctx, struct lsa_String);
873         if (r->out.name == NULL) {
874                 return NT_STATUS_NO_MEMORY;
875         }
876         r->out.name->string = privname;
877
878         return NT_STATUS_OK;    
879 }
880
881
882 /* 
883   lsa_LookupPrivDisplayName
884 */
885 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
886                                           TALLOC_CTX *mem_ctx,
887                                           struct lsa_LookupPrivDisplayName *r)
888 {
889         struct dcesrv_handle *h;
890         struct lsa_policy_state *state;
891         int id;
892
893         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
894
895         state = h->data;
896
897         id = sec_privilege_id(r->in.name->string);
898         if (id == -1) {
899                 return NT_STATUS_NO_SUCH_PRIVILEGE;
900         }
901         
902         r->out.disp_name = talloc_p(mem_ctx, struct lsa_String);
903         if (r->out.disp_name == NULL) {
904                 return NT_STATUS_NO_MEMORY;
905         }
906
907         r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
908         if (r->out.disp_name->string == NULL) {
909                 return NT_STATUS_INTERNAL_ERROR;
910         }
911
912         return NT_STATUS_OK;
913 }
914
915
916 /* 
917   lsa_DeleteObject
918 */
919 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
920                        struct lsa_DeleteObject *r)
921 {
922         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
923 }
924
925
926 /* 
927   lsa_EnumAccountsWithUserRight
928 */
929 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
930                                               TALLOC_CTX *mem_ctx,
931                                               struct lsa_EnumAccountsWithUserRight *r)
932 {
933         struct dcesrv_handle *h;
934         struct lsa_policy_state *state;
935         int ret, i;
936         struct ldb_message **res;
937         const char * const attrs[] = { "objectSid", NULL};
938         const char *privname;
939
940         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
941
942         state = h->data;
943
944         if (r->in.name == NULL) {
945                 return NT_STATUS_NO_SUCH_PRIVILEGE;
946         } 
947
948         privname = r->in.name->string;
949         if (sec_privilege_id(privname) == -1) {
950                 return NT_STATUS_NO_SUCH_PRIVILEGE;
951         }
952
953         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
954                            "privilege=%s", privname);
955         if (ret <= 0) {
956                 return NT_STATUS_NO_SUCH_USER;
957         }
958
959         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_SidPtr, ret);
960         if (r->out.sids->sids == NULL) {
961                 return NT_STATUS_NO_MEMORY;
962         }
963         for (i=0;i<ret;i++) {
964                 const char *sidstr;
965                 sidstr = samdb_result_string(res[i], "objectSid", NULL);
966                 if (sidstr == NULL) {
967                         return NT_STATUS_NO_MEMORY;
968                 }
969                 r->out.sids->sids[i].sid = dom_sid_parse_talloc(r->out.sids->sids,
970                                                                 sidstr);
971                 if (r->out.sids->sids[i].sid == NULL) {
972                         return NT_STATUS_NO_MEMORY;
973                 }
974         }
975         r->out.sids->num_sids = ret;
976
977         return NT_STATUS_OK;
978 }
979
980
981 /* 
982   lsa_EnumAccountRights 
983 */
984 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
985                                       TALLOC_CTX *mem_ctx,
986                                       struct lsa_EnumAccountRights *r)
987 {
988         struct dcesrv_handle *h;
989         struct lsa_policy_state *state;
990         int ret, i;
991         struct ldb_message **res;
992         const char * const attrs[] = { "privilege", NULL};
993         const char *sidstr;
994         struct ldb_message_element *el;
995
996         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
997
998         state = h->data;
999
1000         sidstr = dom_sid_string(mem_ctx, r->in.sid);
1001         if (sidstr == NULL) {
1002                 return NT_STATUS_NO_MEMORY;
1003         }
1004
1005         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
1006                            "objectSid=%s", sidstr);
1007         if (ret != 1) {
1008                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1009         }
1010
1011         el = ldb_msg_find_element(res[0], "privilege");
1012         if (el == NULL || el->num_values == 0) {
1013                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1014         }
1015
1016         r->out.rights->count = el->num_values;
1017         r->out.rights->names = talloc_array_p(r->out.rights, 
1018                                               struct lsa_String, r->out.rights->count);
1019         if (r->out.rights->names == NULL) {
1020                 return NT_STATUS_NO_MEMORY;
1021         }
1022
1023         for (i=0;i<el->num_values;i++) {
1024                 r->out.rights->names[i].string = el->values[i].data;
1025         }
1026
1027         return NT_STATUS_OK;
1028 }
1029
1030
1031 /* 
1032   lsa_AddAccountRights
1033 */
1034 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
1035                                      TALLOC_CTX *mem_ctx,
1036                                      struct lsa_AddAccountRights *r)
1037 {
1038         struct dcesrv_handle *h;
1039         struct lsa_policy_state *state;
1040         const char *sidstr;
1041         struct ldb_message msg;
1042         struct ldb_message_element el;
1043         int i, ret;
1044         const char *dn;
1045
1046         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1047
1048         state = h->data;
1049
1050         sidstr = dom_sid_string(mem_ctx, r->in.sid);
1051         if (sidstr == NULL) {
1052                 return NT_STATUS_NO_MEMORY;
1053         }
1054
1055         dn = samdb_search_string(state->sam_ctx, mem_ctx, NULL, "dn", 
1056                                  "objectSid=%s", sidstr);
1057         if (dn == NULL) {
1058                 return NT_STATUS_NO_SUCH_USER;
1059         }
1060
1061         msg.dn = talloc_strdup(mem_ctx, dn);
1062         if (msg.dn == NULL) {
1063                 return NT_STATUS_NO_MEMORY;
1064         }
1065         msg.num_elements = 1;
1066         msg.elements = &el;
1067         el.flags = LDB_FLAG_MOD_ADD;
1068         el.name = talloc_strdup(mem_ctx, "privilege");
1069         if (el.name == NULL) {
1070                 return NT_STATUS_NO_MEMORY;
1071         }
1072         el.num_values = r->in.rights->count;
1073         el.values = talloc_array_p(mem_ctx, struct ldb_val, el.num_values);
1074         if (el.values == NULL) {
1075                 return NT_STATUS_NO_MEMORY;
1076         }
1077         for (i=0;i<el.num_values;i++) {
1078                 if (sec_privilege_id(r->in.rights->names[i].string) == -1) {
1079                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1080                 }
1081                 el.values[i].length = strlen(r->in.rights->names[i].string);
1082                 el.values[i].data = talloc_strdup(mem_ctx, 
1083                                                   r->in.rights->names[i].string);
1084                 if (el.values[i].data == NULL) {
1085                         return NT_STATUS_NO_MEMORY;
1086                 }
1087         }
1088
1089         ret = samdb_modify(state->sam_ctx, mem_ctx, &msg);
1090         if (ret != 0) {
1091                 return NT_STATUS_UNEXPECTED_IO_ERROR;
1092         }
1093
1094         return NT_STATUS_OK;
1095 }
1096
1097
1098 /* 
1099   lsa_RemoveAccountRights
1100 */
1101 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
1102                                         TALLOC_CTX *mem_ctx,
1103                                         struct lsa_RemoveAccountRights *r)
1104 {
1105         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1106 }
1107
1108
1109 /* 
1110   lsa_QueryTrustedDomainInfoBySid
1111 */
1112 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1113                                                 struct lsa_QueryTrustedDomainInfoBySid *r)
1114 {
1115         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1116 }
1117
1118
1119 /* 
1120   lsa_SetTrustDomainInfo
1121 */
1122 static NTSTATUS lsa_SetTrustDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1123                        struct lsa_SetTrustDomainInfo *r)
1124 {
1125         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1126 }
1127
1128
1129 /* 
1130   lsa_DeleteTrustDomain
1131 */
1132 static NTSTATUS lsa_DeleteTrustDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1133                        struct lsa_DeleteTrustDomain *r)
1134 {
1135         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1136 }
1137
1138
1139 /* 
1140   lsa_StorePrivateData
1141 */
1142 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1143                        struct lsa_StorePrivateData *r)
1144 {
1145         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1146 }
1147
1148
1149 /* 
1150   lsa_RetrievePrivateData
1151 */
1152 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1153                        struct lsa_RetrievePrivateData *r)
1154 {
1155         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1156 }
1157
1158
1159 /* 
1160   lsa_GetUserName
1161 */
1162 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1163                        struct lsa_GetUserName *r)
1164 {
1165         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1166 }
1167
1168 /*
1169   lsa_SetInfoPolicy2
1170 */
1171 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
1172                                    TALLOC_CTX *mem_ctx,
1173                                    struct lsa_SetInfoPolicy2 *r)
1174 {
1175         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1176 }
1177
1178 /*
1179   lsa_QueryTrustedDomainInfoByName
1180 */
1181 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1182                                                  TALLOC_CTX *mem_ctx,
1183                                                  struct lsa_QueryTrustedDomainInfoByName *r)
1184 {
1185         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1186 }
1187
1188 /*
1189   lsa_SetTrustedDomainInfoByName
1190 */
1191 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1192                                                TALLOC_CTX *mem_ctx,
1193                                                struct lsa_SetTrustedDomainInfoByName *r)
1194 {
1195         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1196 }
1197
1198 /*
1199   lsa_EnumTrustedDomainsEx
1200 */
1201 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call,
1202                                          TALLOC_CTX *mem_ctx,
1203                                          struct lsa_EnumTrustedDomainsEx *r)
1204 {
1205         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1206 }
1207
1208 /*
1209   lsa_CreateTrustedDomainEx
1210 */
1211 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1212                                           TALLOC_CTX *mem_ctx,
1213                                           struct lsa_CreateTrustedDomainEx *r)
1214 {
1215         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1216 }
1217
1218 /*
1219   lsa_CloseTrustedDomainEx
1220 */
1221 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1222                                          TALLOC_CTX *mem_ctx,
1223                                          struct lsa_CloseTrustedDomainEx *r)
1224 {
1225         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1226 }
1227
1228 /*
1229   lsa_QueryDomainInformationPolicy
1230 */
1231 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
1232                                                  TALLOC_CTX *mem_ctx,
1233                                                  struct lsa_QueryDomainInformationPolicy *r)
1234 {
1235         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1236 }
1237
1238 /*
1239   lsa_SetDomInfoPolicy
1240 */
1241 static NTSTATUS lsa_SetDomInfoPolicy(struct dcesrv_call_state *dce_call,
1242                                      TALLOC_CTX *mem_ctx,
1243                                      struct lsa_SetDomInfoPolicy *r)
1244 {
1245         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1246 }
1247
1248 /*
1249   lsa_OpenTrustedDomainByName
1250 */
1251 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1252                                             TALLOC_CTX *mem_ctx,
1253                                             struct lsa_OpenTrustedDomainByName *r)
1254 {
1255         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1256 }
1257
1258 /*
1259   lsa_TestCall
1260 */
1261 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
1262                              TALLOC_CTX *mem_ctx,
1263                              struct lsa_TestCall *r)
1264 {
1265         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1266 }
1267
1268 /*
1269   lookup a SID for 1 name
1270 */
1271 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1272                                 const char *name, struct dom_sid **sid, uint32_t *atype)
1273 {
1274         int ret;
1275         struct ldb_message **res;
1276         const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
1277
1278         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", name);
1279         if (ret == 1) {
1280                 const char *sid_str = ldb_msg_find_string(res[0], "objectSid", NULL);
1281                 if (sid_str == NULL) {
1282                         return NT_STATUS_INVALID_SID;
1283                 }
1284
1285                 *sid = dom_sid_parse_talloc(mem_ctx, sid_str);
1286                 if (*sid == NULL) {
1287                         return NT_STATUS_INVALID_SID;
1288                 }
1289
1290                 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1291
1292                 return NT_STATUS_OK;
1293         }
1294
1295         /* need to add a call into sidmap to check for a allocated sid */
1296
1297         return NT_STATUS_INVALID_SID;
1298 }
1299
1300 /*
1301   lsa_LookupNames2
1302 */
1303 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
1304                                  TALLOC_CTX *mem_ctx,
1305                                  struct lsa_LookupNames2 *r)
1306 {
1307         struct lsa_policy_state *state;
1308         struct dcesrv_handle *h;
1309         int i;
1310         NTSTATUS status = NT_STATUS_OK;
1311
1312         r->out.domains = NULL;
1313
1314         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1315
1316         state = h->data;
1317
1318         r->out.domains = talloc_zero_p(mem_ctx,  struct lsa_RefDomainList);
1319         if (r->out.domains == NULL) {
1320                 return NT_STATUS_NO_MEMORY;
1321         }
1322
1323         r->out.sids = talloc_zero_p(mem_ctx,  struct lsa_TransSidArray2);
1324         if (r->out.sids == NULL) {
1325                 return NT_STATUS_NO_MEMORY;
1326         }
1327
1328         *r->out.count = 0;
1329
1330         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid2, 
1331                                            r->in.num_names);
1332         if (r->out.sids->sids == NULL) {
1333                 return NT_STATUS_NO_MEMORY;
1334         }
1335
1336         for (i=0;i<r->in.num_names;i++) {
1337                 const char *name = r->in.names[i].string;
1338                 struct dom_sid *sid;
1339                 uint32_t atype, rtype, sid_index;
1340                 NTSTATUS status2;
1341
1342                 r->out.sids->count++;
1343                 (*r->out.count)++;
1344
1345                 r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
1346                 r->out.sids->sids[i].rid         = 0xFFFFFFFF;
1347                 r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
1348                 r->out.sids->sids[i].unknown     = 0;
1349
1350                 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
1351                 if (!NT_STATUS_IS_OK(status) || sid->num_auths == 0) {
1352                         status = STATUS_SOME_UNMAPPED;
1353                         continue;
1354                 }
1355
1356                 rtype = samdb_atype_map(atype);
1357                 if (rtype == SID_NAME_UNKNOWN) {
1358                         status = STATUS_SOME_UNMAPPED;
1359                         continue;
1360                 }
1361
1362                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1363                 if (!NT_STATUS_IS_OK(status2)) {
1364                         return status2;
1365                 }
1366
1367                 r->out.sids->sids[i].sid_type    = rtype;
1368                 r->out.sids->sids[i].rid         = sid->sub_auths[sid->num_auths-1];
1369                 r->out.sids->sids[i].sid_index   = sid_index;
1370                 r->out.sids->sids[i].unknown     = 0;
1371         }
1372         
1373         return status;
1374 }
1375
1376 /* 
1377   lsa_LookupNames 
1378 */
1379 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1380                        struct lsa_LookupNames *r)
1381 {
1382         struct lsa_LookupNames2 r2;
1383         NTSTATUS status;
1384         int i;
1385
1386         r2.in.handle    = r->in.handle;
1387         r2.in.num_names = r->in.num_names;
1388         r2.in.names     = r->in.names;
1389         r2.in.sids      = NULL;
1390         r2.in.level     = r->in.level;
1391         r2.in.count     = r->in.count;
1392         r2.in.unknown1  = 0;
1393         r2.in.unknown2  = 0;
1394         r2.out.count    = r->out.count;
1395
1396         status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
1397         if (dce_call->fault_code != 0) {
1398                 return status;
1399         }
1400
1401         r->out.domains = r2.out.domains;
1402         r->out.sids = talloc_p(mem_ctx, struct lsa_TransSidArray);
1403         if (r->out.sids == NULL) {
1404                 return NT_STATUS_NO_MEMORY;
1405         }
1406         r->out.sids->count = r2.out.sids->count;
1407         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid, 
1408                                            r->out.sids->count);
1409         if (r->out.sids->sids == NULL) {
1410                 return NT_STATUS_NO_MEMORY;
1411         }
1412         for (i=0;i<r->out.sids->count;i++) {
1413                 r->out.sids->sids[i].sid_type    = r2.out.sids->sids[i].sid_type;
1414                 r->out.sids->sids[i].rid         = r2.out.sids->sids[i].rid;
1415                 r->out.sids->sids[i].sid_index   = r2.out.sids->sids[i].sid_index;
1416         }
1417
1418         return status;
1419 }
1420
1421
1422
1423 /*
1424   lsa_CreateTrustedDomainEx2
1425 */
1426 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1427                                            TALLOC_CTX *mem_ctx,
1428                                            struct lsa_CreateTrustedDomainEx2 *r)
1429 {
1430         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1431 }
1432
1433 /* include the generated boilerplate */
1434 #include "librpc/gen_ndr/ndr_lsa_s.c"