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