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