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