r14964: - move sidmap code from ntvfs_common to SAMDB
[kai/samba-autobuild/.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    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25 #include "rpc_server/dcerpc_server.h"
26 #include "rpc_server/common/common.h"
27 #include "auth/auth.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "libcli/ldap/ldap.h"
30 #include "libcli/security/security.h"
31 #include "libcli/auth/libcli_auth.h"
32 #include "librpc/gen_ndr/ndr_security.h"
33 #include "passdb/secrets.h"
34 #include "db_wrap.h"
35
36 /*
37   this type allows us to distinguish handle types
38 */
39 enum lsa_handle {
40         LSA_HANDLE_POLICY,
41         LSA_HANDLE_ACCOUNT,
42         LSA_HANDLE_SECRET,
43         LSA_HANDLE_TRUSTED_DOMAIN
44 };
45
46 /*
47   state associated with a lsa_OpenPolicy() operation
48 */
49 struct lsa_policy_state {
50         struct dcesrv_handle *handle;
51         struct ldb_context *sam_ldb;
52         struct sidmap_context *sidmap;
53         uint32_t access_mask;
54         const struct ldb_dn *domain_dn;
55         const struct ldb_dn *builtin_dn;
56         const struct ldb_dn *system_dn;
57         const char *domain_name;
58         struct dom_sid *domain_sid;
59         struct dom_sid *builtin_sid;
60 };
61
62
63 /*
64   state associated with a lsa_OpenAccount() operation
65 */
66 struct lsa_account_state {
67         struct lsa_policy_state *policy;
68         uint32_t access_mask;
69         struct dom_sid *account_sid;
70         const struct ldb_dn *account_dn;
71 };
72
73
74 /*
75   state associated with a lsa_OpenSecret() operation
76 */
77 struct lsa_secret_state {
78         struct lsa_policy_state *policy;
79         uint32_t access_mask;
80         const struct ldb_dn *secret_dn;
81         struct ldb_context *sam_ldb;
82         BOOL global;
83 };
84
85 /*
86   state associated with a lsa_OpenTrustedDomain() operation
87 */
88 struct lsa_trusted_domain_state {
89         struct lsa_policy_state *policy;
90         uint32_t access_mask;
91         const struct ldb_dn *trusted_domain_dn;
92 };
93
94 /* 
95   lsa_Close 
96 */
97 static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
98                           struct lsa_Close *r)
99 {
100         struct dcesrv_handle *h;
101
102         *r->out.handle = *r->in.handle;
103
104         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
105
106         talloc_free(h);
107
108         ZERO_STRUCTP(r->out.handle);
109
110         return NT_STATUS_OK;
111 }
112
113
114 /* 
115   lsa_Delete 
116 */
117 static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
118                            struct lsa_Delete *r)
119 {
120         struct dcesrv_handle *h;
121         int ret;
122
123         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
124         if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
125                 struct lsa_secret_state *secret_state = h->data;
126                 ret = samdb_delete(secret_state->sam_ldb, mem_ctx, secret_state->secret_dn);
127                 talloc_free(h);
128                 if (ret != 0) {
129                         return NT_STATUS_INVALID_HANDLE;
130                 }
131
132                 return NT_STATUS_OK;
133         } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
134                 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
135                 ret = samdb_delete(trusted_domain_state->policy->sam_ldb, mem_ctx, 
136                                    trusted_domain_state->trusted_domain_dn);
137                 talloc_free(h);
138                 if (ret != 0) {
139                         return NT_STATUS_INVALID_HANDLE;
140                 }
141
142                 return NT_STATUS_OK;
143         } 
144         
145         return NT_STATUS_INVALID_HANDLE;
146 }
147
148
149 /* 
150   lsa_EnumPrivs 
151 */
152 static NTSTATUS lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
153                               struct lsa_EnumPrivs *r)
154 {
155         struct dcesrv_handle *h;
156         struct lsa_policy_state *state;
157         int i;
158         const char *privname;
159
160         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
161
162         state = h->data;
163
164         i = *r->in.resume_handle;
165         if (i == 0) i = 1;
166
167         while ((privname = sec_privilege_name(i)) &&
168                r->out.privs->count < r->in.max_count) {
169                 struct lsa_PrivEntry *e;
170
171                 r->out.privs->privs = talloc_realloc(r->out.privs,
172                                                        r->out.privs->privs, 
173                                                        struct lsa_PrivEntry, 
174                                                        r->out.privs->count+1);
175                 if (r->out.privs->privs == NULL) {
176                         return NT_STATUS_NO_MEMORY;
177                 }
178                 e = &r->out.privs->privs[r->out.privs->count];
179                 e->luid.low = i;
180                 e->luid.high = 0;
181                 e->name.string = privname;
182                 r->out.privs->count++;
183                 i++;
184         }
185
186         *r->out.resume_handle = i;
187
188         return NT_STATUS_OK;
189 }
190
191
192 /* 
193   lsa_QuerySecObj 
194 */
195 static NTSTATUS lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
196                                   struct lsa_QuerySecurity *r)
197 {
198         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
199 }
200
201
202 /* 
203   lsa_SetSecObj 
204 */
205 static NTSTATUS lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
206                               struct lsa_SetSecObj *r)
207 {
208         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
209 }
210
211
212 /* 
213   lsa_ChangePassword 
214 */
215 static NTSTATUS lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
216                                    struct lsa_ChangePassword *r)
217 {
218         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
219 }
220
221 static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
222                                      struct lsa_policy_state **_state)
223 {
224         struct lsa_policy_state *state;
225
226         state = talloc(mem_ctx, struct lsa_policy_state);
227         if (!state) {
228                 return NT_STATUS_NO_MEMORY;
229         }
230
231         /* make sure the sam database is accessible */
232         state->sam_ldb = samdb_connect(state, dce_call->conn->auth_state.session_info); 
233         if (state->sam_ldb == NULL) {
234                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
235         }
236
237         state->sidmap = sidmap_open(state);
238         if (state->sidmap == NULL) {
239                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
240         }
241
242         /* work out the domain_dn - useful for so many calls its worth
243            fetching here */
244         state->domain_dn = samdb_base_dn(state);
245         if (!state->domain_dn) {
246                 return NT_STATUS_NO_MEMORY;             
247         }
248
249         state->domain_name
250                 = samdb_search_string(state->sam_ldb, state, NULL, "nETBIOSName", 
251                                       "(&(objectclass=crossRef)(ncName=%s))", ldb_dn_linearize(mem_ctx, state->domain_dn));
252         
253         if (!state->domain_name) {
254                 return NT_STATUS_NO_SUCH_DOMAIN;                
255         }
256         talloc_steal(state, state->domain_name);
257
258         /* work out the builtin_dn - useful for so many calls its worth
259            fetching here */
260         state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
261         if (!state->builtin_dn) {
262                 return NT_STATUS_NO_SUCH_DOMAIN;                
263         }
264
265         /* work out the system_dn - useful for so many calls its worth
266            fetching here */
267         state->system_dn = samdb_search_dn(state->sam_ldb, state,
268                                            state->domain_dn, "(&(objectClass=container)(cn=System))");
269         if (!state->system_dn) {
270                 return NT_STATUS_NO_SUCH_DOMAIN;                
271         }
272
273         state->domain_sid = samdb_search_dom_sid(state->sam_ldb, state,
274                                                  state->domain_dn, "objectSid", NULL);
275         if (!state->domain_sid) {
276                 return NT_STATUS_NO_SUCH_DOMAIN;                
277         }
278
279         talloc_steal(state, state->domain_sid);
280
281         state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
282         if (!state->builtin_sid) {
283                 return NT_STATUS_NO_SUCH_DOMAIN;                
284         }
285
286         *_state = state;
287
288         return NT_STATUS_OK;
289 }
290
291 /* 
292   lsa_OpenPolicy2
293 */
294 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
295                                struct lsa_OpenPolicy2 *r)
296 {
297         NTSTATUS status;
298         struct lsa_policy_state *state;
299         struct dcesrv_handle *handle;
300
301         ZERO_STRUCTP(r->out.handle);
302
303         status = lsa_get_policy_state(dce_call, mem_ctx, &state);
304         if (!NT_STATUS_IS_OK(status)) {
305                 return status;
306         }
307
308         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
309         if (!handle) {
310                 return NT_STATUS_NO_MEMORY;
311         }
312
313         handle->data = talloc_steal(handle, state);
314
315         state->access_mask = r->in.access_mask;
316         state->handle = handle;
317         *r->out.handle = handle->wire_handle;
318
319         /* note that we have completely ignored the attr element of
320            the OpenPolicy. As far as I can tell, this is what w2k3
321            does */
322
323         return NT_STATUS_OK;
324 }
325
326 /* 
327   lsa_OpenPolicy
328   a wrapper around lsa_OpenPolicy2
329 */
330 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
331                                 struct lsa_OpenPolicy *r)
332 {
333         struct lsa_OpenPolicy2 r2;
334
335         r2.in.system_name = NULL;
336         r2.in.attr = r->in.attr;
337         r2.in.access_mask = r->in.access_mask;
338         r2.out.handle = r->out.handle;
339
340         return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
341 }
342
343
344
345
346 /*
347   fill in the AccountDomain info
348 */
349 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
350                                        struct lsa_DomainInfo *info)
351 {
352         info->name.string = state->domain_name;
353         info->sid         = state->domain_sid;
354
355         return NT_STATUS_OK;
356 }
357
358 /*
359   fill in the DNS domain info
360 */
361 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
362                              struct lsa_DnsDomainInfo *info)
363 {
364         const char * const attrs[] = { "dnsDomain", "objectGUID", "objectSid", NULL };
365         int ret;
366         struct ldb_message **res;
367
368         ret = gendb_search_dn(state->sam_ldb, mem_ctx, state->domain_dn, &res, attrs);
369         if (ret != 1) {
370                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
371         }
372
373         info->name.string = state->domain_name;
374         info->sid         = state->domain_sid;
375         info->dns_domain.string = samdb_result_string(res[0],           "dnsDomain", NULL);
376         info->dns_forest.string = samdb_result_string(res[0],           "dnsDomain", NULL);
377         info->domain_guid       = samdb_result_guid(res[0],             "objectGUID");
378
379         return NT_STATUS_OK;
380 }
381
382 /* 
383   lsa_QueryInfoPolicy2
384 */
385 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
386                                      struct lsa_QueryInfoPolicy2 *r)
387 {
388         struct lsa_policy_state *state;
389         struct dcesrv_handle *h;
390
391         r->out.info = NULL;
392
393         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
394
395         state = h->data;
396
397         r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
398         if (!r->out.info) {
399                 return NT_STATUS_NO_MEMORY;
400         }
401
402         ZERO_STRUCTP(r->out.info);
403
404         switch (r->in.level) {
405         case LSA_POLICY_INFO_DOMAIN:
406         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
407                 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
408
409         case LSA_POLICY_INFO_DNS:
410                 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
411         }
412
413         return NT_STATUS_INVALID_INFO_CLASS;
414 }
415
416 /* 
417   lsa_QueryInfoPolicy 
418 */
419 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
420                                     struct lsa_QueryInfoPolicy *r)
421 {
422         struct lsa_QueryInfoPolicy2 r2;
423         NTSTATUS status;
424
425         r2.in.handle = r->in.handle;
426         r2.in.level = r->in.level;
427         
428         status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
429
430         r->out.info = r2.out.info;
431
432         return status;
433 }
434
435 /* 
436   lsa_SetInfoPolicy 
437 */
438 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
439                                   struct lsa_SetInfoPolicy *r)
440 {
441         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
442 }
443
444
445 /* 
446   lsa_ClearAuditLog 
447 */
448 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
449                                   struct lsa_ClearAuditLog *r)
450 {
451         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
452 }
453
454
455 /* 
456   lsa_CreateAccount 
457 */
458 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
459                                   struct lsa_CreateAccount *r)
460 {
461         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
462 }
463
464
465 /* 
466   lsa_EnumAccounts 
467 */
468 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
469                                  struct lsa_EnumAccounts *r)
470 {
471         struct dcesrv_handle *h;
472         struct lsa_policy_state *state;
473         int ret, i;
474         struct ldb_message **res;
475         const char * const attrs[] = { "objectSid", NULL};
476         uint32_t count;
477
478         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
479
480         state = h->data;
481
482         ret = gendb_search(state->sam_ldb, mem_ctx, state->builtin_dn, &res, attrs, 
483                            "(|(privilege=*)(objectSid=*))");
484         if (ret <= 0) {
485                 return NT_STATUS_NO_SUCH_USER;
486         }
487
488         if (*r->in.resume_handle >= ret) {
489                 return NT_STATUS_NO_MORE_ENTRIES;
490         }
491
492         count = ret - *r->in.resume_handle;
493         if (count > r->in.num_entries) {
494                 count = r->in.num_entries;
495         }
496
497         if (count == 0) {
498                 return NT_STATUS_NO_MORE_ENTRIES;
499         }
500
501         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
502         if (r->out.sids->sids == NULL) {
503                 return NT_STATUS_NO_MEMORY;
504         }
505
506         for (i=0;i<count;i++) {
507                 r->out.sids->sids[i].sid = 
508                         samdb_result_dom_sid(r->out.sids->sids, 
509                                              res[i + *r->in.resume_handle],
510                                              "objectSid");
511                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
512         }
513
514         r->out.sids->num_sids = count;
515         *r->out.resume_handle = count + *r->in.resume_handle;
516
517         return NT_STATUS_OK;
518         
519 }
520
521
522 /*
523   lsa_CreateTrustedDomainEx2
524 */
525 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
526                                            TALLOC_CTX *mem_ctx,
527                                            struct lsa_CreateTrustedDomainEx2 *r)
528 {
529         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
530 }
531
532 /*
533   lsa_CreateTrustedDomainEx
534 */
535 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
536                                           TALLOC_CTX *mem_ctx,
537                                           struct lsa_CreateTrustedDomainEx *r)
538 {
539         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
540 }
541
542 /* 
543   lsa_CreateTrustedDomain 
544 */
545 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
546                                         struct lsa_CreateTrustedDomain *r)
547 {
548         struct dcesrv_handle *policy_handle;
549         struct lsa_policy_state *policy_state;
550         struct lsa_trusted_domain_state *trusted_domain_state;
551         struct dcesrv_handle *handle;
552         struct ldb_message **msgs, *msg;
553         const char *attrs[] = {
554                 NULL
555         };
556         const char *name;
557         int ret;
558
559         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
560         ZERO_STRUCTP(r->out.trustdom_handle);
561         
562         policy_state = policy_handle->data;
563
564         if (!r->in.info->name.string) {
565                 return NT_STATUS_INVALID_PARAMETER;
566         }
567         name = r->in.info->name.string;
568         
569         trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
570         if (!trusted_domain_state) {
571                 return NT_STATUS_NO_MEMORY;
572         }
573         trusted_domain_state->policy = policy_state;
574
575         msg = ldb_msg_new(mem_ctx);
576         if (msg == NULL) {
577                 return NT_STATUS_NO_MEMORY;
578         }
579
580         /* search for the trusted_domain record */
581         ret = gendb_search(trusted_domain_state->policy->sam_ldb,
582                            mem_ctx, policy_state->system_dn, &msgs, attrs,
583                            "(&(cn=%s)(objectclass=trustedDomain))", 
584                            ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
585         if (ret > 0) {
586                 return NT_STATUS_OBJECT_NAME_COLLISION;
587         }
588         
589         if (ret < 0 || ret > 1) {
590                 DEBUG(0,("Found %d records matching DN %s\n", ret,
591                          ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
592                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
593         }
594         
595         msg->dn = ldb_dn_build_child(mem_ctx, "cn",
596                                      r->in.info->name.string, 
597                                      policy_state->system_dn);
598         if (!msg->dn) {
599                 return NT_STATUS_NO_MEMORY;
600         }
601         
602         samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "cn", name);
603         samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
604
605         if (r->in.info->sid) {
606                 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
607                 if (!sid_string) {
608                         return NT_STATUS_NO_MEMORY;
609                 }
610                         
611                 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
612         }
613
614         samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
615         
616         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
617
618         /* create the trusted_domain */
619         ret = samdb_add(trusted_domain_state->policy->sam_ldb, mem_ctx, msg);
620         if (ret != 0) {
621                 DEBUG(0,("Failed to create trusted_domain record %s\n",
622                          ldb_dn_linearize(mem_ctx, msg->dn)));
623                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
624         }
625
626         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
627         if (!handle) {
628                 return NT_STATUS_NO_MEMORY;
629         }
630         
631         handle->data = talloc_steal(handle, trusted_domain_state);
632         
633         trusted_domain_state->access_mask = r->in.access_mask;
634         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
635         
636         *r->out.trustdom_handle = handle->wire_handle;
637         
638         return NT_STATUS_OK;
639 }
640
641 /* 
642   lsa_OpenTrustedDomain
643 */
644 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
645                                       struct lsa_OpenTrustedDomain *r)
646 {
647         struct dcesrv_handle *policy_handle;
648         
649         struct lsa_policy_state *policy_state;
650         struct lsa_trusted_domain_state *trusted_domain_state;
651         struct dcesrv_handle *handle;
652         struct ldb_message **msgs;
653         const char *attrs[] = {
654                 NULL
655         };
656
657         const char *sid_string;
658         int ret;
659
660         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
661         ZERO_STRUCTP(r->out.trustdom_handle);
662         policy_state = policy_handle->data;
663
664         trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
665         if (!trusted_domain_state) {
666                 return NT_STATUS_NO_MEMORY;
667         }
668         trusted_domain_state->policy = policy_state;
669
670         sid_string = dom_sid_string(mem_ctx, r->in.sid);
671         if (!sid_string) {
672                 return NT_STATUS_NO_MEMORY;
673         }
674
675         /* search for the trusted_domain record */
676         ret = gendb_search(trusted_domain_state->policy->sam_ldb,
677                            mem_ctx, policy_state->system_dn, &msgs, attrs,
678                            "(&(securityIdentifier=%s)(objectclass=trustedDomain))", 
679                            sid_string);
680         if (ret == 0) {
681                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
682         }
683         
684         if (ret != 1) {
685                 DEBUG(0,("Found %d records matching DN %s\n", ret,
686                          ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
687                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
688         }
689
690         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
691         
692         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
693         if (!handle) {
694                 return NT_STATUS_NO_MEMORY;
695         }
696         
697         handle->data = talloc_steal(handle, trusted_domain_state);
698         
699         trusted_domain_state->access_mask = r->in.access_mask;
700         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
701         
702         *r->out.trustdom_handle = handle->wire_handle;
703         
704         return NT_STATUS_OK;
705 }
706
707
708 /*
709   lsa_OpenTrustedDomainByName
710 */
711 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
712                                             TALLOC_CTX *mem_ctx,
713                                             struct lsa_OpenTrustedDomainByName *r)
714 {
715         struct dcesrv_handle *policy_handle;
716         
717         struct lsa_policy_state *policy_state;
718         struct lsa_trusted_domain_state *trusted_domain_state;
719         struct dcesrv_handle *handle;
720         struct ldb_message **msgs;
721         const char *attrs[] = {
722                 NULL
723         };
724
725         int ret;
726
727         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
728         ZERO_STRUCTP(r->out.trustdom_handle);
729         policy_state = policy_handle->data;
730
731         if (!r->in.name.string) {
732                 return NT_STATUS_INVALID_PARAMETER;
733         }
734         
735         trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
736         if (!trusted_domain_state) {
737                 return NT_STATUS_NO_MEMORY;
738         }
739         trusted_domain_state->policy = policy_state;
740
741         /* search for the trusted_domain record */
742         ret = gendb_search(trusted_domain_state->policy->sam_ldb,
743                            mem_ctx, policy_state->system_dn, &msgs, attrs,
744                            "(&(flatname=%s)(objectclass=trustedDomain))", 
745                            ldb_binary_encode_string(mem_ctx, r->in.name.string));
746         if (ret == 0) {
747                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
748         }
749         
750         if (ret != 1) {
751                 DEBUG(0,("Found %d records matching DN %s\n", ret,
752                          ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
753                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
754         }
755
756         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
757         
758         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
759         if (!handle) {
760                 return NT_STATUS_NO_MEMORY;
761         }
762         
763         handle->data = talloc_steal(handle, trusted_domain_state);
764         
765         trusted_domain_state->access_mask = r->in.access_mask;
766         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
767         
768         *r->out.trustdom_handle = handle->wire_handle;
769         
770         return NT_STATUS_OK;
771 }
772
773
774 /* 
775   lsa_QueryTrustedDomainInfoBySid
776 */
777 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
778                                                 struct lsa_QueryTrustedDomainInfoBySid *r)
779 {
780         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
781 }
782
783
784 /* 
785   lsa_SetTrustDomainInfo
786 */
787 static NTSTATUS lsa_SetTrustDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
788                        struct lsa_SetTrustDomainInfo *r)
789 {
790         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
791 }
792
793
794 /* 
795   lsa_DeleteTrustDomain
796 */
797 static NTSTATUS lsa_DeleteTrustDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
798                                       struct lsa_DeleteTrustDomain *r)
799 {
800         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
801 }
802
803
804 /* 
805   lsa_QueryTrustedDomainInfo
806 */
807 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
808                                            struct lsa_QueryTrustedDomainInfo *r)
809 {
810         struct dcesrv_handle *h;
811         struct lsa_trusted_domain_state *trusted_domain_state;
812         struct ldb_message *msg;
813         int ret;
814         struct ldb_message **res;
815         const char *attrs[] = {
816                 "cn",
817                 "flatname",
818                 "posixOffset",
819                 "securityIdentifier",
820                 NULL
821         };
822
823         DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
824
825         trusted_domain_state = h->data;
826
827         /* pull all the user attributes */
828         ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
829                               trusted_domain_state->trusted_domain_dn, &res, attrs);
830         if (ret != 1) {
831                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
832         }
833         msg = res[0];
834         
835         r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
836         if (!r->out.info) {
837                 return NT_STATUS_NO_MEMORY;
838         }
839         switch (r->in.level) {
840         case LSA_TRUSTED_DOMAIN_INFO_NAME:
841                 r->out.info->name.netbios_name.string
842                         = samdb_result_string(msg, "flatname", NULL);                                      
843                 break;
844         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
845                 r->out.info->posix_offset.posix_offset
846                         = samdb_result_uint(msg, "posixOffset", 0);                                        
847                 break;
848         default:
849                 /* oops, we don't want to return the info after all */
850                 talloc_free(r->out.info);
851                 r->out.info = NULL;
852                 return NT_STATUS_INVALID_INFO_CLASS;
853         }
854
855         return NT_STATUS_OK;
856 }
857
858
859 /* 
860   lsa_SetInformationTrustedDomain
861 */
862 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
863                        struct lsa_SetInformationTrustedDomain *r)
864 {
865         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
866 }
867
868
869 /*
870   lsa_QueryTrustedDomainInfoByName
871 */
872 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
873                                                  TALLOC_CTX *mem_ctx,
874                                                  struct lsa_QueryTrustedDomainInfoByName *r)
875 {
876         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
877 }
878
879 /*
880   lsa_SetTrustedDomainInfoByName
881 */
882 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
883                                                TALLOC_CTX *mem_ctx,
884                                                struct lsa_SetTrustedDomainInfoByName *r)
885 {
886         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
887 }
888
889 /*
890   lsa_EnumTrustedDomainsEx
891 */
892 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call,
893                                          TALLOC_CTX *mem_ctx,
894                                          struct lsa_EnumTrustedDomainsEx *r)
895 {
896         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
897 }
898
899 /*
900   lsa_CloseTrustedDomainEx
901 */
902 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
903                                          TALLOC_CTX *mem_ctx,
904                                          struct lsa_CloseTrustedDomainEx *r)
905 {
906         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
907 }
908
909
910 /*
911   comparison function for sorting lsa_DomainInformation array
912 */
913 static int compare_DomainInformation(struct lsa_DomainInformation *e1, struct lsa_DomainInformation *e2)
914 {
915         return strcasecmp(e1->name.string, e2->name.string);
916 }
917
918 /* 
919   lsa_EnumTrustDom 
920 */
921 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
922                                  struct lsa_EnumTrustDom *r)
923 {
924         struct dcesrv_handle *policy_handle;
925         struct lsa_DomainInformation *entries;
926         struct lsa_policy_state *policy_state;
927         struct ldb_message **domains;
928         const char *attrs[] = {
929                 "flatname", 
930                 "securityIdentifier",
931                 NULL
932         };
933
934
935         int count, i;
936
937         *r->out.resume_handle = 0;
938
939         r->out.domains->domains = NULL;
940         r->out.domains->count = 0;
941
942         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
943
944         policy_state = policy_handle->data;
945
946         /* search for all users in this domain. This could possibly be cached and 
947            resumed based on resume_key */
948         count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 
949                              "objectclass=trustedDomain");
950         if (count == -1) {
951                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
952         }
953         if (count == 0 || r->in.max_size == 0) {
954                 return NT_STATUS_OK;
955         }
956
957         /* convert to lsa_DomainInformation format */
958         entries = talloc_array(mem_ctx, struct lsa_DomainInformation, count);
959         if (!entries) {
960                 return NT_STATUS_NO_MEMORY;
961         }
962         for (i=0;i<count;i++) {
963                 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
964                 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
965         }
966
967         /* sort the results by name */
968         qsort(entries, count, sizeof(struct lsa_DomainInformation), 
969               (comparison_fn_t)compare_DomainInformation);
970
971         if (*r->in.resume_handle >= count) {
972                 *r->out.resume_handle = -1;
973
974                 return NT_STATUS_NO_MORE_ENTRIES;
975         }
976
977         /* return the rest, limit by max_size. Note that we 
978            use the w2k3 element size value of 60 */
979         r->out.domains->count = count - *r->in.resume_handle;
980         r->out.domains->count = MIN(r->out.domains->count, 
981                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
982
983         r->out.domains->domains = entries + *r->in.resume_handle;
984         r->out.domains->count = r->out.domains->count;
985
986         if (r->out.domains->count < count - *r->in.resume_handle) {
987                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
988                 return STATUS_MORE_ENTRIES;
989         }
990
991         return NT_STATUS_OK;
992 }
993
994
995 /*
996   return the authority name and authority sid, given a sid
997 */
998 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
999                                    TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1000                                    const char **authority_name,
1001                                    struct dom_sid **authority_sid)
1002 {
1003         if (dom_sid_in_domain(state->domain_sid, sid)) {
1004                 *authority_name = state->domain_name;
1005                 *authority_sid = state->domain_sid;
1006                 return NT_STATUS_OK;
1007         }
1008
1009         if (dom_sid_in_domain(state->builtin_sid, sid)) {
1010                 *authority_name = "BUILTIN";
1011                 *authority_sid = state->builtin_sid;
1012                 return NT_STATUS_OK;
1013         }
1014
1015         *authority_sid = dom_sid_dup(mem_ctx, sid);
1016         if (*authority_sid == NULL) {
1017                 return NT_STATUS_NO_MEMORY;
1018         }
1019         (*authority_sid)->num_auths = 0;
1020         *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1021         if (*authority_name == NULL) {
1022                 return NT_STATUS_NO_MEMORY;
1023         }
1024
1025         return NT_STATUS_OK;
1026 }
1027
1028 /*
1029   add to the lsa_RefDomainList for LookupSids and LookupNames
1030 */
1031 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, 
1032                                    struct dom_sid *sid, 
1033                                    struct lsa_RefDomainList *domains,
1034                                    uint32_t *sid_index)
1035 {
1036         NTSTATUS status;
1037         const char *authority_name;
1038         struct dom_sid *authority_sid;
1039         int i;
1040
1041         /* work out the authority name */
1042         status = lsa_authority_name(state, mem_ctx, sid, 
1043                                     &authority_name, &authority_sid);
1044         if (!NT_STATUS_IS_OK(status)) {
1045                 return status;
1046         }
1047         
1048         /* see if we've already done this authority name */
1049         for (i=0;i<domains->count;i++) {
1050                 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1051                         *sid_index = i;
1052                         return NT_STATUS_OK;
1053                 }
1054         }
1055
1056         domains->domains = talloc_realloc(domains, 
1057                                           domains->domains,
1058                                           struct lsa_TrustInformation,
1059                                           domains->count+1);
1060         if (domains->domains == NULL) {
1061                 return NT_STATUS_NO_MEMORY;
1062         }
1063         domains->domains[i].name.string = authority_name;
1064         domains->domains[i].sid         = authority_sid;
1065         domains->count++;
1066         *sid_index = i;
1067         
1068         return NT_STATUS_OK;
1069 }
1070
1071 /*
1072   lookup a name for 1 SID
1073 */
1074 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1075                                struct dom_sid *sid, const char *sid_str,
1076                                const char **name, uint32_t *atype)
1077 {
1078         int ret;
1079         struct ldb_message **res;
1080         const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1081         NTSTATUS status;
1082
1083         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
1084                            "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1085         if (ret == 1) {
1086                 *name = ldb_msg_find_string(res[0], "sAMAccountName", NULL);
1087                 if (!*name) {
1088                         *name = ldb_msg_find_string(res[0], "name", NULL);
1089                         if (!*name) {
1090                                 *name = talloc_strdup(mem_ctx, sid_str);
1091                                 NTSTATUS_TALLOC_CHECK(*name);
1092                         }
1093                 }
1094
1095                 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1096
1097                 return NT_STATUS_OK;
1098         }
1099
1100         status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1101
1102         return status;
1103 }
1104
1105
1106 /*
1107   lsa_LookupSids3
1108 */
1109 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1110                                 TALLOC_CTX *mem_ctx,
1111                                 struct lsa_LookupSids3 *r)
1112 {
1113         struct lsa_policy_state *state;
1114         int i;
1115         NTSTATUS status = NT_STATUS_OK;
1116
1117         r->out.domains = NULL;
1118
1119         status = lsa_get_policy_state(dce_call, mem_ctx, &state);
1120         if (!NT_STATUS_IS_OK(status)) {
1121                 return status;
1122         }
1123
1124         r->out.domains = talloc_zero(mem_ctx,  struct lsa_RefDomainList);
1125         if (r->out.domains == NULL) {
1126                 return NT_STATUS_NO_MEMORY;
1127         }
1128
1129         r->out.names = talloc_zero(mem_ctx,  struct lsa_TransNameArray2);
1130         if (r->out.names == NULL) {
1131                 return NT_STATUS_NO_MEMORY;
1132         }
1133
1134         *r->out.count = 0;
1135
1136         r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2, 
1137                                              r->in.sids->num_sids);
1138         if (r->out.names->names == NULL) {
1139                 return NT_STATUS_NO_MEMORY;
1140         }
1141
1142         for (i=0;i<r->in.sids->num_sids;i++) {
1143                 struct dom_sid *sid = r->in.sids->sids[i].sid;
1144                 char *sid_str = dom_sid_string(mem_ctx, sid);
1145                 const char *name;
1146                 uint32_t atype, rtype, sid_index;
1147                 NTSTATUS status2;
1148
1149                 r->out.names->count++;
1150                 (*r->out.count)++;
1151
1152                 r->out.names->names[i].sid_type    = SID_NAME_UNKNOWN;
1153                 r->out.names->names[i].name.string = sid_str;
1154                 r->out.names->names[i].sid_index   = 0xFFFFFFFF;
1155                 r->out.names->names[i].unknown     = 0;
1156
1157                 if (sid_str == NULL) {
1158                         r->out.names->names[i].name.string = "(SIDERROR)";
1159                         status = STATUS_SOME_UNMAPPED;
1160                         continue;
1161                 }
1162
1163                 /* work out the authority name */
1164                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1165                 if (!NT_STATUS_IS_OK(status2)) {
1166                         return status2;
1167                 }
1168
1169                 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str, 
1170                                          &name, &atype);
1171                 if (!NT_STATUS_IS_OK(status2)) {
1172                         status = STATUS_SOME_UNMAPPED;
1173                         continue;
1174                 }
1175
1176                 rtype = samdb_atype_map(atype);
1177                 if (rtype == SID_NAME_UNKNOWN) {
1178                         status = STATUS_SOME_UNMAPPED;
1179                         continue;
1180                 }
1181
1182                 r->out.names->names[i].sid_type    = rtype;
1183                 r->out.names->names[i].name.string = name;
1184                 r->out.names->names[i].sid_index   = sid_index;
1185                 r->out.names->names[i].unknown     = 0;
1186         }
1187         
1188         return status;
1189 }
1190
1191
1192 /*
1193   lsa_LookupSids2
1194 */
1195 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1196                                 TALLOC_CTX *mem_ctx,
1197                                 struct lsa_LookupSids2 *r)
1198 {
1199         struct lsa_LookupSids3 r3;
1200         NTSTATUS status;
1201
1202         r3.in.sids     = r->in.sids;
1203         r3.in.names    = r->in.names;
1204         r3.in.level    = r->in.level;
1205         r3.in.count    = r->in.count;
1206         r3.in.unknown1 = r->in.unknown1;
1207         r3.in.unknown2 = r->in.unknown2;
1208         r3.out.count   = r->out.count;
1209         r3.out.names   = r->out.names;
1210
1211         status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1212         if (dce_call->fault_code != 0) {
1213                 return status;
1214         }
1215
1216         r->out.domains = r3.out.domains;
1217         r->out.names   = r3.out.names;
1218         r->out.count   = r3.out.count;
1219
1220         return status;
1221 }
1222
1223
1224 /* 
1225   lsa_LookupSids 
1226 */
1227 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1228                                struct lsa_LookupSids *r)
1229 {
1230         struct lsa_LookupSids3 r3;
1231         NTSTATUS status;
1232         int i;
1233
1234         r3.in.sids     = r->in.sids;
1235         r3.in.names    = NULL;
1236         r3.in.level    = r->in.level;
1237         r3.in.count    = r->in.count;
1238         r3.in.unknown1 = 0;
1239         r3.in.unknown2 = 0;
1240         r3.out.count   = r->out.count;
1241         r3.out.names   = NULL;
1242
1243         status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
1244         if (dce_call->fault_code != 0) {
1245                 return status;
1246         }
1247
1248         r->out.domains = r3.out.domains;
1249         if (!r3.out.names) {
1250                 r->out.names = NULL;
1251                 return status;
1252         }
1253
1254         r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1255         if (r->out.names == NULL) {
1256                 return NT_STATUS_NO_MEMORY;
1257         }
1258         r->out.names->count = r3.out.names->count;
1259         r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName, 
1260                                              r->out.names->count);
1261         if (r->out.names->names == NULL) {
1262                 return NT_STATUS_NO_MEMORY;
1263         }
1264         for (i=0;i<r->out.names->count;i++) {
1265                 r->out.names->names[i].sid_type    = r3.out.names->names[i].sid_type;
1266                 r->out.names->names[i].name.string = r3.out.names->names[i].name.string;
1267                 r->out.names->names[i].sid_index   = r3.out.names->names[i].sid_index;
1268         }
1269
1270         return status;
1271 }
1272
1273
1274 /* 
1275   lsa_OpenAccount 
1276 */
1277 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1278                                 struct lsa_OpenAccount *r)
1279 {
1280         struct dcesrv_handle *h, *ah;
1281         struct lsa_policy_state *state;
1282         struct lsa_account_state *astate;
1283
1284         ZERO_STRUCTP(r->out.acct_handle);
1285
1286         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1287
1288         state = h->data;
1289
1290         astate = talloc(dce_call->conn, struct lsa_account_state);
1291         if (astate == NULL) {
1292                 return NT_STATUS_NO_MEMORY;
1293         }
1294
1295         astate->account_sid = dom_sid_dup(astate, r->in.sid);
1296         if (astate->account_sid == NULL) {
1297                 talloc_free(astate);
1298                 return NT_STATUS_NO_MEMORY;
1299         }
1300         
1301         /* check it really exists */
1302         astate->account_dn = samdb_search_dn(state->sam_ldb, astate,
1303                                              NULL, "(&(objectSid=%s)(objectClass=group))", 
1304                                              ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid));
1305         if (astate->account_dn == NULL) {
1306                 talloc_free(astate);
1307                 return NT_STATUS_NO_SUCH_USER;
1308         }
1309         
1310         astate->policy = talloc_reference(astate, state);
1311         astate->access_mask = r->in.access_mask;
1312
1313         ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1314         if (!ah) {
1315                 talloc_free(astate);
1316                 return NT_STATUS_NO_MEMORY;
1317         }
1318
1319         ah->data = talloc_steal(ah, astate);
1320
1321         *r->out.acct_handle = ah->wire_handle;
1322
1323         return NT_STATUS_OK;
1324 }
1325
1326
1327 /* 
1328   lsa_EnumPrivsAccount 
1329 */
1330 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 
1331                                      TALLOC_CTX *mem_ctx,
1332                                      struct lsa_EnumPrivsAccount *r)
1333 {
1334         struct dcesrv_handle *h;
1335         struct lsa_account_state *astate;
1336         int ret, i;
1337         struct ldb_message **res;
1338         const char * const attrs[] = { "privilege", NULL};
1339         struct ldb_message_element *el;
1340
1341         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1342
1343         astate = h->data;
1344
1345         r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1346         r->out.privs->count = 0;
1347         r->out.privs->unknown = 0;
1348         r->out.privs->set = NULL;
1349
1350         ret = gendb_search_dn(astate->policy->sam_ldb, mem_ctx,
1351                               astate->account_dn, &res, attrs);
1352         if (ret != 1) {
1353                 return NT_STATUS_OK;
1354         }
1355
1356         el = ldb_msg_find_element(res[0], "privilege");
1357         if (el == NULL || el->num_values == 0) {
1358                 return NT_STATUS_OK;
1359         }
1360
1361         r->out.privs->set = talloc_array(r->out.privs, 
1362                                            struct lsa_LUIDAttribute, el->num_values);
1363         if (r->out.privs->set == NULL) {
1364                 return NT_STATUS_NO_MEMORY;
1365         }
1366
1367         for (i=0;i<el->num_values;i++) {
1368                 int id = sec_privilege_id((const char *)el->values[i].data);
1369                 if (id == -1) {
1370                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1371                 }
1372                 r->out.privs->set[i].attribute = 0;
1373                 r->out.privs->set[i].luid.low = id;
1374                 r->out.privs->set[i].luid.high = 0;
1375         }
1376
1377         r->out.privs->count = el->num_values;
1378
1379         return NT_STATUS_OK;
1380 }
1381
1382 /* 
1383   lsa_EnumAccountRights 
1384 */
1385 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
1386                                       TALLOC_CTX *mem_ctx,
1387                                       struct lsa_EnumAccountRights *r)
1388 {
1389         struct dcesrv_handle *h;
1390         struct lsa_policy_state *state;
1391         int ret, i;
1392         struct ldb_message **res;
1393         const char * const attrs[] = { "privilege", NULL};
1394         const char *sidstr;
1395         struct ldb_message_element *el;
1396
1397         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1398
1399         state = h->data;
1400
1401         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1402         if (sidstr == NULL) {
1403                 return NT_STATUS_NO_MEMORY;
1404         }
1405
1406         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
1407                            "objectSid=%s", sidstr);
1408         if (ret != 1) {
1409                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1410         }
1411
1412         el = ldb_msg_find_element(res[0], "privilege");
1413         if (el == NULL || el->num_values == 0) {
1414                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1415         }
1416
1417         r->out.rights->count = el->num_values;
1418         r->out.rights->names = talloc_array(r->out.rights, 
1419                                             struct lsa_StringLarge, r->out.rights->count);
1420         if (r->out.rights->names == NULL) {
1421                 return NT_STATUS_NO_MEMORY;
1422         }
1423
1424         for (i=0;i<el->num_values;i++) {
1425                 r->out.rights->names[i].string = (const char *)el->values[i].data;
1426         }
1427
1428         return NT_STATUS_OK;
1429 }
1430
1431
1432
1433 /* 
1434   helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1435 */
1436 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
1437                                            TALLOC_CTX *mem_ctx,
1438                                            struct lsa_policy_state *state,
1439                                            int ldb_flag,
1440                                            struct dom_sid *sid,
1441                                            const struct lsa_RightSet *rights)
1442 {
1443         const char *sidstr;
1444         struct ldb_message *msg;
1445         struct ldb_message_element el;
1446         int i, ret;
1447         struct lsa_EnumAccountRights r2;
1448
1449         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1450         if (sidstr == NULL) {
1451                 return NT_STATUS_NO_MEMORY;
1452         }
1453
1454         msg = ldb_msg_new(mem_ctx);
1455         if (msg == NULL) {
1456                 return NT_STATUS_NO_MEMORY;
1457         }
1458
1459         msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx, NULL, "objectSid=%s", sidstr);
1460         if (msg->dn == NULL) {
1461                 return NT_STATUS_NO_SUCH_USER;
1462         }
1463
1464         if (ldb_msg_add_empty(msg, "privilege", ldb_flag)) {
1465                 return NT_STATUS_NO_MEMORY;
1466         }
1467
1468         if (ldb_flag == LDB_FLAG_MOD_ADD) {
1469                 NTSTATUS status;
1470
1471                 r2.in.handle = &state->handle->wire_handle;
1472                 r2.in.sid = sid;
1473                 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1474
1475                 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1476                 if (!NT_STATUS_IS_OK(status)) {
1477                         ZERO_STRUCTP(r2.out.rights);
1478                 }
1479         }
1480
1481         el.num_values = 0;
1482         el.values = talloc_array(mem_ctx, struct ldb_val, rights->count);
1483         if (el.values == NULL) {
1484                 return NT_STATUS_NO_MEMORY;
1485         }
1486         for (i=0;i<rights->count;i++) {
1487                 if (sec_privilege_id(rights->names[i].string) == -1) {
1488                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1489                 }
1490
1491                 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1492                         int j;
1493                         for (j=0;j<r2.out.rights->count;j++) {
1494                                 if (strcasecmp_m(r2.out.rights->names[j].string, 
1495                                                rights->names[i].string) == 0) {
1496                                         break;
1497                                 }
1498                         }
1499                         if (j != r2.out.rights->count) continue;
1500                 }
1501
1502
1503                 el.values[el.num_values].length = strlen(rights->names[i].string);
1504                 el.values[el.num_values].data = (uint8_t *)talloc_strdup(mem_ctx, rights->names[i].string);
1505                 if (el.values[el.num_values].data == NULL) {
1506                         return NT_STATUS_NO_MEMORY;
1507                 }
1508                 el.num_values++;
1509         }
1510
1511         if (el.num_values == 0) {
1512                 return NT_STATUS_OK;
1513         }
1514
1515         ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
1516         if (ret != 0) {
1517                 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1518                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1519                 }
1520                 return NT_STATUS_UNEXPECTED_IO_ERROR;
1521         }
1522
1523         return NT_STATUS_OK;
1524 }
1525
1526 /* 
1527   lsa_AddPrivilegesToAccount
1528 */
1529 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1530                                            struct lsa_AddPrivilegesToAccount *r)
1531 {
1532         struct lsa_RightSet rights;
1533         struct dcesrv_handle *h;
1534         struct lsa_account_state *astate;
1535         int i;
1536
1537         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1538
1539         astate = h->data;
1540
1541         rights.count = r->in.privs->count;
1542         rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
1543         if (rights.names == NULL) {
1544                 return NT_STATUS_NO_MEMORY;
1545         }
1546         for (i=0;i<rights.count;i++) {
1547                 int id = r->in.privs->set[i].luid.low;
1548                 if (r->in.privs->set[i].luid.high) {
1549                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1550                 }
1551                 rights.names[i].string = sec_privilege_name(id);
1552                 if (rights.names[i].string == NULL) {
1553                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1554                 }
1555         }
1556
1557         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1558                                           LDB_FLAG_MOD_ADD, astate->account_sid,
1559                                           &rights);
1560 }
1561
1562
1563 /* 
1564   lsa_RemovePrivilegesFromAccount
1565 */
1566 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1567                                                 struct lsa_RemovePrivilegesFromAccount *r)
1568 {
1569         struct lsa_RightSet *rights;
1570         struct dcesrv_handle *h;
1571         struct lsa_account_state *astate;
1572         int i;
1573
1574         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1575
1576         astate = h->data;
1577
1578         rights = talloc(mem_ctx, struct lsa_RightSet);
1579
1580         if (r->in.remove_all == 1 && 
1581             r->in.privs == NULL) {
1582                 struct lsa_EnumAccountRights r2;
1583                 NTSTATUS status;
1584
1585                 r2.in.handle = &astate->policy->handle->wire_handle;
1586                 r2.in.sid = astate->account_sid;
1587                 r2.out.rights = rights;
1588
1589                 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1590                 if (!NT_STATUS_IS_OK(status)) {
1591                         return status;
1592                 }
1593
1594                 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1595                                                   LDB_FLAG_MOD_DELETE, astate->account_sid,
1596                                                   r2.out.rights);
1597         }
1598
1599         if (r->in.remove_all != 0) {
1600                 return NT_STATUS_INVALID_PARAMETER;
1601         }
1602
1603         rights->count = r->in.privs->count;
1604         rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
1605         if (rights->names == NULL) {
1606                 return NT_STATUS_NO_MEMORY;
1607         }
1608         for (i=0;i<rights->count;i++) {
1609                 int id = r->in.privs->set[i].luid.low;
1610                 if (r->in.privs->set[i].luid.high) {
1611                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1612                 }
1613                 rights->names[i].string = sec_privilege_name(id);
1614                 if (rights->names[i].string == NULL) {
1615                         return NT_STATUS_NO_SUCH_PRIVILEGE;
1616                 }
1617         }
1618
1619         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
1620                                           LDB_FLAG_MOD_DELETE, astate->account_sid,
1621                                           rights);
1622 }
1623
1624
1625 /* 
1626   lsa_GetQuotasForAccount
1627 */
1628 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1629                        struct lsa_GetQuotasForAccount *r)
1630 {
1631         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1632 }
1633
1634
1635 /* 
1636   lsa_SetQuotasForAccount
1637 */
1638 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1639                        struct lsa_SetQuotasForAccount *r)
1640 {
1641         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1642 }
1643
1644
1645 /* 
1646   lsa_GetSystemAccessAccount
1647 */
1648 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1649                        struct lsa_GetSystemAccessAccount *r)
1650 {
1651         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1652 }
1653
1654
1655 /* 
1656   lsa_SetSystemAccessAccount
1657 */
1658 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1659                        struct lsa_SetSystemAccessAccount *r)
1660 {
1661         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1662 }
1663
1664
1665 /* 
1666   lsa_CreateSecret 
1667 */
1668 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1669                                  struct lsa_CreateSecret *r)
1670 {
1671         struct dcesrv_handle *policy_handle;
1672         struct lsa_policy_state *policy_state;
1673         struct lsa_secret_state *secret_state;
1674         struct dcesrv_handle *handle;
1675         struct ldb_message **msgs, *msg;
1676         const char *attrs[] = {
1677                 NULL
1678         };
1679
1680         const char *name;
1681
1682         int ret;
1683
1684         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1685         ZERO_STRUCTP(r->out.sec_handle);
1686         
1687         policy_state = policy_handle->data;
1688
1689         if (!r->in.name.string) {
1690                 return NT_STATUS_INVALID_PARAMETER;
1691         }
1692         
1693         secret_state = talloc(mem_ctx, struct lsa_secret_state);
1694         if (!secret_state) {
1695                 return NT_STATUS_NO_MEMORY;
1696         }
1697         secret_state->policy = policy_state;
1698
1699         msg = ldb_msg_new(mem_ctx);
1700         if (msg == NULL) {
1701                 return NT_STATUS_NO_MEMORY;
1702         }
1703
1704         if (strncmp("G$", r->in.name.string, 2) == 0) {
1705                 const char *name2;
1706                 name = &r->in.name.string[2];
1707                 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1708                 secret_state->global = True;
1709
1710                 if (strlen(name) < 1) {
1711                         return NT_STATUS_INVALID_PARAMETER;
1712                 }
1713
1714                 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
1715                 /* search for the secret record */
1716                 ret = gendb_search(secret_state->sam_ldb,
1717                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
1718                                    "(&(cn=%s)(objectclass=secret))", 
1719                                    name2);
1720                 if (ret > 0) {
1721                         return NT_STATUS_OBJECT_NAME_COLLISION;
1722                 }
1723                 
1724                 if (ret < 0 || ret > 1) {
1725                         DEBUG(0,("Found %d records matching DN %s\n", ret,
1726                                  ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1727                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1728                 }
1729
1730                 msg->dn = ldb_dn_build_child(mem_ctx, "cn", name2, policy_state->system_dn);
1731                 if (!name2 || !msg->dn) {
1732                         return NT_STATUS_NO_MEMORY;
1733                 }
1734                 
1735                 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
1736         
1737         } else {
1738                 secret_state->global = False;
1739
1740                 name = r->in.name.string;
1741                 if (strlen(name) < 1) {
1742                         return NT_STATUS_INVALID_PARAMETER;
1743                 }
1744
1745                 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1746                 /* search for the secret record */
1747                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1748                                    ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
1749                                    &msgs, attrs,
1750                                    "(&(cn=%s)(objectclass=secret))", 
1751                                    ldb_binary_encode_string(mem_ctx, name));
1752                 if (ret > 0) {
1753                         return NT_STATUS_OBJECT_NAME_COLLISION;
1754                 }
1755                 
1756                 if (ret < 0 || ret > 1) {
1757                         DEBUG(0,("Found %d records matching DN %s\n", ret,
1758                                  ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1759                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1760                 }
1761
1762                 msg->dn = ldb_dn_string_compose(mem_ctx, NULL, "cn=%s,cn=LSA Secrets", name);
1763                 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1764         } 
1765
1766         /* pull in all the template attributes.  Note this is always from the global samdb */
1767         ret = samdb_copy_template(secret_state->policy->sam_ldb, mem_ctx, msg, 
1768                                   "(&(name=TemplateSecret)(objectclass=secretTemplate))");
1769         if (ret != 0) {
1770                 DEBUG(0,("Failed to load TemplateSecret from samdb\n"));
1771                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1772         }
1773
1774         samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1775         
1776         secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1777
1778         /* create the secret */
1779         ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
1780         if (ret != 0) {
1781                 DEBUG(0,("Failed to create secret record %s\n",
1782                          ldb_dn_linearize(mem_ctx, msg->dn)));
1783                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1784         }
1785
1786         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1787         if (!handle) {
1788                 return NT_STATUS_NO_MEMORY;
1789         }
1790         
1791         handle->data = talloc_steal(handle, secret_state);
1792         
1793         secret_state->access_mask = r->in.access_mask;
1794         secret_state->policy = talloc_reference(secret_state, policy_state);
1795         
1796         *r->out.sec_handle = handle->wire_handle;
1797         
1798         return NT_STATUS_OK;
1799 }
1800
1801
1802 /* 
1803   lsa_OpenSecret 
1804 */
1805 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1806                                struct lsa_OpenSecret *r)
1807 {
1808         struct dcesrv_handle *policy_handle;
1809         
1810         struct lsa_policy_state *policy_state;
1811         struct lsa_secret_state *secret_state;
1812         struct dcesrv_handle *handle;
1813         struct ldb_message **msgs;
1814         const char *attrs[] = {
1815                 NULL
1816         };
1817
1818         const char *name;
1819
1820         int ret;
1821
1822         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1823         ZERO_STRUCTP(r->out.sec_handle);
1824         policy_state = policy_handle->data;
1825
1826         if (!r->in.name.string) {
1827                 return NT_STATUS_INVALID_PARAMETER;
1828         }
1829         
1830         secret_state = talloc(mem_ctx, struct lsa_secret_state);
1831         if (!secret_state) {
1832                 return NT_STATUS_NO_MEMORY;
1833         }
1834         secret_state->policy = policy_state;
1835
1836         if (strncmp("G$", r->in.name.string, 2) == 0) {
1837                 name = &r->in.name.string[2];
1838                 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1839                 secret_state->global = True;
1840
1841                 if (strlen(name) < 1) {
1842                         return NT_STATUS_INVALID_PARAMETER;
1843                 }
1844
1845                 /* search for the secret record */
1846                 ret = gendb_search(secret_state->sam_ldb,
1847                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
1848                                    "(&(cn=%s Secret)(objectclass=secret))", 
1849                                    ldb_binary_encode_string(mem_ctx, name));
1850                 if (ret == 0) {
1851                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1852                 }
1853                 
1854                 if (ret != 1) {
1855                         DEBUG(0,("Found %d records matching DN %s\n", ret,
1856                                  ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1857                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1858                 }
1859         
1860         } else {
1861                 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1862
1863                 secret_state->global = False;
1864                 name = r->in.name.string;
1865                 if (strlen(name) < 1) {
1866                         return NT_STATUS_INVALID_PARAMETER;
1867                 }
1868
1869                 /* search for the secret record */
1870                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1871                                    ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
1872                                    &msgs, attrs,
1873                                    "(&(cn=%s)(objectclass=secret))", 
1874                                    ldb_binary_encode_string(mem_ctx, name));
1875                 if (ret == 0) {
1876                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1877                 }
1878                 
1879                 if (ret != 1) {
1880                         DEBUG(0,("Found %d records matching DN %s\n", ret,
1881                                  ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
1882                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1883                 }
1884         } 
1885
1886         secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1887         
1888         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1889         if (!handle) {
1890                 return NT_STATUS_NO_MEMORY;
1891         }
1892         
1893         handle->data = talloc_steal(handle, secret_state);
1894         
1895         secret_state->access_mask = r->in.access_mask;
1896         secret_state->policy = talloc_reference(secret_state, policy_state);
1897         
1898         *r->out.sec_handle = handle->wire_handle;
1899         
1900         return NT_STATUS_OK;
1901 }
1902
1903
1904 /* 
1905   lsa_SetSecret 
1906 */
1907 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1908                               struct lsa_SetSecret *r)
1909 {
1910
1911         struct dcesrv_handle *h;
1912         struct lsa_secret_state *secret_state;
1913         struct ldb_message *msg;
1914         DATA_BLOB session_key;
1915         DATA_BLOB crypt_secret, secret;
1916         struct ldb_val val;
1917         int ret;
1918         NTSTATUS status = NT_STATUS_OK;
1919
1920         struct timeval now = timeval_current();
1921         NTTIME nt_now = timeval_to_nttime(&now);
1922
1923         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1924
1925         secret_state = h->data;
1926
1927         msg = ldb_msg_new(mem_ctx);
1928         if (msg == NULL) {
1929                 return NT_STATUS_NO_MEMORY;
1930         }
1931
1932         msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1933         if (!msg->dn) {
1934                 return NT_STATUS_NO_MEMORY;
1935         }
1936         status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1937         if (!NT_STATUS_IS_OK(status)) {
1938                 return status;
1939         }
1940
1941         if (r->in.old_val) {
1942                 /* Decrypt */
1943                 crypt_secret.data = r->in.old_val->data;
1944                 crypt_secret.length = r->in.old_val->size;
1945                 
1946                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1947                 if (!NT_STATUS_IS_OK(status)) {
1948                         return status;
1949                 }
1950                 
1951                 val.data = secret.data;
1952                 val.length = secret.length;
1953                 
1954                 /* set value */
1955                 if (samdb_msg_add_value(secret_state->sam_ldb, 
1956                                         mem_ctx, msg, "priorSecret", &val) != 0) {
1957                         return NT_STATUS_NO_MEMORY; 
1958                 }
1959                 
1960                 /* set old value mtime */
1961                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
1962                                          mem_ctx, msg, "priorSetTime", nt_now) != 0) { 
1963                         return NT_STATUS_NO_MEMORY; 
1964                 }
1965
1966                 if (!r->in.new_val) {
1967                         /* This behaviour varies depending of if this is a local, or a global secret... */
1968                         if (secret_state->global) {
1969                                 /* set old value mtime */
1970                                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
1971                                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
1972                                         return NT_STATUS_NO_MEMORY; 
1973                                 }
1974                         } else {
1975                                 if (samdb_msg_add_delete(secret_state->sam_ldb, 
1976                                                          mem_ctx, msg, "secret")) {
1977                                         return NT_STATUS_NO_MEMORY;
1978                                 }
1979                                 if (samdb_msg_add_delete(secret_state->sam_ldb, 
1980                                                          mem_ctx, msg, "lastSetTime")) {
1981                                         return NT_STATUS_NO_MEMORY;
1982                                 }
1983                         }
1984                 }
1985         }
1986
1987         if (r->in.new_val) {
1988                 /* Decrypt */
1989                 crypt_secret.data = r->in.new_val->data;
1990                 crypt_secret.length = r->in.new_val->size;
1991                 
1992                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1993                 if (!NT_STATUS_IS_OK(status)) {
1994                         return status;
1995                 }
1996                 
1997                 val.data = secret.data;
1998                 val.length = secret.length;
1999                 
2000                 /* set value */
2001                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2002                                         mem_ctx, msg, "secret", &val) != 0) {
2003                         return NT_STATUS_NO_MEMORY; 
2004                 }
2005                 
2006                 /* set new value mtime */
2007                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2008                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
2009                         return NT_STATUS_NO_MEMORY; 
2010                 }
2011                 
2012                 /* If the old value is not set, then migrate the
2013                  * current value to the old value */
2014                 if (!r->in.old_val) {
2015                         const struct ldb_val *new_val;
2016                         NTTIME last_set_time;
2017                         struct ldb_message **res;
2018                         const char *attrs[] = {
2019                                 "secret",
2020                                 "lastSetTime",
2021                                 NULL
2022                         };
2023                         
2024                         /* search for the secret record */
2025                         ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2026                                               secret_state->secret_dn, &res, attrs);
2027                         if (ret == 0) {
2028                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2029                         }
2030                         
2031                         if (ret != 1) {
2032                                 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2033                                          ldb_dn_linearize(mem_ctx, secret_state->secret_dn)));
2034                                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2035                         }
2036
2037                         new_val = ldb_msg_find_ldb_val(res[0], "secret");
2038                         last_set_time = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
2039                         
2040                         if (new_val) {
2041                                 /* set value */
2042                                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2043                                                         mem_ctx, msg, "priorSecret", 
2044                                                         new_val) != 0) {
2045                                         return NT_STATUS_NO_MEMORY; 
2046                                 }
2047                         }
2048                         
2049                         /* set new value mtime */
2050                         if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2051                                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2052                                                          mem_ctx, msg, "priorSetTime", last_set_time) != 0) { 
2053                                         return NT_STATUS_NO_MEMORY; 
2054                                 }
2055                         }
2056                 }
2057         }
2058
2059         /* modify the samdb record */
2060         ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2061         if (ret != 0) {
2062                 /* we really need samdb.c to return NTSTATUS */
2063                 return NT_STATUS_UNSUCCESSFUL;
2064         }
2065
2066         return NT_STATUS_OK;
2067 }
2068
2069
2070 /* 
2071   lsa_QuerySecret 
2072 */
2073 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2074                                 struct lsa_QuerySecret *r)
2075 {
2076         struct dcesrv_handle *h;
2077         struct lsa_secret_state *secret_state;
2078         struct ldb_message *msg;
2079         DATA_BLOB session_key;
2080         DATA_BLOB crypt_secret, secret;
2081         int ret;
2082         struct ldb_message **res;
2083         const char *attrs[] = {
2084                 "secret",
2085                 "priorSecret",
2086                 "lastSetTime",
2087                 "priorSetTime", 
2088                 NULL
2089         };
2090
2091         NTSTATUS nt_status;
2092
2093         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2094
2095         secret_state = h->data;
2096
2097         /* pull all the user attributes */
2098         ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2099                               secret_state->secret_dn, &res, attrs);
2100         if (ret != 1) {
2101                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2102         }
2103         msg = res[0];
2104         
2105         nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2106         if (!NT_STATUS_IS_OK(nt_status)) {
2107                 return nt_status;
2108         }
2109         
2110         if (r->in.old_val) {
2111                 const struct ldb_val *prior_val;
2112                 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2113                 if (!r->out.old_val) {
2114                         return NT_STATUS_NO_MEMORY;
2115                 }
2116                 /* Decrypt */
2117                 prior_val = ldb_msg_find_ldb_val(res[0], "priorSecret");
2118                 
2119                 if (prior_val && prior_val->length) {
2120                         secret.data = prior_val->data;
2121                         secret.length = prior_val->length;
2122                 
2123                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2124                         if (!crypt_secret.length) {
2125                                 return NT_STATUS_NO_MEMORY;
2126                         }
2127                         r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2128                         if (!r->out.old_val->buf) {
2129                                 return NT_STATUS_NO_MEMORY;
2130                         }
2131                         r->out.old_val->buf->size = crypt_secret.length;
2132                         r->out.old_val->buf->length = crypt_secret.length;
2133                         r->out.old_val->buf->data = crypt_secret.data;
2134                 }
2135         }
2136         
2137         if (r->in.old_mtime) {
2138                 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2139                 if (!r->out.old_mtime) {
2140                         return NT_STATUS_NO_MEMORY;
2141                 }
2142                 *r->out.old_mtime = ldb_msg_find_uint64(res[0], "priorSetTime", 0);
2143         }
2144         
2145         if (r->in.new_val) {
2146                 const struct ldb_val *new_val;
2147                 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2148                 if (!r->out.new_val) {
2149                         return NT_STATUS_NO_MEMORY;
2150                 }
2151
2152                 /* Decrypt */
2153                 new_val = ldb_msg_find_ldb_val(res[0], "secret");
2154                 
2155                 if (new_val && new_val->length) {
2156                         secret.data = new_val->data;
2157                         secret.length = new_val->length;
2158                 
2159                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2160                         if (!crypt_secret.length) {
2161                                 return NT_STATUS_NO_MEMORY;
2162                         }
2163                         r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2164                         if (!r->out.new_val->buf) {
2165                                 return NT_STATUS_NO_MEMORY;
2166                         }
2167                         r->out.new_val->buf->length = crypt_secret.length;
2168                         r->out.new_val->buf->size = crypt_secret.length;
2169                         r->out.new_val->buf->data = crypt_secret.data;
2170                 }
2171         }
2172         
2173         if (r->in.new_mtime) {
2174                 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2175                 if (!r->out.new_mtime) {
2176                         return NT_STATUS_NO_MEMORY;
2177                 }
2178                 *r->out.new_mtime = ldb_msg_find_uint64(res[0], "lastSetTime", 0);
2179         }
2180         
2181         return NT_STATUS_OK;
2182 }
2183
2184
2185 /* 
2186   lsa_LookupPrivValue
2187 */
2188 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
2189                                     TALLOC_CTX *mem_ctx,
2190                                     struct lsa_LookupPrivValue *r)
2191 {
2192         struct dcesrv_handle *h;
2193         struct lsa_policy_state *state;
2194         int id;
2195
2196         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2197
2198         state = h->data;
2199
2200         id = sec_privilege_id(r->in.name->string);
2201         if (id == -1) {
2202                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2203         }
2204
2205         r->out.luid->low = id;
2206         r->out.luid->high = 0;
2207
2208         return NT_STATUS_OK;    
2209 }
2210
2211
2212 /* 
2213   lsa_LookupPrivName 
2214 */
2215 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
2216                                    TALLOC_CTX *mem_ctx,
2217                                    struct lsa_LookupPrivName *r)
2218 {
2219         struct dcesrv_handle *h;
2220         struct lsa_policy_state *state;
2221         const char *privname;
2222
2223         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2224
2225         state = h->data;
2226
2227         if (r->in.luid->high != 0) {
2228                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2229         }
2230
2231         privname = sec_privilege_name(r->in.luid->low);
2232         if (privname == NULL) {
2233                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2234         }
2235
2236         r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2237         if (r->out.name == NULL) {
2238                 return NT_STATUS_NO_MEMORY;
2239         }
2240         r->out.name->string = privname;
2241
2242         return NT_STATUS_OK;    
2243 }
2244
2245
2246 /* 
2247   lsa_LookupPrivDisplayName
2248 */
2249 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
2250                                           TALLOC_CTX *mem_ctx,
2251                                           struct lsa_LookupPrivDisplayName *r)
2252 {
2253         struct dcesrv_handle *h;
2254         struct lsa_policy_state *state;
2255         int id;
2256
2257         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2258
2259         state = h->data;
2260
2261         id = sec_privilege_id(r->in.name->string);
2262         if (id == -1) {
2263                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2264         }
2265         
2266         r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2267         if (r->out.disp_name == NULL) {
2268                 return NT_STATUS_NO_MEMORY;
2269         }
2270
2271         r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2272         if (r->out.disp_name->string == NULL) {
2273                 return NT_STATUS_INTERNAL_ERROR;
2274         }
2275
2276         return NT_STATUS_OK;
2277 }
2278
2279
2280 /* 
2281   lsa_DeleteObject
2282 */
2283 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2284                        struct lsa_DeleteObject *r)
2285 {
2286         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2287 }
2288
2289
2290 /* 
2291   lsa_EnumAccountsWithUserRight
2292 */
2293 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
2294                                               TALLOC_CTX *mem_ctx,
2295                                               struct lsa_EnumAccountsWithUserRight *r)
2296 {
2297         struct dcesrv_handle *h;
2298         struct lsa_policy_state *state;
2299         int ret, i;
2300         struct ldb_message **res;
2301         const char * const attrs[] = { "objectSid", NULL};
2302         const char *privname;
2303
2304         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2305
2306         state = h->data;
2307
2308         if (r->in.name == NULL) {
2309                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2310         } 
2311
2312         privname = r->in.name->string;
2313         if (sec_privilege_id(privname) == -1) {
2314                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2315         }
2316
2317         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
2318                            "privilege=%s", privname);
2319         if (ret <= 0) {
2320                 return NT_STATUS_NO_SUCH_USER;
2321         }
2322
2323         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2324         if (r->out.sids->sids == NULL) {
2325                 return NT_STATUS_NO_MEMORY;
2326         }
2327         for (i=0;i<ret;i++) {
2328                 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2329                                                                 res[i], "objectSid");
2330                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2331         }
2332         r->out.sids->num_sids = ret;
2333
2334         return NT_STATUS_OK;
2335 }
2336
2337
2338 /* 
2339   lsa_AddAccountRights
2340 */
2341 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
2342                                      TALLOC_CTX *mem_ctx,
2343                                      struct lsa_AddAccountRights *r)
2344 {
2345         struct dcesrv_handle *h;
2346         struct lsa_policy_state *state;
2347
2348         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2349
2350         state = h->data;
2351
2352         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2353                                           LDB_FLAG_MOD_ADD,
2354                                           r->in.sid, r->in.rights);
2355 }
2356
2357
2358 /* 
2359   lsa_RemoveAccountRights
2360 */
2361 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
2362                                         TALLOC_CTX *mem_ctx,
2363                                         struct lsa_RemoveAccountRights *r)
2364 {
2365         struct dcesrv_handle *h;
2366         struct lsa_policy_state *state;
2367
2368         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2369
2370         state = h->data;
2371
2372         return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2373                                           LDB_FLAG_MOD_DELETE,
2374                                           r->in.sid, r->in.rights);
2375 }
2376
2377
2378 /* 
2379   lsa_StorePrivateData
2380 */
2381 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2382                        struct lsa_StorePrivateData *r)
2383 {
2384         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2385 }
2386
2387
2388 /* 
2389   lsa_RetrievePrivateData
2390 */
2391 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2392                        struct lsa_RetrievePrivateData *r)
2393 {
2394         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2395 }
2396
2397
2398 /* 
2399   lsa_GetUserName
2400 */
2401 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2402                                 struct lsa_GetUserName *r)
2403 {
2404         NTSTATUS status = NT_STATUS_OK;
2405         const char *account_name;
2406         const char *authority_name;
2407         struct lsa_String *_account_name;
2408         struct lsa_StringPointer *_authority_name = NULL;
2409
2410         /* this is what w2k3 does */
2411         r->out.account_name = r->in.account_name;
2412         r->out.authority_name = r->in.authority_name;
2413
2414         if (r->in.account_name && r->in.account_name->string) {
2415                 return NT_STATUS_INVALID_PARAMETER;
2416         }
2417
2418         if (r->in.authority_name &&
2419             r->in.authority_name->string &&
2420             r->in.authority_name->string->string) {
2421                 return NT_STATUS_INVALID_PARAMETER;
2422         }
2423
2424         account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2425         authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2426
2427         _account_name = talloc(mem_ctx, struct lsa_String);
2428         NTSTATUS_TALLOC_CHECK(_account_name);
2429         _account_name->string = account_name;
2430
2431         if (r->in.authority_name) {
2432                 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2433                 NTSTATUS_TALLOC_CHECK(_authority_name);
2434                 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2435                 NTSTATUS_TALLOC_CHECK(_authority_name->string);
2436                 _authority_name->string->string = authority_name;
2437         }
2438
2439         r->out.account_name = _account_name;
2440         r->out.authority_name = _authority_name;
2441
2442         return status;
2443 }
2444
2445 /*
2446   lsa_SetInfoPolicy2
2447 */
2448 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2449                                    TALLOC_CTX *mem_ctx,
2450                                    struct lsa_SetInfoPolicy2 *r)
2451 {
2452         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2453 }
2454
2455 /*
2456   lsa_QueryDomainInformationPolicy
2457 */
2458 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2459                                                  TALLOC_CTX *mem_ctx,
2460                                                  struct lsa_QueryDomainInformationPolicy *r)
2461 {
2462         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2463 }
2464
2465 /*
2466   lsa_SetDomInfoPolicy
2467 */
2468 static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2469                                               TALLOC_CTX *mem_ctx,
2470                                               struct lsa_SetDomainInformationPolicy *r)
2471 {
2472         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2473 }
2474
2475 /*
2476   lsa_TestCall
2477 */
2478 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2479                              TALLOC_CTX *mem_ctx,
2480                              struct lsa_TestCall *r)
2481 {
2482         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2483 }
2484
2485 /*
2486   lookup a SID for 1 name
2487 */
2488 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2489                                 const char *name, struct dom_sid **sid, uint32_t *atype)
2490 {
2491         int ret;
2492         struct ldb_message **res;
2493         const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2494         const char *p;
2495
2496         p = strchr_m(name, '\\');
2497         if (p != NULL) {
2498                 /* TODO: properly parse the domain prefix here, and use it to 
2499                    limit the search */
2500                 name = p + 1;
2501         }
2502
2503         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
2504         if (ret == 1) {
2505                 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
2506                 if (*sid == NULL) {
2507                         return NT_STATUS_INVALID_SID;
2508                 }
2509
2510                 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
2511
2512                 return NT_STATUS_OK;
2513         }
2514
2515         /* need to add a call into sidmap to check for a allocated sid */
2516
2517         return NT_STATUS_INVALID_SID;
2518 }
2519
2520
2521 /*
2522   lsa_LookupNames4
2523 */
2524 static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call,
2525                                  TALLOC_CTX *mem_ctx,
2526                                  struct lsa_LookupNames4 *r)
2527 {
2528         struct lsa_policy_state *state;
2529         int i;
2530         NTSTATUS status = NT_STATUS_OK;
2531
2532         status = lsa_get_policy_state(dce_call, mem_ctx, &state);
2533         if (!NT_STATUS_IS_OK(status)) {
2534                 return status;
2535         }
2536
2537         r->out.domains = NULL;
2538
2539         r->out.domains = talloc_zero(mem_ctx,  struct lsa_RefDomainList);
2540         if (r->out.domains == NULL) {
2541                 return NT_STATUS_NO_MEMORY;
2542         }
2543
2544         r->out.sids = talloc_zero(mem_ctx,  struct lsa_TransSidArray3);
2545         if (r->out.sids == NULL) {
2546                 return NT_STATUS_NO_MEMORY;
2547         }
2548
2549         *r->out.count = 0;
2550
2551         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3, 
2552                                            r->in.num_names);
2553         if (r->out.sids->sids == NULL) {
2554                 return NT_STATUS_NO_MEMORY;
2555         }
2556
2557         for (i=0;i<r->in.num_names;i++) {
2558                 const char *name = r->in.names[i].string;
2559                 struct dom_sid *sid;
2560                 uint32_t atype, rtype, sid_index;
2561                 NTSTATUS status2;
2562
2563                 r->out.sids->count++;
2564                 (*r->out.count)++;
2565
2566                 r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
2567                 r->out.sids->sids[i].sid         = NULL;
2568                 r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
2569                 r->out.sids->sids[i].unknown     = 0;
2570
2571                 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2572                 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2573                         status = STATUS_SOME_UNMAPPED;
2574                         continue;
2575                 }
2576
2577                 rtype = samdb_atype_map(atype);
2578                 if (rtype == SID_NAME_UNKNOWN) {
2579                         status = STATUS_SOME_UNMAPPED;
2580                         continue;
2581                 }
2582
2583                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2584                 if (!NT_STATUS_IS_OK(status2)) {
2585                         return status2;
2586                 }
2587
2588                 r->out.sids->sids[i].sid_type    = rtype;
2589                 r->out.sids->sids[i].sid         = sid;
2590                 r->out.sids->sids[i].sid_index   = sid_index;
2591                 r->out.sids->sids[i].unknown     = 0;
2592         }
2593         
2594         return status;
2595 }
2596
2597 /* 
2598   lsa_LookupNames3
2599 */
2600 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2601                                  struct lsa_LookupNames3 *r)
2602 {
2603         struct lsa_LookupNames4 r2;
2604         NTSTATUS status;
2605         struct dcesrv_handle *h;
2606         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2607         
2608         r2.in.num_names = r->in.num_names;
2609         r2.in.names = r->in.names;
2610         r2.in.sids = r->in.sids;
2611         r2.in.count = r->in.count;
2612         r2.in.unknown1 = r->in.unknown1;
2613         r2.in.unknown2 = r->in.unknown2;
2614         r2.out.domains = r->out.domains;
2615         r2.out.sids = r->out.sids;
2616         r2.out.count = r->out.count;
2617         
2618         status = lsa_LookupNames4(dce_call, mem_ctx, &r2);
2619         if (dce_call->fault_code != 0) {
2620                 return status;
2621         }
2622         
2623         r->out.domains = r2.out.domains;
2624         r->out.sids = r2.out.sids;
2625         r->out.count = r2.out.count;
2626         return status;
2627 }
2628
2629 /*
2630   lsa_LookupNames2
2631 */
2632 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
2633                                  TALLOC_CTX *mem_ctx,
2634                                  struct lsa_LookupNames2 *r)
2635 {
2636         struct lsa_policy_state *state;
2637         struct dcesrv_handle *h;
2638         int i;
2639         NTSTATUS status = NT_STATUS_OK;
2640
2641         r->out.domains = NULL;
2642
2643         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2644
2645         state = h->data;
2646
2647         r->out.domains = talloc_zero(mem_ctx,  struct lsa_RefDomainList);
2648         if (r->out.domains == NULL) {
2649                 return NT_STATUS_NO_MEMORY;
2650         }
2651
2652         r->out.sids = talloc_zero(mem_ctx,  struct lsa_TransSidArray2);
2653         if (r->out.sids == NULL) {
2654                 return NT_STATUS_NO_MEMORY;
2655         }
2656
2657         *r->out.count = 0;
2658
2659         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2, 
2660                                            r->in.num_names);
2661         if (r->out.sids->sids == NULL) {
2662                 return NT_STATUS_NO_MEMORY;
2663         }
2664
2665         for (i=0;i<r->in.num_names;i++) {
2666                 const char *name = r->in.names[i].string;
2667                 struct dom_sid *sid;
2668                 uint32_t atype, rtype, sid_index;
2669                 NTSTATUS status2;
2670
2671                 r->out.sids->count++;
2672                 (*r->out.count)++;
2673
2674                 r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
2675                 r->out.sids->sids[i].rid         = 0xFFFFFFFF;
2676                 r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
2677                 r->out.sids->sids[i].unknown     = 0;
2678
2679                 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
2680                 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
2681                         status = STATUS_SOME_UNMAPPED;
2682                         continue;
2683                 }
2684
2685                 rtype = samdb_atype_map(atype);
2686                 if (rtype == SID_NAME_UNKNOWN) {
2687                         status = STATUS_SOME_UNMAPPED;
2688                         continue;
2689                 }
2690
2691                 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
2692                 if (!NT_STATUS_IS_OK(status2)) {
2693                         return status2;
2694                 }
2695
2696                 r->out.sids->sids[i].sid_type    = rtype;
2697                 r->out.sids->sids[i].rid         = sid->sub_auths[sid->num_auths-1];
2698                 r->out.sids->sids[i].sid_index   = sid_index;
2699                 r->out.sids->sids[i].unknown     = 0;
2700         }
2701         
2702         return status;
2703 }
2704
2705 /* 
2706   lsa_LookupNames 
2707 */
2708 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2709                        struct lsa_LookupNames *r)
2710 {
2711         struct lsa_LookupNames2 r2;
2712         NTSTATUS status;
2713         int i;
2714
2715         r2.in.handle    = r->in.handle;
2716         r2.in.num_names = r->in.num_names;
2717         r2.in.names     = r->in.names;
2718         r2.in.sids      = NULL;
2719         r2.in.level     = r->in.level;
2720         r2.in.count     = r->in.count;
2721         r2.in.unknown1  = 0;
2722         r2.in.unknown2  = 0;
2723         r2.out.count    = r->out.count;
2724
2725         status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
2726         if (dce_call->fault_code != 0) {
2727                 return status;
2728         }
2729
2730         r->out.domains = r2.out.domains;
2731         r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
2732         if (r->out.sids == NULL) {
2733                 return NT_STATUS_NO_MEMORY;
2734         }
2735         r->out.sids->count = r2.out.sids->count;
2736         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid, 
2737                                            r->out.sids->count);
2738         if (r->out.sids->sids == NULL) {
2739                 return NT_STATUS_NO_MEMORY;
2740         }
2741         for (i=0;i<r->out.sids->count;i++) {
2742                 r->out.sids->sids[i].sid_type    = r2.out.sids->sids[i].sid_type;
2743                 r->out.sids->sids[i].rid         = r2.out.sids->sids[i].rid;
2744                 r->out.sids->sids[i].sid_index   = r2.out.sids->sids[i].sid_index;
2745         }
2746
2747         return status;
2748 }
2749
2750 /* 
2751   lsa_CREDRWRITE 
2752 */
2753 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2754                        struct lsa_CREDRWRITE *r)
2755 {
2756         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2757 }
2758
2759
2760 /* 
2761   lsa_CREDRREAD 
2762 */
2763 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2764                        struct lsa_CREDRREAD *r)
2765 {
2766         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2767 }
2768
2769
2770 /* 
2771   lsa_CREDRENUMERATE 
2772 */
2773 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2774                        struct lsa_CREDRENUMERATE *r)
2775 {
2776         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2777 }
2778
2779
2780 /* 
2781   lsa_CREDRWRITEDOMAINCREDENTIALS 
2782 */
2783 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2784                        struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2785 {
2786         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2787 }
2788
2789
2790 /* 
2791   lsa_CREDRREADDOMAINCREDENTIALS 
2792 */
2793 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2794                        struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2795 {
2796         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2797 }
2798
2799
2800 /* 
2801   lsa_CREDRDELETE 
2802 */
2803 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2804                        struct lsa_CREDRDELETE *r)
2805 {
2806         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2807 }
2808
2809
2810 /* 
2811   lsa_CREDRGETTARGETINFO 
2812 */
2813 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2814                        struct lsa_CREDRGETTARGETINFO *r)
2815 {
2816         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2817 }
2818
2819
2820 /* 
2821   lsa_CREDRPROFILELOADED 
2822 */
2823 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2824                        struct lsa_CREDRPROFILELOADED *r)
2825 {
2826         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2827 }
2828
2829
2830 /* 
2831   lsa_CREDRGETSESSIONTYPES 
2832 */
2833 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2834                        struct lsa_CREDRGETSESSIONTYPES *r)
2835 {
2836         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2837 }
2838
2839
2840 /* 
2841   lsa_LSARREGISTERAUDITEVENT 
2842 */
2843 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2844                        struct lsa_LSARREGISTERAUDITEVENT *r)
2845 {
2846         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2847 }
2848
2849
2850 /* 
2851   lsa_LSARGENAUDITEVENT 
2852 */
2853 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2854                        struct lsa_LSARGENAUDITEVENT *r)
2855 {
2856         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2857 }
2858
2859
2860 /* 
2861   lsa_LSARUNREGISTERAUDITEVENT 
2862 */
2863 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2864                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
2865 {
2866         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2867 }
2868
2869
2870 /* 
2871   lsa_LSARQUERYFORESTTRUSTINFORMATION 
2872 */
2873 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2874                        struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
2875 {
2876         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2877 }
2878
2879
2880 /* 
2881   lsa_LSARSETFORESTTRUSTINFORMATION 
2882 */
2883 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2884                        struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2885 {
2886         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2887 }
2888
2889
2890 /* 
2891   lsa_CREDRRENAME 
2892 */
2893 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2894                        struct lsa_CREDRRENAME *r)
2895 {
2896         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2897 }
2898
2899
2900
2901 /* 
2902   lsa_LSAROPENPOLICYSCE 
2903 */
2904 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2905                        struct lsa_LSAROPENPOLICYSCE *r)
2906 {
2907         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2908 }
2909
2910
2911 /* 
2912   lsa_LSARADTREGISTERSECURITYEVENTSOURCE 
2913 */
2914 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2915                        struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2916 {
2917         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2918 }
2919
2920
2921 /* 
2922   lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE 
2923 */
2924 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2925                        struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2926 {
2927         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2928 }
2929
2930
2931 /* 
2932   lsa_LSARADTREPORTSECURITYEVENT 
2933 */
2934 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2935                        struct lsa_LSARADTREPORTSECURITYEVENT *r)
2936 {
2937         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2938 }
2939
2940
2941 /* include the generated boilerplate */
2942 #include "librpc/gen_ndr/ndr_lsa_s.c"