s4:param: pass flags via secrets_db_connect() to ldb_wrap_connect()
[metze/samba/wip.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
1 /* need access mask/acl implementation */
2
3 /* 
4    Unix SMB/CIFS implementation.
5
6    endpoint server for the lsarpc pipe
7
8    Copyright (C) Andrew Tridgell 2004
9    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "rpc_server/lsa/lsa.h"
26 #include "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 #include "lib/util/tsort.h"
32 #include "dsdb/common/util.h"
33 #include "libcli/security/session.h"
34 #include "libcli/lsarpc/util_lsarpc.h"
35 #include "lib/messaging/irpc.h"
36 #include "libds/common/roles.h"
37
38 #define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
39        dcesrv_interface_lsarpc_bind(context, iface)
40 static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_connection_context *context,
41                                              const struct dcesrv_interface *iface)
42 {
43         return dcesrv_interface_bind_reject_connect(context, iface);
44 }
45
46 static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
47                                        const struct dcesrv_endpoint_server *ep_server);
48 static const struct dcesrv_interface dcesrv_lsarpc_interface;
49
50 #define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]"
51 #define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]"
52 #define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT NCACN_NP_PIPE_LSASS
53
54 #define DCESRV_INTERFACE_LSARPC_INIT_SERVER     \
55        dcesrv_interface_lsarpc_init_server
56 static NTSTATUS dcesrv_interface_lsarpc_init_server(struct dcesrv_context *dce_ctx,
57                                                     const struct dcesrv_endpoint_server *ep_server)
58 {
59         if (lpcfg_lsa_over_netlogon(dce_ctx->lp_ctx)) {
60                 NTSTATUS ret = dcesrv_interface_register(dce_ctx,
61                                                 NCACN_NP_PIPE_NETLOGON,
62                                                 NCACN_NP_PIPE_LSASS,
63                                                 &dcesrv_lsarpc_interface, NULL);
64                 if (!NT_STATUS_IS_OK(ret)) {
65                         DEBUG(1,("lsarpc_op_init_server: failed to register endpoint '\\pipe\\netlogon'\n"));
66                         return ret;
67                 }
68         }
69         return lsarpc__op_init_server(dce_ctx, ep_server);
70 }
71
72 /*
73   this type allows us to distinguish handle types
74 */
75
76 /*
77   state associated with a lsa_OpenAccount() operation
78 */
79 struct lsa_account_state {
80         struct lsa_policy_state *policy;
81         uint32_t access_mask;
82         struct dom_sid *account_sid;
83 };
84
85
86 /*
87   state associated with a lsa_OpenSecret() operation
88 */
89 struct lsa_secret_state {
90         struct lsa_policy_state *policy;
91         uint32_t access_mask;
92         struct ldb_dn *secret_dn;
93         struct ldb_context *sam_ldb;
94         bool global;
95 };
96
97 /*
98   state associated with a lsa_OpenTrustedDomain() operation
99 */
100 struct lsa_trusted_domain_state {
101         struct lsa_policy_state *policy;
102         uint32_t access_mask;
103         struct ldb_dn *trusted_domain_dn;
104         struct ldb_dn *trusted_domain_user_dn;
105 };
106
107 static bool dcesrc_lsa_valid_AccountRight(const char *right)
108 {
109         enum sec_privilege priv_id;
110         uint32_t right_bit;
111
112         priv_id = sec_privilege_id(right);
113         if (priv_id != SEC_PRIV_INVALID) {
114                 return true;
115         }
116
117         right_bit = sec_right_bit(right);
118         if (right_bit != 0) {
119                 return true;
120         }
121
122         return false;
123 }
124
125 /*
126   this is based on the samba3 function make_lsa_object_sd()
127   It uses the same logic, but with samba4 helper functions
128  */
129 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
130                                     struct security_descriptor **sd,
131                                     struct dom_sid *sid,
132                                     uint32_t sid_access)
133 {
134         NTSTATUS status;
135         uint32_t rid;
136         struct dom_sid *domain_sid, *domain_admins_sid;
137         const char *domain_admins_sid_str, *sidstr;
138         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
139
140         status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
141         if (!NT_STATUS_IS_OK(status)) {
142                 TALLOC_FREE(tmp_ctx);
143                 return status;
144         }
145
146         domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
147         if (domain_admins_sid == NULL) {
148                 TALLOC_FREE(tmp_ctx);
149                 return NT_STATUS_NO_MEMORY;
150         }
151
152         domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
153         if (domain_admins_sid_str == NULL) {
154                 TALLOC_FREE(tmp_ctx);
155                 return NT_STATUS_NO_MEMORY;
156         }
157
158         sidstr = dom_sid_string(tmp_ctx, sid);
159         if (sidstr == NULL) {
160                 TALLOC_FREE(tmp_ctx);
161                 return NT_STATUS_NO_MEMORY;
162         }
163
164         *sd = security_descriptor_dacl_create(mem_ctx,
165                                               0, sidstr, NULL,
166
167                                               SID_WORLD,
168                                               SEC_ACE_TYPE_ACCESS_ALLOWED,
169                                               SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
170
171                                               SID_BUILTIN_ADMINISTRATORS,
172                                               SEC_ACE_TYPE_ACCESS_ALLOWED,
173                                               SEC_GENERIC_ALL, 0,
174
175                                               SID_BUILTIN_ACCOUNT_OPERATORS,
176                                               SEC_ACE_TYPE_ACCESS_ALLOWED,
177                                               SEC_GENERIC_ALL, 0,
178
179                                               domain_admins_sid_str,
180                                               SEC_ACE_TYPE_ACCESS_ALLOWED,
181                                               SEC_GENERIC_ALL, 0,
182
183                                               sidstr,
184                                               SEC_ACE_TYPE_ACCESS_ALLOWED,
185                                               sid_access, 0,
186
187                                               NULL);
188         talloc_free(tmp_ctx);
189
190         NT_STATUS_HAVE_NO_MEMORY(*sd);
191
192         return NT_STATUS_OK;
193 }
194
195
196 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
197                                       TALLOC_CTX *mem_ctx,
198                                       struct lsa_EnumAccountRights *r);
199
200 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
201                                            TALLOC_CTX *mem_ctx,
202                                            struct lsa_policy_state *state,
203                                            int ldb_flag,
204                                            struct dom_sid *sid,
205                                            const struct lsa_RightSet *rights);
206
207 /*
208   lsa_Close
209 */
210 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
211                           struct lsa_Close *r)
212 {
213         enum dcerpc_transport_t transport =
214                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
215         struct dcesrv_handle *h;
216
217         if (transport != NCACN_NP && transport != NCALRPC) {
218                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
219         }
220
221         *r->out.handle = *r->in.handle;
222
223         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
224
225         talloc_free(h);
226
227         ZERO_STRUCTP(r->out.handle);
228
229         return NT_STATUS_OK;
230 }
231
232
233 /*
234   lsa_Delete
235 */
236 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
237                            struct lsa_Delete *r)
238 {
239         return NT_STATUS_NOT_SUPPORTED;
240 }
241
242
243 /*
244   lsa_DeleteObject
245 */
246 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
247                        struct lsa_DeleteObject *r)
248 {
249         struct auth_session_info *session_info =
250                 dcesrv_call_session_info(dce_call);
251         struct dcesrv_handle *h;
252         int ret;
253
254         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
255
256         if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
257                 struct lsa_secret_state *secret_state = h->data;
258
259                 /* Ensure user is permitted to delete this... */
260                 switch (security_session_user_level(session_info, NULL))
261                 {
262                 case SECURITY_SYSTEM:
263                 case SECURITY_ADMINISTRATOR:
264                         break;
265                 default:
266                         /* Users and anonymous are not allowed to delete things */
267                         return NT_STATUS_ACCESS_DENIED;
268                 }
269
270                 ret = ldb_delete(secret_state->sam_ldb,
271                                  secret_state->secret_dn);
272                 if (ret != LDB_SUCCESS) {
273                         return NT_STATUS_INVALID_HANDLE;
274                 }
275
276                 ZERO_STRUCTP(r->out.handle);
277
278                 return NT_STATUS_OK;
279
280         } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
281                 struct lsa_trusted_domain_state *trusted_domain_state =
282                         talloc_get_type(h->data, struct lsa_trusted_domain_state);
283                 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
284                 if (ret != LDB_SUCCESS) {
285                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
286                 }
287
288                 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
289                                  trusted_domain_state->trusted_domain_dn);
290                 if (ret != LDB_SUCCESS) {
291                         ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
292                         return NT_STATUS_INVALID_HANDLE;
293                 }
294
295                 if (trusted_domain_state->trusted_domain_user_dn) {
296                         ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
297                                          trusted_domain_state->trusted_domain_user_dn);
298                         if (ret != LDB_SUCCESS) {
299                                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
300                                 return NT_STATUS_INVALID_HANDLE;
301                         }
302                 }
303
304                 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
305                 if (ret != LDB_SUCCESS) {
306                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
307                 }
308
309                 ZERO_STRUCTP(r->out.handle);
310
311                 return NT_STATUS_OK;
312
313         } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
314                 struct lsa_RightSet *rights;
315                 struct lsa_account_state *astate;
316                 struct lsa_EnumAccountRights r2;
317                 NTSTATUS status;
318
319                 rights = talloc(mem_ctx, struct lsa_RightSet);
320
321                 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
322
323                 astate = h->data;
324
325                 r2.in.handle = &astate->policy->handle->wire_handle;
326                 r2.in.sid = astate->account_sid;
327                 r2.out.rights = rights;
328
329                 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
330                    but we have a LSA_HANDLE_ACCOUNT here, so this call
331                    will always fail */
332                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
333                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
334                         return NT_STATUS_OK;
335                 }
336
337                 if (!NT_STATUS_IS_OK(status)) {
338                         return status;
339                 }
340
341                 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
342                                                     LDB_FLAG_MOD_DELETE, astate->account_sid,
343                                                     r2.out.rights);
344                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
345                         return NT_STATUS_OK;
346                 }
347
348                 if (!NT_STATUS_IS_OK(status)) {
349                         return status;
350                 }
351
352                 ZERO_STRUCTP(r->out.handle);
353
354                 return NT_STATUS_OK;
355         }
356
357         return NT_STATUS_INVALID_HANDLE;
358 }
359
360
361 /*
362   lsa_EnumPrivs
363 */
364 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
365                               struct lsa_EnumPrivs *r)
366 {
367         struct dcesrv_handle *h;
368         uint32_t i;
369         enum sec_privilege priv;
370         const char *privname;
371
372         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
373
374         i = *r->in.resume_handle;
375
376         while (((priv = sec_privilege_from_index(i)) != SEC_PRIV_INVALID) &&
377                r->out.privs->count < r->in.max_count) {
378                 struct lsa_PrivEntry *e;
379                 privname = sec_privilege_name(priv);
380                 r->out.privs->privs = talloc_realloc(r->out.privs,
381                                                        r->out.privs->privs,
382                                                        struct lsa_PrivEntry,
383                                                        r->out.privs->count+1);
384                 if (r->out.privs->privs == NULL) {
385                         return NT_STATUS_NO_MEMORY;
386                 }
387                 e = &r->out.privs->privs[r->out.privs->count];
388                 e->luid.low = priv;
389                 e->luid.high = 0;
390                 e->name.string = privname;
391                 r->out.privs->count++;
392                 i++;
393         }
394
395         *r->out.resume_handle = i;
396
397         return NT_STATUS_OK;
398 }
399
400
401 /*
402   lsa_QuerySecObj
403 */
404 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
405                                          struct lsa_QuerySecurity *r)
406 {
407         struct auth_session_info *session_info =
408                 dcesrv_call_session_info(dce_call);
409         struct dcesrv_handle *h;
410         const struct security_descriptor *sd = NULL;
411         uint32_t access_granted = 0;
412         struct sec_desc_buf *sdbuf = NULL;
413         NTSTATUS status;
414         struct dom_sid *sid;
415
416         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
417
418         sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
419
420         if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
421                 struct lsa_policy_state *pstate = h->data;
422
423                 sd = pstate->sd;
424                 access_granted = pstate->access_mask;
425
426         } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
427                 struct lsa_account_state *astate = h->data;
428                 struct security_descriptor *_sd = NULL;
429
430                 status = dcesrv_build_lsa_sd(mem_ctx, &_sd, sid,
431                                              LSA_ACCOUNT_ALL_ACCESS);
432                 if (!NT_STATUS_IS_OK(status)) {
433                         return status;
434                 }
435                 sd = _sd;
436                 access_granted = astate->access_mask;
437         } else {
438                 return NT_STATUS_INVALID_HANDLE;
439         }
440
441         sdbuf = talloc_zero(mem_ctx, struct sec_desc_buf);
442         if (sdbuf == NULL) {
443                 return NT_STATUS_NO_MEMORY;
444         }
445
446         status = security_descriptor_for_client(sdbuf, sd, r->in.sec_info,
447                                                 access_granted, &sdbuf->sd);
448         if (!NT_STATUS_IS_OK(status)) {
449                 return status;
450         }
451
452         *r->out.sdbuf = sdbuf;
453
454         return NT_STATUS_OK;
455 }
456
457
458 /*
459   lsa_SetSecObj
460 */
461 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
462                               struct lsa_SetSecObj *r)
463 {
464         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
465 }
466
467
468 /*
469   lsa_ChangePassword
470 */
471 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
472                                    struct lsa_ChangePassword *r)
473 {
474         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
475 }
476
477 /*
478   dssetup_DsRoleGetPrimaryDomainInformation
479
480   This is not an LSA call, but is the only call left on the DSSETUP
481   pipe (after the pipe was truncated), and needs lsa_get_policy_state
482 */
483 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
484                                                  TALLOC_CTX *mem_ctx,
485                                                  struct dssetup_DsRoleGetPrimaryDomainInformation *r)
486 {
487         union dssetup_DsRoleInfo *info;
488
489         info = talloc_zero(mem_ctx, union dssetup_DsRoleInfo);
490         W_ERROR_HAVE_NO_MEMORY(info);
491
492         switch (r->in.level) {
493         case DS_ROLE_BASIC_INFORMATION:
494         {
495                 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
496                 uint32_t flags = 0;
497                 const char *domain = NULL;
498                 const char *dns_domain = NULL;
499                 const char *forest = NULL;
500                 struct GUID domain_guid;
501                 struct lsa_policy_state *state;
502
503                 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx,
504                                                               0, /* we skip access checks */
505                                                               &state);
506                 if (!NT_STATUS_IS_OK(status)) {
507                         return ntstatus_to_werror(status);
508                 }
509
510                 ZERO_STRUCT(domain_guid);
511
512                 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
513                 case ROLE_STANDALONE:
514                         role            = DS_ROLE_STANDALONE_SERVER;
515                         break;
516                 case ROLE_DOMAIN_MEMBER:
517                         role            = DS_ROLE_MEMBER_SERVER;
518                         break;
519                 case ROLE_ACTIVE_DIRECTORY_DC:
520                         if (samdb_is_pdc(state->sam_ldb)) {
521                                 role    = DS_ROLE_PRIMARY_DC;
522                         } else {
523                                 role    = DS_ROLE_BACKUP_DC;
524                         }
525                         break;
526                 }
527
528                 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
529                 case ROLE_STANDALONE:
530                         domain          = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
531                         W_ERROR_HAVE_NO_MEMORY(domain);
532                         break;
533                 case ROLE_DOMAIN_MEMBER:
534                         domain          = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
535                         W_ERROR_HAVE_NO_MEMORY(domain);
536                         /* TODO: what is with dns_domain and forest and guid? */
537                         break;
538                 case ROLE_ACTIVE_DIRECTORY_DC:
539                         flags           = DS_ROLE_PRIMARY_DS_RUNNING;
540
541                         if (state->mixed_domain == 1) {
542                                 flags   |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
543                         }
544
545                         domain          = state->domain_name;
546                         dns_domain      = state->domain_dns;
547                         forest          = state->forest_dns;
548
549                         domain_guid     = state->domain_guid;
550                         flags   |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
551                         break;
552                 }
553
554                 info->basic.role        = role;
555                 info->basic.flags       = flags;
556                 info->basic.domain      = domain;
557                 info->basic.dns_domain  = dns_domain;
558                 info->basic.forest      = forest;
559                 info->basic.domain_guid = domain_guid;
560
561                 r->out.info = info;
562                 return WERR_OK;
563         }
564         case DS_ROLE_UPGRADE_STATUS:
565         {
566                 info->upgrade.upgrading     = DS_ROLE_NOT_UPGRADING;
567                 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
568
569                 r->out.info = info;
570                 return WERR_OK;
571         }
572         case DS_ROLE_OP_STATUS:
573         {
574                 info->opstatus.status = DS_ROLE_OP_IDLE;
575
576                 r->out.info = info;
577                 return WERR_OK;
578         }
579         default:
580                 return WERR_INVALID_PARAMETER;
581         }
582 }
583
584 /*
585   fill in the AccountDomain info
586 */
587 static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
588                                        struct lsa_DomainInfo *info)
589 {
590         info->name.string = state->domain_name;
591         info->sid         = state->domain_sid;
592
593         return NT_STATUS_OK;
594 }
595
596 /*
597   fill in the DNS domain info
598 */
599 static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
600                              struct lsa_DnsDomainInfo *info)
601 {
602         info->name.string = state->domain_name;
603         info->sid         = state->domain_sid;
604         info->dns_domain.string = state->domain_dns;
605         info->dns_forest.string = state->forest_dns;
606         info->domain_guid       = state->domain_guid;
607
608         return NT_STATUS_OK;
609 }
610
611 /*
612   lsa_QueryInfoPolicy2
613 */
614 static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
615                                      struct lsa_QueryInfoPolicy2 *r)
616 {
617         struct lsa_policy_state *state;
618         struct dcesrv_handle *h;
619         union lsa_PolicyInformation *info;
620
621         *r->out.info = NULL;
622
623         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
624
625         state = h->data;
626
627         info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
628         if (!info) {
629                 return NT_STATUS_NO_MEMORY;
630         }
631         *r->out.info = info;
632
633         switch (r->in.level) {
634         case LSA_POLICY_INFO_AUDIT_LOG:
635                 /* we don't need to fill in any of this */
636                 ZERO_STRUCT(info->audit_log);
637                 return NT_STATUS_OK;
638         case LSA_POLICY_INFO_AUDIT_EVENTS:
639                 /* we don't need to fill in any of this */
640                 ZERO_STRUCT(info->audit_events);
641                 return NT_STATUS_OK;
642         case LSA_POLICY_INFO_PD:
643                 /* we don't need to fill in any of this */
644                 ZERO_STRUCT(info->pd);
645                 return NT_STATUS_OK;
646
647         case LSA_POLICY_INFO_DOMAIN:
648                 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
649         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
650                 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
651         case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
652                 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
653
654         case LSA_POLICY_INFO_ROLE:
655                 info->role.role = LSA_ROLE_PRIMARY;
656                 return NT_STATUS_OK;
657
658         case LSA_POLICY_INFO_DNS:
659         case LSA_POLICY_INFO_DNS_INT:
660                 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
661
662         case LSA_POLICY_INFO_REPLICA:
663                 ZERO_STRUCT(info->replica);
664                 return NT_STATUS_OK;
665
666         case LSA_POLICY_INFO_QUOTA:
667                 ZERO_STRUCT(info->quota);
668                 return NT_STATUS_OK;
669
670         case LSA_POLICY_INFO_MOD:
671         case LSA_POLICY_INFO_AUDIT_FULL_SET:
672         case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
673                 /* windows gives INVALID_PARAMETER */
674                 *r->out.info = NULL;
675                 return NT_STATUS_INVALID_PARAMETER;
676         }
677
678         *r->out.info = NULL;
679         return NT_STATUS_INVALID_INFO_CLASS;
680 }
681
682 /*
683   lsa_QueryInfoPolicy
684 */
685 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
686                                     struct lsa_QueryInfoPolicy *r)
687 {
688         struct lsa_QueryInfoPolicy2 r2;
689         NTSTATUS status;
690
691         ZERO_STRUCT(r2);
692
693         r2.in.handle = r->in.handle;
694         r2.in.level = r->in.level;
695         r2.out.info = r->out.info;
696
697         status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
698
699         return status;
700 }
701
702 /*
703   lsa_SetInfoPolicy
704 */
705 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
706                                   struct lsa_SetInfoPolicy *r)
707 {
708         /* need to support this */
709         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
710 }
711
712
713 /*
714   lsa_ClearAuditLog
715 */
716 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
717                                   struct lsa_ClearAuditLog *r)
718 {
719         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
720 }
721
722
723 static const struct generic_mapping dcesrv_lsa_account_mapping = {
724         LSA_ACCOUNT_READ,
725         LSA_ACCOUNT_WRITE,
726         LSA_ACCOUNT_EXECUTE,
727         LSA_ACCOUNT_ALL_ACCESS
728 };
729
730 /*
731   lsa_CreateAccount
732
733   This call does not seem to have any long-term effects, hence no database operations
734
735   we need to talk to the MS product group to find out what this account database means!
736
737   answer is that the lsa database is totally separate from the SAM and
738   ldap databases. We are going to need a separate ldb to store these
739   accounts. The SIDs on this account bear no relation to the SIDs in
740   AD
741 */
742 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
743                                   struct lsa_CreateAccount *r)
744 {
745         struct lsa_account_state *astate;
746
747         struct lsa_policy_state *state;
748         struct dcesrv_handle *h, *ah;
749
750         ZERO_STRUCTP(r->out.acct_handle);
751
752         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
753
754         state = h->data;
755
756         astate = talloc(dce_call->conn, struct lsa_account_state);
757         if (astate == NULL) {
758                 return NT_STATUS_NO_MEMORY;
759         }
760
761         astate->account_sid = dom_sid_dup(astate, r->in.sid);
762         if (astate->account_sid == NULL) {
763                 talloc_free(astate);
764                 return NT_STATUS_NO_MEMORY;
765         }
766
767         astate->policy = talloc_reference(astate, state);
768         astate->access_mask = r->in.access_mask;
769
770         /*
771          * For now we grant all requested access.
772          *
773          * We will fail at the ldb layer later.
774          */
775         if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
776                 astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
777                 astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS;
778         }
779         se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping);
780
781         DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X].\n",
782                   __func__, dom_sid_string(mem_ctx, astate->account_sid),
783                  (unsigned)r->in.access_mask,
784                  (unsigned)astate->access_mask));
785
786         ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
787         if (!ah) {
788                 talloc_free(astate);
789                 return NT_STATUS_NO_MEMORY;
790         }
791
792         ah->data = talloc_steal(ah, astate);
793
794         *r->out.acct_handle = ah->wire_handle;
795
796         return NT_STATUS_OK;
797 }
798
799
800 /*
801   lsa_EnumAccounts
802 */
803 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
804                                  struct lsa_EnumAccounts *r)
805 {
806         struct dcesrv_handle *h;
807         struct lsa_policy_state *state;
808         int ret;
809         struct ldb_message **res;
810         const char * const attrs[] = { "objectSid", NULL};
811         uint32_t count, i;
812
813         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
814
815         state = h->data;
816
817         /* NOTE: This call must only return accounts that have at least
818            one privilege set
819         */
820         ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
821                            "(&(objectSid=*)(privilege=*))");
822         if (ret < 0) {
823                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
824         }
825
826         if (*r->in.resume_handle >= ret) {
827                 return NT_STATUS_NO_MORE_ENTRIES;
828         }
829
830         count = ret - *r->in.resume_handle;
831         if (count > r->in.num_entries) {
832                 count = r->in.num_entries;
833         }
834
835         if (count == 0) {
836                 return NT_STATUS_NO_MORE_ENTRIES;
837         }
838
839         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
840         if (r->out.sids->sids == NULL) {
841                 return NT_STATUS_NO_MEMORY;
842         }
843
844         for (i=0;i<count;i++) {
845                 r->out.sids->sids[i].sid =
846                         samdb_result_dom_sid(r->out.sids->sids,
847                                              res[i + *r->in.resume_handle],
848                                              "objectSid");
849                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
850         }
851
852         r->out.sids->num_sids = count;
853         *r->out.resume_handle = count + *r->in.resume_handle;
854
855         return NT_STATUS_OK;
856 }
857
858 /* This decrypts and returns Trusted Domain Auth Information Internal data */
859 static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
860                                        TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
861                                        struct trustDomainPasswords *auth_struct)
862 {
863         DATA_BLOB session_key = data_blob(NULL, 0);
864         enum ndr_err_code ndr_err;
865         NTSTATUS nt_status;
866
867         nt_status = dcesrv_transport_session_key(dce_call, &session_key);
868         if (!NT_STATUS_IS_OK(nt_status)) {
869                 return nt_status;
870         }
871
872         arcfour_crypt_blob(auth_blob->data, auth_blob->length, &session_key);
873         ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
874                                        auth_struct,
875                                        (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
876         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
877                 return NT_STATUS_INVALID_PARAMETER;
878         }
879
880         return NT_STATUS_OK;
881 }
882
883 static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
884                                          TALLOC_CTX *mem_ctx,
885                                          struct trustAuthInOutBlob *iopw,
886                                          DATA_BLOB *trustauth_blob)
887 {
888         enum ndr_err_code ndr_err;
889
890         if (iopw->current.count != iopw->count) {
891                 return NT_STATUS_INVALID_PARAMETER;
892         }
893
894         if (iopw->previous.count > iopw->current.count) {
895                 return NT_STATUS_INVALID_PARAMETER;
896         }
897
898         if (iopw->previous.count == 0) {
899                 /*
900                  * If the previous credentials are not present
901                  * we need to make a copy.
902                  */
903                 iopw->previous = iopw->current;
904         }
905
906         if (iopw->previous.count < iopw->current.count) {
907                 struct AuthenticationInformationArray *c = &iopw->current;
908                 struct AuthenticationInformationArray *p = &iopw->previous;
909
910                 /*
911                  * The previous array needs to have the same size
912                  * as the current one.
913                  *
914                  * We may have to fill with TRUST_AUTH_TYPE_NONE
915                  * elements.
916                  */
917                 p->array = talloc_realloc(mem_ctx, p->array,
918                                    struct AuthenticationInformation,
919                                    c->count);
920                 if (p->array == NULL) {
921                         return NT_STATUS_NO_MEMORY;
922                 }
923
924                 while (p->count < c->count) {
925                         struct AuthenticationInformation *a =
926                                 &p->array[p->count++];
927
928                         *a = (struct AuthenticationInformation) {
929                                 .LastUpdateTime = p->array[0].LastUpdateTime,
930                                 .AuthType = TRUST_AUTH_TYPE_NONE,
931                         };
932                 }
933         }
934
935         ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
936                                        iopw,
937                                        (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
938         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
939                 return NT_STATUS_INVALID_PARAMETER;
940         }
941
942         return NT_STATUS_OK;
943 }
944
945 static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
946                                struct ldb_context *sam_ldb,
947                                struct ldb_dn *base_dn,
948                                const char *netbios_name,
949                                struct trustAuthInOutBlob *in,
950                                struct ldb_dn **user_dn)
951 {
952         struct ldb_request *req;
953         struct ldb_message *msg;
954         struct ldb_dn *dn;
955         uint32_t i;
956         int ret;
957
958         dn = ldb_dn_copy(mem_ctx, base_dn);
959         if (!dn) {
960                 return NT_STATUS_NO_MEMORY;
961         }
962         if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) {
963                 return NT_STATUS_NO_MEMORY;
964         }
965
966         msg = ldb_msg_new(mem_ctx);
967         if (!msg) {
968                 return NT_STATUS_NO_MEMORY;
969         }
970         msg->dn = dn;
971
972         ret = ldb_msg_add_string(msg, "objectClass", "user");
973         if (ret != LDB_SUCCESS) {
974                 return NT_STATUS_NO_MEMORY;
975         }
976
977         ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
978         if (ret != LDB_SUCCESS) {
979                 return NT_STATUS_NO_MEMORY;
980         }
981
982         ret = samdb_msg_add_uint(sam_ldb, msg, msg, "userAccountControl",
983                                  UF_INTERDOMAIN_TRUST_ACCOUNT);
984         if (ret != LDB_SUCCESS) {
985                 return NT_STATUS_NO_MEMORY;
986         }
987
988         for (i = 0; i < in->count; i++) {
989                 const char *attribute;
990                 struct ldb_val v;
991                 switch (in->current.array[i].AuthType) {
992                 case TRUST_AUTH_TYPE_NT4OWF:
993                         attribute = "unicodePwd";
994                         v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
995                         v.length = 16;
996                         break;
997                 case TRUST_AUTH_TYPE_CLEAR:
998                         attribute = "clearTextPassword";
999                         v.data = in->current.array[i].AuthInfo.clear.password;
1000                         v.length = in->current.array[i].AuthInfo.clear.size;
1001                         break;
1002                 default:
1003                         continue;
1004                 }
1005
1006                 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1007                 if (ret != LDB_SUCCESS) {
1008                         return NT_STATUS_NO_MEMORY;
1009                 }
1010         }
1011
1012         /* create the trusted_domain user account */
1013         ret = ldb_build_add_req(&req, sam_ldb, mem_ctx, msg, NULL, NULL,
1014                                 ldb_op_default_callback, NULL);
1015         if (ret != LDB_SUCCESS) {
1016                 return NT_STATUS_NO_MEMORY;
1017         }
1018
1019         ret = ldb_request_add_control(req, DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID,
1020                                       false, NULL);
1021         if (ret != LDB_SUCCESS) {
1022                 return NT_STATUS_NO_MEMORY;
1023         }
1024
1025         ret = dsdb_autotransaction_request(sam_ldb, req);
1026         if (ret != LDB_SUCCESS) {
1027                 DEBUG(0,("Failed to create user record %s: %s\n",
1028                          ldb_dn_get_linearized(msg->dn),
1029                          ldb_errstring(sam_ldb)));
1030
1031                 switch (ret) {
1032                 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1033                         return NT_STATUS_DOMAIN_EXISTS;
1034                 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1035                         return NT_STATUS_ACCESS_DENIED;
1036                 default:
1037                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1038                 }
1039         }
1040
1041         if (user_dn) {
1042                 *user_dn = dn;
1043         }
1044         return NT_STATUS_OK;
1045 }
1046
1047 /*
1048   lsa_CreateTrustedDomainEx2
1049 */
1050 static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
1051                                                     TALLOC_CTX *mem_ctx,
1052                                                     struct lsa_CreateTrustedDomainEx2 *r,
1053                                                     int op,
1054                                                     struct lsa_TrustDomainInfoAuthInfo *unencrypted_auth_info)
1055 {
1056         struct dcesrv_handle *policy_handle;
1057         struct lsa_policy_state *policy_state;
1058         struct lsa_trusted_domain_state *trusted_domain_state;
1059         struct dcesrv_handle *handle;
1060         struct ldb_message **msgs, *msg;
1061         const char *attrs[] = {
1062                 NULL
1063         };
1064         const char *netbios_name;
1065         const char *dns_name;
1066         DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1067         struct trustDomainPasswords auth_struct;
1068         int ret;
1069         NTSTATUS nt_status;
1070         struct ldb_context *sam_ldb;
1071         struct server_id *server_ids = NULL;
1072         uint32_t num_server_ids = 0;
1073         NTSTATUS status;
1074         bool ok;
1075         char *dns_encoded = NULL;
1076         char *netbios_encoded = NULL;
1077         char *sid_encoded = NULL;
1078
1079         DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
1080         ZERO_STRUCTP(r->out.trustdom_handle);
1081
1082         policy_state = policy_handle->data;
1083         sam_ldb = policy_state->sam_ldb;
1084
1085         netbios_name = r->in.info->netbios_name.string;
1086         if (!netbios_name) {
1087                 return NT_STATUS_INVALID_PARAMETER;
1088         }
1089
1090         dns_name = r->in.info->domain_name.string;
1091         if (dns_name == NULL) {
1092                 return NT_STATUS_INVALID_PARAMETER;
1093         }
1094
1095         if (r->in.info->sid == NULL) {
1096                 return NT_STATUS_INVALID_SID;
1097         }
1098
1099         /*
1100          * We expect S-1-5-21-A-B-C, but we don't
1101          * allow S-1-5-21-0-0-0 as this is used
1102          * for claims and compound identities.
1103          */
1104         ok = dom_sid_is_valid_account_domain(r->in.info->sid);
1105         if (!ok) {
1106                 return NT_STATUS_INVALID_PARAMETER;
1107         }
1108
1109         dns_encoded = ldb_binary_encode_string(mem_ctx, dns_name);
1110         if (dns_encoded == NULL) {
1111                 return NT_STATUS_NO_MEMORY;
1112         }
1113         netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
1114         if (netbios_encoded == NULL) {
1115                 return NT_STATUS_NO_MEMORY;
1116         }
1117         sid_encoded = ldap_encode_ndr_dom_sid(mem_ctx, r->in.info->sid);
1118         if (sid_encoded == NULL) {
1119                 return NT_STATUS_NO_MEMORY;
1120         }
1121
1122         trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1123         if (!trusted_domain_state) {
1124                 return NT_STATUS_NO_MEMORY;
1125         }
1126         trusted_domain_state->policy = policy_state;
1127
1128         if (strcasecmp(netbios_name, "BUILTIN") == 0
1129             || (strcasecmp(dns_name, "BUILTIN") == 0)
1130             || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
1131                 return NT_STATUS_INVALID_PARAMETER;
1132         }
1133
1134         if (strcasecmp(netbios_name, policy_state->domain_name) == 0
1135             || strcasecmp(netbios_name, policy_state->domain_dns) == 0
1136             || strcasecmp(dns_name, policy_state->domain_dns) == 0
1137             || strcasecmp(dns_name, policy_state->domain_name) == 0
1138             || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
1139                 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
1140         }
1141
1142         /* While this is a REF pointer, some of the functions that wrap this don't provide this */
1143         if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
1144                 /* No secrets are created at this time, for this function */
1145                 auth_struct.outgoing.count = 0;
1146                 auth_struct.incoming.count = 0;
1147         } else if (op == NDR_LSA_CREATETRUSTEDDOMAINEX2) {
1148                 auth_blob = data_blob_const(r->in.auth_info_internal->auth_blob.data,
1149                                             r->in.auth_info_internal->auth_blob.size);
1150                 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1151                                                    &auth_blob, &auth_struct);
1152                 if (!NT_STATUS_IS_OK(nt_status)) {
1153                         return nt_status;
1154                 }
1155         } else if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
1156
1157                 if (unencrypted_auth_info->incoming_count > 1) {
1158                         return NT_STATUS_INVALID_PARAMETER;
1159                 }
1160
1161                 /* more investigation required here, do not create secrets for
1162                  * now */
1163                 auth_struct.outgoing.count = 0;
1164                 auth_struct.incoming.count = 0;
1165         } else {
1166                 return NT_STATUS_INVALID_PARAMETER;
1167         }
1168
1169         if (auth_struct.incoming.count) {
1170                 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1171                                                      &auth_struct.incoming,
1172                                                      &trustAuthIncoming);
1173                 if (!NT_STATUS_IS_OK(nt_status)) {
1174                         return nt_status;
1175                 }
1176         } else {
1177                 trustAuthIncoming = data_blob(NULL, 0);
1178         }
1179
1180         if (auth_struct.outgoing.count) {
1181                 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1182                                                      &auth_struct.outgoing,
1183                                                      &trustAuthOutgoing);
1184                 if (!NT_STATUS_IS_OK(nt_status)) {
1185                         return nt_status;
1186                 }
1187         } else {
1188                 trustAuthOutgoing = data_blob(NULL, 0);
1189         }
1190
1191         ret = ldb_transaction_start(sam_ldb);
1192         if (ret != LDB_SUCCESS) {
1193                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1194         }
1195
1196         /* search for the trusted_domain record */
1197         ret = gendb_search(sam_ldb,
1198                            mem_ctx, policy_state->system_dn, &msgs, attrs,
1199                            "(&(objectClass=trustedDomain)(|"
1200                              "(flatname=%s)(trustPartner=%s)"
1201                              "(flatname=%s)(trustPartner=%s)"
1202                              "(securityIdentifier=%s)))",
1203                            dns_encoded, dns_encoded,
1204                            netbios_encoded, netbios_encoded,
1205                            sid_encoded);
1206         if (ret > 0) {
1207                 ldb_transaction_cancel(sam_ldb);
1208                 return NT_STATUS_OBJECT_NAME_COLLISION;
1209         }
1210         if (ret < 0) {
1211                 ldb_transaction_cancel(sam_ldb);
1212                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1213         }
1214
1215         msg = ldb_msg_new(mem_ctx);
1216         if (msg == NULL) {
1217                 return NT_STATUS_NO_MEMORY;
1218         }
1219
1220         msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1221         if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", dns_name)) {
1222                         ldb_transaction_cancel(sam_ldb);
1223                 return NT_STATUS_NO_MEMORY;
1224         }
1225
1226         ret = ldb_msg_add_string(msg, "objectClass", "trustedDomain");
1227         if (ret != LDB_SUCCESS) {
1228                 ldb_transaction_cancel(sam_ldb);
1229                 return NT_STATUS_NO_MEMORY;;
1230         }
1231
1232         ret = ldb_msg_add_string(msg, "flatname", netbios_name);
1233         if (ret != LDB_SUCCESS) {
1234                 ldb_transaction_cancel(sam_ldb);
1235                 return NT_STATUS_NO_MEMORY;
1236         }
1237
1238         ret = ldb_msg_add_string(msg, "trustPartner", dns_name);
1239         if (ret != LDB_SUCCESS) {
1240                 ldb_transaction_cancel(sam_ldb);
1241                 return NT_STATUS_NO_MEMORY;;
1242         }
1243
1244         ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier",
1245                                     r->in.info->sid);
1246         if (ret != LDB_SUCCESS) {
1247                 ldb_transaction_cancel(sam_ldb);
1248                 return NT_STATUS_NO_MEMORY;;
1249         }
1250
1251         ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
1252         if (ret != LDB_SUCCESS) {
1253                 ldb_transaction_cancel(sam_ldb);
1254                 return NT_STATUS_NO_MEMORY;;
1255         }
1256
1257         ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
1258         if (ret != LDB_SUCCESS) {
1259                 ldb_transaction_cancel(sam_ldb);
1260                 return NT_STATUS_NO_MEMORY;;
1261         }
1262
1263         ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
1264         if (ret != LDB_SUCCESS) {
1265                 ldb_transaction_cancel(sam_ldb);
1266                 return NT_STATUS_NO_MEMORY;;
1267         }
1268
1269         if (trustAuthIncoming.data) {
1270                 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
1271                 if (ret != LDB_SUCCESS) {
1272                         ldb_transaction_cancel(sam_ldb);
1273                         return NT_STATUS_NO_MEMORY;
1274                 }
1275         }
1276         if (trustAuthOutgoing.data) {
1277                 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
1278                 if (ret != LDB_SUCCESS) {
1279                         ldb_transaction_cancel(sam_ldb);
1280                         return NT_STATUS_NO_MEMORY;
1281                 }
1282         }
1283
1284         trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
1285
1286         /* create the trusted_domain */
1287         ret = ldb_add(sam_ldb, msg);
1288         switch (ret) {
1289         case  LDB_SUCCESS:
1290                 break;
1291         case  LDB_ERR_ENTRY_ALREADY_EXISTS:
1292                 ldb_transaction_cancel(sam_ldb);
1293                 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1294                          ldb_dn_get_linearized(msg->dn),
1295                          ldb_errstring(sam_ldb)));
1296                 return NT_STATUS_DOMAIN_EXISTS;
1297         case  LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1298                 ldb_transaction_cancel(sam_ldb);
1299                 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1300                          ldb_dn_get_linearized(msg->dn),
1301                          ldb_errstring(sam_ldb)));
1302                 return NT_STATUS_ACCESS_DENIED;
1303         default:
1304                 ldb_transaction_cancel(sam_ldb);
1305                 DEBUG(0,("Failed to create user record %s: %s\n",
1306                          ldb_dn_get_linearized(msg->dn),
1307                          ldb_errstring(sam_ldb)));
1308                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1309         }
1310
1311         if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1312                 struct ldb_dn *user_dn;
1313                 /* Inbound trusts must also create a cn=users object to match */
1314                 nt_status = add_trust_user(mem_ctx, sam_ldb,
1315                                            policy_state->domain_dn,
1316                                            netbios_name,
1317                                            &auth_struct.incoming,
1318                                            &user_dn);
1319                 if (!NT_STATUS_IS_OK(nt_status)) {
1320                         ldb_transaction_cancel(sam_ldb);
1321                         return nt_status;
1322                 }
1323
1324                 /* save the trust user dn */
1325                 trusted_domain_state->trusted_domain_user_dn
1326                         = talloc_steal(trusted_domain_state, user_dn);
1327         }
1328
1329         ret = ldb_transaction_commit(sam_ldb);
1330         if (ret != LDB_SUCCESS) {
1331                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1332         }
1333
1334         /*
1335          * Notify winbindd that we have a new trust
1336          */
1337         status = irpc_servers_byname(dce_call->msg_ctx,
1338                                      mem_ctx,
1339                                      "winbind_server",
1340                                      &num_server_ids, &server_ids);
1341         if (NT_STATUS_IS_OK(status) && num_server_ids >= 1) {
1342                 imessaging_send(dce_call->msg_ctx, server_ids[0],
1343                                 MSG_WINBIND_RELOAD_TRUSTED_DOMAINS, NULL);
1344         }
1345         TALLOC_FREE(server_ids);
1346
1347         handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
1348         if (!handle) {
1349                 return NT_STATUS_NO_MEMORY;
1350         }
1351
1352         handle->data = talloc_steal(handle, trusted_domain_state);
1353
1354         trusted_domain_state->access_mask = r->in.access_mask;
1355         trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1356
1357         *r->out.trustdom_handle = handle->wire_handle;
1358
1359         return NT_STATUS_OK;
1360 }
1361
1362 /*
1363   lsa_CreateTrustedDomainEx2
1364 */
1365 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1366                                            TALLOC_CTX *mem_ctx,
1367                                            struct lsa_CreateTrustedDomainEx2 *r)
1368 {
1369         return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2, NULL);
1370 }
1371 /*
1372   lsa_CreateTrustedDomainEx
1373 */
1374 static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1375                                           TALLOC_CTX *mem_ctx,
1376                                           struct lsa_CreateTrustedDomainEx *r)
1377 {
1378         struct lsa_CreateTrustedDomainEx2 r2;
1379
1380         r2.in.policy_handle = r->in.policy_handle;
1381         r2.in.info = r->in.info;
1382         r2.out.trustdom_handle = r->out.trustdom_handle;
1383         return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX, r->in.auth_info);
1384 }
1385
1386 /*
1387   lsa_CreateTrustedDomain
1388 */
1389 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1390                                         struct lsa_CreateTrustedDomain *r)
1391 {
1392         struct lsa_CreateTrustedDomainEx2 r2;
1393
1394         r2.in.policy_handle = r->in.policy_handle;
1395         r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1396         if (!r2.in.info) {
1397                 return NT_STATUS_NO_MEMORY;
1398         }
1399
1400         r2.in.info->domain_name = r->in.info->name;
1401         r2.in.info->netbios_name = r->in.info->name;
1402         r2.in.info->sid = r->in.info->sid;
1403         r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1404         r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1405         r2.in.info->trust_attributes = 0;
1406
1407         r2.in.access_mask = r->in.access_mask;
1408         r2.out.trustdom_handle = r->out.trustdom_handle;
1409
1410         return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN, NULL);
1411 }
1412
1413 static NTSTATUS dcesrv_lsa_OpenTrustedDomain_common(
1414                                         struct dcesrv_call_state *dce_call,
1415                                         TALLOC_CTX *tmp_mem,
1416                                         struct lsa_policy_state *policy_state,
1417                                         const char *filter,
1418                                         uint32_t access_mask,
1419                                         struct dcesrv_handle **_handle)
1420 {
1421         struct lsa_trusted_domain_state *trusted_domain_state;
1422         struct dcesrv_handle *handle;
1423         struct ldb_message **msgs;
1424         const char *attrs[] = {
1425                 "trustDirection",
1426                 "flatname",
1427                 NULL
1428         };
1429         uint32_t direction;
1430         int ret;
1431
1432         /* TODO: perform access checks */
1433
1434         /* search for the trusted_domain record */
1435         ret = gendb_search(policy_state->sam_ldb, tmp_mem,
1436                            policy_state->system_dn,
1437                            &msgs, attrs, "%s", filter);
1438         if (ret == 0) {
1439                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1440         }
1441
1442         if (ret != 1) {
1443                 DEBUG(0,("Found %d records matching %s under %s\n", ret,
1444                          filter,
1445                          ldb_dn_get_linearized(policy_state->system_dn)));
1446                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1447         }
1448
1449         trusted_domain_state = talloc_zero(tmp_mem,
1450                                            struct lsa_trusted_domain_state);
1451         if (!trusted_domain_state) {
1452                 return NT_STATUS_NO_MEMORY;
1453         }
1454         trusted_domain_state->policy = policy_state;
1455
1456         trusted_domain_state->trusted_domain_dn =
1457                 talloc_steal(trusted_domain_state, msgs[0]->dn);
1458
1459         direction = ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0);
1460         if (direction & LSA_TRUST_DIRECTION_INBOUND) {
1461                 const char *flatname = ldb_msg_find_attr_as_string(msgs[0],
1462                                                         "flatname", NULL);
1463
1464                 /* search for the trusted_domain account */
1465                 ret = gendb_search(policy_state->sam_ldb, tmp_mem,
1466                                    policy_state->domain_dn,
1467                                    &msgs, attrs,
1468                                    "(&(samaccountname=%s$)(objectclass=user)"
1469                                    "(userAccountControl:%s:=%u))",
1470                                    flatname,
1471                                    LDB_OID_COMPARATOR_AND,
1472                                    UF_INTERDOMAIN_TRUST_ACCOUNT);
1473                 if (ret == 1) {
1474                         trusted_domain_state->trusted_domain_user_dn =
1475                                 talloc_steal(trusted_domain_state, msgs[0]->dn);
1476                 }
1477         }
1478
1479         handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
1480         if (!handle) {
1481                 return NT_STATUS_NO_MEMORY;
1482         }
1483
1484         handle->data = talloc_steal(handle, trusted_domain_state);
1485
1486         trusted_domain_state->access_mask = access_mask;
1487         trusted_domain_state->policy = talloc_reference(trusted_domain_state,
1488                                                         policy_state);
1489
1490         *_handle = handle;
1491
1492         return NT_STATUS_OK;
1493 }
1494
1495 /*
1496   lsa_OpenTrustedDomain
1497 */
1498 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1499                                       struct lsa_OpenTrustedDomain *r)
1500 {
1501         struct dcesrv_handle *policy_handle;
1502         struct lsa_policy_state *policy_state;
1503         struct dcesrv_handle *handle;
1504         const char *sid_string;
1505         char *filter;
1506         NTSTATUS status;
1507
1508         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1509         ZERO_STRUCTP(r->out.trustdom_handle);
1510         policy_state = policy_handle->data;
1511
1512         sid_string = dom_sid_string(mem_ctx, r->in.sid);
1513         if (!sid_string) {
1514                 return NT_STATUS_NO_MEMORY;
1515         }
1516
1517         filter = talloc_asprintf(mem_ctx,
1518                                  "(&(securityIdentifier=%s)"
1519                                  "(objectclass=trustedDomain))",
1520                                  sid_string);
1521         if (filter == NULL) {
1522                 return NT_STATUS_NO_MEMORY;
1523         }
1524
1525         status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx,
1526                                                      policy_state,
1527                                                      filter,
1528                                                      r->in.access_mask,
1529                                                      &handle);
1530         if (!NT_STATUS_IS_OK(status)) {
1531                 return status;
1532         }
1533
1534         *r->out.trustdom_handle = handle->wire_handle;
1535
1536         return NT_STATUS_OK;
1537 }
1538
1539
1540 /*
1541   lsa_OpenTrustedDomainByName
1542 */
1543 static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1544                                             TALLOC_CTX *mem_ctx,
1545                                             struct lsa_OpenTrustedDomainByName *r)
1546 {
1547         struct dcesrv_handle *policy_handle;
1548         struct lsa_policy_state *policy_state;
1549         struct dcesrv_handle *handle;
1550         char *td_name;
1551         char *filter;
1552         NTSTATUS status;
1553
1554         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1555         ZERO_STRUCTP(r->out.trustdom_handle);
1556         policy_state = policy_handle->data;
1557
1558         if (!r->in.name.string) {
1559                 return NT_STATUS_INVALID_PARAMETER;
1560         }
1561
1562         /* search for the trusted_domain record */
1563         td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1564         if (td_name == NULL) {
1565                 return NT_STATUS_NO_MEMORY;
1566         }
1567
1568         filter = talloc_asprintf(mem_ctx,
1569                            "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1570                              "(objectclass=trustedDomain))",
1571                            td_name, td_name, td_name);
1572         if (filter == NULL) {
1573                 return NT_STATUS_NO_MEMORY;
1574         }
1575
1576         status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx,
1577                                                      policy_state,
1578                                                      filter,
1579                                                      r->in.access_mask,
1580                                                      &handle);
1581         if (!NT_STATUS_IS_OK(status)) {
1582                 return status;
1583         }
1584
1585         *r->out.trustdom_handle = handle->wire_handle;
1586
1587         return NT_STATUS_OK;
1588 }
1589
1590
1591
1592 /*
1593   lsa_SetTrustedDomainInfo
1594 */
1595 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1596                                          struct lsa_SetTrustedDomainInfo *r)
1597 {
1598         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1599 }
1600
1601
1602
1603 /* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
1604  * otherwise at least one must be provided */
1605 static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx,
1606                         struct ldb_dn *basedn, const char *dns_domain,
1607                         const char *netbios, struct dom_sid2 *sid,
1608                         struct ldb_message ***msgs)
1609 {
1610         const char *attrs[] = { "flatname", "trustPartner",
1611                                 "securityIdentifier", "trustDirection",
1612                                 "trustType", "trustAttributes",
1613                                 "trustPosixOffset",
1614                                 "msDs-supportedEncryptionTypes",
1615                                 "msDS-TrustForestTrustInfo",
1616                                 NULL
1617         };
1618         char *dns = NULL;
1619         char *nbn = NULL;
1620         char *sidstr = NULL;
1621         char *filter;
1622         int ret;
1623
1624
1625         if (dns_domain || netbios || sid) {
1626                 filter = talloc_strdup(mem_ctx,
1627                                    "(&(objectclass=trustedDomain)(|");
1628         } else {
1629                 filter = talloc_strdup(mem_ctx,
1630                                        "(objectclass=trustedDomain)");
1631         }
1632         if (!filter) {
1633                 return NT_STATUS_NO_MEMORY;
1634         }
1635
1636         if (dns_domain) {
1637                 dns = ldb_binary_encode_string(mem_ctx, dns_domain);
1638                 if (!dns) {
1639                         return NT_STATUS_NO_MEMORY;
1640                 }
1641                 filter = talloc_asprintf_append(filter,
1642                                                 "(trustPartner=%s)", dns);
1643                 if (!filter) {
1644                         return NT_STATUS_NO_MEMORY;
1645                 }
1646         }
1647         if (netbios) {
1648                 nbn = ldb_binary_encode_string(mem_ctx, netbios);
1649                 if (!nbn) {
1650                         return NT_STATUS_NO_MEMORY;
1651                 }
1652                 filter = talloc_asprintf_append(filter,
1653                                                 "(flatname=%s)", nbn);
1654                 if (!filter) {
1655                         return NT_STATUS_NO_MEMORY;
1656                 }
1657         }
1658         if (sid) {
1659                 sidstr = dom_sid_string(mem_ctx, sid);
1660                 if (!sidstr) {
1661                         return NT_STATUS_INVALID_PARAMETER;
1662                 }
1663                 filter = talloc_asprintf_append(filter,
1664                                                 "(securityIdentifier=%s)",
1665                                                 sidstr);
1666                 if (!filter) {
1667                         return NT_STATUS_NO_MEMORY;
1668                 }
1669         }
1670         if (dns_domain || netbios || sid) {
1671                 filter = talloc_asprintf_append(filter, "))");
1672                 if (!filter) {
1673                         return NT_STATUS_NO_MEMORY;
1674                 }
1675         }
1676
1677         ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter);
1678         if (ret == 0) {
1679                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1680         }
1681
1682         if (ret != 1) {
1683                 return NT_STATUS_OBJECT_NAME_COLLISION;
1684         }
1685
1686         return NT_STATUS_OK;
1687 }
1688
1689 static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx,
1690                                       struct ldb_context *sam_ldb,
1691                                       struct ldb_message *orig,
1692                                       struct ldb_message *dest,
1693                                       const char *attribute,
1694                                       uint32_t value,
1695                                       uint32_t *orig_value)
1696 {
1697         const struct ldb_val *orig_val;
1698         uint32_t orig_uint = 0;
1699         unsigned int flags = 0;
1700         int ret;
1701
1702         orig_val = ldb_msg_find_ldb_val(orig, attribute);
1703         if (!orig_val || !orig_val->data) {
1704                 /* add new attribute */
1705                 flags = LDB_FLAG_MOD_ADD;
1706
1707         } else {
1708                 errno = 0;
1709                 orig_uint = strtoul((const char *)orig_val->data, NULL, 0);
1710                 if (errno != 0 || orig_uint != value) {
1711                         /* replace also if can't get value */
1712                         flags = LDB_FLAG_MOD_REPLACE;
1713                 }
1714         }
1715
1716         if (flags == 0) {
1717                 /* stored value is identical, nothing to change */
1718                 goto done;
1719         }
1720
1721         ret = ldb_msg_add_empty(dest, attribute, flags, NULL);
1722         if (ret != LDB_SUCCESS) {
1723                 return NT_STATUS_NO_MEMORY;
1724         }
1725
1726         ret = samdb_msg_add_uint(sam_ldb, dest, dest, attribute, value);
1727         if (ret != LDB_SUCCESS) {
1728                 return NT_STATUS_NO_MEMORY;
1729         }
1730
1731 done:
1732         if (orig_value) {
1733                 *orig_value = orig_uint;
1734         }
1735         return NT_STATUS_OK;
1736 }
1737
1738 static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
1739                                   struct ldb_context *sam_ldb,
1740                                   struct ldb_dn *base_dn,
1741                                   bool delete_user,
1742                                   const char *netbios_name,
1743                                   struct trustAuthInOutBlob *in)
1744 {
1745         const char *attrs[] = { "userAccountControl", NULL };
1746         struct ldb_message **msgs;
1747         struct ldb_message *msg;
1748         uint32_t uac;
1749         uint32_t i;
1750         int ret;
1751
1752         ret = gendb_search(sam_ldb, mem_ctx,
1753                            base_dn, &msgs, attrs,
1754                            "samAccountName=%s$", netbios_name);
1755         if (ret > 1) {
1756                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1757         }
1758
1759         if (ret == 0) {
1760                 if (delete_user) {
1761                         return NT_STATUS_OK;
1762                 }
1763
1764                 /* ok no existing user, add it from scratch */
1765                 return add_trust_user(mem_ctx, sam_ldb, base_dn,
1766                                       netbios_name, in, NULL);
1767         }
1768
1769         /* check user is what we are looking for */
1770         uac = ldb_msg_find_attr_as_uint(msgs[0],
1771                                         "userAccountControl", 0);
1772         if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
1773                 return NT_STATUS_OBJECT_NAME_COLLISION;
1774         }
1775
1776         if (delete_user) {
1777                 ret = ldb_delete(sam_ldb, msgs[0]->dn);
1778                 switch (ret) {
1779                 case LDB_SUCCESS:
1780                         return NT_STATUS_OK;
1781                 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1782                         return NT_STATUS_ACCESS_DENIED;
1783                 default:
1784                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1785                 }
1786         }
1787
1788         /* entry exists, just modify secret if any */
1789         if (in == NULL || in->count == 0) {
1790                 return NT_STATUS_OK;
1791         }
1792
1793         msg = ldb_msg_new(mem_ctx);
1794         if (!msg) {
1795                 return NT_STATUS_NO_MEMORY;
1796         }
1797         msg->dn = msgs[0]->dn;
1798
1799         for (i = 0; i < in->count; i++) {
1800                 const char *attribute;
1801                 struct ldb_val v;
1802                 switch (in->current.array[i].AuthType) {
1803                 case TRUST_AUTH_TYPE_NT4OWF:
1804                         attribute = "unicodePwd";
1805                         v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
1806                         v.length = 16;
1807                         break;
1808                 case TRUST_AUTH_TYPE_CLEAR:
1809                         attribute = "clearTextPassword";
1810                         v.data = in->current.array[i].AuthInfo.clear.password;
1811                         v.length = in->current.array[i].AuthInfo.clear.size;
1812                         break;
1813                 default:
1814                         continue;
1815                 }
1816
1817                 ret = ldb_msg_add_empty(msg, attribute,
1818                                         LDB_FLAG_MOD_REPLACE, NULL);
1819                 if (ret != LDB_SUCCESS) {
1820                         return NT_STATUS_NO_MEMORY;
1821                 }
1822
1823                 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1824                 if (ret != LDB_SUCCESS) {
1825                         return NT_STATUS_NO_MEMORY;
1826                 }
1827         }
1828
1829         /* create the trusted_domain user account */
1830         ret = ldb_modify(sam_ldb, msg);
1831         if (ret != LDB_SUCCESS) {
1832                 DEBUG(0,("Failed to create user record %s: %s\n",
1833                          ldb_dn_get_linearized(msg->dn),
1834                          ldb_errstring(sam_ldb)));
1835
1836                 switch (ret) {
1837                 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1838                         return NT_STATUS_DOMAIN_EXISTS;
1839                 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1840                         return NT_STATUS_ACCESS_DENIED;
1841                 default:
1842                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1843                 }
1844         }
1845
1846         return NT_STATUS_OK;
1847 }
1848
1849
1850 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
1851                                           struct lsa_policy_state *p_state,
1852                                           TALLOC_CTX *mem_ctx,
1853                                           struct ldb_message *dom_msg,
1854                                           enum lsa_TrustDomInfoEnum level,
1855                                           union lsa_TrustedDomainInfo *info)
1856 {
1857         uint32_t *posix_offset = NULL;
1858         struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
1859         struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
1860         struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
1861         uint32_t *enc_types = NULL;
1862         DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1863         struct trustDomainPasswords auth_struct;
1864         struct trustAuthInOutBlob *current_passwords = NULL;
1865         NTSTATUS nt_status;
1866         struct ldb_message **msgs;
1867         struct ldb_message *msg;
1868         bool add_outgoing = false;
1869         bool add_incoming = false;
1870         bool del_outgoing = false;
1871         bool del_incoming = false;
1872         bool del_forest_info = false;
1873         bool in_transaction = false;
1874         int ret;
1875         bool am_rodc;
1876
1877         switch (level) {
1878         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1879                 posix_offset = &info->posix_offset.posix_offset;
1880                 break;
1881         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1882                 info_ex = &info->info_ex;
1883                 break;
1884         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1885                 auth_info = &info->auth_info;
1886                 break;
1887         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1888                 posix_offset = &info->full_info.posix_offset.posix_offset;
1889                 info_ex = &info->full_info.info_ex;
1890                 auth_info = &info->full_info.auth_info;
1891                 break;
1892         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1893                 auth_info_int = &info->auth_info_internal;
1894                 break;
1895         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1896                 posix_offset = &info->full_info_internal.posix_offset.posix_offset;
1897                 info_ex = &info->full_info_internal.info_ex;
1898                 auth_info_int = &info->full_info_internal.auth_info;
1899                 break;
1900         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1901                 enc_types = &info->enc_types.enc_types;
1902                 break;
1903         default:
1904                 return NT_STATUS_INVALID_PARAMETER;
1905         }
1906
1907         if (auth_info) {
1908                 nt_status = auth_info_2_auth_blob(mem_ctx, auth_info,
1909                                                   &trustAuthIncoming,
1910                                                   &trustAuthOutgoing);
1911                 if (!NT_STATUS_IS_OK(nt_status)) {
1912                         return nt_status;
1913                 }
1914                 if (trustAuthIncoming.data) {
1915                         /* This does the decode of some of this twice, but it is easier that way */
1916                         nt_status = auth_info_2_trustauth_inout(mem_ctx,
1917                                                                 auth_info->incoming_count,
1918                                                                 auth_info->incoming_current_auth_info,
1919                                                                 NULL,
1920                                                                 &current_passwords);
1921                         if (!NT_STATUS_IS_OK(nt_status)) {
1922                                 return nt_status;
1923                         }
1924                 }
1925         }
1926
1927         /* decode auth_info_int if set */
1928         if (auth_info_int) {
1929
1930                 /* now decrypt blob */
1931                 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
1932                                             auth_info_int->auth_blob.size);
1933
1934                 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1935                                                    &auth_blob, &auth_struct);
1936                 if (!NT_STATUS_IS_OK(nt_status)) {
1937                         return nt_status;
1938                 }
1939         }
1940
1941         if (info_ex) {
1942                 /* verify data matches */
1943                 if (info_ex->trust_attributes &
1944                     LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1945                         /* TODO: check what behavior level we have */
1946                        if (strcasecmp_m(p_state->domain_dns,
1947                                         p_state->forest_dns) != 0) {
1948                                 return NT_STATUS_INVALID_DOMAIN_STATE;
1949                         }
1950                 }
1951
1952                 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
1953                 if (ret == LDB_SUCCESS && am_rodc) {
1954                         return NT_STATUS_NO_SUCH_DOMAIN;
1955                 }
1956
1957                 /* verify only one object matches the dns/netbios/sid
1958                  * triplet and that this is the one we already have */
1959                 nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
1960                                     p_state->system_dn,
1961                                     info_ex->domain_name.string,
1962                                     info_ex->netbios_name.string,
1963                                     info_ex->sid, &msgs);
1964                 if (!NT_STATUS_IS_OK(nt_status)) {
1965                         return nt_status;
1966                 }
1967                 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
1968                         return NT_STATUS_OBJECT_NAME_COLLISION;
1969                 }
1970                 talloc_free(msgs);
1971         }
1972
1973         /* TODO: should we fetch previous values from the existing entry
1974          * and append them ? */
1975         if (auth_info_int && auth_struct.incoming.count) {
1976                 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1977                                                      &auth_struct.incoming,
1978                                                      &trustAuthIncoming);
1979                 if (!NT_STATUS_IS_OK(nt_status)) {
1980                         return nt_status;
1981                 }
1982
1983                 current_passwords = &auth_struct.incoming;
1984
1985         } else {
1986                 trustAuthIncoming = data_blob(NULL, 0);
1987         }
1988
1989         if (auth_info_int && auth_struct.outgoing.count) {
1990                 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1991                                                      &auth_struct.outgoing,
1992                                                      &trustAuthOutgoing);
1993                 if (!NT_STATUS_IS_OK(nt_status)) {
1994                         return nt_status;
1995                 }
1996         } else {
1997                 trustAuthOutgoing = data_blob(NULL, 0);
1998         }
1999
2000         msg = ldb_msg_new(mem_ctx);
2001         if (msg == NULL) {
2002                 return NT_STATUS_NO_MEMORY;
2003         }
2004         msg->dn = dom_msg->dn;
2005
2006         if (posix_offset) {
2007                 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2008                                                   dom_msg, msg,
2009                                                   "trustPosixOffset",
2010                                                   *posix_offset, NULL);
2011                 if (!NT_STATUS_IS_OK(nt_status)) {
2012                         return nt_status;
2013                 }
2014         }
2015
2016         if (info_ex) {
2017                 uint32_t origattrs;
2018                 uint32_t changed_attrs;
2019                 uint32_t origdir;
2020                 int origtype;
2021
2022                 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2023                                                   dom_msg, msg,
2024                                                   "trustDirection",
2025                                                   info_ex->trust_direction,
2026                                                   &origdir);
2027                 if (!NT_STATUS_IS_OK(nt_status)) {
2028                         return nt_status;
2029                 }
2030
2031                 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
2032                         if (auth_info != NULL && trustAuthIncoming.length > 0) {
2033                                 add_incoming = true;
2034                         }
2035                 }
2036                 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
2037                         if (auth_info != NULL && trustAuthOutgoing.length > 0) {
2038                                 add_outgoing = true;
2039                         }
2040                 }
2041
2042                 if ((origdir & LSA_TRUST_DIRECTION_INBOUND) &&
2043                     !(info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND)) {
2044                         del_incoming = true;
2045                 }
2046                 if ((origdir & LSA_TRUST_DIRECTION_OUTBOUND) &&
2047                     !(info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) {
2048                         del_outgoing = true;
2049                 }
2050
2051                 origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1);
2052                 if (origtype == -1 || origtype != info_ex->trust_type) {
2053                         DEBUG(1, ("Attempted to change trust type! "
2054                                   "Operation not handled\n"));
2055                         return NT_STATUS_INVALID_PARAMETER;
2056                 }
2057
2058                 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2059                                                   dom_msg, msg,
2060                                                   "trustAttributes",
2061                                                   info_ex->trust_attributes,
2062                                                   &origattrs);
2063                 if (!NT_STATUS_IS_OK(nt_status)) {
2064                         return nt_status;
2065                 }
2066                 /* TODO: check forestFunctionality from ldb opaque */
2067                 /* TODO: check what is set makes sense */
2068
2069                 changed_attrs = origattrs ^ info_ex->trust_attributes;
2070                 if (changed_attrs & ~LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2071                         /*
2072                          * For now we only allow
2073                          * LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE to be changed.
2074                          *
2075                          * TODO: we may need to support more attribute changes
2076                          */
2077                         DEBUG(1, ("Attempted to change trust attributes "
2078                                   "(0x%08x != 0x%08x)! "
2079                                   "Operation not handled yet...\n",
2080                                   (unsigned)origattrs,
2081                                   (unsigned)info_ex->trust_attributes));
2082                         return NT_STATUS_INVALID_PARAMETER;
2083                 }
2084
2085                 if (!(info_ex->trust_attributes &
2086                       LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE))
2087                 {
2088                         struct ldb_message_element *orig_forest_el = NULL;
2089
2090                         orig_forest_el = ldb_msg_find_element(dom_msg,
2091                                                 "msDS-TrustForestTrustInfo");
2092                         if (orig_forest_el != NULL) {
2093                                 del_forest_info = true;
2094                         }
2095                 }
2096         }
2097
2098         if (enc_types) {
2099                 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2100                                                   dom_msg, msg,
2101                                                   "msDS-SupportedEncryptionTypes",
2102                                                   *enc_types, NULL);
2103                 if (!NT_STATUS_IS_OK(nt_status)) {
2104                         return nt_status;
2105                 }
2106         }
2107
2108         if (add_incoming || del_incoming) {
2109                 ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
2110                                         LDB_FLAG_MOD_REPLACE, NULL);
2111                 if (ret != LDB_SUCCESS) {
2112                         return NT_STATUS_NO_MEMORY;
2113                 }
2114                 if (add_incoming) {
2115                         ret = ldb_msg_add_value(msg, "trustAuthIncoming",
2116                                                 &trustAuthIncoming, NULL);
2117                         if (ret != LDB_SUCCESS) {
2118                                 return NT_STATUS_NO_MEMORY;
2119                         }
2120                 }
2121         }
2122         if (add_outgoing || del_outgoing) {
2123                 ret = ldb_msg_add_empty(msg, "trustAuthOutgoing",
2124                                         LDB_FLAG_MOD_REPLACE, NULL);
2125                 if (ret != LDB_SUCCESS) {
2126                         return NT_STATUS_NO_MEMORY;
2127                 }
2128                 if (add_outgoing) {
2129                         ret = ldb_msg_add_value(msg, "trustAuthOutgoing",
2130                                                 &trustAuthOutgoing, NULL);
2131                         if (ret != LDB_SUCCESS) {
2132                                 return NT_STATUS_NO_MEMORY;
2133                         }
2134                 }
2135         }
2136         if (del_forest_info) {
2137                 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
2138                                         LDB_FLAG_MOD_REPLACE, NULL);
2139                 if (ret != LDB_SUCCESS) {
2140                         return NT_STATUS_NO_MEMORY;
2141                 }
2142         }
2143
2144         /* start transaction */
2145         ret = ldb_transaction_start(p_state->sam_ldb);
2146         if (ret != LDB_SUCCESS) {
2147                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2148         }
2149         in_transaction = true;
2150
2151         if (msg->num_elements) {
2152                 ret = ldb_modify(p_state->sam_ldb, msg);
2153                 if (ret != LDB_SUCCESS) {
2154                         DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
2155                                  ldb_dn_get_linearized(msg->dn),
2156                                  ldb_errstring(p_state->sam_ldb)));
2157                         nt_status = dsdb_ldb_err_to_ntstatus(ret);
2158                         goto done;
2159                 }
2160         }
2161
2162         if (add_incoming || del_incoming) {
2163                 const char *netbios_name;
2164
2165                 netbios_name = ldb_msg_find_attr_as_string(dom_msg,
2166                                                            "flatname", NULL);
2167                 if (!netbios_name) {
2168                         nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
2169                         goto done;
2170                 }
2171
2172                 /* We use trustAuthIncoming.data to incidate that auth_struct.incoming is valid */
2173                 nt_status = update_trust_user(mem_ctx,
2174                                               p_state->sam_ldb,
2175                                               p_state->domain_dn,
2176                                               del_incoming,
2177                                               netbios_name,
2178                                               current_passwords);
2179                 if (!NT_STATUS_IS_OK(nt_status)) {
2180                         goto done;
2181                 }
2182         }
2183
2184         /* ok, all fine, commit transaction and return */
2185         ret = ldb_transaction_commit(p_state->sam_ldb);
2186         if (ret != LDB_SUCCESS) {
2187                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2188         }
2189         in_transaction = false;
2190
2191         nt_status = NT_STATUS_OK;
2192
2193 done:
2194         if (in_transaction) {
2195                 ldb_transaction_cancel(p_state->sam_ldb);
2196         }
2197         return nt_status;
2198 }
2199
2200 /*
2201   lsa_SetInfomrationTrustedDomain
2202 */
2203 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
2204                                 struct dcesrv_call_state *dce_call,
2205                                 TALLOC_CTX *mem_ctx,
2206                                 struct lsa_SetInformationTrustedDomain *r)
2207 {
2208         struct dcesrv_handle *h;
2209         struct lsa_trusted_domain_state *td_state;
2210         struct ldb_message **msgs;
2211         NTSTATUS nt_status;
2212
2213         DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
2214                            LSA_HANDLE_TRUSTED_DOMAIN);
2215
2216         td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2217
2218         /* get the trusted domain object */
2219         nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
2220                             td_state->trusted_domain_dn,
2221                             NULL, NULL, NULL, &msgs);
2222         if (!NT_STATUS_IS_OK(nt_status)) {
2223                 if (NT_STATUS_EQUAL(nt_status,
2224                                     NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2225                         return nt_status;
2226                 }
2227                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2228         }
2229
2230         return setInfoTrustedDomain_base(dce_call, td_state->policy, mem_ctx,
2231                                          msgs[0], r->in.level, r->in.info);
2232 }
2233
2234
2235 /*
2236   lsa_DeleteTrustedDomain
2237 */
2238 static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2239                                       struct lsa_DeleteTrustedDomain *r)
2240 {
2241         NTSTATUS status;
2242         struct lsa_OpenTrustedDomain opn = {{0},{0}};
2243         struct lsa_DeleteObject del;
2244         struct dcesrv_handle *h;
2245
2246         opn.in.handle = r->in.handle;
2247         opn.in.sid = r->in.dom_sid;
2248         opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2249         opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2250         if (!opn.out.trustdom_handle) {
2251                 return NT_STATUS_NO_MEMORY;
2252         }
2253         status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2254         if (!NT_STATUS_IS_OK(status)) {
2255                 return status;
2256         }
2257
2258         DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2259         talloc_steal(mem_ctx, h);
2260
2261         del.in.handle = opn.out.trustdom_handle;
2262         del.out.handle = opn.out.trustdom_handle;
2263         status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
2264         if (!NT_STATUS_IS_OK(status)) {
2265                 return status;
2266         }
2267         return NT_STATUS_OK;
2268 }
2269
2270 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
2271                                      struct ldb_message *msg,
2272                                      struct lsa_TrustDomainInfoInfoEx *info_ex)
2273 {
2274         info_ex->domain_name.string
2275                 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
2276         info_ex->netbios_name.string
2277                 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2278         info_ex->sid
2279                 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2280         info_ex->trust_direction
2281                 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
2282         info_ex->trust_type
2283                 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
2284         info_ex->trust_attributes
2285                 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
2286         return NT_STATUS_OK;
2287 }
2288
2289 /*
2290   lsa_QueryTrustedDomainInfo
2291 */
2292 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2293                                            struct lsa_QueryTrustedDomainInfo *r)
2294 {
2295         union lsa_TrustedDomainInfo *info = NULL;
2296         struct dcesrv_handle *h;
2297         struct lsa_trusted_domain_state *trusted_domain_state;
2298         struct ldb_message *msg;
2299         int ret;
2300         struct ldb_message **res;
2301         const char *attrs[] = {
2302                 "flatname",
2303                 "trustPartner",
2304                 "securityIdentifier",
2305                 "trustDirection",
2306                 "trustType",
2307                 "trustAttributes",
2308                 "msDs-supportedEncryptionTypes",
2309                 NULL
2310         };
2311
2312         DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
2313
2314         trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2315
2316         /* pull all the user attributes */
2317         ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
2318                               trusted_domain_state->trusted_domain_dn, &res, attrs);
2319         if (ret != 1) {
2320                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2321         }
2322         msg = res[0];
2323
2324         info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
2325         if (!info) {
2326                 return NT_STATUS_NO_MEMORY;
2327         }
2328         *r->out.info = info;
2329
2330         switch (r->in.level) {
2331         case LSA_TRUSTED_DOMAIN_INFO_NAME:
2332                 info->name.netbios_name.string
2333                         = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2334                 break;
2335         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2336                 info->posix_offset.posix_offset
2337                         = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2338                 break;
2339 #if 0  /* Win2k3 doesn't implement this */
2340         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2341                 r->out.info->info_basic.netbios_name.string
2342                         = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2343                 r->out.info->info_basic.sid
2344                         = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2345                 break;
2346 #endif
2347         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2348                 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
2349
2350         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2351                 ZERO_STRUCT(info->full_info);
2352                 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
2353         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2354                 ZERO_STRUCT(info->full_info2_internal);
2355                 info->full_info2_internal.posix_offset.posix_offset
2356                         = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2357                 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
2358
2359         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2360                 info->enc_types.enc_types
2361                         = ldb_msg_find_attr_as_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
2362                 break;
2363
2364         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2365         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2366                 /* oops, we don't want to return the info after all */
2367                 talloc_free(info);
2368                 *r->out.info = NULL;
2369                 return NT_STATUS_INVALID_PARAMETER;
2370         default:
2371                 /* oops, we don't want to return the info after all */
2372                 talloc_free(info);
2373                 *r->out.info = NULL;
2374                 return NT_STATUS_INVALID_INFO_CLASS;
2375         }
2376
2377         return NT_STATUS_OK;
2378 }
2379
2380
2381 /*
2382   lsa_QueryTrustedDomainInfoBySid
2383 */
2384 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2385                                                 struct lsa_QueryTrustedDomainInfoBySid *r)
2386 {
2387         NTSTATUS status;
2388         struct lsa_OpenTrustedDomain opn = {{0},{0}};
2389         struct lsa_QueryTrustedDomainInfo query;
2390         struct dcesrv_handle *h;
2391
2392         opn.in.handle = r->in.handle;
2393         opn.in.sid = r->in.dom_sid;
2394         opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2395         opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2396         if (!opn.out.trustdom_handle) {
2397                 return NT_STATUS_NO_MEMORY;
2398         }
2399         status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2400         if (!NT_STATUS_IS_OK(status)) {
2401                 return status;
2402         }
2403
2404         /* Ensure this handle goes away at the end of this call */
2405         DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2406         talloc_steal(mem_ctx, h);
2407
2408         query.in.trustdom_handle = opn.out.trustdom_handle;
2409         query.in.level = r->in.level;
2410         query.out.info = r->out.info;
2411         status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2412         if (!NT_STATUS_IS_OK(status)) {
2413                 return status;
2414         }
2415
2416         return NT_STATUS_OK;
2417 }
2418
2419 /*
2420   lsa_SetTrustedDomainInfoByName
2421 */
2422 static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2423                                                TALLOC_CTX *mem_ctx,
2424                                                struct lsa_SetTrustedDomainInfoByName *r)
2425 {
2426         struct dcesrv_handle *policy_handle;
2427         struct lsa_policy_state *policy_state;
2428         struct ldb_message **msgs;
2429         NTSTATUS nt_status;
2430
2431         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2432         policy_state = policy_handle->data;
2433
2434         /* get the trusted domain object */
2435         nt_status = get_tdo(policy_state->sam_ldb, mem_ctx,
2436                             policy_state->domain_dn,
2437                             r->in.trusted_domain->string,
2438                             r->in.trusted_domain->string,
2439                             NULL, &msgs);
2440         if (!NT_STATUS_IS_OK(nt_status)) {
2441                 if (NT_STATUS_EQUAL(nt_status,
2442                                     NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2443                         return nt_status;
2444                 }
2445                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2446         }
2447
2448         return setInfoTrustedDomain_base(dce_call, policy_state, mem_ctx,
2449                                          msgs[0], r->in.level, r->in.info);
2450 }
2451
2452 /*
2453    lsa_QueryTrustedDomainInfoByName
2454 */
2455 static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2456                                                  TALLOC_CTX *mem_ctx,
2457                                                  struct lsa_QueryTrustedDomainInfoByName *r)
2458 {
2459         NTSTATUS status;
2460         struct lsa_OpenTrustedDomainByName opn = {{0},{0}};
2461         struct lsa_QueryTrustedDomainInfo query;
2462         struct dcesrv_handle *h;
2463
2464         opn.in.handle = r->in.handle;
2465         opn.in.name = *r->in.trusted_domain;
2466         opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2467         opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2468         if (!opn.out.trustdom_handle) {
2469                 return NT_STATUS_NO_MEMORY;
2470         }
2471         status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
2472         if (!NT_STATUS_IS_OK(status)) {
2473                 return status;
2474         }
2475
2476         /* Ensure this handle goes away at the end of this call */
2477         DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2478         talloc_steal(mem_ctx, h);
2479
2480         query.in.trustdom_handle = opn.out.trustdom_handle;
2481         query.in.level = r->in.level;
2482         query.out.info = r->out.info;
2483         status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2484         if (!NT_STATUS_IS_OK(status)) {
2485                 return status;
2486         }
2487
2488         return NT_STATUS_OK;
2489 }
2490
2491 /*
2492   lsa_CloseTrustedDomainEx
2493 */
2494 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
2495                                          TALLOC_CTX *mem_ctx,
2496                                          struct lsa_CloseTrustedDomainEx *r)
2497 {
2498         /* The result of a bad hair day from an IDL programmer?  Not
2499          * implmented in Win2k3.  You should always just lsa_Close
2500          * anyway. */
2501         return NT_STATUS_NOT_IMPLEMENTED;
2502 }
2503
2504
2505 /*
2506   comparison function for sorting lsa_DomainInformation array
2507 */
2508 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
2509 {
2510         return strcasecmp_m(e1->name.string, e2->name.string);
2511 }
2512
2513 /*
2514   lsa_EnumTrustDom
2515 */
2516 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2517                                  struct lsa_EnumTrustDom *r)
2518 {
2519         struct dcesrv_handle *policy_handle;
2520         struct lsa_DomainInfo *entries;
2521         struct lsa_policy_state *policy_state;
2522         struct ldb_message **domains;
2523         const char *attrs[] = {
2524                 "flatname",
2525                 "securityIdentifier",
2526                 NULL
2527         };
2528
2529
2530         int count, i;
2531
2532         *r->out.resume_handle = 0;
2533
2534         r->out.domains->domains = NULL;
2535         r->out.domains->count = 0;
2536
2537         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2538
2539         policy_state = policy_handle->data;
2540
2541         /* search for all users in this domain. This could possibly be cached and
2542            resumed based on resume_key */
2543         count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2544                              "objectclass=trustedDomain");
2545         if (count < 0) {
2546                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2547         }
2548
2549         /* convert to lsa_TrustInformation format */
2550         entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
2551         if (!entries) {
2552                 return NT_STATUS_NO_MEMORY;
2553         }
2554         for (i=0;i<count;i++) {
2555                 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
2556                 entries[i].name.string = ldb_msg_find_attr_as_string(domains[i], "flatname", NULL);
2557         }
2558
2559         /* sort the results by name */
2560         TYPESAFE_QSORT(entries, count, compare_DomainInfo);
2561
2562         if (*r->in.resume_handle >= count) {
2563                 *r->out.resume_handle = -1;
2564
2565                 return NT_STATUS_NO_MORE_ENTRIES;
2566         }
2567
2568         /* return the rest, limit by max_size. Note that we
2569            use the w2k3 element size value of 60 */
2570         r->out.domains->count = count - *r->in.resume_handle;
2571         r->out.domains->count = MIN(r->out.domains->count,
2572                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
2573
2574         r->out.domains->domains = entries + *r->in.resume_handle;
2575
2576         if (r->out.domains->count < count - *r->in.resume_handle) {
2577                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2578                 return STATUS_MORE_ENTRIES;
2579         }
2580
2581         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2582          * always be larger than the previous input resume handle, in
2583          * particular when hitting the last query it is vital to set the
2584          * resume handle correctly to avoid infinite client loops, as
2585          * seen e.g. with Windows XP SP3 when resume handle is 0 and
2586          * status is NT_STATUS_OK - gd */
2587
2588         *r->out.resume_handle = (uint32_t)-1;
2589
2590         return NT_STATUS_OK;
2591 }
2592
2593 /*
2594   comparison function for sorting lsa_DomainInformation array
2595 */
2596 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
2597 {
2598         return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
2599 }
2600
2601 /*
2602   lsa_EnumTrustedDomainsEx
2603 */
2604 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2605                                         struct lsa_EnumTrustedDomainsEx *r)
2606 {
2607         struct dcesrv_handle *policy_handle;
2608         struct lsa_TrustDomainInfoInfoEx *entries;
2609         struct lsa_policy_state *policy_state;
2610         struct ldb_message **domains;
2611         const char *attrs[] = {
2612                 "flatname",
2613                 "trustPartner",
2614                 "securityIdentifier",
2615                 "trustDirection",
2616                 "trustType",
2617                 "trustAttributes",
2618                 NULL
2619         };
2620         NTSTATUS nt_status;
2621
2622         int count, i;
2623
2624         *r->out.resume_handle = 0;
2625
2626         r->out.domains->domains = NULL;
2627         r->out.domains->count = 0;
2628
2629         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2630
2631         policy_state = policy_handle->data;
2632
2633         /* search for all users in this domain. This could possibly be cached and
2634            resumed based on resume_key */
2635         count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2636                              "objectclass=trustedDomain");
2637         if (count < 0) {
2638                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2639         }
2640
2641         /* convert to lsa_DomainInformation format */
2642         entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
2643         if (!entries) {
2644                 return NT_STATUS_NO_MEMORY;
2645         }
2646         for (i=0;i<count;i++) {
2647                 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
2648                 if (!NT_STATUS_IS_OK(nt_status)) {
2649                         return nt_status;
2650                 }
2651         }
2652
2653         /* sort the results by name */
2654         TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
2655
2656         if (*r->in.resume_handle >= count) {
2657                 *r->out.resume_handle = -1;
2658
2659                 return NT_STATUS_NO_MORE_ENTRIES;
2660         }
2661
2662         /* return the rest, limit by max_size. Note that we
2663            use the w2k3 element size value of 60 */
2664         r->out.domains->count = count - *r->in.resume_handle;
2665         r->out.domains->count = MIN(r->out.domains->count,
2666                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
2667
2668         r->out.domains->domains = entries + *r->in.resume_handle;
2669
2670         if (r->out.domains->count < count - *r->in.resume_handle) {
2671                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2672                 return STATUS_MORE_ENTRIES;
2673         }
2674
2675         *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2676
2677         return NT_STATUS_OK;
2678 }
2679
2680
2681 /*
2682   lsa_OpenAccount
2683 */
2684 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2685                                 struct lsa_OpenAccount *r)
2686 {
2687         struct dcesrv_handle *h, *ah;
2688         struct lsa_policy_state *state;
2689         struct lsa_account_state *astate;
2690
2691         ZERO_STRUCTP(r->out.acct_handle);
2692
2693         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2694
2695         state = h->data;
2696
2697         astate = talloc(dce_call->conn, struct lsa_account_state);
2698         if (astate == NULL) {
2699                 return NT_STATUS_NO_MEMORY;
2700         }
2701
2702         astate->account_sid = dom_sid_dup(astate, r->in.sid);
2703         if (astate->account_sid == NULL) {
2704                 talloc_free(astate);
2705                 return NT_STATUS_NO_MEMORY;
2706         }
2707
2708         astate->policy = talloc_reference(astate, state);
2709         astate->access_mask = r->in.access_mask;
2710
2711         /*
2712          * For now we grant all requested access.
2713          *
2714          * We will fail at the ldb layer later.
2715          */
2716         if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
2717                 astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
2718                 astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS;
2719         }
2720         se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping);
2721
2722         DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X] - success.\n",
2723                   __func__, dom_sid_string(mem_ctx, astate->account_sid),
2724                  (unsigned)r->in.access_mask,
2725                  (unsigned)astate->access_mask));
2726
2727         ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
2728         if (!ah) {
2729                 talloc_free(astate);
2730                 return NT_STATUS_NO_MEMORY;
2731         }
2732
2733         ah->data = talloc_steal(ah, astate);
2734
2735         *r->out.acct_handle = ah->wire_handle;
2736
2737         return NT_STATUS_OK;
2738 }
2739
2740
2741 /*
2742   lsa_EnumPrivsAccount
2743 */
2744 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
2745                                      TALLOC_CTX *mem_ctx,
2746                                      struct lsa_EnumPrivsAccount *r)
2747 {
2748         struct dcesrv_handle *h;
2749         struct lsa_account_state *astate;
2750         int ret;
2751         unsigned int i, j;
2752         struct ldb_message **res;
2753         const char * const attrs[] = { "privilege", NULL};
2754         struct ldb_message_element *el;
2755         const char *sidstr;
2756         struct lsa_PrivilegeSet *privs;
2757
2758         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2759
2760         astate = h->data;
2761
2762         privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2763         if (privs == NULL) {
2764                 return NT_STATUS_NO_MEMORY;
2765         }
2766         privs->count = 0;
2767         privs->unknown = 0;
2768         privs->set = NULL;
2769
2770         *r->out.privs = privs;
2771
2772         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2773         if (sidstr == NULL) {
2774                 return NT_STATUS_NO_MEMORY;
2775         }
2776
2777         ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2778                            "objectSid=%s", sidstr);
2779         if (ret < 0) {
2780                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2781         }
2782         if (ret != 1) {
2783                 return NT_STATUS_OK;
2784         }
2785
2786         el = ldb_msg_find_element(res[0], "privilege");
2787         if (el == NULL || el->num_values == 0) {
2788                 return NT_STATUS_OK;
2789         }
2790
2791         privs->set = talloc_array(privs,
2792                                   struct lsa_LUIDAttribute, el->num_values);
2793         if (privs->set == NULL) {
2794                 return NT_STATUS_NO_MEMORY;
2795         }
2796
2797         j = 0;
2798         for (i=0;i<el->num_values;i++) {
2799                 int id = sec_privilege_id((const char *)el->values[i].data);
2800                 if (id == SEC_PRIV_INVALID) {
2801                         /* Perhaps an account right, not a privilege */
2802                         continue;
2803                 }
2804                 privs->set[j].attribute = 0;
2805                 privs->set[j].luid.low = id;
2806                 privs->set[j].luid.high = 0;
2807                 j++;
2808         }
2809
2810         privs->count = j;
2811
2812         return NT_STATUS_OK;
2813 }
2814
2815 /*
2816   lsa_EnumAccountRights
2817 */
2818 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
2819                                       TALLOC_CTX *mem_ctx,
2820                                       struct lsa_EnumAccountRights *r)
2821 {
2822         struct dcesrv_handle *h;
2823         struct lsa_policy_state *state;
2824         int ret;
2825         unsigned int i;
2826         struct ldb_message **res;
2827         const char * const attrs[] = { "privilege", NULL};
2828         const char *sidstr;
2829         struct ldb_message_element *el;
2830
2831         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2832
2833         state = h->data;
2834
2835         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
2836         if (sidstr == NULL) {
2837                 return NT_STATUS_NO_MEMORY;
2838         }
2839
2840         ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2841                            "(&(objectSid=%s)(privilege=*))", sidstr);
2842         if (ret == 0) {
2843                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2844         }
2845         if (ret != 1) {
2846                 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
2847                           dom_sid_string(mem_ctx, r->in.sid),
2848                           ldb_errstring(state->pdb)));
2849                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2850         }
2851
2852         el = ldb_msg_find_element(res[0], "privilege");
2853         if (el == NULL || el->num_values == 0) {
2854                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2855         }
2856
2857         r->out.rights->count = el->num_values;
2858         r->out.rights->names = talloc_array(r->out.rights,
2859                                             struct lsa_StringLarge, r->out.rights->count);
2860         if (r->out.rights->names == NULL) {
2861                 return NT_STATUS_NO_MEMORY;
2862         }
2863
2864         for (i=0;i<el->num_values;i++) {
2865                 r->out.rights->names[i].string = (const char *)el->values[i].data;
2866         }
2867
2868         return NT_STATUS_OK;
2869 }
2870
2871
2872
2873 /*
2874   helper for lsa_AddAccountRights and lsa_RemoveAccountRights
2875 */
2876 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
2877                                            TALLOC_CTX *mem_ctx,
2878                                            struct lsa_policy_state *state,
2879                                            int ldb_flag,
2880                                            struct dom_sid *sid,
2881                                            const struct lsa_RightSet *rights)
2882 {
2883         struct auth_session_info *session_info =
2884                 dcesrv_call_session_info(dce_call);
2885         const char *sidstr, *sidndrstr;
2886         struct ldb_message *msg;
2887         struct ldb_message_element *el;
2888         int ret;
2889         uint32_t i;
2890         struct lsa_EnumAccountRights r2;
2891         char *dnstr;
2892
2893         if (security_session_user_level(session_info, NULL) <
2894             SECURITY_ADMINISTRATOR) {
2895                 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
2896                 return NT_STATUS_ACCESS_DENIED;
2897         }
2898
2899         msg = ldb_msg_new(mem_ctx);
2900         if (msg == NULL) {
2901                 return NT_STATUS_NO_MEMORY;
2902         }
2903
2904         sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
2905         if (sidndrstr == NULL) {
2906                 TALLOC_FREE(msg);
2907                 return NT_STATUS_NO_MEMORY;
2908         }
2909
2910         sidstr = dom_sid_string(msg, sid);
2911         if (sidstr == NULL) {
2912                 TALLOC_FREE(msg);
2913                 return NT_STATUS_NO_MEMORY;
2914         }
2915
2916         dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
2917         if (dnstr == NULL) {
2918                 TALLOC_FREE(msg);
2919                 return NT_STATUS_NO_MEMORY;
2920         }
2921
2922         msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
2923         if (msg->dn == NULL) {
2924                 TALLOC_FREE(msg);
2925                 return NT_STATUS_NO_MEMORY;
2926         }
2927
2928         if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2929                 NTSTATUS status;
2930
2931                 r2.in.handle = &state->handle->wire_handle;
2932                 r2.in.sid = sid;
2933                 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
2934
2935                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2936                 if (!NT_STATUS_IS_OK(status)) {
2937                         ZERO_STRUCTP(r2.out.rights);
2938                 }
2939         }
2940
2941         for (i=0;i<rights->count;i++) {
2942                 bool ok;
2943
2944                 ok = dcesrc_lsa_valid_AccountRight(rights->names[i].string);
2945                 if (!ok) {
2946                         talloc_free(msg);
2947                         return NT_STATUS_NO_SUCH_PRIVILEGE;
2948                 }
2949
2950                 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2951                         uint32_t j;
2952                         for (j=0;j<r2.out.rights->count;j++) {
2953                                 if (strcasecmp_m(r2.out.rights->names[j].string,
2954                                                rights->names[i].string) == 0) {
2955                                         break;
2956                                 }
2957                         }
2958                         if (j != r2.out.rights->count) continue;
2959                 }
2960
2961                 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2962                 if (ret != LDB_SUCCESS) {
2963                         talloc_free(msg);
2964                         return NT_STATUS_NO_MEMORY;
2965                 }
2966         }
2967
2968         el = ldb_msg_find_element(msg, "privilege");
2969         if (!el) {
2970                 talloc_free(msg);
2971                 return NT_STATUS_OK;
2972         }
2973
2974         el->flags = ldb_flag;
2975
2976         ret = ldb_modify(state->pdb, msg);
2977         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
2978                 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
2979                         talloc_free(msg);
2980                         return NT_STATUS_NO_MEMORY;
2981                 }
2982                 ldb_msg_add_string(msg, "comment", "added via LSA");
2983                 ret = ldb_add(state->pdb, msg);
2984         }
2985         if (ret != LDB_SUCCESS) {
2986                 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2987                         talloc_free(msg);
2988                         return NT_STATUS_OK;
2989                 }
2990                 DEBUG(3, ("Could not %s attributes from %s: %s",
2991                           LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2992                           ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
2993                 talloc_free(msg);
2994                 return NT_STATUS_UNEXPECTED_IO_ERROR;
2995         }
2996
2997         talloc_free(msg);
2998         return NT_STATUS_OK;
2999 }
3000
3001 /*
3002   lsa_AddPrivilegesToAccount
3003 */
3004 static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3005                                            struct lsa_AddPrivilegesToAccount *r)
3006 {
3007         struct lsa_RightSet rights;
3008         struct dcesrv_handle *h;
3009         struct lsa_account_state *astate;
3010         uint32_t i;
3011
3012         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3013
3014         astate = h->data;
3015
3016         rights.count = r->in.privs->count;
3017         rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
3018         if (rights.names == NULL) {
3019                 return NT_STATUS_NO_MEMORY;
3020         }
3021         for (i=0;i<rights.count;i++) {
3022                 int id = r->in.privs->set[i].luid.low;
3023                 if (r->in.privs->set[i].luid.high) {
3024                         return NT_STATUS_NO_SUCH_PRIVILEGE;
3025                 }
3026                 rights.names[i].string = sec_privilege_name(id);
3027                 if (rights.names[i].string == NULL) {
3028                         return NT_STATUS_NO_SUCH_PRIVILEGE;
3029                 }
3030         }
3031
3032         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3033                                           LDB_FLAG_MOD_ADD, astate->account_sid,
3034                                           &rights);
3035 }
3036
3037
3038 /*
3039   lsa_RemovePrivilegesFromAccount
3040 */
3041 static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3042                                                 struct lsa_RemovePrivilegesFromAccount *r)
3043 {
3044         struct lsa_RightSet *rights;
3045         struct dcesrv_handle *h;
3046         struct lsa_account_state *astate;
3047         uint32_t i;
3048
3049         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3050
3051         astate = h->data;
3052
3053         rights = talloc(mem_ctx, struct lsa_RightSet);
3054
3055         if (r->in.remove_all == 1 &&
3056             r->in.privs == NULL) {
3057                 struct lsa_EnumAccountRights r2;
3058                 NTSTATUS status;
3059
3060                 r2.in.handle = &astate->policy->handle->wire_handle;
3061                 r2.in.sid = astate->account_sid;
3062                 r2.out.rights = rights;
3063
3064                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
3065                 if (!NT_STATUS_IS_OK(status)) {
3066                         return status;
3067                 }
3068
3069                 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3070                                                   LDB_FLAG_MOD_DELETE, astate->account_sid,
3071                                                   r2.out.rights);
3072         }
3073
3074         if (r->in.remove_all != 0) {
3075                 return NT_STATUS_INVALID_PARAMETER;
3076         }
3077
3078         rights->count = r->in.privs->count;
3079         rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
3080         if (rights->names == NULL) {
3081                 return NT_STATUS_NO_MEMORY;
3082         }
3083         for (i=0;i<rights->count;i++) {
3084                 int id = r->in.privs->set[i].luid.low;
3085                 if (r->in.privs->set[i].luid.high) {
3086                         return NT_STATUS_NO_SUCH_PRIVILEGE;
3087                 }
3088                 rights->names[i].string = sec_privilege_name(id);
3089                 if (rights->names[i].string == NULL) {
3090                         return NT_STATUS_NO_SUCH_PRIVILEGE;
3091                 }
3092         }
3093
3094         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3095                                           LDB_FLAG_MOD_DELETE, astate->account_sid,
3096                                           rights);
3097 }
3098
3099
3100 /*
3101   lsa_GetQuotasForAccount
3102 */
3103 static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3104                        struct lsa_GetQuotasForAccount *r)
3105 {
3106         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3107 }
3108
3109
3110 /*
3111   lsa_SetQuotasForAccount
3112 */
3113 static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3114                        struct lsa_SetQuotasForAccount *r)
3115 {
3116         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3117 }
3118
3119
3120 /*
3121   lsa_GetSystemAccessAccount
3122 */
3123 static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3124                        struct lsa_GetSystemAccessAccount *r)
3125 {
3126         struct dcesrv_handle *h;
3127         struct lsa_account_state *astate;
3128         int ret;
3129         unsigned int i;
3130         struct ldb_message **res;
3131         const char * const attrs[] = { "privilege", NULL};
3132         struct ldb_message_element *el;
3133         const char *sidstr;
3134
3135         *(r->out.access_mask) = 0x00000000;
3136
3137         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3138
3139         astate = h->data;
3140
3141         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
3142         if (sidstr == NULL) {
3143                 return NT_STATUS_NO_MEMORY;
3144         }
3145
3146         ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
3147                            "objectSid=%s", sidstr);
3148         if (ret < 0) {
3149                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3150         }
3151         if (ret != 1) {
3152                 return NT_STATUS_OK;
3153         }
3154
3155         el = ldb_msg_find_element(res[0], "privilege");
3156         if (el == NULL || el->num_values == 0) {
3157                 return NT_STATUS_OK;
3158         }
3159
3160         for (i=0;i<el->num_values;i++) {
3161                 uint32_t right_bit = sec_right_bit((const char *)el->values[i].data);
3162                 if (right_bit == 0) {
3163                         /* Perhaps an privilege, not a right */
3164                         continue;
3165                 }
3166                 *(r->out.access_mask) |= right_bit;
3167         }
3168
3169         return NT_STATUS_OK;
3170 }
3171
3172
3173 /*
3174   lsa_SetSystemAccessAccount
3175 */
3176 static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3177                        struct lsa_SetSystemAccessAccount *r)
3178 {
3179         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3180 }
3181 /*
3182   lsa_CreateSecret
3183 */
3184 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3185                                  struct lsa_CreateSecret *r)
3186 {
3187         struct auth_session_info *session_info =
3188                 dcesrv_call_session_info(dce_call);
3189         struct dcesrv_handle *policy_handle;
3190         struct lsa_policy_state *policy_state;
3191         struct lsa_secret_state *secret_state;
3192         struct dcesrv_handle *handle;
3193         struct ldb_message **msgs, *msg;
3194         struct ldb_context *samdb = NULL;
3195         const char *attrs[] = {
3196                 NULL
3197         };
3198
3199         const char *name;
3200
3201         int ret;
3202
3203         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3204         ZERO_STRUCTP(r->out.sec_handle);
3205
3206         switch (security_session_user_level(session_info, NULL))
3207         {
3208         case SECURITY_SYSTEM:
3209         case SECURITY_ADMINISTRATOR:
3210                 break;
3211         default:
3212                 /* Users and annonymous are not allowed create secrets */
3213                 return NT_STATUS_ACCESS_DENIED;
3214         }
3215
3216         policy_state = policy_handle->data;
3217
3218         if (!r->in.name.string) {
3219                 return NT_STATUS_INVALID_PARAMETER;
3220         }
3221
3222         secret_state = talloc(mem_ctx, struct lsa_secret_state);
3223         NT_STATUS_HAVE_NO_MEMORY(secret_state);
3224         secret_state->policy = policy_state;
3225
3226         msg = ldb_msg_new(mem_ctx);
3227         if (msg == NULL) {
3228                 return NT_STATUS_NO_MEMORY;
3229         }
3230
3231         if (strncmp("G$", r->in.name.string, 2) == 0) {
3232                 const char *name2;
3233
3234                 secret_state->global = true;
3235
3236                 name = &r->in.name.string[2];
3237                 if (strlen(name) == 0) {
3238                         return NT_STATUS_INVALID_PARAMETER;
3239                 }
3240
3241                 name2 = talloc_asprintf(mem_ctx, "%s Secret",
3242                                         ldb_binary_encode_string(mem_ctx, name));
3243                 NT_STATUS_HAVE_NO_MEMORY(name2);
3244
3245                 /*
3246                  * We need to connect to the database as system, as this is
3247                  * one of the rare RPC calls that must read the secrets
3248                  * (and this is denied otherwise)
3249                  *
3250                  * We also save the current remote session details so they can
3251                  * used by the audit logging module. This allows the audit
3252                  * logging to report the remote users details, rather than the
3253                  * system users details.
3254                  */
3255                 samdb = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
3256                 secret_state->sam_ldb = talloc_reference(secret_state, samdb);
3257                 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3258
3259                 /* search for the secret record */
3260                 ret = gendb_search(secret_state->sam_ldb,
3261                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
3262                                    "(&(cn=%s)(objectclass=secret))",
3263                                    name2);
3264                 if (ret > 0) {
3265                         return NT_STATUS_OBJECT_NAME_COLLISION;
3266                 }
3267
3268                 if (ret < 0) {
3269                         DEBUG(0,("Failure searching for CN=%s: %s\n",
3270                                  name2, ldb_errstring(secret_state->sam_ldb)));
3271                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
3272                 }
3273
3274                 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
3275                 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
3276                 if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
3277                         return NT_STATUS_NO_MEMORY;
3278                 }
3279
3280                 ret = ldb_msg_add_string(msg, "cn", name2);
3281                 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3282         } else {
3283                 secret_state->global = false;
3284
3285                 name = r->in.name.string;
3286                 if (strlen(name) == 0) {
3287                         return NT_STATUS_INVALID_PARAMETER;
3288                 }
3289
3290                 secret_state->sam_ldb = talloc_reference(secret_state,
3291                                                          secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, 0));
3292                 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3293
3294                 /* search for the secret record */
3295                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3296                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3297                                    &msgs, attrs,
3298                                    "(&(cn=%s)(objectclass=secret))",
3299                                    ldb_binary_encode_string(mem_ctx, name));
3300                 if (ret > 0) {
3301                         return NT_STATUS_OBJECT_NAME_COLLISION;
3302                 }
3303
3304                 if (ret < 0) {
3305                         DEBUG(0,("Failure searching for CN=%s: %s\n",
3306                                  name, ldb_errstring(secret_state->sam_ldb)));
3307                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
3308                 }
3309
3310                 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb,
3311                                          "cn=%s,cn=LSA Secrets", name);
3312                 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
3313                 ret = ldb_msg_add_string(msg, "cn", name);
3314                 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3315         }
3316
3317         ret = ldb_msg_add_string(msg, "objectClass", "secret");
3318         if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3319
3320         secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
3321         NT_STATUS_HAVE_NO_MEMORY(secret_state->secret_dn);
3322
3323         /* create the secret */
3324         ret = ldb_add(secret_state->sam_ldb, msg);
3325         if (ret != LDB_SUCCESS) {
3326                 DEBUG(0,("Failed to create secret record %s: %s\n",
3327                          ldb_dn_get_linearized(msg->dn),
3328                          ldb_errstring(secret_state->sam_ldb)));
3329                 return NT_STATUS_ACCESS_DENIED;
3330         }
3331
3332         handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
3333         NT_STATUS_HAVE_NO_MEMORY(handle);
3334
3335         handle->data = talloc_steal(handle, secret_state);
3336
3337         secret_state->access_mask = r->in.access_mask;
3338         secret_state->policy = talloc_reference(secret_state, policy_state);
3339         NT_STATUS_HAVE_NO_MEMORY(secret_state->policy);
3340
3341         *r->out.sec_handle = handle->wire_handle;
3342
3343         return NT_STATUS_OK;
3344 }
3345
3346
3347 /*
3348   lsa_OpenSecret
3349 */
3350 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3351                                struct lsa_OpenSecret *r)
3352 {
3353         struct auth_session_info *session_info =
3354                 dcesrv_call_session_info(dce_call);
3355         struct dcesrv_handle *policy_handle;
3356         struct lsa_policy_state *policy_state;
3357         struct lsa_secret_state *secret_state;
3358         struct dcesrv_handle *handle;
3359         struct ldb_message **msgs;
3360         struct ldb_context *samdb = NULL;
3361         const char *attrs[] = {
3362                 NULL
3363         };
3364         const char *name;
3365         int ret;
3366
3367         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3368         ZERO_STRUCTP(r->out.sec_handle);
3369         policy_state = policy_handle->data;
3370
3371         if (!r->in.name.string) {
3372                 return NT_STATUS_INVALID_PARAMETER;
3373         }
3374
3375         switch (security_session_user_level(session_info, NULL))
3376         {
3377         case SECURITY_SYSTEM:
3378         case SECURITY_ADMINISTRATOR:
3379                 break;
3380         default:
3381                 /* Users and annonymous are not allowed to access secrets */
3382                 return NT_STATUS_ACCESS_DENIED;
3383         }
3384
3385         secret_state = talloc(mem_ctx, struct lsa_secret_state);
3386         if (!secret_state) {
3387                 return NT_STATUS_NO_MEMORY;
3388         }
3389         secret_state->policy = policy_state;
3390
3391         if (strncmp("G$", r->in.name.string, 2) == 0) {
3392                 name = &r->in.name.string[2];
3393                 /*
3394                  * We need to connect to the database as system, as this is
3395                  * one of the rare RPC calls that must read the secrets
3396                  * (and this is denied otherwise)
3397                  *
3398                  * We also save the current remote session details so they can
3399                  * used by the audit logging module. This allows the audit
3400                  * logging to report the remote users details, rather than the
3401                  * system users details.
3402                  */
3403                 samdb = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
3404                 secret_state->sam_ldb = talloc_reference(secret_state, samdb);
3405                 secret_state->global = true;
3406
3407                 if (strlen(name) < 1) {
3408                         return NT_STATUS_INVALID_PARAMETER;
3409                 }
3410
3411                 /* search for the secret record */
3412                 ret = gendb_search(secret_state->sam_ldb,
3413                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
3414                                    "(&(cn=%s Secret)(objectclass=secret))",
3415                                    ldb_binary_encode_string(mem_ctx, name));
3416                 if (ret == 0) {
3417                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3418                 }
3419
3420                 if (ret != 1) {
3421                         DEBUG(0,("Found %d records matching DN %s\n", ret,
3422                                  ldb_dn_get_linearized(policy_state->system_dn)));
3423                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
3424                 }
3425         } else {
3426                 secret_state->global = false;
3427                 secret_state->sam_ldb = talloc_reference(secret_state,
3428                                                          secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, 0));
3429
3430                 name = r->in.name.string;
3431                 if (strlen(name) < 1) {
3432                         return NT_STATUS_INVALID_PARAMETER;
3433                 }
3434
3435                 /* search for the secret record */
3436                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3437                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3438                                    &msgs, attrs,
3439                                    "(&(cn=%s)(objectclass=secret))",
3440                                    ldb_binary_encode_string(mem_ctx, name));
3441                 if (ret == 0) {
3442                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3443                 }
3444
3445                 if (ret != 1) {
3446                         DEBUG(0,("Found %d records matching CN=%s\n",
3447                                  ret, ldb_binary_encode_string(mem_ctx, name)));
3448                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
3449                 }
3450         }
3451
3452         secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
3453
3454         handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
3455         if (!handle) {
3456                 return NT_STATUS_NO_MEMORY;
3457         }
3458
3459         handle->data = talloc_steal(handle, secret_state);
3460
3461         secret_state->access_mask = r->in.access_mask;
3462         secret_state->policy = talloc_reference(secret_state, policy_state);
3463
3464         *r->out.sec_handle = handle->wire_handle;
3465
3466         return NT_STATUS_OK;
3467 }
3468
3469
3470 /*
3471   lsa_SetSecret
3472 */
3473 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3474                               struct lsa_SetSecret *r)
3475 {
3476
3477         struct dcesrv_handle *h;
3478         struct lsa_secret_state *secret_state;
3479         struct ldb_message *msg;
3480         DATA_BLOB session_key;
3481         DATA_BLOB crypt_secret, secret;
3482         struct ldb_val val;
3483         int ret;
3484         NTSTATUS status = NT_STATUS_OK;
3485
3486         struct timeval now = timeval_current();
3487         NTTIME nt_now = timeval_to_nttime(&now);
3488
3489         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3490
3491         secret_state = h->data;
3492
3493         msg = ldb_msg_new(mem_ctx);
3494         if (msg == NULL) {
3495                 return NT_STATUS_NO_MEMORY;
3496         }
3497
3498         msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
3499         if (!msg->dn) {
3500                 return NT_STATUS_NO_MEMORY;
3501         }
3502         status = dcesrv_transport_session_key(dce_call, &session_key);
3503         if (!NT_STATUS_IS_OK(status)) {
3504                 return status;
3505         }
3506
3507         if (r->in.old_val) {
3508                 /* Decrypt */
3509                 crypt_secret.data = r->in.old_val->data;
3510                 crypt_secret.length = r->in.old_val->size;
3511
3512                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3513                 if (!NT_STATUS_IS_OK(status)) {
3514                         return status;
3515                 }
3516
3517                 val.data = secret.data;
3518                 val.length = secret.length;
3519
3520                 /* set value */
3521                 if (ldb_msg_add_value(msg, "priorValue", &val, NULL) != LDB_SUCCESS) {
3522                         return NT_STATUS_NO_MEMORY;
3523                 }
3524
3525                 /* set old value mtime */
3526                 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3527                                          mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3528                         return NT_STATUS_NO_MEMORY;
3529                 }
3530
3531         } else {
3532                 /* If the old value is not set, then migrate the
3533                  * current value to the old value */
3534                 const struct ldb_val *old_val;
3535                 NTTIME last_set_time;
3536                 struct ldb_message **res;
3537                 const char *attrs[] = {
3538                         "currentValue",
3539                         "lastSetTime",
3540                         NULL
3541                 };
3542
3543                 /* search for the secret record */
3544                 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
3545                                       secret_state->secret_dn, &res, attrs);
3546                 if (ret == 0) {
3547                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3548                 }
3549
3550                 if (ret != 1) {
3551                         DEBUG(0,("Found %d records matching dn=%s\n", ret,
3552                                  ldb_dn_get_linearized(secret_state->secret_dn)));
3553                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
3554                 }
3555
3556                 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3557                 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3558
3559                 if (old_val) {
3560                         /* set old value */
3561                         if (ldb_msg_add_value(msg, "priorValue",
3562                                               old_val, NULL) != LDB_SUCCESS) {
3563                                 return NT_STATUS_NO_MEMORY;
3564                         }
3565                 } else {
3566                         if (samdb_msg_add_delete(secret_state->sam_ldb,
3567                                                  mem_ctx, msg, "priorValue") != LDB_SUCCESS) {
3568                                 return NT_STATUS_NO_MEMORY;
3569                         }
3570                 }
3571
3572                 /* set old value mtime */
3573                 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
3574                         if (samdb_msg_add_uint64(secret_state->sam_ldb,
3575                                                  mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
3576                                 return NT_STATUS_NO_MEMORY;
3577                         }
3578                 } else {
3579                         if (samdb_msg_add_uint64(secret_state->sam_ldb,
3580                                                  mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3581                                 return NT_STATUS_NO_MEMORY;
3582                         }
3583                 }
3584         }
3585
3586         if (r->in.new_val) {
3587                 /* Decrypt */
3588                 crypt_secret.data = r->in.new_val->data;
3589                 crypt_secret.length = r->in.new_val->size;
3590
3591                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3592                 if (!NT_STATUS_IS_OK(status)) {
3593                         return status;
3594                 }
3595
3596                 val.data = secret.data;
3597                 val.length = secret.length;
3598
3599                 /* set value */
3600                 if (ldb_msg_add_value(msg, "currentValue", &val, NULL) != LDB_SUCCESS) {
3601                         return NT_STATUS_NO_MEMORY;
3602                 }
3603
3604                 /* set new value mtime */
3605                 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3606                                          mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3607                         return NT_STATUS_NO_MEMORY;
3608                 }
3609         } else {
3610                 /* NULL out the NEW value */
3611                 if (samdb_msg_add_uint64(secret_state->sam_ldb,
3612                                          mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3613                         return NT_STATUS_NO_MEMORY;
3614                 }
3615                 if (samdb_msg_add_delete(secret_state->sam_ldb,
3616                                          mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
3617                         return NT_STATUS_NO_MEMORY;
3618                 }
3619         }
3620
3621         /* modify the samdb record */
3622         ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
3623         if (ret != LDB_SUCCESS) {
3624                 return dsdb_ldb_err_to_ntstatus(ret);
3625         }
3626
3627         return NT_STATUS_OK;
3628 }
3629
3630
3631 /*
3632   lsa_QuerySecret
3633 */
3634 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3635                                 struct lsa_QuerySecret *r)
3636 {
3637         struct auth_session_info *session_info =
3638                 dcesrv_call_session_info(dce_call);
3639         struct dcesrv_handle *h;
3640         struct lsa_secret_state *secret_state;
3641         struct ldb_message *msg;
3642         DATA_BLOB session_key;
3643         DATA_BLOB crypt_secret, secret;
3644         int ret;
3645         struct ldb_message **res;
3646         const char *attrs[] = {
3647                 "currentValue",
3648                 "priorValue",
3649                 "lastSetTime",
3650                 "priorSetTime",
3651                 NULL
3652         };
3653
3654         NTSTATUS nt_status;
3655
3656         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3657
3658         /* Ensure user is permitted to read this... */
3659         switch (security_session_user_level(session_info, NULL))
3660         {
3661         case SECURITY_SYSTEM:
3662         case SECURITY_ADMINISTRATOR:
3663                 break;
3664         default:
3665                 /* Users and annonymous are not allowed to read secrets */
3666                 return NT_STATUS_ACCESS_DENIED;
3667         }
3668
3669         secret_state = h->data;
3670
3671         /* pull all the user attributes */
3672         ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
3673                               secret_state->secret_dn, &res, attrs);
3674         if (ret != 1) {
3675                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3676         }
3677         msg = res[0];
3678
3679         nt_status = dcesrv_transport_session_key(dce_call, &session_key);
3680         if (!NT_STATUS_IS_OK(nt_status)) {
3681                 return nt_status;
3682         }
3683
3684         if (r->in.old_val) {
3685                 const struct ldb_val *prior_val;
3686                 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3687                 if (!r->out.old_val) {
3688                         return NT_STATUS_NO_MEMORY;
3689                 }
3690                 prior_val = ldb_msg_find_ldb_val(msg, "priorValue");
3691
3692                 if (prior_val && prior_val->length) {
3693                         secret.data = prior_val->data;
3694                         secret.length = prior_val->length;
3695
3696                         /* Encrypt */
3697                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3698                         if (!crypt_secret.length) {
3699                                 return NT_STATUS_NO_MEMORY;
3700                         }
3701                         r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3702                         if (!r->out.old_val->buf) {
3703                                 return NT_STATUS_NO_MEMORY;
3704                         }
3705                         r->out.old_val->buf->size = crypt_secret.length;
3706                         r->out.old_val->buf->length = crypt_secret.length;
3707                         r->out.old_val->buf->data = crypt_secret.data;
3708                 }
3709         }
3710
3711         if (r->in.old_mtime) {
3712                 r->out.old_mtime = talloc(mem_ctx, NTTIME);
3713                 if (!r->out.old_mtime) {
3714                         return NT_STATUS_NO_MEMORY;
3715                 }
3716                 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(msg, "priorSetTime", 0);
3717         }
3718
3719         if (r->in.new_val) {
3720                 const struct ldb_val *new_val;
3721                 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3722                 if (!r->out.new_val) {
3723                         return NT_STATUS_NO_MEMORY;
3724                 }
3725
3726                 new_val = ldb_msg_find_ldb_val(msg, "currentValue");
3727
3728                 if (new_val && new_val->length) {
3729                         secret.data = new_val->data;
3730                         secret.length = new_val->length;
3731
3732                         /* Encrypt */
3733                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3734                         if (!crypt_secret.length) {
3735                                 return NT_STATUS_NO_MEMORY;
3736                         }
3737                         r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3738                         if (!r->out.new_val->buf) {
3739                                 return NT_STATUS_NO_MEMORY;
3740                         }
3741                         r->out.new_val->buf->length = crypt_secret.length;
3742                         r->out.new_val->buf->size = crypt_secret.length;
3743                         r->out.new_val->buf->data = crypt_secret.data;
3744                 }
3745         }
3746
3747         if (r->in.new_mtime) {
3748                 r->out.new_mtime = talloc(mem_ctx, NTTIME);
3749                 if (!r->out.new_mtime) {
3750                         return NT_STATUS_NO_MEMORY;
3751                 }
3752                 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(msg, "lastSetTime", 0);
3753         }
3754
3755         return NT_STATUS_OK;
3756 }
3757
3758
3759 /*
3760   lsa_LookupPrivValue
3761 */
3762 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
3763                                     TALLOC_CTX *mem_ctx,
3764                                     struct lsa_LookupPrivValue *r)
3765 {
3766         struct dcesrv_handle *h;
3767         int id;
3768
3769         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3770
3771         id = sec_privilege_id(r->in.name->string);
3772         if (id == SEC_PRIV_INVALID) {
3773                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3774         }
3775
3776         r->out.luid->low = id;
3777         r->out.luid->high = 0;
3778
3779         return NT_STATUS_OK;
3780 }
3781
3782
3783 /*
3784   lsa_LookupPrivName
3785 */
3786 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
3787                                    TALLOC_CTX *mem_ctx,
3788                                    struct lsa_LookupPrivName *r)
3789 {
3790         struct dcesrv_handle *h;
3791         struct lsa_StringLarge *name;
3792         const char *privname;
3793
3794         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3795
3796         if (r->in.luid->high != 0) {
3797                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3798         }
3799
3800         privname = sec_privilege_name(r->in.luid->low);
3801         if (privname == NULL) {
3802                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3803         }
3804
3805         name = talloc(mem_ctx, struct lsa_StringLarge);
3806         if (name == NULL) {
3807                 return NT_STATUS_NO_MEMORY;
3808         }
3809
3810         name->string = privname;
3811
3812         *r->out.name = name;
3813
3814         return NT_STATUS_OK;
3815 }
3816
3817
3818 /*
3819   lsa_LookupPrivDisplayName
3820 */
3821 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
3822                                           TALLOC_CTX *mem_ctx,
3823                                           struct lsa_LookupPrivDisplayName *r)
3824 {
3825         struct dcesrv_handle *h;
3826         struct lsa_StringLarge *disp_name = NULL;
3827         enum sec_privilege id;
3828
3829         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3830
3831         id = sec_privilege_id(r->in.name->string);
3832         if (id == SEC_PRIV_INVALID) {
3833                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3834         }
3835
3836         disp_name = talloc(mem_ctx, struct lsa_StringLarge);
3837         if (disp_name == NULL) {
3838                 return NT_STATUS_NO_MEMORY;
3839         }
3840
3841         disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
3842         if (disp_name->string == NULL) {
3843                 return NT_STATUS_INTERNAL_ERROR;
3844         }
3845
3846         *r->out.disp_name = disp_name;
3847         *r->out.returned_language_id = 0;
3848
3849         return NT_STATUS_OK;
3850 }
3851
3852
3853 /*
3854   lsa_EnumAccountsWithUserRight
3855 */
3856 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
3857                                               TALLOC_CTX *mem_ctx,
3858                                               struct lsa_EnumAccountsWithUserRight *r)
3859 {
3860         struct dcesrv_handle *h;
3861         struct lsa_policy_state *state;
3862         int ret, i;
3863         struct ldb_message **res;
3864         const char * const attrs[] = { "objectSid", NULL};
3865         const char *privname;
3866         bool ok;
3867
3868         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3869
3870         state = h->data;
3871
3872         if (r->in.name == NULL) {
3873                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3874         }
3875
3876         privname = r->in.name->string;
3877
3878         ok = dcesrc_lsa_valid_AccountRight(privname);
3879         if (!ok) {
3880                 return NT_STATUS_NO_SUCH_PRIVILEGE;
3881         }
3882
3883         ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
3884                            "privilege=%s", privname);
3885         if (ret < 0) {
3886                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
3887         }
3888         if (ret == 0) {
3889                 return NT_STATUS_NO_MORE_ENTRIES;
3890         }
3891
3892         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
3893         if (r->out.sids->sids == NULL) {
3894                 return NT_STATUS_NO_MEMORY;
3895         }
3896         for (i=0;i<ret;i++) {
3897                 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
3898                                                                 res[i], "objectSid");
3899                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
3900         }
3901         r->out.sids->num_sids = ret;
3902
3903         return NT_STATUS_OK;
3904 }
3905
3906
3907 /*
3908   lsa_AddAccountRights
3909 */
3910 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
3911                                      TALLOC_CTX *mem_ctx,
3912                                      struct lsa_AddAccountRights *r)
3913 {
3914         struct dcesrv_handle *h;
3915         struct lsa_policy_state *state;
3916
3917         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3918
3919         state = h->data;
3920
3921         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3922                                           LDB_FLAG_MOD_ADD,
3923                                           r->in.sid, r->in.rights);
3924 }
3925
3926
3927 /*
3928   lsa_RemoveAccountRights
3929 */
3930 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
3931                                         TALLOC_CTX *mem_ctx,
3932                                         struct lsa_RemoveAccountRights *r)
3933 {
3934         struct dcesrv_handle *h;
3935         struct lsa_policy_state *state;
3936
3937         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3938
3939         state = h->data;
3940
3941         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3942                                           LDB_FLAG_MOD_DELETE,
3943                                           r->in.sid, r->in.rights);
3944 }
3945
3946
3947 /*
3948   lsa_StorePrivateData
3949 */
3950 static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3951                        struct lsa_StorePrivateData *r)
3952 {
3953         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3954 }
3955
3956
3957 /*
3958   lsa_RetrievePrivateData
3959 */
3960 static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3961                        struct lsa_RetrievePrivateData *r)
3962 {
3963         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3964 }
3965
3966
3967 /*
3968   lsa_GetUserName
3969 */
3970 static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3971                                 struct lsa_GetUserName *r)
3972 {
3973         enum dcerpc_transport_t transport =
3974                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
3975         struct auth_session_info *session_info =
3976                 dcesrv_call_session_info(dce_call);
3977         NTSTATUS status = NT_STATUS_OK;
3978         const char *account_name;
3979         const char *authority_name;
3980         struct lsa_String *_account_name;
3981         struct lsa_String *_authority_name = NULL;
3982
3983         if (transport != NCACN_NP && transport != NCALRPC) {
3984                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
3985         }
3986
3987         /* this is what w2k3 does */
3988         r->out.account_name = r->in.account_name;
3989         r->out.authority_name = r->in.authority_name;
3990
3991         if (r->in.account_name
3992             && *r->in.account_name
3993             /* && *(*r->in.account_name)->string */
3994             ) {
3995                 return NT_STATUS_INVALID_PARAMETER;
3996         }
3997
3998         if (r->in.authority_name
3999             && *r->in.authority_name
4000             /* && *(*r->in.authority_name)->string */
4001             ) {
4002                 return NT_STATUS_INVALID_PARAMETER;
4003         }
4004
4005         account_name = talloc_reference(mem_ctx, session_info->info->account_name);
4006         authority_name = talloc_reference(mem_ctx, session_info->info->domain_name);
4007
4008         _account_name = talloc(mem_ctx, struct lsa_String);
4009         NT_STATUS_HAVE_NO_MEMORY(_account_name);
4010         _account_name->string = account_name;
4011
4012         if (r->in.authority_name) {
4013                 _authority_name = talloc(mem_ctx, struct lsa_String);
4014                 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
4015                 _authority_name->string = authority_name;
4016         }
4017
4018         *r->out.account_name = _account_name;
4019         if (r->out.authority_name) {
4020                 *r->out.authority_name = _authority_name;
4021         }
4022
4023         return status;
4024 }
4025
4026 /*
4027   lsa_SetInfoPolicy2
4028 */
4029 static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
4030                                    TALLOC_CTX *mem_ctx,
4031                                    struct lsa_SetInfoPolicy2 *r)
4032 {
4033         /* need to support these */
4034         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4035 }
4036
4037 static void kdc_get_policy(TALLOC_CTX *mem_ctx,
4038                            struct loadparm_context *lp_ctx,
4039                            struct smb_krb5_context *smb_krb5_context,
4040                            struct lsa_DomainInfoKerberos *k)
4041 {
4042         time_t svc_tkt_lifetime;
4043         time_t usr_tkt_lifetime;
4044         time_t renewal_lifetime;
4045
4046         /* Our KDC always re-validates the client */
4047         k->authentication_options = LSA_POLICY_KERBEROS_VALIDATE_CLIENT;
4048
4049         lpcfg_default_kdc_policy(mem_ctx, lp_ctx, &svc_tkt_lifetime,
4050                                  &usr_tkt_lifetime, &renewal_lifetime);
4051
4052         unix_to_nt_time(&k->service_tkt_lifetime, svc_tkt_lifetime);
4053         unix_to_nt_time(&k->user_tkt_lifetime, usr_tkt_lifetime);
4054         unix_to_nt_time(&k->user_tkt_renewaltime, renewal_lifetime);
4055 #ifdef SAMBA4_USES_HEIMDAL /* MIT lacks krb5_get_max_time_skew.
4056         However in the parent function we basically just did a full
4057         krb5_context init with the only purpose of getting a global
4058         config option (the max skew), it would probably make more sense
4059         to have a lp_ or ldb global option as the samba default */
4060         if (smb_krb5_context) {
4061                 unix_to_nt_time(&k->clock_skew,
4062                                 krb5_get_max_time_skew(smb_krb5_context->krb5_context));
4063         }
4064 #endif
4065         k->reserved = 0;
4066 }
4067 /*
4068   lsa_QueryDomainInformationPolicy
4069 */
4070 static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
4071                                                  TALLOC_CTX *mem_ctx,
4072                                                  struct lsa_QueryDomainInformationPolicy *r)
4073 {
4074         union lsa_DomainInformationPolicy *info;
4075
4076         info = talloc_zero(r->out.info, union lsa_DomainInformationPolicy);
4077         if (!info) {
4078                 return NT_STATUS_NO_MEMORY;
4079         }
4080
4081         switch (r->in.level) {
4082         case LSA_DOMAIN_INFO_POLICY_EFS:
4083                 talloc_free(info);
4084                 *r->out.info = NULL;
4085                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4086         case LSA_DOMAIN_INFO_POLICY_KERBEROS:
4087         {
4088                 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
4089                 struct smb_krb5_context *smb_krb5_context;
4090                 int ret = smb_krb5_init_context(mem_ctx,
4091                                                         dce_call->conn->dce_ctx->lp_ctx,
4092                                                         &smb_krb5_context);
4093                 if (ret != 0) {
4094                         talloc_free(info);
4095                         *r->out.info = NULL;
4096                         return NT_STATUS_INTERNAL_ERROR;
4097                 }
4098                 kdc_get_policy(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
4099                                smb_krb5_context,
4100                                k);
4101                 talloc_free(smb_krb5_context);
4102                 *r->out.info = info;
4103                 return NT_STATUS_OK;
4104         }
4105         default:
4106                 talloc_free(info);
4107                 *r->out.info = NULL;
4108                 return NT_STATUS_INVALID_INFO_CLASS;
4109         }
4110 }
4111
4112 /*
4113   lsa_SetDomInfoPolicy
4114 */
4115 static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
4116                                               TALLOC_CTX *mem_ctx,
4117                                               struct lsa_SetDomainInformationPolicy *r)
4118 {
4119         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4120 }
4121
4122 /*
4123   lsa_TestCall
4124 */
4125 static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
4126                              TALLOC_CTX *mem_ctx,
4127                              struct lsa_TestCall *r)
4128 {
4129         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4130 }
4131
4132 /*
4133   lsa_CREDRWRITE
4134 */
4135 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4136                        struct lsa_CREDRWRITE *r)
4137 {
4138         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4139 }
4140
4141
4142 /*
4143   lsa_CREDRREAD
4144 */
4145 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4146                        struct lsa_CREDRREAD *r)
4147 {
4148         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4149 }
4150
4151
4152 /*
4153   lsa_CREDRENUMERATE
4154 */
4155 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4156                        struct lsa_CREDRENUMERATE *r)
4157 {
4158         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4159 }
4160
4161
4162 /*
4163   lsa_CREDRWRITEDOMAINCREDENTIALS
4164 */
4165 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4166                        struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4167 {
4168         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4169 }
4170
4171
4172 /*
4173   lsa_CREDRREADDOMAINCREDENTIALS
4174 */
4175 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4176                        struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4177 {
4178         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4179 }
4180
4181
4182 /*
4183   lsa_CREDRDELETE
4184 */
4185 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4186                        struct lsa_CREDRDELETE *r)
4187 {
4188         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4189 }
4190
4191
4192 /*
4193   lsa_CREDRGETTARGETINFO
4194 */
4195 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4196                        struct lsa_CREDRGETTARGETINFO *r)
4197 {
4198         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4199 }
4200
4201
4202 /*
4203   lsa_CREDRPROFILELOADED
4204 */
4205 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4206                        struct lsa_CREDRPROFILELOADED *r)
4207 {
4208         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4209 }
4210
4211
4212 /*
4213   lsa_CREDRGETSESSIONTYPES
4214 */
4215 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4216                        struct lsa_CREDRGETSESSIONTYPES *r)
4217 {
4218         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4219 }
4220
4221
4222 /*
4223   lsa_LSARREGISTERAUDITEVENT
4224 */
4225 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4226                        struct lsa_LSARREGISTERAUDITEVENT *r)
4227 {
4228         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4229 }
4230
4231
4232 /*
4233   lsa_LSARGENAUDITEVENT
4234 */
4235 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4236                        struct lsa_LSARGENAUDITEVENT *r)
4237 {
4238         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4239 }
4240
4241
4242 /*
4243   lsa_LSARUNREGISTERAUDITEVENT
4244 */
4245 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4246                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
4247 {
4248         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4249 }
4250
4251
4252 /*
4253   lsa_lsaRQueryForestTrustInformation
4254 */
4255 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4256                        struct lsa_lsaRQueryForestTrustInformation *r)
4257 {
4258         struct dcesrv_handle *h = NULL;
4259         struct lsa_policy_state *p_state = NULL;
4260         int forest_level = DS_DOMAIN_FUNCTION_2000;
4261         const char * const trust_attrs[] = {
4262                 "securityIdentifier",
4263                 "flatName",
4264                 "trustPartner",
4265                 "trustAttributes",
4266                 "trustDirection",
4267                 "trustType",
4268                 "msDS-TrustForestTrustInfo",
4269                 NULL
4270         };
4271         struct ldb_message *trust_tdo_msg = NULL;
4272         struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
4273         struct ForestTrustInfo *trust_fti = NULL;
4274         struct lsa_ForestTrustInformation *trust_lfti = NULL;
4275         NTSTATUS status;
4276
4277         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4278
4279         p_state = h->data;
4280
4281         if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4282                 return NT_STATUS_INVALID_DOMAIN_STATE;
4283         }
4284
4285         forest_level = dsdb_forest_functional_level(p_state->sam_ldb);
4286         if (forest_level < DS_DOMAIN_FUNCTION_2003) {
4287                 return NT_STATUS_INVALID_DOMAIN_STATE;
4288         }
4289
4290         if (r->in.trusted_domain_name->string == NULL) {
4291                 return NT_STATUS_NO_SUCH_DOMAIN;
4292         }
4293
4294         status = dsdb_trust_search_tdo(p_state->sam_ldb,
4295                                        r->in.trusted_domain_name->string,
4296                                        r->in.trusted_domain_name->string,
4297                                        trust_attrs, mem_ctx, &trust_tdo_msg);
4298         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4299                 return NT_STATUS_NO_SUCH_DOMAIN;
4300         }
4301         if (!NT_STATUS_IS_OK(status)) {
4302                 return status;
4303         }
4304
4305         status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
4306         if (!NT_STATUS_IS_OK(status)) {
4307                 return status;
4308         }
4309
4310         if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4311                 return NT_STATUS_INVALID_PARAMETER;
4312         }
4313
4314         if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4315                 return NT_STATUS_INVALID_PARAMETER;
4316         }
4317
4318         status = dsdb_trust_parse_forest_info(mem_ctx,
4319                                               trust_tdo_msg,
4320                                               &trust_fti);
4321         if (!NT_STATUS_IS_OK(status)) {
4322                 return status;
4323         }
4324
4325         status = dsdb_trust_forest_info_to_lsa(mem_ctx, trust_fti,
4326                                                &trust_lfti);
4327         if (!NT_STATUS_IS_OK(status)) {
4328                 return status;
4329         }
4330
4331         *r->out.forest_trust_info = trust_lfti;
4332         return NT_STATUS_OK;
4333 }
4334
4335 /*
4336   lsa_lsaRSetForestTrustInformation
4337 */
4338 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call,
4339                                                          TALLOC_CTX *mem_ctx,
4340                                                          struct lsa_lsaRSetForestTrustInformation *r)
4341 {
4342         struct dcesrv_handle *h;
4343         struct lsa_policy_state *p_state;
4344         const char * const trust_attrs[] = {
4345                 "securityIdentifier",
4346                 "flatName",
4347                 "trustPartner",
4348                 "trustAttributes",
4349                 "trustDirection",
4350                 "trustType",
4351                 "msDS-TrustForestTrustInfo",
4352                 NULL
4353         };
4354         struct ldb_message *trust_tdo_msg = NULL;
4355         struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
4356         struct lsa_ForestTrustInformation *step1_lfti = NULL;
4357         struct lsa_ForestTrustInformation *step2_lfti = NULL;
4358         struct ForestTrustInfo *trust_fti = NULL;
4359         struct ldb_result *trusts_res = NULL;
4360         unsigned int i;
4361         struct lsa_TrustDomainInfoInfoEx *xref_tdo = NULL;
4362         struct lsa_ForestTrustInformation *xref_lfti = NULL;
4363         struct lsa_ForestTrustCollisionInfo *c_info = NULL;
4364         DATA_BLOB ft_blob = {};
4365         struct ldb_message *msg = NULL;
4366         struct server_id *server_ids = NULL;
4367         uint32_t num_server_ids = 0;
4368         NTSTATUS status;
4369         enum ndr_err_code ndr_err;
4370         int ret;
4371         bool in_transaction = false;
4372
4373         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4374
4375         p_state = h->data;
4376
4377         if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4378                 return NT_STATUS_INVALID_DOMAIN_STATE;
4379         }
4380
4381         if (r->in.check_only == 0) {
4382                 ret = ldb_transaction_start(p_state->sam_ldb);
4383                 if (ret != LDB_SUCCESS) {
4384                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
4385                 }
4386                 in_transaction = true;
4387         }
4388
4389         /*
4390          * abort if we are not a PDC
4391          *
4392          * In future we should use a function like IsEffectiveRoleOwner()
4393          */
4394         if (!samdb_is_pdc(p_state->sam_ldb)) {
4395                 status = NT_STATUS_INVALID_DOMAIN_ROLE;
4396                 goto done;
4397         }
4398
4399         if (r->in.trusted_domain_name->string == NULL) {
4400                 status = NT_STATUS_NO_SUCH_DOMAIN;
4401                 goto done;
4402         }
4403
4404         status = dsdb_trust_search_tdo(p_state->sam_ldb,
4405                                        r->in.trusted_domain_name->string,
4406                                        r->in.trusted_domain_name->string,
4407                                        trust_attrs, mem_ctx, &trust_tdo_msg);
4408         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4409                 status = NT_STATUS_NO_SUCH_DOMAIN;
4410                 goto done;
4411         }
4412         if (!NT_STATUS_IS_OK(status)) {
4413                 goto done;
4414         }
4415
4416         status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
4417         if (!NT_STATUS_IS_OK(status)) {
4418                 goto done;
4419         }
4420
4421         if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4422                 status = NT_STATUS_INVALID_PARAMETER;
4423                 goto done;
4424         }
4425
4426         if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4427                 status = NT_STATUS_INVALID_PARAMETER;
4428                 goto done;
4429         }
4430
4431         /*
4432          * verify and normalize the given forest trust info.
4433          *
4434          * Step1: doesn't reorder yet, so step1_lfti might contain
4435          * NULL entries. This means dsdb_trust_verify_forest_info()
4436          * can generate collision entries with the callers index.
4437          */
4438         status = dsdb_trust_normalize_forest_info_step1(mem_ctx,
4439                                                         r->in.forest_trust_info,
4440                                                         &step1_lfti);
4441         if (!NT_STATUS_IS_OK(status)) {
4442                 goto done;
4443         }
4444
4445         c_info = talloc_zero(r->out.collision_info,
4446                              struct lsa_ForestTrustCollisionInfo);
4447         if (c_info == NULL) {
4448                 status = NT_STATUS_NO_MEMORY;
4449                 goto done;
4450         }
4451
4452         /*
4453          * First check our own forest, then other domains/forests
4454          */
4455
4456         status = dsdb_trust_xref_tdo_info(mem_ctx, p_state->sam_ldb,
4457                                           &xref_tdo);
4458         if (!NT_STATUS_IS_OK(status)) {
4459                 goto done;
4460         }
4461         status = dsdb_trust_xref_forest_info(mem_ctx, p_state->sam_ldb,
4462                                              &xref_lfti);
4463         if (!NT_STATUS_IS_OK(status)) {
4464                 goto done;
4465         }
4466
4467         /*
4468          * The documentation proposed to generate
4469          * LSA_FOREST_TRUST_COLLISION_XREF collisions.
4470          * But Windows always uses LSA_FOREST_TRUST_COLLISION_TDO.
4471          */
4472         status = dsdb_trust_verify_forest_info(xref_tdo, xref_lfti,
4473                                                LSA_FOREST_TRUST_COLLISION_TDO,
4474                                                c_info, step1_lfti);
4475         if (!NT_STATUS_IS_OK(status)) {
4476                 goto done;
4477         }
4478
4479         /* fetch all other trusted domain objects */
4480         status = dsdb_trust_search_tdos(p_state->sam_ldb,
4481                                         trust_tdo->domain_name.string,
4482                                         trust_attrs,
4483                                         mem_ctx, &trusts_res);
4484         if (!NT_STATUS_IS_OK(status)) {
4485                 goto done;
4486         }
4487
4488         /*
4489          * now check against the other domains.
4490          * and generate LSA_FOREST_TRUST_COLLISION_TDO collisions.
4491          */
4492         for (i = 0; i < trusts_res->count; i++) {
4493                 struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
4494                 struct ForestTrustInfo *fti = NULL;
4495                 struct lsa_ForestTrustInformation *lfti = NULL;
4496
4497                 status = dsdb_trust_parse_tdo_info(mem_ctx,
4498                                                    trusts_res->msgs[i],
4499                                                    &tdo);
4500                 if (!NT_STATUS_IS_OK(status)) {
4501                         goto done;
4502                 }
4503
4504                 status = dsdb_trust_parse_forest_info(tdo,
4505                                                       trusts_res->msgs[i],
4506                                                       &fti);
4507                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
4508                         continue;
4509                 }
4510                 if (!NT_STATUS_IS_OK(status)) {
4511                         goto done;
4512                 }
4513
4514                 status = dsdb_trust_forest_info_to_lsa(tdo, fti, &lfti);
4515                 if (!NT_STATUS_IS_OK(status)) {
4516                         goto done;
4517                 }
4518
4519                 status = dsdb_trust_verify_forest_info(tdo, lfti,
4520                                                 LSA_FOREST_TRUST_COLLISION_TDO,
4521                                                 c_info, step1_lfti);
4522                 if (!NT_STATUS_IS_OK(status)) {
4523                         goto done;
4524                 }
4525
4526                 TALLOC_FREE(tdo);
4527         }
4528
4529         if (r->in.check_only != 0) {
4530                 status = NT_STATUS_OK;
4531                 goto done;
4532         }
4533
4534         /*
4535          * not just a check, write info back
4536          */
4537
4538         /*
4539          * normalize the given forest trust info.
4540          *
4541          * Step2: adds TOP_LEVEL_NAME[_EX] in reverse order,
4542          * followed by DOMAIN_INFO in reverse order. It also removes
4543          * possible NULL entries from Step1.
4544          */
4545         status = dsdb_trust_normalize_forest_info_step2(mem_ctx, step1_lfti,
4546                                                         &step2_lfti);
4547         if (!NT_STATUS_IS_OK(status)) {
4548                 goto done;
4549         }
4550
4551         status = dsdb_trust_forest_info_from_lsa(mem_ctx, step2_lfti,
4552                                                  &trust_fti);
4553         if (!NT_STATUS_IS_OK(status)) {
4554                 goto done;
4555         }
4556
4557         ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, trust_fti,
4558                                        (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4559         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4560                 status = NT_STATUS_INVALID_PARAMETER;
4561                 goto done;
4562         }
4563
4564         msg = ldb_msg_new(mem_ctx);
4565         if (msg == NULL) {
4566                 status = NT_STATUS_NO_MEMORY;
4567                 goto done;
4568         }
4569
4570         msg->dn = ldb_dn_copy(mem_ctx, trust_tdo_msg->dn);
4571         if (!msg->dn) {
4572                 status = NT_STATUS_NO_MEMORY;
4573                 goto done;
4574         }
4575
4576         ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
4577                                 LDB_FLAG_MOD_REPLACE, NULL);
4578         if (ret != LDB_SUCCESS) {
4579                 status = NT_STATUS_NO_MEMORY;
4580                 goto done;
4581         }
4582         ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo",
4583                                 &ft_blob, NULL);
4584         if (ret != LDB_SUCCESS) {
4585                 status = NT_STATUS_NO_MEMORY;
4586                 goto done;
4587         }
4588
4589         ret = ldb_modify(p_state->sam_ldb, msg);
4590         if (ret != LDB_SUCCESS) {
4591                 status = dsdb_ldb_err_to_ntstatus(ret);
4592
4593                 DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
4594                           ldb_errstring(p_state->sam_ldb)));
4595
4596                 goto done;
4597         }
4598
4599         /* ok, all fine, commit transaction and return */
4600         in_transaction = false;
4601         ret = ldb_transaction_commit(p_state->sam_ldb);
4602         if (ret != LDB_SUCCESS) {
4603                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
4604                 goto done;
4605         }
4606
4607         /*
4608          * Notify winbindd that we have a acquired forest trust info
4609          */
4610         status = irpc_servers_byname(dce_call->msg_ctx,
4611                                      mem_ctx,
4612                                      "winbind_server",
4613                                      &num_server_ids, &server_ids);
4614         if (!NT_STATUS_IS_OK(status)) {
4615                 DBG_ERR("irpc_servers_byname failed\n");
4616                 goto done;
4617         }
4618
4619         imessaging_send(dce_call->msg_ctx, server_ids[0],
4620                         MSG_WINBIND_RELOAD_TRUSTED_DOMAINS, NULL);
4621
4622         status = NT_STATUS_OK;
4623
4624 done:
4625         if (NT_STATUS_IS_OK(status) && c_info->count != 0) {
4626                 *r->out.collision_info = c_info;
4627         }
4628
4629         if (in_transaction) {
4630                 ldb_transaction_cancel(p_state->sam_ldb);
4631         }
4632
4633         return status;
4634 }
4635
4636 /*
4637   lsa_CREDRRENAME
4638 */
4639 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4640                        struct lsa_CREDRRENAME *r)
4641 {
4642         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4643 }
4644
4645
4646
4647 /*
4648   lsa_LSAROPENPOLICYSCE
4649 */
4650 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4651                        struct lsa_LSAROPENPOLICYSCE *r)
4652 {
4653         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4654 }
4655
4656
4657 /*
4658   lsa_LSARADTREGISTERSECURITYEVENTSOURCE
4659 */
4660 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4661                        struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4662 {
4663         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4664 }
4665
4666
4667 /*
4668   lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
4669 */
4670 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4671                        struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4672 {
4673         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4674 }
4675
4676
4677 /*
4678   lsa_LSARADTREPORTSECURITYEVENT
4679 */
4680 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4681                        struct lsa_LSARADTREPORTSECURITYEVENT *r)
4682 {
4683         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4684 }
4685
4686
4687 /* include the generated boilerplate */
4688 #include "librpc/gen_ndr/ndr_lsa_s.c"
4689
4690
4691
4692 /*****************************************
4693 NOTE! The remaining calls below were
4694 removed in w2k3, so the DCESRV_FAULT()
4695 replies are the correct implementation. Do
4696 not try and fill these in with anything else
4697 ******************************************/
4698
4699 /*
4700   dssetup_DsRoleDnsNameToFlatName
4701 */
4702 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4703                                         struct dssetup_DsRoleDnsNameToFlatName *r)
4704 {
4705         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4706 }
4707
4708
4709 /*
4710   dssetup_DsRoleDcAsDc
4711 */
4712 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4713                              struct dssetup_DsRoleDcAsDc *r)
4714 {
4715         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4716 }
4717
4718
4719 /*
4720   dssetup_DsRoleDcAsReplica
4721 */
4722 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4723                                   struct dssetup_DsRoleDcAsReplica *r)
4724 {
4725         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4726 }
4727
4728
4729 /*
4730   dssetup_DsRoleDemoteDc
4731 */
4732 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4733                                struct dssetup_DsRoleDemoteDc *r)
4734 {
4735         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4736 }
4737
4738
4739 /*
4740   dssetup_DsRoleGetDcOperationProgress
4741 */
4742 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4743                                              struct dssetup_DsRoleGetDcOperationProgress *r)
4744 {
4745         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4746 }
4747
4748
4749 /* 
4750   dssetup_DsRoleGetDcOperationResults 
4751 */
4752 static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4753                                             struct dssetup_DsRoleGetDcOperationResults *r)
4754 {
4755         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4756 }
4757
4758
4759 /* 
4760   dssetup_DsRoleCancel 
4761 */
4762 static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4763                              struct dssetup_DsRoleCancel *r)
4764 {
4765         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4766 }
4767
4768
4769 /*
4770   dssetup_DsRoleServerSaveStateForUpgrade
4771 */
4772 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4773                                                 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
4774 {
4775         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4776 }
4777
4778
4779 /*
4780   dssetup_DsRoleUpgradeDownlevelServer
4781 */
4782 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4783                                              struct dssetup_DsRoleUpgradeDownlevelServer *r)
4784 {
4785         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4786 }
4787
4788
4789 /*
4790   dssetup_DsRoleAbortDownlevelServerUpgrade
4791 */
4792 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4793                                                   struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
4794 {
4795         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4796 }
4797
4798
4799 /* include the generated boilerplate */
4800 #include "librpc/gen_ndr/ndr_dssetup_s.c"
4801
4802 NTSTATUS dcerpc_server_lsa_init(TALLOC_CTX *ctx)
4803 {
4804         NTSTATUS ret;
4805
4806         ret = dcerpc_server_dssetup_init(ctx);
4807         if (!NT_STATUS_IS_OK(ret)) {
4808                 return ret;
4809         }
4810         ret = dcerpc_server_lsarpc_init(ctx);
4811         if (!NT_STATUS_IS_OK(ret)) {
4812                 return ret;
4813         }
4814         return ret;
4815 }