r4278: - added server support for lsa_EnumPrivsAccount()
[samba.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the lsarpc pipe
5
6    Copyright (C) Andrew Tridgell 2004
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "librpc/gen_ndr/ndr_lsa.h"
25 #include "librpc/gen_ndr/ndr_samr.h"
26 #include "rpc_server/dcerpc_server.h"
27 #include "rpc_server/common/common.h"
28 #include "lib/ldb/include/ldb.h"
29
30 /*
31   this type allows us to distinguish handle types
32 */
33 enum lsa_handle {
34         LSA_HANDLE_POLICY,
35         LSA_HANDLE_ACCOUNT,
36         LSA_HANDLE_SECRET
37 };
38
39 /*
40   state associated with a lsa_OpenPolicy() operation
41 */
42 struct lsa_policy_state {
43         void *sam_ctx;
44         struct sidmap_context *sidmap;
45         uint32_t access_mask;
46         const char *domain_dn;
47         const char *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_dn;
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_dn = samdb_search_string(state->sam_ctx, astate,
798                                                  NULL, "dn", 
799                                                  "(&(objectSid=%s)(objectClass=group))", 
800                                                  astate->account_sid_str);
801         if (astate->account_dn == NULL) {
802                 talloc_free(astate);
803                 return NT_STATUS_NO_SUCH_USER;
804         }
805         
806         astate->policy = talloc_reference(astate, state);
807         astate->access_mask = r->in.access_mask;
808
809         ah = dcesrv_handle_new(dce_call->conn, LSA_HANDLE_ACCOUNT);
810         if (!ah) {
811                 talloc_free(astate);
812                 return NT_STATUS_NO_MEMORY;
813         }
814
815         ah->data = astate;
816         ah->destroy = lsa_Account_destroy;
817
818         *r->out.acct_handle = ah->wire_handle;
819
820         return NT_STATUS_OK;
821 }
822
823
824 /* 
825   lsa_EnumPrivsAccount 
826 */
827 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 
828                                      TALLOC_CTX *mem_ctx,
829                                      struct lsa_EnumPrivsAccount *r)
830 {
831         struct dcesrv_handle *h;
832         struct lsa_account_state *astate;
833         int ret, i;
834         struct ldb_message **res;
835         const char * const attrs[] = { "privilege", NULL};
836         struct ldb_message_element *el;
837
838         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
839
840         astate = h->data;
841
842         r->out.privs = talloc_p(mem_ctx, struct lsa_PrivilegeSet);
843         r->out.privs->count = 0;
844         r->out.privs->unknown = 0;
845         r->out.privs->set = NULL;
846
847         ret = samdb_search(astate->policy->sam_ctx, mem_ctx, NULL, &res, attrs, 
848                            "dn=%s", astate->account_dn);
849         if (ret != 1) {
850                 return NT_STATUS_OK;
851         }
852
853         el = ldb_msg_find_element(res[0], "privilege");
854         if (el == NULL || el->num_values == 0) {
855                 return NT_STATUS_OK;
856         }
857
858         r->out.privs->set = talloc_array_p(r->out.privs, 
859                                            struct lsa_LUIDAttribute, el->num_values);
860         if (r->out.privs->set == NULL) {
861                 return NT_STATUS_NO_MEMORY;
862         }
863
864         for (i=0;i<el->num_values;i++) {
865                 int id = sec_privilege_id(el->values[i].data);
866                 if (id == -1) {
867                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
868                 }
869                 r->out.privs->set[i].attribute = 0;
870                 r->out.privs->set[i].luid.low = id;
871                 r->out.privs->set[i].luid.high = 0;
872         }
873
874         r->out.privs->count = el->num_values;
875
876         return NT_STATUS_OK;
877 }
878
879
880 /* 
881   lsa_AddPrivilegesToAccount
882 */
883 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
884                        struct lsa_AddPrivilegesToAccount *r)
885 {
886         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
887 }
888
889
890 /* 
891   lsa_RemovePrivilegesFromAccount
892 */
893 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
894                        struct lsa_RemovePrivilegesFromAccount *r)
895 {
896         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
897 }
898
899
900 /* 
901   lsa_GetQuotasForAccount
902 */
903 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
904                        struct lsa_GetQuotasForAccount *r)
905 {
906         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
907 }
908
909
910 /* 
911   lsa_SetQuotasForAccount
912 */
913 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
914                        struct lsa_SetQuotasForAccount *r)
915 {
916         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
917 }
918
919
920 /* 
921   lsa_GetSystemAccessAccount
922 */
923 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
924                        struct lsa_GetSystemAccessAccount *r)
925 {
926         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
927 }
928
929
930 /* 
931   lsa_SetSystemAccessAccount
932 */
933 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
934                        struct lsa_SetSystemAccessAccount *r)
935 {
936         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
937 }
938
939
940 /* 
941   lsa_OpenTrustedDomain
942 */
943 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
944                        struct lsa_OpenTrustedDomain *r)
945 {
946         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
947 }
948
949
950 /* 
951   lsa_QueryTrustedDomainInfo
952 */
953 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
954                        struct lsa_QueryTrustedDomainInfo *r)
955 {
956         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
957 }
958
959
960 /* 
961   lsa_SetInformationTrustedDomain
962 */
963 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
964                        struct lsa_SetInformationTrustedDomain *r)
965 {
966         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
967 }
968
969
970 /* 
971   lsa_OpenSecret 
972 */
973 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
974                        struct lsa_OpenSecret *r)
975 {
976         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
977 }
978
979
980 /* 
981   lsa_SetSecret 
982 */
983 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
984                        struct lsa_SetSecret *r)
985 {
986         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
987 }
988
989
990 /* 
991   lsa_QuerySecret 
992 */
993 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
994                        struct lsa_QuerySecret *r)
995 {
996         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
997 }
998
999
1000 /* 
1001   lsa_LookupPrivValue
1002 */
1003 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
1004                                     TALLOC_CTX *mem_ctx,
1005                                     struct lsa_LookupPrivValue *r)
1006 {
1007         struct dcesrv_handle *h;
1008         struct lsa_policy_state *state;
1009         int id;
1010
1011         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1012
1013         state = h->data;
1014
1015         id = sec_privilege_id(r->in.name->string);
1016         if (id == -1) {
1017                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1018         }
1019
1020         r->out.luid->low = id;
1021         r->out.luid->high = 0;
1022
1023         return NT_STATUS_OK;    
1024 }
1025
1026
1027 /* 
1028   lsa_LookupPrivName 
1029 */
1030 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
1031                                    TALLOC_CTX *mem_ctx,
1032                                    struct lsa_LookupPrivName *r)
1033 {
1034         struct dcesrv_handle *h;
1035         struct lsa_policy_state *state;
1036         const char *privname;
1037
1038         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1039
1040         state = h->data;
1041
1042         if (r->in.luid->high != 0) {
1043                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1044         }
1045
1046         privname = sec_privilege_name(r->in.luid->low);
1047         if (privname == NULL) {
1048                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1049         }
1050
1051         r->out.name = talloc_p(mem_ctx, struct lsa_String);
1052         if (r->out.name == NULL) {
1053                 return NT_STATUS_NO_MEMORY;
1054         }
1055         r->out.name->string = privname;
1056
1057         return NT_STATUS_OK;    
1058 }
1059
1060
1061 /* 
1062   lsa_LookupPrivDisplayName
1063 */
1064 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
1065                                           TALLOC_CTX *mem_ctx,
1066                                           struct lsa_LookupPrivDisplayName *r)
1067 {
1068         struct dcesrv_handle *h;
1069         struct lsa_policy_state *state;
1070         int id;
1071
1072         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1073
1074         state = h->data;
1075
1076         id = sec_privilege_id(r->in.name->string);
1077         if (id == -1) {
1078                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1079         }
1080         
1081         r->out.disp_name = talloc_p(mem_ctx, struct lsa_String);
1082         if (r->out.disp_name == NULL) {
1083                 return NT_STATUS_NO_MEMORY;
1084         }
1085
1086         r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
1087         if (r->out.disp_name->string == NULL) {
1088                 return NT_STATUS_INTERNAL_ERROR;
1089         }
1090
1091         return NT_STATUS_OK;
1092 }
1093
1094
1095 /* 
1096   lsa_DeleteObject
1097 */
1098 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1099                        struct lsa_DeleteObject *r)
1100 {
1101         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1102 }
1103
1104
1105 /* 
1106   lsa_EnumAccountsWithUserRight
1107 */
1108 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
1109                                               TALLOC_CTX *mem_ctx,
1110                                               struct lsa_EnumAccountsWithUserRight *r)
1111 {
1112         struct dcesrv_handle *h;
1113         struct lsa_policy_state *state;
1114         int ret, i;
1115         struct ldb_message **res;
1116         const char * const attrs[] = { "objectSid", NULL};
1117         const char *privname;
1118
1119         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1120
1121         state = h->data;
1122
1123         if (r->in.name == NULL) {
1124                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1125         } 
1126
1127         privname = r->in.name->string;
1128         if (sec_privilege_id(privname) == -1) {
1129                 return NT_STATUS_NO_SUCH_PRIVILEGE;
1130         }
1131
1132         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
1133                            "privilege=%s", privname);
1134         if (ret <= 0) {
1135                 return NT_STATUS_NO_SUCH_USER;
1136         }
1137
1138         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_SidPtr, ret);
1139         if (r->out.sids->sids == NULL) {
1140                 return NT_STATUS_NO_MEMORY;
1141         }
1142         for (i=0;i<ret;i++) {
1143                 const char *sidstr;
1144                 sidstr = samdb_result_string(res[i], "objectSid", NULL);
1145                 if (sidstr == NULL) {
1146                         return NT_STATUS_NO_MEMORY;
1147                 }
1148                 r->out.sids->sids[i].sid = dom_sid_parse_talloc(r->out.sids->sids,
1149                                                                 sidstr);
1150                 if (r->out.sids->sids[i].sid == NULL) {
1151                         return NT_STATUS_NO_MEMORY;
1152                 }
1153         }
1154         r->out.sids->num_sids = ret;
1155
1156         return NT_STATUS_OK;
1157 }
1158
1159
1160 /* 
1161   lsa_EnumAccountRights 
1162 */
1163 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
1164                                       TALLOC_CTX *mem_ctx,
1165                                       struct lsa_EnumAccountRights *r)
1166 {
1167         struct dcesrv_handle *h;
1168         struct lsa_policy_state *state;
1169         int ret, i;
1170         struct ldb_message **res;
1171         const char * const attrs[] = { "privilege", NULL};
1172         const char *sidstr;
1173         struct ldb_message_element *el;
1174
1175         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1176
1177         state = h->data;
1178
1179         sidstr = dom_sid_string(mem_ctx, r->in.sid);
1180         if (sidstr == NULL) {
1181                 return NT_STATUS_NO_MEMORY;
1182         }
1183
1184         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
1185                            "objectSid=%s", sidstr);
1186         if (ret != 1) {
1187                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1188         }
1189
1190         el = ldb_msg_find_element(res[0], "privilege");
1191         if (el == NULL || el->num_values == 0) {
1192                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1193         }
1194
1195         r->out.rights->count = el->num_values;
1196         r->out.rights->names = talloc_array_p(r->out.rights, 
1197                                               struct lsa_String, r->out.rights->count);
1198         if (r->out.rights->names == NULL) {
1199                 return NT_STATUS_NO_MEMORY;
1200         }
1201
1202         for (i=0;i<el->num_values;i++) {
1203                 r->out.rights->names[i].string = el->values[i].data;
1204         }
1205
1206         return NT_STATUS_OK;
1207 }
1208
1209
1210 /* 
1211   helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1212 */
1213 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
1214                                            TALLOC_CTX *mem_ctx,
1215                                            struct lsa_policy_state *state,
1216                                            int ldb_flag,
1217                                            const struct dom_sid *sid,
1218                                            const struct lsa_RightSet *rights)
1219 {
1220         const char *sidstr;
1221         struct ldb_message msg;
1222         struct ldb_message_element el;
1223         int i, ret;
1224         const char *dn;
1225
1226         sidstr = dom_sid_string(mem_ctx, sid);
1227         if (sidstr == NULL) {
1228                 return NT_STATUS_NO_MEMORY;
1229         }
1230
1231         dn = samdb_search_string(state->sam_ctx, mem_ctx, NULL, "dn", 
1232                                  "objectSid=%s", sidstr);
1233         if (dn == NULL) {
1234                 return NT_STATUS_NO_SUCH_USER;
1235         }
1236
1237         msg.dn = talloc_strdup(mem_ctx, dn);
1238         if (msg.dn == NULL) {
1239                 return NT_STATUS_NO_MEMORY;
1240         }
1241         msg.num_elements = 1;
1242         msg.elements = &el;
1243         el.flags = ldb_flag;
1244         el.name = talloc_strdup(mem_ctx, "privilege");
1245         if (el.name == NULL) {
1246                 return NT_STATUS_NO_MEMORY;
1247         }
1248         el.num_values = rights->count;
1249         el.values = talloc_array_p(mem_ctx, struct ldb_val, el.num_values);
1250         if (el.values == NULL) {
1251                 return NT_STATUS_NO_MEMORY;
1252         }
1253         for (i=0;i<el.num_values;i++) {
1254                 if (sec_privilege_id(rights->names[i].string) == -1) {
1255                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1256                 }
1257                 el.values[i].length = strlen(rights->names[i].string);
1258                 el.values[i].data = talloc_strdup(mem_ctx, rights->names[i].string);
1259                 if (el.values[i].data == NULL) {
1260                         return NT_STATUS_NO_MEMORY;
1261                 }
1262         }
1263
1264         ret = samdb_modify(state->sam_ctx, mem_ctx, &msg);
1265         if (ret != 0) {
1266                 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1267                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1268                 }
1269                 return NT_STATUS_UNEXPECTED_IO_ERROR;
1270         }
1271
1272         return NT_STATUS_OK;
1273 }
1274
1275 /* 
1276   lsa_AddAccountRights
1277 */
1278 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
1279                                      TALLOC_CTX *mem_ctx,
1280                                      struct lsa_AddAccountRights *r)
1281 {
1282         struct dcesrv_handle *h;
1283         struct lsa_policy_state *state;
1284
1285         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1286
1287         state = h->data;
1288
1289         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
1290                                           LDB_FLAG_MOD_ADD,
1291                                           r->in.sid, r->in.rights);
1292 }
1293
1294
1295 /* 
1296   lsa_RemoveAccountRights
1297 */
1298 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
1299                                         TALLOC_CTX *mem_ctx,
1300                                         struct lsa_RemoveAccountRights *r)
1301 {
1302         struct dcesrv_handle *h;
1303         struct lsa_policy_state *state;
1304
1305         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1306
1307         state = h->data;
1308
1309         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
1310                                           LDB_FLAG_MOD_DELETE,
1311                                           r->in.sid, r->in.rights);
1312 }
1313
1314
1315 /* 
1316   lsa_QueryTrustedDomainInfoBySid
1317 */
1318 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1319                                                 struct lsa_QueryTrustedDomainInfoBySid *r)
1320 {
1321         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1322 }
1323
1324
1325 /* 
1326   lsa_SetTrustDomainInfo
1327 */
1328 static NTSTATUS lsa_SetTrustDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1329                        struct lsa_SetTrustDomainInfo *r)
1330 {
1331         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1332 }
1333
1334
1335 /* 
1336   lsa_DeleteTrustDomain
1337 */
1338 static NTSTATUS lsa_DeleteTrustDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1339                        struct lsa_DeleteTrustDomain *r)
1340 {
1341         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1342 }
1343
1344
1345 /* 
1346   lsa_StorePrivateData
1347 */
1348 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1349                        struct lsa_StorePrivateData *r)
1350 {
1351         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1352 }
1353
1354
1355 /* 
1356   lsa_RetrievePrivateData
1357 */
1358 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1359                        struct lsa_RetrievePrivateData *r)
1360 {
1361         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1362 }
1363
1364
1365 /* 
1366   lsa_GetUserName
1367 */
1368 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1369                        struct lsa_GetUserName *r)
1370 {
1371         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1372 }
1373
1374 /*
1375   lsa_SetInfoPolicy2
1376 */
1377 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
1378                                    TALLOC_CTX *mem_ctx,
1379                                    struct lsa_SetInfoPolicy2 *r)
1380 {
1381         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1382 }
1383
1384 /*
1385   lsa_QueryTrustedDomainInfoByName
1386 */
1387 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1388                                                  TALLOC_CTX *mem_ctx,
1389                                                  struct lsa_QueryTrustedDomainInfoByName *r)
1390 {
1391         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1392 }
1393
1394 /*
1395   lsa_SetTrustedDomainInfoByName
1396 */
1397 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1398                                                TALLOC_CTX *mem_ctx,
1399                                                struct lsa_SetTrustedDomainInfoByName *r)
1400 {
1401         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1402 }
1403
1404 /*
1405   lsa_EnumTrustedDomainsEx
1406 */
1407 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call,
1408                                          TALLOC_CTX *mem_ctx,
1409                                          struct lsa_EnumTrustedDomainsEx *r)
1410 {
1411         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1412 }
1413
1414 /*
1415   lsa_CreateTrustedDomainEx
1416 */
1417 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1418                                           TALLOC_CTX *mem_ctx,
1419                                           struct lsa_CreateTrustedDomainEx *r)
1420 {
1421         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1422 }
1423
1424 /*
1425   lsa_CloseTrustedDomainEx
1426 */
1427 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1428                                          TALLOC_CTX *mem_ctx,
1429                                          struct lsa_CloseTrustedDomainEx *r)
1430 {
1431         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1432 }
1433
1434 /*
1435   lsa_QueryDomainInformationPolicy
1436 */
1437 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
1438                                                  TALLOC_CTX *mem_ctx,
1439                                                  struct lsa_QueryDomainInformationPolicy *r)
1440 {
1441         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1442 }
1443
1444 /*
1445   lsa_SetDomInfoPolicy
1446 */
1447 static NTSTATUS lsa_SetDomInfoPolicy(struct dcesrv_call_state *dce_call,
1448                                      TALLOC_CTX *mem_ctx,
1449                                      struct lsa_SetDomInfoPolicy *r)
1450 {
1451         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1452 }
1453
1454 /*
1455   lsa_OpenTrustedDomainByName
1456 */
1457 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1458                                             TALLOC_CTX *mem_ctx,
1459                                             struct lsa_OpenTrustedDomainByName *r)
1460 {
1461         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1462 }
1463
1464 /*
1465   lsa_TestCall
1466 */
1467 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
1468                              TALLOC_CTX *mem_ctx,
1469                              struct lsa_TestCall *r)
1470 {
1471         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1472 }
1473
1474 /*
1475   lookup a SID for 1 name
1476 */
1477 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1478                                 const char *name, struct dom_sid **sid, uint32_t *atype)
1479 {
1480         int ret;
1481         struct ldb_message **res;
1482         const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
1483
1484         ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", name);
1485         if (ret == 1) {
1486                 const char *sid_str = ldb_msg_find_string(res[0], "objectSid", NULL);
1487                 if (sid_str == NULL) {
1488                         return NT_STATUS_INVALID_SID;
1489                 }
1490
1491                 *sid = dom_sid_parse_talloc(mem_ctx, sid_str);
1492                 if (*sid == NULL) {
1493                         return NT_STATUS_INVALID_SID;
1494                 }
1495
1496                 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1497
1498                 return NT_STATUS_OK;
1499         }
1500
1501         /* need to add a call into sidmap to check for a allocated sid */
1502
1503         return NT_STATUS_INVALID_SID;
1504 }
1505
1506 /*
1507   lsa_LookupNames2
1508 */
1509 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
1510                                  TALLOC_CTX *mem_ctx,
1511                                  struct lsa_LookupNames2 *r)
1512 {
1513         struct lsa_policy_state *state;
1514         struct dcesrv_handle *h;
1515         int i;
1516         NTSTATUS status = NT_STATUS_OK;
1517
1518         r->out.domains = NULL;
1519
1520         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1521
1522         state = h->data;
1523
1524         r->out.domains = talloc_zero_p(mem_ctx,  struct lsa_RefDomainList);
1525         if (r->out.domains == NULL) {
1526                 return NT_STATUS_NO_MEMORY;
1527         }
1528
1529         r->out.sids = talloc_zero_p(mem_ctx,  struct lsa_TransSidArray2);
1530         if (r->out.sids == NULL) {
1531                 return NT_STATUS_NO_MEMORY;
1532         }
1533
1534         *r->out.count = 0;
1535
1536         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid2, 
1537                                            r->in.num_names);
1538         if (r->out.sids->sids == NULL) {
1539                 return NT_STATUS_NO_MEMORY;
1540         }
1541
1542         for (i=0;i<r->in.num_names;i++) {
1543                 const char *name = r->in.names[i].string;
1544                 struct dom_sid *sid;
1545                 uint32_t atype, rtype, sid_index;
1546                 NTSTATUS status2;
1547
1548                 r->out.sids->count++;
1549                 (*r->out.count)++;
1550
1551                 r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
1552                 r->out.sids->sids[i].rid         = 0xFFFFFFFF;
1553                 r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
1554                 r->out.sids->sids[i].unknown     = 0;
1555
1556                 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
1557                 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
1558                         status = STATUS_SOME_UNMAPPED;
1559                         continue;
1560                 }
1561
1562                 rtype = samdb_atype_map(atype);
1563                 if (rtype == SID_NAME_UNKNOWN) {
1564                         status = STATUS_SOME_UNMAPPED;
1565                         continue;
1566                 }
1567
1568                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1569                 if (!NT_STATUS_IS_OK(status2)) {
1570                         return status2;
1571                 }
1572
1573                 r->out.sids->sids[i].sid_type    = rtype;
1574                 r->out.sids->sids[i].rid         = sid->sub_auths[sid->num_auths-1];
1575                 r->out.sids->sids[i].sid_index   = sid_index;
1576                 r->out.sids->sids[i].unknown     = 0;
1577         }
1578         
1579         return status;
1580 }
1581
1582 /* 
1583   lsa_LookupNames 
1584 */
1585 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1586                        struct lsa_LookupNames *r)
1587 {
1588         struct lsa_LookupNames2 r2;
1589         NTSTATUS status;
1590         int i;
1591
1592         r2.in.handle    = r->in.handle;
1593         r2.in.num_names = r->in.num_names;
1594         r2.in.names     = r->in.names;
1595         r2.in.sids      = NULL;
1596         r2.in.level     = r->in.level;
1597         r2.in.count     = r->in.count;
1598         r2.in.unknown1  = 0;
1599         r2.in.unknown2  = 0;
1600         r2.out.count    = r->out.count;
1601
1602         status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
1603         if (dce_call->fault_code != 0) {
1604                 return status;
1605         }
1606
1607         r->out.domains = r2.out.domains;
1608         r->out.sids = talloc_p(mem_ctx, struct lsa_TransSidArray);
1609         if (r->out.sids == NULL) {
1610                 return NT_STATUS_NO_MEMORY;
1611         }
1612         r->out.sids->count = r2.out.sids->count;
1613         r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid, 
1614                                            r->out.sids->count);
1615         if (r->out.sids->sids == NULL) {
1616                 return NT_STATUS_NO_MEMORY;
1617         }
1618         for (i=0;i<r->out.sids->count;i++) {
1619                 r->out.sids->sids[i].sid_type    = r2.out.sids->sids[i].sid_type;
1620                 r->out.sids->sids[i].rid         = r2.out.sids->sids[i].rid;
1621                 r->out.sids->sids[i].sid_index   = r2.out.sids->sids[i].sid_index;
1622         }
1623
1624         return status;
1625 }
1626
1627
1628
1629 /*
1630   lsa_CreateTrustedDomainEx2
1631 */
1632 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1633                                            TALLOC_CTX *mem_ctx,
1634                                            struct lsa_CreateTrustedDomainEx2 *r)
1635 {
1636         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1637 }
1638
1639 /* include the generated boilerplate */
1640 #include "librpc/gen_ndr/ndr_lsa_s.c"