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