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