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