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