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 								&current_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