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