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