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