93c1ee9e4d34fc8e979ff5a34c14e22532b4c095
[jelmer/samba4-debian.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                 /* search for the secret record */
1718                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1719                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1720                                    &msgs, attrs,
1721                                    "(&(cn=%s)(objectclass=secret))", 
1722                                    ldb_binary_encode_string(mem_ctx, name));
1723                 if (ret > 0) {
1724                         return NT_STATUS_OBJECT_NAME_COLLISION;
1725                 }
1726                 
1727                 if (ret == -1) {
1728                         DEBUG(0,("Failure searching for CN=%s: %s\n", 
1729                                  name, ldb_errstring(secret_state->sam_ldb)));
1730                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1731                 }
1732
1733                 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
1734                 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
1735         } 
1736
1737         /* pull in all the template attributes.  Note this is always from the global samdb */
1738         ret = samdb_copy_template(secret_state->policy->sam_ldb, msg, 
1739                                   "secret", &errstr);
1740         if (ret != 0) {
1741                 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
1742                          errstr));
1743                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1744         }
1745
1746         samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
1747         
1748         secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
1749
1750         /* create the secret */
1751         ret = ldb_add(secret_state->sam_ldb, msg);
1752         if (ret != 0) {
1753                 DEBUG(0,("Failed to create secret record %s: %s\n",
1754                          ldb_dn_get_linearized(msg->dn), 
1755                          ldb_errstring(secret_state->sam_ldb)));
1756                 return NT_STATUS_ACCESS_DENIED;
1757         }
1758
1759         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1760         if (!handle) {
1761                 return NT_STATUS_NO_MEMORY;
1762         }
1763         
1764         handle->data = talloc_steal(handle, secret_state);
1765         
1766         secret_state->access_mask = r->in.access_mask;
1767         secret_state->policy = talloc_reference(secret_state, policy_state);
1768         
1769         *r->out.sec_handle = handle->wire_handle;
1770         
1771         return NT_STATUS_OK;
1772 }
1773
1774
1775 /* 
1776   lsa_OpenSecret 
1777 */
1778 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1779                                struct lsa_OpenSecret *r)
1780 {
1781         struct dcesrv_handle *policy_handle;
1782         
1783         struct lsa_policy_state *policy_state;
1784         struct lsa_secret_state *secret_state;
1785         struct dcesrv_handle *handle;
1786         struct ldb_message **msgs;
1787         const char *attrs[] = {
1788                 NULL
1789         };
1790
1791         const char *name;
1792
1793         int ret;
1794
1795         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1796         ZERO_STRUCTP(r->out.sec_handle);
1797         policy_state = policy_handle->data;
1798
1799         if (!r->in.name.string) {
1800                 return NT_STATUS_INVALID_PARAMETER;
1801         }
1802         
1803         secret_state = talloc(mem_ctx, struct lsa_secret_state);
1804         if (!secret_state) {
1805                 return NT_STATUS_NO_MEMORY;
1806         }
1807         secret_state->policy = policy_state;
1808
1809         if (strncmp("G$", r->in.name.string, 2) == 0) {
1810                 name = &r->in.name.string[2];
1811                 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
1812                 secret_state->global = true;
1813
1814                 if (strlen(name) < 1) {
1815                         return NT_STATUS_INVALID_PARAMETER;
1816                 }
1817
1818                 /* search for the secret record */
1819                 ret = gendb_search(secret_state->sam_ldb,
1820                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
1821                                    "(&(cn=%s Secret)(objectclass=secret))", 
1822                                    ldb_binary_encode_string(mem_ctx, name));
1823                 if (ret == 0) {
1824                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1825                 }
1826                 
1827                 if (ret != 1) {
1828                         DEBUG(0,("Found %d records matching DN %s\n", ret,
1829                                  ldb_dn_get_linearized(policy_state->system_dn)));
1830                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1831                 }
1832         
1833         } else {
1834                 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
1835
1836                 secret_state->global = false;
1837                 name = r->in.name.string;
1838                 if (strlen(name) < 1) {
1839                         return NT_STATUS_INVALID_PARAMETER;
1840                 }
1841
1842                 /* search for the secret record */
1843                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
1844                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
1845                                    &msgs, attrs,
1846                                    "(&(cn=%s)(objectclass=secret))", 
1847                                    ldb_binary_encode_string(mem_ctx, name));
1848                 if (ret == 0) {
1849                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1850                 }
1851                 
1852                 if (ret != 1) {
1853                         DEBUG(0,("Found %d records matching CN=%s\n", 
1854                                  ret, ldb_binary_encode_string(mem_ctx, name)));
1855                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1856                 }
1857         } 
1858
1859         secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
1860         
1861         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
1862         if (!handle) {
1863                 return NT_STATUS_NO_MEMORY;
1864         }
1865         
1866         handle->data = talloc_steal(handle, secret_state);
1867         
1868         secret_state->access_mask = r->in.access_mask;
1869         secret_state->policy = talloc_reference(secret_state, policy_state);
1870         
1871         *r->out.sec_handle = handle->wire_handle;
1872         
1873         return NT_STATUS_OK;
1874 }
1875
1876
1877 /* 
1878   lsa_SetSecret 
1879 */
1880 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1881                               struct lsa_SetSecret *r)
1882 {
1883
1884         struct dcesrv_handle *h;
1885         struct lsa_secret_state *secret_state;
1886         struct ldb_message *msg;
1887         DATA_BLOB session_key;
1888         DATA_BLOB crypt_secret, secret;
1889         struct ldb_val val;
1890         int ret;
1891         NTSTATUS status = NT_STATUS_OK;
1892
1893         struct timeval now = timeval_current();
1894         NTTIME nt_now = timeval_to_nttime(&now);
1895
1896         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
1897
1898         secret_state = h->data;
1899
1900         msg = ldb_msg_new(mem_ctx);
1901         if (msg == NULL) {
1902                 return NT_STATUS_NO_MEMORY;
1903         }
1904
1905         msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
1906         if (!msg->dn) {
1907                 return NT_STATUS_NO_MEMORY;
1908         }
1909         status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
1910         if (!NT_STATUS_IS_OK(status)) {
1911                 return status;
1912         }
1913
1914         if (r->in.old_val) {
1915                 /* Decrypt */
1916                 crypt_secret.data = r->in.old_val->data;
1917                 crypt_secret.length = r->in.old_val->size;
1918                 
1919                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1920                 if (!NT_STATUS_IS_OK(status)) {
1921                         return status;
1922                 }
1923                 
1924                 val.data = secret.data;
1925                 val.length = secret.length;
1926                 
1927                 /* set value */
1928                 if (samdb_msg_add_value(secret_state->sam_ldb, 
1929                                         mem_ctx, msg, "priorValue", &val) != 0) {
1930                         return NT_STATUS_NO_MEMORY; 
1931                 }
1932                 
1933                 /* set old value mtime */
1934                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
1935                                          mem_ctx, msg, "priorSetTime", nt_now) != 0) { 
1936                         return NT_STATUS_NO_MEMORY; 
1937                 }
1938
1939                 if (!r->in.new_val) {
1940                         /* This behaviour varies depending of if this is a local, or a global secret... */
1941                         if (secret_state->global) {
1942                                 /* set old value mtime */
1943                                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
1944                                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
1945                                         return NT_STATUS_NO_MEMORY; 
1946                                 }
1947                         } else {
1948                                 if (samdb_msg_add_delete(secret_state->sam_ldb, 
1949                                                          mem_ctx, msg, "currentValue")) {
1950                                         return NT_STATUS_NO_MEMORY;
1951                                 }
1952                                 if (samdb_msg_add_delete(secret_state->sam_ldb, 
1953                                                          mem_ctx, msg, "lastSetTime")) {
1954                                         return NT_STATUS_NO_MEMORY;
1955                                 }
1956                         }
1957                 }
1958         }
1959
1960         if (r->in.new_val) {
1961                 /* Decrypt */
1962                 crypt_secret.data = r->in.new_val->data;
1963                 crypt_secret.length = r->in.new_val->size;
1964                 
1965                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
1966                 if (!NT_STATUS_IS_OK(status)) {
1967                         return status;
1968                 }
1969                 
1970                 val.data = secret.data;
1971                 val.length = secret.length;
1972                 
1973                 /* set value */
1974                 if (samdb_msg_add_value(secret_state->sam_ldb, 
1975                                         mem_ctx, msg, "currentValue", &val) != 0) {
1976                         return NT_STATUS_NO_MEMORY; 
1977                 }
1978                 
1979                 /* set new value mtime */
1980                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
1981                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
1982                         return NT_STATUS_NO_MEMORY; 
1983                 }
1984                 
1985                 /* If the old value is not set, then migrate the
1986                  * current value to the old value */
1987                 if (!r->in.old_val) {
1988                         const struct ldb_val *new_val;
1989                         NTTIME last_set_time;
1990                         struct ldb_message **res;
1991                         const char *attrs[] = {
1992                                 "currentValue",
1993                                 "lastSetTime",
1994                                 NULL
1995                         };
1996                         
1997                         /* search for the secret record */
1998                         ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
1999                                               secret_state->secret_dn, &res, attrs);
2000                         if (ret == 0) {
2001                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2002                         }
2003                         
2004                         if (ret != 1) {
2005                                 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2006                                          ldb_dn_get_linearized(secret_state->secret_dn)));
2007                                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2008                         }
2009
2010                         new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2011                         last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2012                         
2013                         if (new_val) {
2014                                 /* set value */
2015                                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2016                                                         mem_ctx, msg, "priorValue", 
2017                                                         new_val) != 0) {
2018                                         return NT_STATUS_NO_MEMORY; 
2019                                 }
2020                         }
2021                         
2022                         /* set new value mtime */
2023                         if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2024                                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2025                                                          mem_ctx, msg, "priorSetTime", last_set_time) != 0) { 
2026                                         return NT_STATUS_NO_MEMORY; 
2027                                 }
2028                         }
2029                 }
2030         }
2031
2032         /* modify the samdb record */
2033         ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2034         if (ret != 0) {
2035                 /* we really need samdb.c to return NTSTATUS */
2036                 return NT_STATUS_UNSUCCESSFUL;
2037         }
2038
2039         return NT_STATUS_OK;
2040 }
2041
2042
2043 /* 
2044   lsa_QuerySecret 
2045 */
2046 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2047                                 struct lsa_QuerySecret *r)
2048 {
2049         struct dcesrv_handle *h;
2050         struct lsa_secret_state *secret_state;
2051         struct ldb_message *msg;
2052         DATA_BLOB session_key;
2053         DATA_BLOB crypt_secret, secret;
2054         int ret;
2055         struct ldb_message **res;
2056         const char *attrs[] = {
2057                 "currentValue",
2058                 "priorValue",
2059                 "lastSetTime",
2060                 "priorSetTime", 
2061                 NULL
2062         };
2063
2064         NTSTATUS nt_status;
2065
2066         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2067
2068         secret_state = h->data;
2069
2070         /* pull all the user attributes */
2071         ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2072                               secret_state->secret_dn, &res, attrs);
2073         if (ret != 1) {
2074                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2075         }
2076         msg = res[0];
2077         
2078         nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2079         if (!NT_STATUS_IS_OK(nt_status)) {
2080                 return nt_status;
2081         }
2082         
2083         if (r->in.old_val) {
2084                 const struct ldb_val *prior_val;
2085                 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2086                 if (!r->out.old_val) {
2087                         return NT_STATUS_NO_MEMORY;
2088                 }
2089                 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2090                 
2091                 if (prior_val && prior_val->length) {
2092                         secret.data = prior_val->data;
2093                         secret.length = prior_val->length;
2094                 
2095                         /* Encrypt */
2096                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2097                         if (!crypt_secret.length) {
2098                                 return NT_STATUS_NO_MEMORY;
2099                         }
2100                         r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2101                         if (!r->out.old_val->buf) {
2102                                 return NT_STATUS_NO_MEMORY;
2103                         }
2104                         r->out.old_val->buf->size = crypt_secret.length;
2105                         r->out.old_val->buf->length = crypt_secret.length;
2106                         r->out.old_val->buf->data = crypt_secret.data;
2107                 }
2108         }
2109         
2110         if (r->in.old_mtime) {
2111                 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2112                 if (!r->out.old_mtime) {
2113                         return NT_STATUS_NO_MEMORY;
2114                 }
2115                 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2116         }
2117         
2118         if (r->in.new_val) {
2119                 const struct ldb_val *new_val;
2120                 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2121                 if (!r->out.new_val) {
2122                         return NT_STATUS_NO_MEMORY;
2123                 }
2124
2125                 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2126                 
2127                 if (new_val && new_val->length) {
2128                         secret.data = new_val->data;
2129                         secret.length = new_val->length;
2130                 
2131                         /* Encrypt */
2132                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2133                         if (!crypt_secret.length) {
2134                                 return NT_STATUS_NO_MEMORY;
2135                         }
2136                         r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2137                         if (!r->out.new_val->buf) {
2138                                 return NT_STATUS_NO_MEMORY;
2139                         }
2140                         r->out.new_val->buf->length = crypt_secret.length;
2141                         r->out.new_val->buf->size = crypt_secret.length;
2142                         r->out.new_val->buf->data = crypt_secret.data;
2143                 }
2144         }
2145         
2146         if (r->in.new_mtime) {
2147                 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2148                 if (!r->out.new_mtime) {
2149                         return NT_STATUS_NO_MEMORY;
2150                 }
2151                 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2152         }
2153         
2154         return NT_STATUS_OK;
2155 }
2156
2157
2158 /* 
2159   lsa_LookupPrivValue
2160 */
2161 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
2162                                     TALLOC_CTX *mem_ctx,
2163                                     struct lsa_LookupPrivValue *r)
2164 {
2165         struct dcesrv_handle *h;
2166         struct lsa_policy_state *state;
2167         int id;
2168
2169         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2170
2171         state = h->data;
2172
2173         id = sec_privilege_id(r->in.name->string);
2174         if (id == -1) {
2175                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2176         }
2177
2178         r->out.luid->low = id;
2179         r->out.luid->high = 0;
2180
2181         return NT_STATUS_OK;    
2182 }
2183
2184
2185 /* 
2186   lsa_LookupPrivName 
2187 */
2188 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
2189                                    TALLOC_CTX *mem_ctx,
2190                                    struct lsa_LookupPrivName *r)
2191 {
2192         struct dcesrv_handle *h;
2193         struct lsa_policy_state *state;
2194         const char *privname;
2195
2196         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2197
2198         state = h->data;
2199
2200         if (r->in.luid->high != 0) {
2201                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2202         }
2203
2204         privname = sec_privilege_name(r->in.luid->low);
2205         if (privname == NULL) {
2206                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2207         }
2208
2209         r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2210         if (r->out.name == NULL) {
2211                 return NT_STATUS_NO_MEMORY;
2212         }
2213         r->out.name->string = privname;
2214
2215         return NT_STATUS_OK;    
2216 }
2217
2218
2219 /* 
2220   lsa_LookupPrivDisplayName
2221 */
2222 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
2223                                           TALLOC_CTX *mem_ctx,
2224                                           struct lsa_LookupPrivDisplayName *r)
2225 {
2226         struct dcesrv_handle *h;
2227         struct lsa_policy_state *state;
2228         int id;
2229
2230         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2231
2232         state = h->data;
2233
2234         id = sec_privilege_id(r->in.name->string);
2235         if (id == -1) {
2236                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2237         }
2238         
2239         r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2240         if (r->out.disp_name == NULL) {
2241                 return NT_STATUS_NO_MEMORY;
2242         }
2243
2244         r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2245         if (r->out.disp_name->string == NULL) {
2246                 return NT_STATUS_INTERNAL_ERROR;
2247         }
2248
2249         return NT_STATUS_OK;
2250 }
2251
2252
2253 /* 
2254   lsa_DeleteObject
2255 */
2256 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2257                        struct lsa_DeleteObject *r)
2258 {
2259         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2260 }
2261
2262
2263 /* 
2264   lsa_EnumAccountsWithUserRight
2265 */
2266 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
2267                                               TALLOC_CTX *mem_ctx,
2268                                               struct lsa_EnumAccountsWithUserRight *r)
2269 {
2270         struct dcesrv_handle *h;
2271         struct lsa_policy_state *state;
2272         int ret, i;
2273         struct ldb_message **res;
2274         const char * const attrs[] = { "objectSid", NULL};
2275         const char *privname;
2276
2277         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2278
2279         state = h->data;
2280
2281         if (r->in.name == NULL) {
2282                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2283         } 
2284
2285         privname = r->in.name->string;
2286         if (sec_privilege_id(privname) == -1) {
2287                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2288         }
2289
2290         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
2291                            "privilege=%s", privname);
2292         if (ret == -1) {
2293                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2294         }
2295         if (ret == 0) {
2296                 return NT_STATUS_NO_MORE_ENTRIES;
2297         }
2298
2299         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2300         if (r->out.sids->sids == NULL) {
2301                 return NT_STATUS_NO_MEMORY;
2302         }
2303         for (i=0;i<ret;i++) {
2304                 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2305                                                                 res[i], "objectSid");
2306                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2307         }
2308         r->out.sids->num_sids = ret;
2309
2310         return NT_STATUS_OK;
2311 }
2312
2313
2314 /* 
2315   lsa_AddAccountRights
2316 */
2317 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
2318                                      TALLOC_CTX *mem_ctx,
2319                                      struct lsa_AddAccountRights *r)
2320 {
2321         struct dcesrv_handle *h;
2322         struct lsa_policy_state *state;
2323
2324         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2325
2326         state = h->data;
2327
2328         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2329                                           LDB_FLAG_MOD_ADD,
2330                                           r->in.sid, r->in.rights);
2331 }
2332
2333
2334 /* 
2335   lsa_RemoveAccountRights
2336 */
2337 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
2338                                         TALLOC_CTX *mem_ctx,
2339                                         struct lsa_RemoveAccountRights *r)
2340 {
2341         struct dcesrv_handle *h;
2342         struct lsa_policy_state *state;
2343
2344         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2345
2346         state = h->data;
2347
2348         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2349                                           LDB_FLAG_MOD_DELETE,
2350                                           r->in.sid, r->in.rights);
2351 }
2352
2353
2354 /* 
2355   lsa_StorePrivateData
2356 */
2357 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2358                        struct lsa_StorePrivateData *r)
2359 {
2360         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2361 }
2362
2363
2364 /* 
2365   lsa_RetrievePrivateData
2366 */
2367 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2368                        struct lsa_RetrievePrivateData *r)
2369 {
2370         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2371 }
2372
2373
2374 /* 
2375   lsa_GetUserName
2376 */
2377 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2378                                 struct lsa_GetUserName *r)
2379 {
2380         NTSTATUS status = NT_STATUS_OK;
2381         const char *account_name;
2382         const char *authority_name;
2383         struct lsa_String *_account_name;
2384         struct lsa_StringPointer *_authority_name = NULL;
2385
2386         /* this is what w2k3 does */
2387         r->out.account_name = r->in.account_name;
2388         r->out.authority_name = r->in.authority_name;
2389
2390         if (r->in.account_name && r->in.account_name->string) {
2391                 return NT_STATUS_INVALID_PARAMETER;
2392         }
2393
2394         if (r->in.authority_name &&
2395             r->in.authority_name->string &&
2396             r->in.authority_name->string->string) {
2397                 return NT_STATUS_INVALID_PARAMETER;
2398         }
2399
2400         account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2401         authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2402
2403         _account_name = talloc(mem_ctx, struct lsa_String);
2404         NT_STATUS_HAVE_NO_MEMORY(_account_name);
2405         _account_name->string = account_name;
2406
2407         if (r->in.authority_name) {
2408                 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2409                 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2410                 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2411                 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2412                 _authority_name->string->string = authority_name;
2413         }
2414
2415         r->out.account_name = _account_name;
2416         r->out.authority_name = _authority_name;
2417
2418         return status;
2419 }
2420
2421 /*
2422   lsa_SetInfoPolicy2
2423 */
2424 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2425                                    TALLOC_CTX *mem_ctx,
2426                                    struct lsa_SetInfoPolicy2 *r)
2427 {
2428         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2429 }
2430
2431 /*
2432   lsa_QueryDomainInformationPolicy
2433 */
2434 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2435                                                  TALLOC_CTX *mem_ctx,
2436                                                  struct lsa_QueryDomainInformationPolicy *r)
2437 {
2438         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2439 }
2440
2441 /*
2442   lsa_SetDomInfoPolicy
2443 */
2444 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2445                                               TALLOC_CTX *mem_ctx,
2446                                               struct lsa_SetDomainInformationPolicy *r)
2447 {
2448         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2449 }
2450
2451 /*
2452   lsa_TestCall
2453 */
2454 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2455                              TALLOC_CTX *mem_ctx,
2456                              struct lsa_TestCall *r)
2457 {
2458         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2459 }
2460
2461 /* 
2462   lsa_CREDRWRITE 
2463 */
2464 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2465                        struct lsa_CREDRWRITE *r)
2466 {
2467         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2468 }
2469
2470
2471 /* 
2472   lsa_CREDRREAD 
2473 */
2474 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2475                        struct lsa_CREDRREAD *r)
2476 {
2477         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2478 }
2479
2480
2481 /* 
2482   lsa_CREDRENUMERATE 
2483 */
2484 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2485                        struct lsa_CREDRENUMERATE *r)
2486 {
2487         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2488 }
2489
2490
2491 /* 
2492   lsa_CREDRWRITEDOMAINCREDENTIALS 
2493 */
2494 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2495                        struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2496 {
2497         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2498 }
2499
2500
2501 /* 
2502   lsa_CREDRREADDOMAINCREDENTIALS 
2503 */
2504 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2505                        struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2506 {
2507         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2508 }
2509
2510
2511 /* 
2512   lsa_CREDRDELETE 
2513 */
2514 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2515                        struct lsa_CREDRDELETE *r)
2516 {
2517         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2518 }
2519
2520
2521 /* 
2522   lsa_CREDRGETTARGETINFO 
2523 */
2524 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2525                        struct lsa_CREDRGETTARGETINFO *r)
2526 {
2527         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2528 }
2529
2530
2531 /* 
2532   lsa_CREDRPROFILELOADED 
2533 */
2534 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2535                        struct lsa_CREDRPROFILELOADED *r)
2536 {
2537         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2538 }
2539
2540
2541 /* 
2542   lsa_CREDRGETSESSIONTYPES 
2543 */
2544 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2545                        struct lsa_CREDRGETSESSIONTYPES *r)
2546 {
2547         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2548 }
2549
2550
2551 /* 
2552   lsa_LSARREGISTERAUDITEVENT 
2553 */
2554 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2555                        struct lsa_LSARREGISTERAUDITEVENT *r)
2556 {
2557         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2558 }
2559
2560
2561 /* 
2562   lsa_LSARGENAUDITEVENT 
2563 */
2564 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2565                        struct lsa_LSARGENAUDITEVENT *r)
2566 {
2567         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2568 }
2569
2570
2571 /* 
2572   lsa_LSARUNREGISTERAUDITEVENT 
2573 */
2574 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2575                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
2576 {
2577         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2578 }
2579
2580
2581 /* 
2582   lsa_lsaRQueryForestTrustInformation 
2583 */
2584 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2585                        struct lsa_lsaRQueryForestTrustInformation *r)
2586 {
2587         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2588 }
2589
2590
2591 /* 
2592   lsa_LSARSETFORESTTRUSTINFORMATION 
2593 */
2594 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2595                        struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2596 {
2597         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2598 }
2599
2600
2601 /* 
2602   lsa_CREDRRENAME 
2603 */
2604 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2605                        struct lsa_CREDRRENAME *r)
2606 {
2607         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2608 }
2609
2610
2611
2612 /* 
2613   lsa_LSAROPENPOLICYSCE 
2614 */
2615 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2616                        struct lsa_LSAROPENPOLICYSCE *r)
2617 {
2618         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2619 }
2620
2621
2622 /* 
2623   lsa_LSARADTREGISTERSECURITYEVENTSOURCE 
2624 */
2625 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2626                        struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
2627 {
2628         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2629 }
2630
2631
2632 /* 
2633   lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE 
2634 */
2635 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2636                        struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
2637 {
2638         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2639 }
2640
2641
2642 /* 
2643   lsa_LSARADTREPORTSECURITYEVENT 
2644 */
2645 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2646                        struct lsa_LSARADTREPORTSECURITYEVENT *r)
2647 {
2648         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2649 }
2650
2651
2652 /* include the generated boilerplate */
2653 #include "librpc/gen_ndr/ndr_lsa_s.c"
2654
2655
2656
2657 /*****************************************
2658 NOTE! The remaining calls below were
2659 removed in w2k3, so the DCESRV_FAULT()
2660 replies are the correct implementation. Do
2661 not try and fill these in with anything else
2662 ******************************************/
2663
2664 /* 
2665   dssetup_DsRoleDnsNameToFlatName 
2666 */
2667 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2668                                         struct dssetup_DsRoleDnsNameToFlatName *r)
2669 {
2670         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2671 }
2672
2673
2674 /* 
2675   dssetup_DsRoleDcAsDc 
2676 */
2677 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2678                              struct dssetup_DsRoleDcAsDc *r)
2679 {
2680         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2681 }
2682
2683
2684 /* 
2685   dssetup_DsRoleDcAsReplica 
2686 */
2687 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2688                                   struct dssetup_DsRoleDcAsReplica *r)
2689 {
2690         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2691 }
2692
2693
2694 /* 
2695   dssetup_DsRoleDemoteDc 
2696 */
2697 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2698                                struct dssetup_DsRoleDemoteDc *r)
2699 {
2700         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2701 }
2702
2703
2704 /* 
2705   dssetup_DsRoleGetDcOperationProgress 
2706 */
2707 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2708                                              struct dssetup_DsRoleGetDcOperationProgress *r)
2709 {
2710         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2711 }
2712
2713
2714 /* 
2715   dssetup_DsRoleGetDcOperationResults 
2716 */
2717 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2718                                             struct dssetup_DsRoleGetDcOperationResults *r)
2719 {
2720         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2721 }
2722
2723
2724 /* 
2725   dssetup_DsRoleCancel 
2726 */
2727 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2728                              struct dssetup_DsRoleCancel *r)
2729 {
2730         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2731 }
2732
2733
2734 /* 
2735   dssetup_DsRoleServerSaveStateForUpgrade 
2736 */
2737 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2738                                                 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
2739 {
2740         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2741 }
2742
2743
2744 /* 
2745   dssetup_DsRoleUpgradeDownlevelServer 
2746 */
2747 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2748                                              struct dssetup_DsRoleUpgradeDownlevelServer *r)
2749 {
2750         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2751 }
2752
2753
2754 /* 
2755   dssetup_DsRoleAbortDownlevelServerUpgrade 
2756 */
2757 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2758                                                   struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
2759 {
2760         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2761 }
2762
2763
2764 /* include the generated boilerplate */
2765 #include "librpc/gen_ndr/ndr_dssetup_s.c"
2766
2767 NTSTATUS dcerpc_server_lsa_init(void)
2768 {
2769         NTSTATUS ret;
2770         
2771         ret = dcerpc_server_dssetup_init();
2772         if (!NT_STATUS_IS_OK(ret)) {
2773                 return ret;
2774         }
2775         ret = dcerpc_server_lsarpc_init();
2776         if (!NT_STATUS_IS_OK(ret)) {
2777                 return ret;
2778         }
2779         return ret;
2780 }