69061ee092c2c781c9d737b673f4e940babf062a
[kai/samba.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the lsarpc pipe
5
6    Copyright (C) Andrew Tridgell 2004
7    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-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 trustAuthInAndOutBlob 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_trustAuthInAndOutBlob);
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_trustAuthInOutBlob);
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_trustAuthInOutBlob);
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->array[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->array[i].AuthInfo.nt4owf.password);
866                                 } else if (auth_struct.incoming.current->array[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->array[i].AuthInfo.clear.password,
875                                                auth_struct.incoming.current->array[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                 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2022                 secret_state->global = true;
2023
2024                 if (strlen(name) < 1) {
2025                         return NT_STATUS_INVALID_PARAMETER;
2026                 }
2027
2028                 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2029                 /* search for the secret record */
2030                 ret = gendb_search(secret_state->sam_ldb,
2031                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
2032                                    "(&(cn=%s)(objectclass=secret))", 
2033                                    name2);
2034                 if (ret > 0) {
2035                         return NT_STATUS_OBJECT_NAME_COLLISION;
2036                 }
2037                 
2038                 if (ret == -1) {
2039                         DEBUG(0,("Failure searching for CN=%s: %s\n", 
2040                                  name2, ldb_errstring(secret_state->sam_ldb)));
2041                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2042                 }
2043
2044                 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2045                 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2046                         return NT_STATUS_NO_MEMORY;
2047                 }
2048                 
2049                 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2050         
2051         } else {
2052                 secret_state->global = false;
2053
2054                 name = r->in.name.string;
2055                 if (strlen(name) < 1) {
2056                         return NT_STATUS_INVALID_PARAMETER;
2057                 }
2058
2059                 secret_state->sam_ldb = talloc_reference(secret_state, 
2060                                                          secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2061                 /* search for the secret record */
2062                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2063                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2064                                    &msgs, attrs,
2065                                    "(&(cn=%s)(objectclass=secret))", 
2066                                    ldb_binary_encode_string(mem_ctx, name));
2067                 if (ret > 0) {
2068                         return NT_STATUS_OBJECT_NAME_COLLISION;
2069                 }
2070                 
2071                 if (ret == -1) {
2072                         DEBUG(0,("Failure searching for CN=%s: %s\n", 
2073                                  name, ldb_errstring(secret_state->sam_ldb)));
2074                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2075                 }
2076
2077                 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2078                 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2079         } 
2080
2081         /* pull in all the template attributes.  Note this is always from the global samdb */
2082         ret = samdb_copy_template(secret_state->policy->sam_ldb, msg, 
2083                                   "secret", &errstr);
2084         if (ret != 0) {
2085                 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2086                          errstr));
2087                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2088         }
2089
2090         samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2091         
2092         secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2093
2094         /* create the secret */
2095         ret = ldb_add(secret_state->sam_ldb, msg);
2096         if (ret != 0) {
2097                 DEBUG(0,("Failed to create secret record %s: %s\n",
2098                          ldb_dn_get_linearized(msg->dn), 
2099                          ldb_errstring(secret_state->sam_ldb)));
2100                 return NT_STATUS_ACCESS_DENIED;
2101         }
2102
2103         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2104         if (!handle) {
2105                 return NT_STATUS_NO_MEMORY;
2106         }
2107         
2108         handle->data = talloc_steal(handle, secret_state);
2109         
2110         secret_state->access_mask = r->in.access_mask;
2111         secret_state->policy = talloc_reference(secret_state, policy_state);
2112         
2113         *r->out.sec_handle = handle->wire_handle;
2114         
2115         return NT_STATUS_OK;
2116 }
2117
2118
2119 /* 
2120   lsa_OpenSecret 
2121 */
2122 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2123                                struct lsa_OpenSecret *r)
2124 {
2125         struct dcesrv_handle *policy_handle;
2126         
2127         struct lsa_policy_state *policy_state;
2128         struct lsa_secret_state *secret_state;
2129         struct dcesrv_handle *handle;
2130         struct ldb_message **msgs;
2131         const char *attrs[] = {
2132                 NULL
2133         };
2134
2135         const char *name;
2136
2137         int ret;
2138
2139         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2140         ZERO_STRUCTP(r->out.sec_handle);
2141         policy_state = policy_handle->data;
2142
2143         if (!r->in.name.string) {
2144                 return NT_STATUS_INVALID_PARAMETER;
2145         }
2146         
2147         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2148         {
2149         case SECURITY_SYSTEM:
2150         case SECURITY_ADMINISTRATOR:
2151                 break;
2152         default:
2153                 /* Users and annonymous are not allowed to access secrets */
2154                 return NT_STATUS_ACCESS_DENIED;
2155         }
2156
2157         secret_state = talloc(mem_ctx, struct lsa_secret_state);
2158         if (!secret_state) {
2159                 return NT_STATUS_NO_MEMORY;
2160         }
2161         secret_state->policy = policy_state;
2162
2163         if (strncmp("G$", r->in.name.string, 2) == 0) {
2164                 name = &r->in.name.string[2];
2165                 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2166                 secret_state->global = true;
2167
2168                 if (strlen(name) < 1) {
2169                         return NT_STATUS_INVALID_PARAMETER;
2170                 }
2171
2172                 /* search for the secret record */
2173                 ret = gendb_search(secret_state->sam_ldb,
2174                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
2175                                    "(&(cn=%s Secret)(objectclass=secret))", 
2176                                    ldb_binary_encode_string(mem_ctx, name));
2177                 if (ret == 0) {
2178                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2179                 }
2180                 
2181                 if (ret != 1) {
2182                         DEBUG(0,("Found %d records matching DN %s\n", ret,
2183                                  ldb_dn_get_linearized(policy_state->system_dn)));
2184                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2185                 }
2186         
2187         } else {
2188                 secret_state->global = false;
2189                 secret_state->sam_ldb = talloc_reference(secret_state, 
2190                                  secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));
2191
2192                 name = r->in.name.string;
2193                 if (strlen(name) < 1) {
2194                         return NT_STATUS_INVALID_PARAMETER;
2195                 }
2196
2197                 /* search for the secret record */
2198                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2199                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2200                                    &msgs, attrs,
2201                                    "(&(cn=%s)(objectclass=secret))", 
2202                                    ldb_binary_encode_string(mem_ctx, name));
2203                 if (ret == 0) {
2204                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2205                 }
2206                 
2207                 if (ret != 1) {
2208                         DEBUG(0,("Found %d records matching CN=%s\n", 
2209                                  ret, ldb_binary_encode_string(mem_ctx, name)));
2210                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2211                 }
2212         } 
2213
2214         secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2215         
2216         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2217         if (!handle) {
2218                 return NT_STATUS_NO_MEMORY;
2219         }
2220         
2221         handle->data = talloc_steal(handle, secret_state);
2222         
2223         secret_state->access_mask = r->in.access_mask;
2224         secret_state->policy = talloc_reference(secret_state, policy_state);
2225         
2226         *r->out.sec_handle = handle->wire_handle;
2227         
2228         return NT_STATUS_OK;
2229 }
2230
2231
2232 /* 
2233   lsa_SetSecret 
2234 */
2235 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2236                               struct lsa_SetSecret *r)
2237 {
2238
2239         struct dcesrv_handle *h;
2240         struct lsa_secret_state *secret_state;
2241         struct ldb_message *msg;
2242         DATA_BLOB session_key;
2243         DATA_BLOB crypt_secret, secret;
2244         struct ldb_val val;
2245         int ret;
2246         NTSTATUS status = NT_STATUS_OK;
2247
2248         struct timeval now = timeval_current();
2249         NTTIME nt_now = timeval_to_nttime(&now);
2250
2251         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2252
2253         secret_state = h->data;
2254
2255         msg = ldb_msg_new(mem_ctx);
2256         if (msg == NULL) {
2257                 return NT_STATUS_NO_MEMORY;
2258         }
2259
2260         msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2261         if (!msg->dn) {
2262                 return NT_STATUS_NO_MEMORY;
2263         }
2264         status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2265         if (!NT_STATUS_IS_OK(status)) {
2266                 return status;
2267         }
2268
2269         if (r->in.old_val) {
2270                 /* Decrypt */
2271                 crypt_secret.data = r->in.old_val->data;
2272                 crypt_secret.length = r->in.old_val->size;
2273                 
2274                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2275                 if (!NT_STATUS_IS_OK(status)) {
2276                         return status;
2277                 }
2278                 
2279                 val.data = secret.data;
2280                 val.length = secret.length;
2281                 
2282                 /* set value */
2283                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2284                                         mem_ctx, msg, "priorValue", &val) != 0) {
2285                         return NT_STATUS_NO_MEMORY; 
2286                 }
2287                 
2288                 /* set old value mtime */
2289                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2290                                          mem_ctx, msg, "priorSetTime", nt_now) != 0) { 
2291                         return NT_STATUS_NO_MEMORY; 
2292                 }
2293
2294                 if (!r->in.new_val) {
2295                         /* set old value mtime */
2296                         if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2297                                                  mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
2298                                 return NT_STATUS_NO_MEMORY; 
2299                         }
2300                         if (samdb_msg_add_delete(secret_state->sam_ldb, 
2301                                                  mem_ctx, msg, "currentValue")) {
2302                                 return NT_STATUS_NO_MEMORY;
2303                         }
2304                 }
2305         }
2306
2307         if (r->in.new_val) {
2308                 /* Decrypt */
2309                 crypt_secret.data = r->in.new_val->data;
2310                 crypt_secret.length = r->in.new_val->size;
2311                 
2312                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2313                 if (!NT_STATUS_IS_OK(status)) {
2314                         return status;
2315                 }
2316                 
2317                 val.data = secret.data;
2318                 val.length = secret.length;
2319                 
2320                 /* set value */
2321                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2322                                         mem_ctx, msg, "currentValue", &val) != 0) {
2323                         return NT_STATUS_NO_MEMORY; 
2324                 }
2325                 
2326                 /* set new value mtime */
2327                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2328                                          mem_ctx, msg, "lastSetTime", nt_now) != 0) { 
2329                         return NT_STATUS_NO_MEMORY; 
2330                 }
2331                 
2332                 /* If the old value is not set, then migrate the
2333                  * current value to the old value */
2334                 if (!r->in.old_val) {
2335                         const struct ldb_val *new_val;
2336                         NTTIME last_set_time;
2337                         struct ldb_message **res;
2338                         const char *attrs[] = {
2339                                 "currentValue",
2340                                 "lastSetTime",
2341                                 NULL
2342                         };
2343                         
2344                         /* search for the secret record */
2345                         ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2346                                               secret_state->secret_dn, &res, attrs);
2347                         if (ret == 0) {
2348                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2349                         }
2350                         
2351                         if (ret != 1) {
2352                                 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2353                                          ldb_dn_get_linearized(secret_state->secret_dn)));
2354                                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2355                         }
2356
2357                         new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2358                         last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2359                         
2360                         if (new_val) {
2361                                 /* set value */
2362                                 if (samdb_msg_add_value(secret_state->sam_ldb, 
2363                                                         mem_ctx, msg, "priorValue", 
2364                                                         new_val) != 0) {
2365                                         return NT_STATUS_NO_MEMORY; 
2366                                 }
2367                         }
2368                         
2369                         /* set new value mtime */
2370                         if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2371                                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
2372                                                          mem_ctx, msg, "priorSetTime", last_set_time) != 0) { 
2373                                         return NT_STATUS_NO_MEMORY; 
2374                                 }
2375                         }
2376                 }
2377         }
2378
2379         /* modify the samdb record */
2380         ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2381         if (ret != 0) {
2382                 /* we really need samdb.c to return NTSTATUS */
2383                 return NT_STATUS_UNSUCCESSFUL;
2384         }
2385
2386         return NT_STATUS_OK;
2387 }
2388
2389
2390 /* 
2391   lsa_QuerySecret 
2392 */
2393 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2394                                 struct lsa_QuerySecret *r)
2395 {
2396         struct dcesrv_handle *h;
2397         struct lsa_secret_state *secret_state;
2398         struct ldb_message *msg;
2399         DATA_BLOB session_key;
2400         DATA_BLOB crypt_secret, secret;
2401         int ret;
2402         struct ldb_message **res;
2403         const char *attrs[] = {
2404                 "currentValue",
2405                 "priorValue",
2406                 "lastSetTime",
2407                 "priorSetTime", 
2408                 NULL
2409         };
2410
2411         NTSTATUS nt_status;
2412
2413         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2414
2415         /* Ensure user is permitted to read this... */
2416         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
2417         {
2418         case SECURITY_SYSTEM:
2419         case SECURITY_ADMINISTRATOR:
2420                 break;
2421         default:
2422                 /* Users and annonymous are not allowed to read secrets */
2423                 return NT_STATUS_ACCESS_DENIED;
2424         }
2425
2426         secret_state = h->data;
2427
2428         /* pull all the user attributes */
2429         ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2430                               secret_state->secret_dn, &res, attrs);
2431         if (ret != 1) {
2432                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2433         }
2434         msg = res[0];
2435         
2436         nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2437         if (!NT_STATUS_IS_OK(nt_status)) {
2438                 return nt_status;
2439         }
2440         
2441         if (r->in.old_val) {
2442                 const struct ldb_val *prior_val;
2443                 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2444                 if (!r->out.old_val) {
2445                         return NT_STATUS_NO_MEMORY;
2446                 }
2447                 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2448                 
2449                 if (prior_val && prior_val->length) {
2450                         secret.data = prior_val->data;
2451                         secret.length = prior_val->length;
2452                 
2453                         /* Encrypt */
2454                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2455                         if (!crypt_secret.length) {
2456                                 return NT_STATUS_NO_MEMORY;
2457                         }
2458                         r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2459                         if (!r->out.old_val->buf) {
2460                                 return NT_STATUS_NO_MEMORY;
2461                         }
2462                         r->out.old_val->buf->size = crypt_secret.length;
2463                         r->out.old_val->buf->length = crypt_secret.length;
2464                         r->out.old_val->buf->data = crypt_secret.data;
2465                 }
2466         }
2467         
2468         if (r->in.old_mtime) {
2469                 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2470                 if (!r->out.old_mtime) {
2471                         return NT_STATUS_NO_MEMORY;
2472                 }
2473                 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2474         }
2475         
2476         if (r->in.new_val) {
2477                 const struct ldb_val *new_val;
2478                 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2479                 if (!r->out.new_val) {
2480                         return NT_STATUS_NO_MEMORY;
2481                 }
2482
2483                 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2484                 
2485                 if (new_val && new_val->length) {
2486                         secret.data = new_val->data;
2487                         secret.length = new_val->length;
2488                 
2489                         /* Encrypt */
2490                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2491                         if (!crypt_secret.length) {
2492                                 return NT_STATUS_NO_MEMORY;
2493                         }
2494                         r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2495                         if (!r->out.new_val->buf) {
2496                                 return NT_STATUS_NO_MEMORY;
2497                         }
2498                         r->out.new_val->buf->length = crypt_secret.length;
2499                         r->out.new_val->buf->size = crypt_secret.length;
2500                         r->out.new_val->buf->data = crypt_secret.data;
2501                 }
2502         }
2503         
2504         if (r->in.new_mtime) {
2505                 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2506                 if (!r->out.new_mtime) {
2507                         return NT_STATUS_NO_MEMORY;
2508                 }
2509                 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2510         }
2511         
2512         return NT_STATUS_OK;
2513 }
2514
2515
2516 /* 
2517   lsa_LookupPrivValue
2518 */
2519 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
2520                                     TALLOC_CTX *mem_ctx,
2521                                     struct lsa_LookupPrivValue *r)
2522 {
2523         struct dcesrv_handle *h;
2524         struct lsa_policy_state *state;
2525         int id;
2526
2527         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2528
2529         state = h->data;
2530
2531         id = sec_privilege_id(r->in.name->string);
2532         if (id == -1) {
2533                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2534         }
2535
2536         r->out.luid->low = id;
2537         r->out.luid->high = 0;
2538
2539         return NT_STATUS_OK;    
2540 }
2541
2542
2543 /* 
2544   lsa_LookupPrivName 
2545 */
2546 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
2547                                    TALLOC_CTX *mem_ctx,
2548                                    struct lsa_LookupPrivName *r)
2549 {
2550         struct dcesrv_handle *h;
2551         struct lsa_policy_state *state;
2552         const char *privname;
2553
2554         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2555
2556         state = h->data;
2557
2558         if (r->in.luid->high != 0) {
2559                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2560         }
2561
2562         privname = sec_privilege_name(r->in.luid->low);
2563         if (privname == NULL) {
2564                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2565         }
2566
2567         r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2568         if (r->out.name == NULL) {
2569                 return NT_STATUS_NO_MEMORY;
2570         }
2571         r->out.name->string = privname;
2572
2573         return NT_STATUS_OK;    
2574 }
2575
2576
2577 /* 
2578   lsa_LookupPrivDisplayName
2579 */
2580 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
2581                                           TALLOC_CTX *mem_ctx,
2582                                           struct lsa_LookupPrivDisplayName *r)
2583 {
2584         struct dcesrv_handle *h;
2585         struct lsa_policy_state *state;
2586         int id;
2587
2588         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2589
2590         state = h->data;
2591
2592         id = sec_privilege_id(r->in.name->string);
2593         if (id == -1) {
2594                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2595         }
2596         
2597         r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2598         if (r->out.disp_name == NULL) {
2599                 return NT_STATUS_NO_MEMORY;
2600         }
2601
2602         r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2603         if (r->out.disp_name->string == NULL) {
2604                 return NT_STATUS_INTERNAL_ERROR;
2605         }
2606
2607         return NT_STATUS_OK;
2608 }
2609
2610
2611 /* 
2612   lsa_EnumAccountsWithUserRight
2613 */
2614 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
2615                                               TALLOC_CTX *mem_ctx,
2616                                               struct lsa_EnumAccountsWithUserRight *r)
2617 {
2618         struct dcesrv_handle *h;
2619         struct lsa_policy_state *state;
2620         int ret, i;
2621         struct ldb_message **res;
2622         const char * const attrs[] = { "objectSid", NULL};
2623         const char *privname;
2624
2625         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2626
2627         state = h->data;
2628
2629         if (r->in.name == NULL) {
2630                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2631         } 
2632
2633         privname = r->in.name->string;
2634         if (sec_privilege_id(privname) == -1) {
2635                 return NT_STATUS_NO_SUCH_PRIVILEGE;
2636         }
2637
2638         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
2639                            "privilege=%s", privname);
2640         if (ret == -1) {
2641                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2642         }
2643         if (ret == 0) {
2644                 return NT_STATUS_NO_MORE_ENTRIES;
2645         }
2646
2647         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2648         if (r->out.sids->sids == NULL) {
2649                 return NT_STATUS_NO_MEMORY;
2650         }
2651         for (i=0;i<ret;i++) {
2652                 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2653                                                                 res[i], "objectSid");
2654                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2655         }
2656         r->out.sids->num_sids = ret;
2657
2658         return NT_STATUS_OK;
2659 }
2660
2661
2662 /* 
2663   lsa_AddAccountRights
2664 */
2665 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
2666                                      TALLOC_CTX *mem_ctx,
2667                                      struct lsa_AddAccountRights *r)
2668 {
2669         struct dcesrv_handle *h;
2670         struct lsa_policy_state *state;
2671
2672         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2673
2674         state = h->data;
2675
2676         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2677                                           LDB_FLAG_MOD_ADD,
2678                                           r->in.sid, r->in.rights);
2679 }
2680
2681
2682 /* 
2683   lsa_RemoveAccountRights
2684 */
2685 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
2686                                         TALLOC_CTX *mem_ctx,
2687                                         struct lsa_RemoveAccountRights *r)
2688 {
2689         struct dcesrv_handle *h;
2690         struct lsa_policy_state *state;
2691
2692         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2693
2694         state = h->data;
2695
2696         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
2697                                           LDB_FLAG_MOD_DELETE,
2698                                           r->in.sid, r->in.rights);
2699 }
2700
2701
2702 /* 
2703   lsa_StorePrivateData
2704 */
2705 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2706                        struct lsa_StorePrivateData *r)
2707 {
2708         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2709 }
2710
2711
2712 /* 
2713   lsa_RetrievePrivateData
2714 */
2715 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2716                        struct lsa_RetrievePrivateData *r)
2717 {
2718         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2719 }
2720
2721
2722 /* 
2723   lsa_GetUserName
2724 */
2725 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2726                                 struct lsa_GetUserName *r)
2727 {
2728         NTSTATUS status = NT_STATUS_OK;
2729         const char *account_name;
2730         const char *authority_name;
2731         struct lsa_String *_account_name;
2732         struct lsa_StringPointer *_authority_name = NULL;
2733
2734         /* this is what w2k3 does */
2735         r->out.account_name = r->in.account_name;
2736         r->out.authority_name = r->in.authority_name;
2737
2738         if (r->in.account_name && r->in.account_name->string) {
2739                 return NT_STATUS_INVALID_PARAMETER;
2740         }
2741
2742         if (r->in.authority_name &&
2743             r->in.authority_name->string &&
2744             r->in.authority_name->string->string) {
2745                 return NT_STATUS_INVALID_PARAMETER;
2746         }
2747
2748         account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2749         authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2750
2751         _account_name = talloc(mem_ctx, struct lsa_String);
2752         NT_STATUS_HAVE_NO_MEMORY(_account_name);
2753         _account_name->string = account_name;
2754
2755         if (r->in.authority_name) {
2756                 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2757                 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2758                 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2759                 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2760                 _authority_name->string->string = authority_name;
2761         }
2762
2763         r->out.account_name = _account_name;
2764         r->out.authority_name = _authority_name;
2765
2766         return status;
2767 }
2768
2769 /*
2770   lsa_SetInfoPolicy2
2771 */
2772 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2773                                    TALLOC_CTX *mem_ctx,
2774                                    struct lsa_SetInfoPolicy2 *r)
2775 {
2776         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2777 }
2778
2779 /*
2780   lsa_QueryDomainInformationPolicy
2781 */
2782 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2783                                                  TALLOC_CTX *mem_ctx,
2784                                                  struct lsa_QueryDomainInformationPolicy *r)
2785 {
2786         r->out.info = talloc(mem_ctx, union lsa_DomainInformationPolicy);
2787         if (!r->out.info) {
2788                 return NT_STATUS_NO_MEMORY;
2789         }
2790
2791         switch (r->in.level) {
2792         case LSA_DOMAIN_INFO_POLICY_EFS:
2793                 talloc_free(r->out.info);
2794                 r->out.info = NULL;
2795                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2796         case LSA_DOMAIN_INFO_POLICY_KERBEROS:
2797         {
2798                 struct lsa_DomainInfoKerberos *k = &r->out.info->kerberos_info;
2799                 struct smb_krb5_context *smb_krb5_context;
2800                 int ret = smb_krb5_init_context(mem_ctx, 
2801                                                         dce_call->event_ctx, 
2802                                                         dce_call->conn->dce_ctx->lp_ctx,
2803                                                         &smb_krb5_context);
2804                 if (ret != 0) {
2805                         talloc_free(r->out.info);
2806                         r->out.info = NULL;
2807                         return NT_STATUS_INTERNAL_ERROR;
2808                 }
2809                 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */
2810                 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */
2811                 k->user_tkt_lifetime = 0;    /* Need to find somewhere to store this, and query in KDC too */
2812                 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */
2813                 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context);
2814                 talloc_free(smb_krb5_context);
2815                 return NT_STATUS_OK;
2816         }
2817         default:
2818                 talloc_free(r->out.info);
2819                 r->out.info = NULL;
2820                 return NT_STATUS_INVALID_INFO_CLASS;
2821         }
2822 }
2823
2824 /*
2825   lsa_SetDomInfoPolicy
2826 */
2827 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2828                                               TALLOC_CTX *mem_ctx,
2829                                               struct lsa_SetDomainInformationPolicy *r)
2830 {
2831         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2832 }
2833
2834 /*
2835   lsa_TestCall
2836 */
2837 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
2838                              TALLOC_CTX *mem_ctx,
2839                              struct lsa_TestCall *r)
2840 {
2841         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2842 }
2843
2844 /* 
2845   lsa_CREDRWRITE 
2846 */
2847 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2848                        struct lsa_CREDRWRITE *r)
2849 {
2850         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2851 }
2852
2853
2854 /* 
2855   lsa_CREDRREAD 
2856 */
2857 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2858                        struct lsa_CREDRREAD *r)
2859 {
2860         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2861 }
2862
2863
2864 /* 
2865   lsa_CREDRENUMERATE 
2866 */
2867 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2868                        struct lsa_CREDRENUMERATE *r)
2869 {
2870         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2871 }
2872
2873
2874 /* 
2875   lsa_CREDRWRITEDOMAINCREDENTIALS 
2876 */
2877 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2878                        struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
2879 {
2880         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2881 }
2882
2883
2884 /* 
2885   lsa_CREDRREADDOMAINCREDENTIALS 
2886 */
2887 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2888                        struct lsa_CREDRREADDOMAINCREDENTIALS *r)
2889 {
2890         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2891 }
2892
2893
2894 /* 
2895   lsa_CREDRDELETE 
2896 */
2897 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2898                        struct lsa_CREDRDELETE *r)
2899 {
2900         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2901 }
2902
2903
2904 /* 
2905   lsa_CREDRGETTARGETINFO 
2906 */
2907 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2908                        struct lsa_CREDRGETTARGETINFO *r)
2909 {
2910         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2911 }
2912
2913
2914 /* 
2915   lsa_CREDRPROFILELOADED 
2916 */
2917 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2918                        struct lsa_CREDRPROFILELOADED *r)
2919 {
2920         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2921 }
2922
2923
2924 /* 
2925   lsa_CREDRGETSESSIONTYPES 
2926 */
2927 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2928                        struct lsa_CREDRGETSESSIONTYPES *r)
2929 {
2930         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2931 }
2932
2933
2934 /* 
2935   lsa_LSARREGISTERAUDITEVENT 
2936 */
2937 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2938                        struct lsa_LSARREGISTERAUDITEVENT *r)
2939 {
2940         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2941 }
2942
2943
2944 /* 
2945   lsa_LSARGENAUDITEVENT 
2946 */
2947 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2948                        struct lsa_LSARGENAUDITEVENT *r)
2949 {
2950         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2951 }
2952
2953
2954 /* 
2955   lsa_LSARUNREGISTERAUDITEVENT 
2956 */
2957 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2958                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
2959 {
2960         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2961 }
2962
2963
2964 /* 
2965   lsa_lsaRQueryForestTrustInformation 
2966 */
2967 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2968                        struct lsa_lsaRQueryForestTrustInformation *r)
2969 {
2970         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2971 }
2972
2973
2974 /* 
2975   lsa_LSARSETFORESTTRUSTINFORMATION 
2976 */
2977 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2978                        struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
2979 {
2980         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2981 }
2982
2983
2984 /* 
2985   lsa_CREDRRENAME 
2986 */
2987 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2988                        struct lsa_CREDRRENAME *r)
2989 {
2990         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2991 }
2992
2993
2994
2995 /* 
2996   lsa_LSAROPENPOLICYSCE 
2997 */
2998 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2999                        struct lsa_LSAROPENPOLICYSCE *r)
3000 {
3001         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3002 }
3003
3004
3005 /* 
3006   lsa_LSARADTREGISTERSECURITYEVENTSOURCE 
3007 */
3008 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3009                        struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3010 {
3011         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3012 }
3013
3014
3015 /* 
3016   lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE 
3017 */
3018 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3019                        struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3020 {
3021         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3022 }
3023
3024
3025 /* 
3026   lsa_LSARADTREPORTSECURITYEVENT 
3027 */
3028 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3029                        struct lsa_LSARADTREPORTSECURITYEVENT *r)
3030 {
3031         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3032 }
3033
3034
3035 /* include the generated boilerplate */
3036 #include "librpc/gen_ndr/ndr_lsa_s.c"
3037
3038
3039
3040 /*****************************************
3041 NOTE! The remaining calls below were
3042 removed in w2k3, so the DCESRV_FAULT()
3043 replies are the correct implementation. Do
3044 not try and fill these in with anything else
3045 ******************************************/
3046
3047 /* 
3048   dssetup_DsRoleDnsNameToFlatName 
3049 */
3050 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3051                                         struct dssetup_DsRoleDnsNameToFlatName *r)
3052 {
3053         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3054 }
3055
3056
3057 /* 
3058   dssetup_DsRoleDcAsDc 
3059 */
3060 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3061                              struct dssetup_DsRoleDcAsDc *r)
3062 {
3063         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3064 }
3065
3066
3067 /* 
3068   dssetup_DsRoleDcAsReplica 
3069 */
3070 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3071                                   struct dssetup_DsRoleDcAsReplica *r)
3072 {
3073         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3074 }
3075
3076
3077 /* 
3078   dssetup_DsRoleDemoteDc 
3079 */
3080 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3081                                struct dssetup_DsRoleDemoteDc *r)
3082 {
3083         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3084 }
3085
3086
3087 /* 
3088   dssetup_DsRoleGetDcOperationProgress 
3089 */
3090 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3091                                              struct dssetup_DsRoleGetDcOperationProgress *r)
3092 {
3093         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3094 }
3095
3096
3097 /* 
3098   dssetup_DsRoleGetDcOperationResults 
3099 */
3100 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3101                                             struct dssetup_DsRoleGetDcOperationResults *r)
3102 {
3103         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3104 }
3105
3106
3107 /* 
3108   dssetup_DsRoleCancel 
3109 */
3110 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3111                              struct dssetup_DsRoleCancel *r)
3112 {
3113         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3114 }
3115
3116
3117 /* 
3118   dssetup_DsRoleServerSaveStateForUpgrade 
3119 */
3120 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3121                                                 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3122 {
3123         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3124 }
3125
3126
3127 /* 
3128   dssetup_DsRoleUpgradeDownlevelServer 
3129 */
3130 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3131                                              struct dssetup_DsRoleUpgradeDownlevelServer *r)
3132 {
3133         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3134 }
3135
3136
3137 /* 
3138   dssetup_DsRoleAbortDownlevelServerUpgrade 
3139 */
3140 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3141                                                   struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3142 {
3143         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3144 }
3145
3146
3147 /* include the generated boilerplate */
3148 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3149
3150 NTSTATUS dcerpc_server_lsa_init(void)
3151 {
3152         NTSTATUS ret;
3153         
3154         ret = dcerpc_server_dssetup_init();
3155         if (!NT_STATUS_IS_OK(ret)) {
3156                 return ret;
3157         }
3158         ret = dcerpc_server_lsarpc_init();
3159         if (!NT_STATUS_IS_OK(ret)) {
3160                 return ret;
3161         }
3162         return ret;
3163 }