r4206: fixed a status code check in lsa_LookupNames2 that could cause a segv
[samba.git] / source / 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, 
695                                      TALLOC_CTX *mem_ctx,
696                                      struct lsa_EnumPrivsAccount *r)
697 {
698         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
699 }
700
701
702 /* 
703   lsa_AddPrivilegesToAccount
704 */
705 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
706                        struct lsa_AddPrivilegesToAccount *r)
707 {
708         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
709 }
710
711
712 /* 
713   lsa_RemovePrivilegesFromAccount
714 */
715 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
716                        struct lsa_RemovePrivilegesFromAccount *r)
717 {
718         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
719 }
720
721
722 /* 
723   lsa_GetQuotasForAccount
724 */
725 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
726                        struct lsa_GetQuotasForAccount *r)
727 {
728         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
729 }
730
731
732 /* 
733   lsa_SetQuotasForAccount
734 */
735 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
736                        struct lsa_SetQuotasForAccount *r)
737 {
738         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
739 }
740
741
742 /* 
743   lsa_GetSystemAccessAccount
744 */
745 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
746                        struct lsa_GetSystemAccessAccount *r)
747 {
748         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
749 }
750
751
752 /* 
753   lsa_SetSystemAccessAccount
754 */
755 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
756                        struct lsa_SetSystemAccessAccount *r)
757 {
758         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
759 }
760
761
762 /* 
763   lsa_OpenTrustedDomain
764 */
765 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
766                        struct lsa_OpenTrustedDomain *r)
767 {
768         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
769 }
770
771
772 /* 
773   lsa_QueryTrustedDomainInfo
774 */
775 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
776                        struct lsa_QueryTrustedDomainInfo *r)
777 {
778         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
779 }
780
781
782 /* 
783   lsa_SetInformationTrustedDomain
784 */
785 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
786                        struct lsa_SetInformationTrustedDomain *r)
787 {
788         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
789 }
790
791
792 /* 
793   lsa_OpenSecret 
794 */
795 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
796                        struct lsa_OpenSecret *r)
797 {
798         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
799 }
800
801
802 /* 
803   lsa_SetSecret 
804 */
805 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
806                        struct lsa_SetSecret *r)
807 {
808         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
809 }
810
811
812 /* 
813   lsa_QuerySecret 
814 */
815 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
816                        struct lsa_QuerySecret *r)
817 {
818         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
819 }
820
821
822 /* 
823   lsa_LookupPrivValue
824 */
825 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
826                                     TALLOC_CTX *mem_ctx,
827                                     struct lsa_LookupPrivValue *r)
828 {
829         struct dcesrv_handle *h;
830         struct lsa_policy_state *state;
831         int id;
832
833         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
834
835         state = h->data;
836
837         id = sec_privilege_id(r->in.name->string);
838         if (id == -1) {
839                 return NT_STATUS_NO_SUCH_PRIVILEGE;
840         }
841
842         r->out.luid->low = id;
843         r->out.luid->high = 0;
844
845         return NT_STATUS_OK;    
846 }
847
848
849 /* 
850   lsa_LookupPrivName 
851 */
852 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
853                                    TALLOC_CTX *mem_ctx,
854                                    struct lsa_LookupPrivName *r)
855 {
856         struct dcesrv_handle *h;
857         struct lsa_policy_state *state;
858         const char *privname;
859
860         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
861
862         state = h->data;
863
864         if (r->in.luid->high != 0) {
865                 return NT_STATUS_NO_SUCH_PRIVILEGE;
866         }
867
868         privname = sec_privilege_name(r->in.luid->low);
869         if (privname == NULL) {
870                 return NT_STATUS_NO_SUCH_PRIVILEGE;
871         }
872
873         r->out.name = talloc_p(mem_ctx, struct lsa_String);
874         if (r->out.name == NULL) {
875                 return NT_STATUS_NO_MEMORY;
876         }
877         r->out.name->string = privname;
878
879         return NT_STATUS_OK;    
880 }
881
882
883 /* 
884   lsa_LookupPrivDisplayName
885 */
886 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
887                                           TALLOC_CTX *mem_ctx,
888                                           struct lsa_LookupPrivDisplayName *r)
889 {
890         struct dcesrv_handle *h;
891         struct lsa_policy_state *state;
892         int id;
893
894         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
895
896         state = h->data;
897
898         id = sec_privilege_id(r->in.name->string);
899         if (id == -1) {
900                 return NT_STATUS_NO_SUCH_PRIVILEGE;
901         }
902         
903         r->out.disp_name = talloc_p(mem_ctx, struct lsa_String);
904         if (r->out.disp_name == NULL) {
905                 return NT_STATUS_NO_MEMORY;
906         }
907
908         r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
909         if (r->out.disp_name->string == NULL) {
910                 return NT_STATUS_INTERNAL_ERROR;
911         }
912
913         return NT_STATUS_OK;
914 }
915
916
917 /* 
918   lsa_DeleteObject
919 */
920 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
921                        struct lsa_DeleteObject *r)
922 {
923         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
924 }
925
926
927 /* 
928   lsa_EnumAccountsWithUserRight
929 */
930 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
931                                               TALLOC_CTX *mem_ctx,
932                                               struct lsa_EnumAccountsWithUserRight *r)
933 {
934         struct dcesrv_handle *h;
935         struct lsa_policy_state *state;
936         int ret, i;
937         struct ldb_message **res;
938         const char * const attrs[] = { "objectSid", NULL};
939         const char *privname;
940
941         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
942
943         state = h->data;
944
945         if (r->in.name == NULL) {
946                 return NT_STATUS_NO_SUCH_PRIVILEGE;
947         } 
948
949         privname = r->in.name->string;
950         if (sec_privilege_id(privname) == -1) {
951                 return NT_STATUS_NO_SUCH_PRIVILEGE;
952         }
953
954         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
955                            "privilege=%s", privname);
956         if (ret <= 0) {
957                 return NT_STATUS_NO_SUCH_USER;
958         }
959
960         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_SidPtr, ret);
961         if (r->out.sids->sids == NULL) {
962                 return NT_STATUS_NO_MEMORY;
963         }
964         for (i=0;i<ret;i++) {
965                 const char *sidstr;
966                 sidstr = samdb_result_string(res[i], "objectSid", NULL);
967                 if (sidstr == NULL) {
968                         return NT_STATUS_NO_MEMORY;
969                 }
970                 r->out.sids->sids[i].sid = dom_sid_parse_talloc(r->out.sids->sids,
971                                                                 sidstr);
972                 if (r->out.sids->sids[i].sid == NULL) {
973                         return NT_STATUS_NO_MEMORY;
974                 }
975         }
976         r->out.sids->num_sids = ret;
977
978         return NT_STATUS_OK;
979 }
980
981
982 /* 
983   lsa_EnumAccountRights 
984 */
985 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
986                                       TALLOC_CTX *mem_ctx,
987                                       struct lsa_EnumAccountRights *r)
988 {
989         struct dcesrv_handle *h;
990         struct lsa_policy_state *state;
991         int ret, i;
992         struct ldb_message **res;
993         const char * const attrs[] = { "privilege", NULL};
994         const char *sidstr;
995         struct ldb_message_element *el;
996
997         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
998
999         state = h->data;
1000
1001         sidstr = dom_sid_string(mem_ctx, r->in.sid);
1002         if (sidstr == NULL) {
1003                 return NT_STATUS_NO_MEMORY;
1004         }
1005
1006         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
1007                            "objectSid=%s", sidstr);
1008         if (ret != 1) {
1009                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1010         }
1011
1012         el = ldb_msg_find_element(res[0], "privilege");
1013         if (el == NULL || el->num_values == 0) {
1014                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1015         }
1016
1017         r->out.rights->count = el->num_values;
1018         r->out.rights->names = talloc_array_p(r->out.rights, 
1019                                               struct lsa_String, r->out.rights->count);
1020         if (r->out.rights->names == NULL) {
1021                 return NT_STATUS_NO_MEMORY;
1022         }
1023
1024         for (i=0;i<el->num_values;i++) {
1025                 r->out.rights->names[i].string = el->values[i].data;
1026         }
1027
1028         return NT_STATUS_OK;
1029 }
1030
1031
1032 /* 
1033   helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1034 */
1035 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
1036                                            TALLOC_CTX *mem_ctx,
1037                                            struct lsa_policy_state *state,
1038                                            int ldb_flag,
1039                                            const struct dom_sid *sid,
1040                                            const struct lsa_RightSet *rights)
1041 {
1042         const char *sidstr;
1043         struct ldb_message msg;
1044         struct ldb_message_element el;
1045         int i, ret;
1046         const char *dn;
1047
1048         sidstr = dom_sid_string(mem_ctx, sid);
1049         if (sidstr == NULL) {
1050                 return NT_STATUS_NO_MEMORY;
1051         }
1052
1053         dn = samdb_search_string(state->sam_ctx, mem_ctx, NULL, "dn", 
1054                                  "objectSid=%s", sidstr);
1055         if (dn == NULL) {
1056                 return NT_STATUS_NO_SUCH_USER;
1057         }
1058
1059         msg.dn = talloc_strdup(mem_ctx, dn);
1060         if (msg.dn == NULL) {
1061                 return NT_STATUS_NO_MEMORY;
1062         }
1063         msg.num_elements = 1;
1064         msg.elements = &el;
1065         el.flags = ldb_flag;
1066         el.name = talloc_strdup(mem_ctx, "privilege");
1067         if (el.name == NULL) {
1068                 return NT_STATUS_NO_MEMORY;
1069         }
1070         el.num_values = rights->count;
1071         el.values = talloc_array_p(mem_ctx, struct ldb_val, el.num_values);
1072         if (el.values == NULL) {
1073                 return NT_STATUS_NO_MEMORY;
1074         }
1075         for (i=0;i<el.num_values;i++) {
1076                 if (sec_privilege_id(rights->names[i].string) == -1) {
1077                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1078                 }
1079                 el.values[i].length = strlen(rights->names[i].string);
1080                 el.values[i].data = talloc_strdup(mem_ctx, rights->names[i].string);
1081                 if (el.values[i].data == NULL) {
1082                         return NT_STATUS_NO_MEMORY;
1083                 }
1084         }
1085
1086         ret = samdb_modify(state->sam_ctx, mem_ctx, &msg);
1087         if (ret != 0) {
1088                 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1089                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1090                 }
1091                 return NT_STATUS_UNEXPECTED_IO_ERROR;
1092         }
1093
1094         return NT_STATUS_OK;
1095 }
1096
1097 /* 
1098   lsa_AddAccountRights
1099 */
1100 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
1101                                      TALLOC_CTX *mem_ctx,
1102                                      struct lsa_AddAccountRights *r)
1103 {
1104         struct dcesrv_handle *h;
1105         struct lsa_policy_state *state;
1106
1107         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1108
1109         state = h->data;
1110
1111         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
1112                                           LDB_FLAG_MOD_ADD,
1113                                           r->in.sid, r->in.rights);
1114 }
1115
1116
1117 /* 
1118   lsa_RemoveAccountRights
1119 */
1120 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
1121                                         TALLOC_CTX *mem_ctx,
1122                                         struct lsa_RemoveAccountRights *r)
1123 {
1124         struct dcesrv_handle *h;
1125         struct lsa_policy_state *state;
1126
1127         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1128
1129         state = h->data;
1130
1131         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
1132                                           LDB_FLAG_MOD_DELETE,
1133                                           r->in.sid, r->in.rights);
1134 }
1135
1136
1137 /* 
1138   lsa_QueryTrustedDomainInfoBySid
1139 */
1140 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1141                                                 struct lsa_QueryTrustedDomainInfoBySid *r)
1142 {
1143         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1144 }
1145
1146
1147 /* 
1148   lsa_SetTrustDomainInfo
1149 */
1150 static NTSTATUS lsa_SetTrustDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1151                        struct lsa_SetTrustDomainInfo *r)
1152 {
1153         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1154 }
1155
1156
1157 /* 
1158   lsa_DeleteTrustDomain
1159 */
1160 static NTSTATUS lsa_DeleteTrustDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1161                        struct lsa_DeleteTrustDomain *r)
1162 {
1163         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1164 }
1165
1166
1167 /* 
1168   lsa_StorePrivateData
1169 */
1170 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1171                        struct lsa_StorePrivateData *r)
1172 {
1173         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1174 }
1175
1176
1177 /* 
1178   lsa_RetrievePrivateData
1179 */
1180 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1181                        struct lsa_RetrievePrivateData *r)
1182 {
1183         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1184 }
1185
1186
1187 /* 
1188   lsa_GetUserName
1189 */
1190 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1191                        struct lsa_GetUserName *r)
1192 {
1193         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1194 }
1195
1196 /*
1197   lsa_SetInfoPolicy2
1198 */
1199 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
1200                                    TALLOC_CTX *mem_ctx,
1201                                    struct lsa_SetInfoPolicy2 *r)
1202 {
1203         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1204 }
1205
1206 /*
1207   lsa_QueryTrustedDomainInfoByName
1208 */
1209 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1210                                                  TALLOC_CTX *mem_ctx,
1211                                                  struct lsa_QueryTrustedDomainInfoByName *r)
1212 {
1213         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1214 }
1215
1216 /*
1217   lsa_SetTrustedDomainInfoByName
1218 */
1219 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1220                                                TALLOC_CTX *mem_ctx,
1221                                                struct lsa_SetTrustedDomainInfoByName *r)
1222 {
1223         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1224 }
1225
1226 /*
1227   lsa_EnumTrustedDomainsEx
1228 */
1229 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call,
1230                                          TALLOC_CTX *mem_ctx,
1231                                          struct lsa_EnumTrustedDomainsEx *r)
1232 {
1233         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1234 }
1235
1236 /*
1237   lsa_CreateTrustedDomainEx
1238 */
1239 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1240                                           TALLOC_CTX *mem_ctx,
1241                                           struct lsa_CreateTrustedDomainEx *r)
1242 {
1243         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1244 }
1245
1246 /*
1247   lsa_CloseTrustedDomainEx
1248 */
1249 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1250                                          TALLOC_CTX *mem_ctx,
1251                                          struct lsa_CloseTrustedDomainEx *r)
1252 {
1253         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1254 }
1255
1256 /*
1257   lsa_QueryDomainInformationPolicy
1258 */
1259 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
1260                                                  TALLOC_CTX *mem_ctx,
1261                                                  struct lsa_QueryDomainInformationPolicy *r)
1262 {
1263         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1264 }
1265
1266 /*
1267   lsa_SetDomInfoPolicy
1268 */
1269 static NTSTATUS lsa_SetDomInfoPolicy(struct dcesrv_call_state *dce_call,
1270                                      TALLOC_CTX *mem_ctx,
1271                                      struct lsa_SetDomInfoPolicy *r)
1272 {
1273         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1274 }
1275
1276 /*
1277   lsa_OpenTrustedDomainByName
1278 */
1279 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1280                                             TALLOC_CTX *mem_ctx,
1281                                             struct lsa_OpenTrustedDomainByName *r)
1282 {
1283         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1284 }
1285
1286 /*
1287   lsa_TestCall
1288 */
1289 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
1290                              TALLOC_CTX *mem_ctx,
1291                              struct lsa_TestCall *r)
1292 {
1293         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1294 }
1295
1296 /*
1297   lookup a SID for 1 name
1298 */
1299 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1300                                 const char *name, struct dom_sid **sid, uint32_t *atype)
1301 {
1302         int ret;
1303         struct ldb_message **res;
1304         const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
1305
1306         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", name);
1307         if (ret == 1) {
1308                 const char *sid_str = ldb_msg_find_string(res[0], "objectSid", NULL);
1309                 if (sid_str == NULL) {
1310                         return NT_STATUS_INVALID_SID;
1311                 }
1312
1313                 *sid = dom_sid_parse_talloc(mem_ctx, sid_str);
1314                 if (*sid == NULL) {
1315                         return NT_STATUS_INVALID_SID;
1316                 }
1317
1318                 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1319
1320                 return NT_STATUS_OK;
1321         }
1322
1323         /* need to add a call into sidmap to check for a allocated sid */
1324
1325         return NT_STATUS_INVALID_SID;
1326 }
1327
1328 /*
1329   lsa_LookupNames2
1330 */
1331 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
1332                                  TALLOC_CTX *mem_ctx,
1333                                  struct lsa_LookupNames2 *r)
1334 {
1335         struct lsa_policy_state *state;
1336         struct dcesrv_handle *h;
1337         int i;
1338         NTSTATUS status = NT_STATUS_OK;
1339
1340         r->out.domains = NULL;
1341
1342         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1343
1344         state = h->data;
1345
1346         r->out.domains = talloc_zero_p(mem_ctx,  struct lsa_RefDomainList);
1347         if (r->out.domains == NULL) {
1348                 return NT_STATUS_NO_MEMORY;
1349         }
1350
1351         r->out.sids = talloc_zero_p(mem_ctx,  struct lsa_TransSidArray2);
1352         if (r->out.sids == NULL) {
1353                 return NT_STATUS_NO_MEMORY;
1354         }
1355
1356         *r->out.count = 0;
1357
1358         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid2, 
1359                                            r->in.num_names);
1360         if (r->out.sids->sids == NULL) {
1361                 return NT_STATUS_NO_MEMORY;
1362         }
1363
1364         for (i=0;i<r->in.num_names;i++) {
1365                 const char *name = r->in.names[i].string;
1366                 struct dom_sid *sid;
1367                 uint32_t atype, rtype, sid_index;
1368                 NTSTATUS status2;
1369
1370                 r->out.sids->count++;
1371                 (*r->out.count)++;
1372
1373                 r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
1374                 r->out.sids->sids[i].rid         = 0xFFFFFFFF;
1375                 r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
1376                 r->out.sids->sids[i].unknown     = 0;
1377
1378                 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
1379                 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
1380                         status = STATUS_SOME_UNMAPPED;
1381                         continue;
1382                 }
1383
1384                 rtype = samdb_atype_map(atype);
1385                 if (rtype == SID_NAME_UNKNOWN) {
1386                         status = STATUS_SOME_UNMAPPED;
1387                         continue;
1388                 }
1389
1390                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1391                 if (!NT_STATUS_IS_OK(status2)) {
1392                         return status2;
1393                 }
1394
1395                 r->out.sids->sids[i].sid_type    = rtype;
1396                 r->out.sids->sids[i].rid         = sid->sub_auths[sid->num_auths-1];
1397                 r->out.sids->sids[i].sid_index   = sid_index;
1398                 r->out.sids->sids[i].unknown     = 0;
1399         }
1400         
1401         return status;
1402 }
1403
1404 /* 
1405   lsa_LookupNames 
1406 */
1407 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1408                        struct lsa_LookupNames *r)
1409 {
1410         struct lsa_LookupNames2 r2;
1411         NTSTATUS status;
1412         int i;
1413
1414         r2.in.handle    = r->in.handle;
1415         r2.in.num_names = r->in.num_names;
1416         r2.in.names     = r->in.names;
1417         r2.in.sids      = NULL;
1418         r2.in.level     = r->in.level;
1419         r2.in.count     = r->in.count;
1420         r2.in.unknown1  = 0;
1421         r2.in.unknown2  = 0;
1422         r2.out.count    = r->out.count;
1423
1424         status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
1425         if (dce_call->fault_code != 0) {
1426                 return status;
1427         }
1428
1429         r->out.domains = r2.out.domains;
1430         r->out.sids = talloc_p(mem_ctx, struct lsa_TransSidArray);
1431         if (r->out.sids == NULL) {
1432                 return NT_STATUS_NO_MEMORY;
1433         }
1434         r->out.sids->count = r2.out.sids->count;
1435         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid, 
1436                                            r->out.sids->count);
1437         if (r->out.sids->sids == NULL) {
1438                 return NT_STATUS_NO_MEMORY;
1439         }
1440         for (i=0;i<r->out.sids->count;i++) {
1441                 r->out.sids->sids[i].sid_type    = r2.out.sids->sids[i].sid_type;
1442                 r->out.sids->sids[i].rid         = r2.out.sids->sids[i].rid;
1443                 r->out.sids->sids[i].sid_index   = r2.out.sids->sids[i].sid_index;
1444         }
1445
1446         return status;
1447 }
1448
1449
1450
1451 /*
1452   lsa_CreateTrustedDomainEx2
1453 */
1454 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1455                                            TALLOC_CTX *mem_ctx,
1456                                            struct lsa_CreateTrustedDomainEx2 *r)
1457 {
1458         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1459 }
1460
1461 /* include the generated boilerplate */
1462 #include "librpc/gen_ndr/ndr_lsa_s.c"