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