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