Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * RPC Pipe client / server routines
4 : * Copyright (C) Andrew Tridgell 1992-1997,
5 : * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 : * Copyright (C) Paul Ashton 1997,
7 : * Copyright (C) Jeremy Allison 2001, 2006.
8 : * Copyright (C) Rafal Szczesniak 2002,
9 : * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
10 : * Copyright (C) Simo Sorce 2003.
11 : * Copyright (C) Gerald (Jerry) Carter 2005.
12 : * Copyright (C) Volker Lendecke 2005.
13 : * Copyright (C) Guenther Deschner 2008.
14 : * Copyright (C) Andrew Bartlett 2010.
15 : *
16 : * This program is free software; you can redistribute it and/or modify
17 : * it under the terms of the GNU General Public License as published by
18 : * the Free Software Foundation; either version 3 of the License, or
19 : * (at your option) any later version.
20 : *
21 : * This program is distributed in the hope that it will be useful,
22 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 : * GNU General Public License for more details.
25 : *
26 : * You should have received a copy of the GNU General Public License
27 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
28 : */
29 :
30 : /* This is the implementation of the lsa server code. */
31 :
32 : #include "includes.h"
33 : #include "ntdomain.h"
34 : #include "librpc/gen_ndr/ndr_lsa.h"
35 : #include "librpc/gen_ndr/ndr_lsa_scompat.h"
36 : #include "secrets.h"
37 : #include "../librpc/gen_ndr/netlogon.h"
38 : #include "rpc_client/init_lsa.h"
39 : #include "../libcli/security/security.h"
40 : #include "../libcli/security/dom_sid.h"
41 : #include "../librpc/gen_ndr/drsblobs.h"
42 : #include "../librpc/gen_ndr/ndr_drsblobs.h"
43 : #include "../libcli/security/dom_sid.h"
44 : #include "../librpc/gen_ndr/ndr_security.h"
45 : #include "passdb.h"
46 : #include "auth.h"
47 : #include "lib/privileges.h"
48 : #include "rpc_server/srv_access_check.h"
49 : #include "../librpc/gen_ndr/ndr_wkssvc.h"
50 : #include "../libcli/auth/libcli_auth.h"
51 : #include "../libcli/lsarpc/util_lsarpc.h"
52 : #include "lsa.h"
53 : #include "librpc/rpc/dcesrv_core.h"
54 : #include "librpc/rpc/dcerpc_helper.h"
55 : #include "lib/param/loadparm.h"
56 : #include "source3/lib/substitute.h"
57 :
58 : #include "lib/crypto/gnutls_helpers.h"
59 : #include <gnutls/gnutls.h>
60 : #include <gnutls/crypto.h>
61 :
62 : #undef DBGC_CLASS
63 : #define DBGC_CLASS DBGC_RPC_SRV
64 :
65 : #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
66 :
67 : enum lsa_handle_type {
68 : LSA_HANDLE_POLICY_TYPE = 1,
69 : LSA_HANDLE_ACCOUNT_TYPE = 2,
70 : LSA_HANDLE_TRUST_TYPE = 3,
71 : LSA_HANDLE_SECRET_TYPE = 4};
72 :
73 : struct lsa_info {
74 : struct dom_sid sid;
75 : const char *name;
76 : uint32_t access;
77 : enum lsa_handle_type type;
78 : struct security_descriptor *sd;
79 : };
80 :
81 : const struct generic_mapping lsa_account_mapping = {
82 : LSA_ACCOUNT_READ,
83 : LSA_ACCOUNT_WRITE,
84 : LSA_ACCOUNT_EXECUTE,
85 : LSA_ACCOUNT_ALL_ACCESS
86 : };
87 :
88 : const struct generic_mapping lsa_policy_mapping = {
89 : LSA_POLICY_READ,
90 : LSA_POLICY_WRITE,
91 : LSA_POLICY_EXECUTE,
92 : LSA_POLICY_ALL_ACCESS
93 : };
94 :
95 : const struct generic_mapping lsa_secret_mapping = {
96 : LSA_SECRET_READ,
97 : LSA_SECRET_WRITE,
98 : LSA_SECRET_EXECUTE,
99 : LSA_SECRET_ALL_ACCESS
100 : };
101 :
102 : const struct generic_mapping lsa_trusted_domain_mapping = {
103 : LSA_TRUSTED_DOMAIN_READ,
104 : LSA_TRUSTED_DOMAIN_WRITE,
105 : LSA_TRUSTED_DOMAIN_EXECUTE,
106 : LSA_TRUSTED_DOMAIN_ALL_ACCESS
107 : };
108 :
109 : /***************************************************************************
110 : initialize a lsa_DomainInfo structure.
111 : ***************************************************************************/
112 :
113 60 : static void init_dom_query_3(struct lsa_DomainInfo *r,
114 : const char *name,
115 : struct dom_sid *sid)
116 : {
117 60 : init_lsa_StringLarge(&r->name, name);
118 60 : r->sid = sid;
119 60 : }
120 :
121 : /***************************************************************************
122 : initialize a lsa_DomainInfo structure.
123 : ***************************************************************************/
124 :
125 774 : static void init_dom_query_5(struct lsa_DomainInfo *r,
126 : const char *name,
127 : struct dom_sid *sid)
128 : {
129 774 : init_lsa_StringLarge(&r->name, name);
130 774 : r->sid = sid;
131 774 : }
132 :
133 : /***************************************************************************
134 : lookup_lsa_rids. Must be called as root for lookup_name to work.
135 : ***************************************************************************/
136 :
137 322 : static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
138 : struct lsa_RefDomainList *ref,
139 : struct lsa_TranslatedSid *prid,
140 : uint32_t num_entries,
141 : struct lsa_String *name,
142 : int flags,
143 : uint32_t *pmapped_count)
144 : {
145 0 : uint32_t mapped_count, i;
146 :
147 322 : SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
148 :
149 322 : mapped_count = 0;
150 322 : *pmapped_count = 0;
151 :
152 862 : for (i = 0; i < num_entries; i++) {
153 0 : struct dom_sid sid;
154 0 : uint32_t rid;
155 0 : int dom_idx;
156 0 : const char *full_name;
157 0 : const char *domain;
158 0 : enum lsa_SidType type;
159 :
160 : /* Split name into domain and user component */
161 :
162 : /* follow w2k8 behavior and return the builtin domain when no
163 : * input has been passed in */
164 :
165 540 : if (name[i].string) {
166 538 : full_name = name[i].string;
167 : } else {
168 2 : full_name = "BUILTIN";
169 : }
170 :
171 540 : DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
172 :
173 540 : if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
174 : &sid, &type)) {
175 18 : type = SID_NAME_UNKNOWN;
176 : }
177 :
178 540 : switch (type) {
179 522 : case SID_NAME_USER:
180 : case SID_NAME_DOM_GRP:
181 : case SID_NAME_DOMAIN:
182 : case SID_NAME_ALIAS:
183 : case SID_NAME_WKN_GRP:
184 522 : DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
185 : /* Leave these unchanged */
186 522 : break;
187 18 : default:
188 : /* Don't hand out anything but the list above */
189 18 : DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
190 18 : type = SID_NAME_UNKNOWN;
191 18 : break;
192 : }
193 :
194 540 : rid = 0;
195 540 : dom_idx = -1;
196 :
197 540 : if (type != SID_NAME_UNKNOWN) {
198 522 : if (type == SID_NAME_DOMAIN) {
199 24 : rid = (uint32_t)-1;
200 : } else {
201 498 : sid_split_rid(&sid, &rid);
202 : }
203 522 : dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
204 522 : mapped_count++;
205 : }
206 :
207 540 : prid[i].sid_type = type;
208 540 : prid[i].rid = rid;
209 540 : prid[i].sid_index = dom_idx;
210 : }
211 :
212 322 : *pmapped_count = mapped_count;
213 322 : return NT_STATUS_OK;
214 : }
215 :
216 : /***************************************************************************
217 : lookup_lsa_sids. Must be called as root for lookup_name to work.
218 : ***************************************************************************/
219 :
220 52 : static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
221 : struct lsa_RefDomainList *ref,
222 : struct lsa_TranslatedSid3 *trans_sids,
223 : uint32_t num_entries,
224 : struct lsa_String *name,
225 : int flags,
226 : uint32_t *pmapped_count)
227 : {
228 0 : uint32_t mapped_count, i;
229 :
230 52 : SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
231 :
232 52 : mapped_count = 0;
233 52 : *pmapped_count = 0;
234 :
235 2466 : for (i = 0; i < num_entries; i++) {
236 0 : struct dom_sid sid;
237 0 : uint32_t rid;
238 0 : int dom_idx;
239 0 : const char *full_name;
240 0 : const char *domain;
241 0 : enum lsa_SidType type;
242 :
243 2414 : ZERO_STRUCT(sid);
244 :
245 : /* Split name into domain and user component */
246 :
247 2414 : full_name = name[i].string;
248 2414 : if (full_name == NULL) {
249 0 : return NT_STATUS_NO_MEMORY;
250 : }
251 :
252 2414 : DEBUG(5, ("lookup_lsa_sids: looking up name %s\n", full_name));
253 :
254 2414 : if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
255 : &sid, &type)) {
256 0 : type = SID_NAME_UNKNOWN;
257 : }
258 :
259 2414 : switch (type) {
260 2414 : case SID_NAME_USER:
261 : case SID_NAME_DOM_GRP:
262 : case SID_NAME_DOMAIN:
263 : case SID_NAME_ALIAS:
264 : case SID_NAME_WKN_GRP:
265 2414 : DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name));
266 : /* Leave these unchanged */
267 2414 : break;
268 0 : default:
269 : /* Don't hand out anything but the list above */
270 0 : DEBUG(5, ("lookup_lsa_sids: %s not found\n", full_name));
271 0 : type = SID_NAME_UNKNOWN;
272 0 : break;
273 : }
274 :
275 2414 : rid = 0;
276 2414 : dom_idx = -1;
277 :
278 2414 : if (type != SID_NAME_UNKNOWN) {
279 0 : struct dom_sid domain_sid;
280 2414 : sid_copy(&domain_sid, &sid);
281 2414 : sid_split_rid(&domain_sid, &rid);
282 2414 : dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
283 2414 : mapped_count++;
284 : }
285 :
286 : /* Initialize the lsa_TranslatedSid3 return. */
287 2414 : trans_sids[i].sid_type = type;
288 2414 : trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
289 2414 : trans_sids[i].sid_index = dom_idx;
290 : }
291 :
292 52 : *pmapped_count = mapped_count;
293 52 : return NT_STATUS_OK;
294 : }
295 :
296 3189 : static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
297 : const struct generic_mapping *map,
298 : struct dom_sid *sid, uint32_t sid_access)
299 : {
300 0 : struct dom_sid adm_sid;
301 0 : struct security_ace ace[5];
302 3189 : size_t i = 0;
303 :
304 3189 : struct security_acl *psa = NULL;
305 :
306 : /* READ|EXECUTE access for Everyone */
307 :
308 3189 : init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
309 3189 : map->generic_execute | map->generic_read, 0);
310 :
311 : /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
312 :
313 3189 : init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
314 3189 : SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
315 3189 : init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
316 3189 : SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
317 :
318 : /* Add Full Access for Domain Admins */
319 3189 : sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
320 3189 : init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
321 3189 : map->generic_all, 0);
322 :
323 : /* If we have a sid, give it some special access */
324 :
325 3189 : if (sid) {
326 18 : init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
327 : sid_access, 0);
328 : }
329 :
330 3189 : if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
331 0 : return NT_STATUS_NO_MEMORY;
332 :
333 3189 : if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
334 : SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
335 : psa, sd_size)) == NULL)
336 0 : return NT_STATUS_NO_MEMORY;
337 :
338 3189 : return NT_STATUS_OK;
339 : }
340 :
341 : /***************************************************************************
342 : ***************************************************************************/
343 :
344 3143 : static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
345 : struct pipes_struct *p,
346 : enum lsa_handle_type type,
347 : uint32_t acc_granted,
348 : struct dom_sid *sid,
349 : const char *name,
350 : const struct security_descriptor *sd,
351 : struct policy_handle *handle)
352 : {
353 0 : struct lsa_info *info;
354 :
355 3143 : ZERO_STRUCTP(handle);
356 :
357 3143 : info = talloc_zero(mem_ctx, struct lsa_info);
358 3143 : if (!info) {
359 0 : return NT_STATUS_NO_MEMORY;
360 : }
361 :
362 3143 : info->type = type;
363 3143 : info->access = acc_granted;
364 :
365 3143 : if (sid) {
366 2511 : sid_copy(&info->sid, sid);
367 : }
368 :
369 3143 : info->name = talloc_strdup(info, name);
370 :
371 3143 : if (sd != NULL) {
372 3143 : info->sd = security_descriptor_copy(info, sd);
373 3143 : if (info->sd == NULL) {
374 0 : talloc_free(info);
375 0 : return NT_STATUS_NO_MEMORY;
376 : }
377 : }
378 :
379 3143 : if (!create_policy_hnd(p, handle, type, info)) {
380 0 : talloc_free(info);
381 0 : ZERO_STRUCTP(handle);
382 0 : return NT_STATUS_NO_MEMORY;
383 : }
384 :
385 3143 : return NT_STATUS_OK;
386 : }
387 :
388 : /***************************************************************************
389 : _lsa_OpenPolicy2
390 : ***************************************************************************/
391 :
392 2431 : NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
393 : struct lsa_OpenPolicy2 *r)
394 : {
395 2431 : struct dcesrv_call_state *dce_call = p->dce_call;
396 0 : struct auth_session_info *session_info =
397 2431 : dcesrv_call_session_info(dce_call);
398 2431 : struct security_descriptor *psd = NULL;
399 0 : size_t sd_size;
400 2431 : uint32_t des_access = r->in.access_mask;
401 0 : uint32_t acc_granted;
402 0 : NTSTATUS status;
403 :
404 2431 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
405 4 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
406 4 : return NT_STATUS_ACCESS_DENIED;
407 : }
408 :
409 : /* Work out max allowed. */
410 2427 : map_max_allowed_access(session_info->security_token,
411 2427 : session_info->unix_token,
412 : &des_access);
413 :
414 : /* map the generic bits to the lsa policy ones */
415 2427 : se_map_generic(&des_access, &lsa_policy_mapping);
416 :
417 : /* get the generic lsa policy SD until we store it */
418 2427 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
419 : NULL, 0);
420 2427 : if (!NT_STATUS_IS_OK(status)) {
421 0 : return status;
422 : }
423 :
424 2427 : status = access_check_object(psd, session_info->security_token,
425 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
426 : &acc_granted, "_lsa_OpenPolicy2" );
427 2427 : if (!NT_STATUS_IS_OK(status)) {
428 0 : return status;
429 : }
430 :
431 2427 : status = create_lsa_policy_handle(p->mem_ctx, p,
432 : LSA_HANDLE_POLICY_TYPE,
433 : acc_granted,
434 : get_global_sam_sid(),
435 : NULL,
436 : psd,
437 : r->out.handle);
438 2427 : if (!NT_STATUS_IS_OK(status)) {
439 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
440 : }
441 :
442 2427 : return NT_STATUS_OK;
443 : }
444 :
445 : /***************************************************************************
446 : _lsa_OpenPolicy
447 : ***************************************************************************/
448 :
449 1551 : NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
450 : struct lsa_OpenPolicy *r)
451 : {
452 0 : struct lsa_OpenPolicy2 o;
453 :
454 : /* _lsa_OpenPolicy2 will check if this is a NCACN_NP connection */
455 :
456 1551 : o.in.system_name = NULL; /* should be ignored */
457 1551 : o.in.attr = r->in.attr;
458 1551 : o.in.access_mask = r->in.access_mask;
459 :
460 1551 : o.out.handle = r->out.handle;
461 :
462 1551 : return _lsa_OpenPolicy2(p, &o);
463 : }
464 :
465 : /***************************************************************************
466 : _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
467 : ufff, done :) mimir
468 : ***************************************************************************/
469 :
470 0 : NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
471 : struct lsa_EnumTrustDom *r)
472 : {
473 0 : struct lsa_info *info;
474 0 : uint32_t i, count;
475 0 : struct trustdom_info **domains;
476 0 : struct lsa_DomainInfo *entries;
477 0 : NTSTATUS nt_status;
478 :
479 0 : info = find_policy_by_hnd(p,
480 : r->in.handle,
481 : LSA_HANDLE_POLICY_TYPE,
482 : struct lsa_info,
483 0 : &nt_status);
484 0 : if (!NT_STATUS_IS_OK(nt_status)) {
485 0 : return NT_STATUS_INVALID_HANDLE;
486 : }
487 :
488 : /* check if the user has enough rights */
489 0 : if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
490 0 : return NT_STATUS_ACCESS_DENIED;
491 :
492 0 : become_root();
493 0 : nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
494 0 : unbecome_root();
495 :
496 0 : if (!NT_STATUS_IS_OK(nt_status)) {
497 0 : return nt_status;
498 : }
499 :
500 0 : entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
501 0 : if (!entries) {
502 0 : return NT_STATUS_NO_MEMORY;
503 : }
504 :
505 0 : for (i=0; i<count; i++) {
506 0 : init_lsa_StringLarge(&entries[i].name, domains[i]->name);
507 0 : entries[i].sid = &domains[i]->sid;
508 : }
509 :
510 0 : if (*r->in.resume_handle >= count) {
511 0 : *r->out.resume_handle = -1;
512 0 : TALLOC_FREE(entries);
513 0 : return NT_STATUS_NO_MORE_ENTRIES;
514 : }
515 :
516 : /* return the rest, limit by max_size. Note that we
517 : use the w2k3 element size value of 60 */
518 0 : r->out.domains->count = count - *r->in.resume_handle;
519 0 : r->out.domains->count = MIN(r->out.domains->count,
520 : 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
521 :
522 0 : r->out.domains->domains = entries + *r->in.resume_handle;
523 :
524 0 : if (r->out.domains->count < count - *r->in.resume_handle) {
525 0 : *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
526 0 : return STATUS_MORE_ENTRIES;
527 : }
528 :
529 : /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
530 : * always be larger than the previous input resume handle, in
531 : * particular when hitting the last query it is vital to set the
532 : * resume handle correctly to avoid infinite client loops, as
533 : * seen e.g. with Windows XP SP3 when resume handle is 0 and
534 : * status is NT_STATUS_OK - gd */
535 :
536 0 : *r->out.resume_handle = (uint32_t)-1;
537 :
538 0 : return NT_STATUS_OK;
539 : }
540 :
541 : #define LSA_AUDIT_NUM_CATEGORIES_NT4 7
542 : #define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
543 : #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
544 :
545 : /***************************************************************************
546 : _lsa_QueryInfoPolicy
547 : ***************************************************************************/
548 :
549 860 : NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
550 : struct lsa_QueryInfoPolicy *r)
551 : {
552 860 : NTSTATUS status = NT_STATUS_OK;
553 0 : struct lsa_info *handle;
554 0 : struct dom_sid domain_sid;
555 0 : const char *name;
556 860 : struct dom_sid *sid = NULL;
557 860 : union lsa_PolicyInformation *info = NULL;
558 860 : uint32_t acc_required = 0;
559 :
560 860 : handle = find_policy_by_hnd(p,
561 : r->in.handle,
562 : LSA_HANDLE_POLICY_TYPE,
563 : struct lsa_info,
564 0 : &status);
565 860 : if (!NT_STATUS_IS_OK(status)) {
566 0 : return NT_STATUS_INVALID_HANDLE;
567 : }
568 :
569 860 : switch (r->in.level) {
570 4 : case LSA_POLICY_INFO_AUDIT_LOG:
571 : case LSA_POLICY_INFO_AUDIT_EVENTS:
572 4 : acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
573 4 : break;
574 60 : case LSA_POLICY_INFO_DOMAIN:
575 60 : acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
576 60 : break;
577 2 : case LSA_POLICY_INFO_PD:
578 2 : acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
579 2 : break;
580 774 : case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
581 774 : acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
582 774 : break;
583 4 : case LSA_POLICY_INFO_ROLE:
584 : case LSA_POLICY_INFO_REPLICA:
585 4 : acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
586 4 : break;
587 2 : case LSA_POLICY_INFO_QUOTA:
588 2 : acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
589 2 : break;
590 4 : case LSA_POLICY_INFO_MOD:
591 : case LSA_POLICY_INFO_AUDIT_FULL_SET:
592 : /* according to MS-LSAD 3.1.4.4.3 */
593 4 : return NT_STATUS_INVALID_PARAMETER;
594 2 : case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
595 2 : acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
596 2 : break;
597 8 : case LSA_POLICY_INFO_DNS:
598 : case LSA_POLICY_INFO_DNS_INT:
599 : case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
600 8 : acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
601 8 : break;
602 0 : default:
603 0 : break;
604 : }
605 :
606 856 : if (!(handle->access & acc_required)) {
607 : /* return NT_STATUS_ACCESS_DENIED; */
608 0 : }
609 :
610 856 : info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
611 856 : if (!info) {
612 0 : return NT_STATUS_NO_MEMORY;
613 : }
614 :
615 856 : switch (r->in.level) {
616 : /* according to MS-LSAD 3.1.4.4.3 */
617 2 : case LSA_POLICY_INFO_MOD:
618 : case LSA_POLICY_INFO_AUDIT_FULL_SET:
619 : case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
620 2 : return NT_STATUS_INVALID_PARAMETER;
621 2 : case LSA_POLICY_INFO_AUDIT_LOG:
622 2 : info->audit_log.percent_full = 0;
623 2 : info->audit_log.maximum_log_size = 0;
624 2 : info->audit_log.retention_time = 0;
625 2 : info->audit_log.shutdown_in_progress = 0;
626 2 : info->audit_log.time_to_shutdown = 0;
627 2 : info->audit_log.next_audit_record = 0;
628 2 : status = NT_STATUS_OK;
629 2 : break;
630 2 : case LSA_POLICY_INFO_PD:
631 2 : info->pd.name.string = NULL;
632 2 : status = NT_STATUS_OK;
633 2 : break;
634 2 : case LSA_POLICY_INFO_REPLICA:
635 2 : info->replica.source.string = NULL;
636 2 : info->replica.account.string = NULL;
637 2 : status = NT_STATUS_OK;
638 2 : break;
639 2 : case LSA_POLICY_INFO_QUOTA:
640 2 : info->quota.paged_pool = 0;
641 2 : info->quota.non_paged_pool = 0;
642 2 : info->quota.min_wss = 0;
643 2 : info->quota.max_wss = 0;
644 2 : info->quota.pagefile = 0;
645 2 : info->quota.unknown = 0;
646 2 : status = NT_STATUS_OK;
647 2 : break;
648 2 : case LSA_POLICY_INFO_AUDIT_EVENTS:
649 : {
650 :
651 2 : uint32_t policy_def = LSA_AUDIT_POLICY_ALL;
652 :
653 : /* check if the user has enough rights */
654 2 : if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
655 0 : DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
656 0 : return NT_STATUS_ACCESS_DENIED;
657 : }
658 :
659 : /* fake info: We audit everything. ;) */
660 :
661 2 : info->audit_events.auditing_mode = true;
662 2 : info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
663 2 : info->audit_events.settings = talloc_zero_array(p->mem_ctx,
664 : enum lsa_PolicyAuditPolicy,
665 : info->audit_events.count);
666 2 : if (!info->audit_events.settings) {
667 0 : return NT_STATUS_NO_MEMORY;
668 : }
669 :
670 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
671 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
672 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
673 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
674 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
675 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
676 2 : info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
677 :
678 2 : break;
679 : }
680 60 : case LSA_POLICY_INFO_DOMAIN:
681 : /* check if the user has enough rights */
682 60 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
683 0 : return NT_STATUS_ACCESS_DENIED;
684 :
685 : /* Request PolicyPrimaryDomainInformation. */
686 60 : switch (lp_server_role()) {
687 60 : case ROLE_DOMAIN_PDC:
688 : case ROLE_DOMAIN_BDC:
689 : case ROLE_IPA_DC:
690 60 : name = get_global_sam_name();
691 60 : sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
692 60 : if (!sid) {
693 0 : return NT_STATUS_NO_MEMORY;
694 : }
695 60 : break;
696 0 : case ROLE_DOMAIN_MEMBER:
697 0 : name = lp_workgroup();
698 : /* We need to return the Domain SID here. */
699 0 : if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
700 0 : sid = dom_sid_dup(p->mem_ctx, &domain_sid);
701 0 : if (!sid) {
702 0 : return NT_STATUS_NO_MEMORY;
703 : }
704 : } else {
705 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
706 : }
707 0 : break;
708 0 : case ROLE_STANDALONE:
709 0 : name = lp_workgroup();
710 0 : sid = NULL;
711 0 : break;
712 0 : default:
713 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
714 : }
715 60 : init_dom_query_3(&info->domain, name, sid);
716 60 : break;
717 774 : case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
718 : /* check if the user has enough rights */
719 774 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
720 0 : return NT_STATUS_ACCESS_DENIED;
721 :
722 : /* Request PolicyAccountDomainInformation. */
723 774 : name = get_global_sam_name();
724 774 : sid = get_global_sam_sid();
725 :
726 774 : init_dom_query_5(&info->account_domain, name, sid);
727 774 : break;
728 2 : case LSA_POLICY_INFO_ROLE:
729 : /* check if the user has enough rights */
730 2 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
731 0 : return NT_STATUS_ACCESS_DENIED;
732 :
733 2 : switch (lp_server_role()) {
734 0 : case ROLE_DOMAIN_BDC:
735 : /*
736 : * only a BDC is a backup controller
737 : * of the domain, it controls.
738 : */
739 0 : info->role.role = LSA_ROLE_BACKUP;
740 0 : break;
741 2 : default:
742 : /*
743 : * any other role is a primary
744 : * of the domain, it controls.
745 : */
746 2 : info->role.role = LSA_ROLE_PRIMARY;
747 2 : break;
748 : }
749 2 : break;
750 6 : case LSA_POLICY_INFO_DNS:
751 : case LSA_POLICY_INFO_DNS_INT: {
752 0 : struct pdb_domain_info *dominfo;
753 :
754 6 : if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
755 4 : DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
756 : "without ADS passdb backend\n"));
757 4 : status = NT_STATUS_INVALID_INFO_CLASS;
758 4 : break;
759 : }
760 :
761 2 : dominfo = pdb_get_domain_info(info);
762 2 : if (dominfo == NULL) {
763 0 : status = NT_STATUS_NO_MEMORY;
764 0 : break;
765 : }
766 :
767 2 : init_lsa_StringLarge(&info->dns.name,
768 2 : dominfo->name);
769 2 : init_lsa_StringLarge(&info->dns.dns_domain,
770 2 : dominfo->dns_domain);
771 2 : init_lsa_StringLarge(&info->dns.dns_forest,
772 2 : dominfo->dns_forest);
773 2 : info->dns.domain_guid = dominfo->guid;
774 2 : info->dns.sid = &dominfo->sid;
775 2 : break;
776 : }
777 2 : default:
778 2 : DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
779 : r->in.level));
780 2 : status = NT_STATUS_INVALID_INFO_CLASS;
781 2 : break;
782 : }
783 :
784 854 : *r->out.info = info;
785 :
786 854 : return status;
787 : }
788 :
789 : /***************************************************************************
790 : _lsa_QueryInfoPolicy2
791 : ***************************************************************************/
792 :
793 158 : NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
794 : struct lsa_QueryInfoPolicy2 *r2)
795 : {
796 0 : struct lsa_QueryInfoPolicy r;
797 :
798 158 : if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
799 156 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
800 156 : return NT_STATUS_NOT_IMPLEMENTED;
801 : }
802 :
803 2 : ZERO_STRUCT(r);
804 2 : r.in.handle = r2->in.handle;
805 2 : r.in.level = r2->in.level;
806 2 : r.out.info = r2->out.info;
807 :
808 2 : return _lsa_QueryInfoPolicy(p, &r);
809 : }
810 :
811 : /***************************************************************************
812 : _lsa_lookup_sids_internal
813 : ***************************************************************************/
814 :
815 3136 : static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
816 : TALLOC_CTX *mem_ctx,
817 : uint16_t level, /* input */
818 : int num_sids, /* input */
819 : struct lsa_SidPtr *sid, /* input */
820 : struct lsa_RefDomainList **pp_ref, /* input/output */
821 : struct lsa_TranslatedName2 **pp_names,/* input/output */
822 : uint32_t *pp_mapped_count) /* input/output */
823 : {
824 0 : NTSTATUS status;
825 0 : int i;
826 3136 : const struct dom_sid **sids = NULL;
827 3136 : struct lsa_RefDomainList *ref = NULL;
828 3136 : uint32_t mapped_count = 0;
829 3136 : struct lsa_dom_info *dom_infos = NULL;
830 3136 : struct lsa_name_info *name_infos = NULL;
831 3136 : struct lsa_TranslatedName2 *names = NULL;
832 :
833 3136 : *pp_mapped_count = 0;
834 3136 : *pp_names = NULL;
835 3136 : *pp_ref = NULL;
836 :
837 3136 : if (num_sids == 0) {
838 0 : return NT_STATUS_OK;
839 : }
840 :
841 3136 : sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
842 3136 : ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
843 :
844 3136 : if (sids == NULL || ref == NULL) {
845 0 : return NT_STATUS_NO_MEMORY;
846 : }
847 :
848 8876 : for (i=0; i<num_sids; i++) {
849 5740 : sids[i] = sid[i].sid;
850 : }
851 :
852 3136 : status = lookup_sids(p->mem_ctx, num_sids, sids, level,
853 : &dom_infos, &name_infos);
854 :
855 3136 : if (!NT_STATUS_IS_OK(status)) {
856 0 : return status;
857 : }
858 :
859 3136 : names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
860 3136 : if (names == NULL) {
861 0 : return NT_STATUS_NO_MEMORY;
862 : }
863 :
864 6276 : for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
865 :
866 6276 : if (!dom_infos[i].valid) {
867 3136 : break;
868 : }
869 :
870 3140 : if (init_lsa_ref_domain_list(mem_ctx, ref,
871 3140 : dom_infos[i].name,
872 3140 : &dom_infos[i].sid) != i) {
873 0 : DEBUG(0, ("Domain %s mentioned twice??\n",
874 : dom_infos[i].name));
875 0 : return NT_STATUS_INTERNAL_ERROR;
876 : }
877 : }
878 :
879 8876 : for (i=0; i<num_sids; i++) {
880 5740 : struct lsa_name_info *name = &name_infos[i];
881 :
882 5740 : if (name->type == SID_NAME_UNKNOWN) {
883 164 : name->dom_idx = -1;
884 : /* Unknown sids should return the string
885 : * representation of the SID. Windows 2003 behaves
886 : * rather erratic here, in many cases it returns the
887 : * RID as 8 bytes hex, in others it returns the full
888 : * SID. We (Jerry/VL) could not figure out which the
889 : * hard cases are, so leave it with the SID. */
890 164 : name->name = dom_sid_string(p->mem_ctx, sids[i]);
891 164 : if (name->name == NULL) {
892 0 : return NT_STATUS_NO_MEMORY;
893 : }
894 : } else {
895 5576 : mapped_count += 1;
896 : }
897 :
898 5740 : names[i].sid_type = name->type;
899 5740 : names[i].name.string = name->name;
900 5740 : names[i].sid_index = name->dom_idx;
901 5740 : names[i].unknown = 0;
902 : }
903 :
904 3136 : status = NT_STATUS_NONE_MAPPED;
905 3136 : if (mapped_count > 0) {
906 2982 : status = (mapped_count < num_sids) ?
907 0 : STATUS_SOME_UNMAPPED : NT_STATUS_OK;
908 : }
909 :
910 3136 : DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
911 : num_sids, mapped_count, nt_errstr(status)));
912 :
913 3136 : *pp_mapped_count = mapped_count;
914 3136 : *pp_names = names;
915 3136 : *pp_ref = ref;
916 :
917 3136 : return status;
918 : }
919 :
920 : /***************************************************************************
921 : _lsa_LookupSids
922 : ***************************************************************************/
923 :
924 3110 : NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
925 : struct lsa_LookupSids *r)
926 : {
927 0 : NTSTATUS status;
928 0 : struct lsa_info *handle;
929 3110 : int num_sids = r->in.sids->num_sids;
930 3110 : uint32_t mapped_count = 0;
931 3110 : struct lsa_RefDomainList *domains = NULL;
932 3110 : struct lsa_TranslatedName *names_out = NULL;
933 3110 : struct lsa_TranslatedName2 *names = NULL;
934 0 : int i;
935 :
936 3110 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
937 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
938 0 : return NT_STATUS_ACCESS_DENIED;
939 : }
940 :
941 3110 : if ((r->in.level < 1) || (r->in.level > 6)) {
942 0 : return NT_STATUS_INVALID_PARAMETER;
943 : }
944 :
945 3110 : handle = find_policy_by_hnd(p,
946 : r->in.handle,
947 : LSA_HANDLE_POLICY_TYPE,
948 : struct lsa_info,
949 0 : &status);
950 3110 : if (!NT_STATUS_IS_OK(status)) {
951 0 : return NT_STATUS_INVALID_HANDLE;
952 : }
953 :
954 : /* check if the user has enough rights */
955 3110 : if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
956 0 : return NT_STATUS_ACCESS_DENIED;
957 : }
958 :
959 3110 : if (num_sids > MAX_LOOKUP_SIDS) {
960 0 : DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
961 : MAX_LOOKUP_SIDS, num_sids));
962 0 : return NT_STATUS_NONE_MAPPED;
963 : }
964 :
965 3110 : status = _lsa_lookup_sids_internal(p,
966 : p->mem_ctx,
967 3110 : r->in.level,
968 : num_sids,
969 3110 : r->in.sids->sids,
970 : &domains,
971 : &names,
972 : &mapped_count);
973 :
974 : /* Only return here when there is a real error.
975 : NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
976 : the requested sids could be resolved. Older versions of XP (pre SP3)
977 : rely that we return with the string representations of those SIDs in
978 : that case. If we don't, XP crashes - Guenther
979 : */
980 :
981 3110 : if (NT_STATUS_IS_ERR(status) &&
982 154 : !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
983 0 : return status;
984 : }
985 :
986 : /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
987 3110 : names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
988 : num_sids);
989 3110 : if (!names_out) {
990 0 : return NT_STATUS_NO_MEMORY;
991 : }
992 :
993 6438 : for (i=0; i<num_sids; i++) {
994 3328 : names_out[i].sid_type = names[i].sid_type;
995 3328 : names_out[i].name = names[i].name;
996 3328 : names_out[i].sid_index = names[i].sid_index;
997 : }
998 :
999 3110 : *r->out.domains = domains;
1000 3110 : r->out.names->count = num_sids;
1001 3110 : r->out.names->names = names_out;
1002 3110 : *r->out.count = mapped_count;
1003 :
1004 3110 : return status;
1005 : }
1006 :
1007 26 : static NTSTATUS _lsa_LookupSids_common(struct pipes_struct *p,
1008 : struct lsa_LookupSids2 *r)
1009 : {
1010 26 : struct dcesrv_call_state *dce_call = p->dce_call;
1011 0 : NTSTATUS status;
1012 0 : struct lsa_info *handle;
1013 26 : int num_sids = r->in.sids->num_sids;
1014 26 : uint32_t mapped_count = 0;
1015 26 : struct lsa_RefDomainList *domains = NULL;
1016 26 : struct lsa_TranslatedName2 *names = NULL;
1017 26 : bool check_policy = true;
1018 :
1019 26 : switch (dce_call->pkt.u.request.opnum) {
1020 24 : case NDR_LSA_LOOKUPSIDS3:
1021 24 : check_policy = false;
1022 24 : break;
1023 2 : case NDR_LSA_LOOKUPSIDS2:
1024 : default:
1025 2 : check_policy = true;
1026 : }
1027 :
1028 26 : if ((r->in.level < 1) || (r->in.level > 6)) {
1029 0 : return NT_STATUS_INVALID_PARAMETER;
1030 : }
1031 :
1032 26 : if (check_policy) {
1033 2 : handle = find_policy_by_hnd(p,
1034 : r->in.handle,
1035 : LSA_HANDLE_POLICY_TYPE,
1036 : struct lsa_info,
1037 0 : &status);
1038 2 : if (!NT_STATUS_IS_OK(status)) {
1039 0 : return NT_STATUS_INVALID_HANDLE;
1040 : }
1041 :
1042 : /* check if the user has enough rights */
1043 2 : if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1044 0 : return NT_STATUS_ACCESS_DENIED;
1045 : }
1046 : }
1047 :
1048 26 : if (num_sids > MAX_LOOKUP_SIDS) {
1049 0 : DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
1050 : MAX_LOOKUP_SIDS, num_sids));
1051 0 : return NT_STATUS_NONE_MAPPED;
1052 : }
1053 :
1054 26 : status = _lsa_lookup_sids_internal(p,
1055 : p->mem_ctx,
1056 26 : r->in.level,
1057 : num_sids,
1058 26 : r->in.sids->sids,
1059 : &domains,
1060 : &names,
1061 : &mapped_count);
1062 :
1063 26 : *r->out.domains = domains;
1064 26 : r->out.names->count = num_sids;
1065 26 : r->out.names->names = names;
1066 26 : *r->out.count = mapped_count;
1067 :
1068 26 : return status;
1069 : }
1070 :
1071 : /***************************************************************************
1072 : _lsa_LookupSids2
1073 : ***************************************************************************/
1074 :
1075 2 : NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
1076 : struct lsa_LookupSids2 *r)
1077 : {
1078 2 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1079 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1080 0 : return NT_STATUS_ACCESS_DENIED;
1081 : }
1082 :
1083 2 : return _lsa_LookupSids_common(p, r);
1084 : }
1085 :
1086 : /***************************************************************************
1087 : _lsa_LookupSids3
1088 : ***************************************************************************/
1089 :
1090 28 : NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
1091 : struct lsa_LookupSids3 *r)
1092 : {
1093 28 : struct dcesrv_call_state *dce_call = p->dce_call;
1094 28 : enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1095 28 : enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
1096 0 : struct lsa_LookupSids2 q;
1097 :
1098 28 : if (p->transport != NCACN_IP_TCP) {
1099 2 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1100 2 : return NT_STATUS_ACCESS_DENIED;
1101 : }
1102 :
1103 26 : dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
1104 :
1105 : /* No policy handle on this call. Restrict to crypto connections. */
1106 26 : if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1107 24 : auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1108 2 : DEBUG(1, ("_lsa_LookupSids3: The client %s is not using "
1109 : "a secure connection over netlogon\n",
1110 : get_remote_machine_name() ));
1111 2 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1112 2 : return NT_STATUS_ACCESS_DENIED;
1113 : }
1114 :
1115 24 : q.in.handle = NULL;
1116 24 : q.in.sids = r->in.sids;
1117 24 : q.in.level = r->in.level;
1118 24 : q.in.lookup_options = r->in.lookup_options;
1119 24 : q.in.client_revision = r->in.client_revision;
1120 24 : q.in.names = r->in.names;
1121 24 : q.in.count = r->in.count;
1122 :
1123 24 : q.out.domains = r->out.domains;
1124 24 : q.out.names = r->out.names;
1125 24 : q.out.count = r->out.count;
1126 :
1127 24 : return _lsa_LookupSids_common(p, &q);
1128 : }
1129 :
1130 : /***************************************************************************
1131 : ***************************************************************************/
1132 :
1133 374 : static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
1134 : {
1135 0 : int flags;
1136 :
1137 374 : switch (level) {
1138 358 : case LSA_LOOKUP_NAMES_ALL: /* 1 */
1139 358 : flags = LOOKUP_NAME_ALL;
1140 358 : break;
1141 16 : case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
1142 16 : flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
1143 16 : break;
1144 0 : case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
1145 0 : flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
1146 0 : break;
1147 0 : case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
1148 : case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
1149 : case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
1150 : case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
1151 : default:
1152 0 : flags = LOOKUP_NAME_NONE;
1153 0 : break;
1154 : }
1155 :
1156 374 : return flags;
1157 : }
1158 :
1159 : /***************************************************************************
1160 : _lsa_LookupNames
1161 : ***************************************************************************/
1162 :
1163 322 : NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
1164 : struct lsa_LookupNames *r)
1165 : {
1166 322 : NTSTATUS status = NT_STATUS_NONE_MAPPED;
1167 0 : struct lsa_info *handle;
1168 322 : struct lsa_String *names = r->in.names;
1169 322 : uint32_t num_entries = r->in.num_names;
1170 322 : struct lsa_RefDomainList *domains = NULL;
1171 322 : struct lsa_TranslatedSid *rids = NULL;
1172 322 : uint32_t mapped_count = 0;
1173 322 : int flags = 0;
1174 :
1175 322 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1176 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1177 0 : return NT_STATUS_ACCESS_DENIED;
1178 : }
1179 :
1180 322 : if (num_entries > MAX_LOOKUP_SIDS) {
1181 0 : num_entries = MAX_LOOKUP_SIDS;
1182 0 : DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
1183 : num_entries));
1184 : }
1185 :
1186 322 : flags = lsa_lookup_level_to_flags(r->in.level);
1187 :
1188 322 : domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1189 322 : if (!domains) {
1190 0 : return NT_STATUS_NO_MEMORY;
1191 : }
1192 :
1193 322 : if (num_entries) {
1194 322 : rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
1195 : num_entries);
1196 322 : if (!rids) {
1197 0 : return NT_STATUS_NO_MEMORY;
1198 : }
1199 : } else {
1200 0 : rids = NULL;
1201 : }
1202 :
1203 322 : handle = find_policy_by_hnd(p,
1204 : r->in.handle,
1205 : LSA_HANDLE_POLICY_TYPE,
1206 : struct lsa_info,
1207 0 : &status);
1208 322 : if (!NT_STATUS_IS_OK(status)) {
1209 0 : status = NT_STATUS_INVALID_HANDLE;
1210 0 : goto done;
1211 : }
1212 :
1213 : /* check if the user has enough rights */
1214 322 : if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1215 0 : status = NT_STATUS_ACCESS_DENIED;
1216 0 : goto done;
1217 : }
1218 :
1219 : /* set up the LSA Lookup RIDs response */
1220 322 : become_root(); /* lookup_name can require root privs */
1221 322 : status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
1222 : names, flags, &mapped_count);
1223 322 : unbecome_root();
1224 :
1225 322 : done:
1226 :
1227 322 : if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
1228 322 : if (mapped_count == 0) {
1229 18 : status = NT_STATUS_NONE_MAPPED;
1230 304 : } else if (mapped_count != num_entries) {
1231 0 : status = STATUS_SOME_UNMAPPED;
1232 : }
1233 : }
1234 :
1235 322 : *r->out.count = mapped_count;
1236 322 : *r->out.domains = domains;
1237 322 : r->out.sids->sids = rids;
1238 322 : r->out.sids->count = num_entries;
1239 :
1240 322 : return status;
1241 : }
1242 :
1243 : /***************************************************************************
1244 : _lsa_LookupNames2
1245 : ***************************************************************************/
1246 :
1247 4 : NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
1248 : struct lsa_LookupNames2 *r)
1249 : {
1250 0 : NTSTATUS status;
1251 0 : struct lsa_LookupNames q;
1252 4 : struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
1253 4 : struct lsa_TransSidArray *sid_array = NULL;
1254 0 : uint32_t i;
1255 :
1256 4 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1257 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1258 0 : return NT_STATUS_ACCESS_DENIED;
1259 : }
1260 :
1261 4 : sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
1262 4 : if (!sid_array) {
1263 0 : return NT_STATUS_NO_MEMORY;
1264 : }
1265 :
1266 4 : q.in.handle = r->in.handle;
1267 4 : q.in.num_names = r->in.num_names;
1268 4 : q.in.names = r->in.names;
1269 4 : q.in.level = r->in.level;
1270 4 : q.in.sids = sid_array;
1271 4 : q.in.count = r->in.count;
1272 : /* we do not know what this is for */
1273 : /* = r->in.unknown1; */
1274 : /* = r->in.unknown2; */
1275 :
1276 4 : q.out.domains = r->out.domains;
1277 4 : q.out.sids = sid_array;
1278 4 : q.out.count = r->out.count;
1279 :
1280 4 : status = _lsa_LookupNames(p, &q);
1281 :
1282 4 : sid_array2->count = sid_array->count;
1283 4 : sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
1284 4 : if (!sid_array2->sids) {
1285 0 : return NT_STATUS_NO_MEMORY;
1286 : }
1287 :
1288 18 : for (i=0; i<sid_array->count; i++) {
1289 14 : sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type;
1290 14 : sid_array2->sids[i].rid = sid_array->sids[i].rid;
1291 14 : sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
1292 14 : sid_array2->sids[i].unknown = 0;
1293 : }
1294 :
1295 4 : r->out.sids = sid_array2;
1296 :
1297 4 : return status;
1298 : }
1299 :
1300 52 : static NTSTATUS _lsa_LookupNames_common(struct pipes_struct *p,
1301 : struct lsa_LookupNames3 *r)
1302 : {
1303 52 : struct dcesrv_call_state *dce_call = p->dce_call;
1304 0 : NTSTATUS status;
1305 0 : struct lsa_info *handle;
1306 52 : struct lsa_String *names = r->in.names;
1307 52 : uint32_t num_entries = r->in.num_names;
1308 52 : struct lsa_RefDomainList *domains = NULL;
1309 52 : struct lsa_TranslatedSid3 *trans_sids = NULL;
1310 52 : uint32_t mapped_count = 0;
1311 52 : int flags = 0;
1312 52 : bool check_policy = true;
1313 :
1314 52 : switch (dce_call->pkt.u.request.opnum) {
1315 48 : case NDR_LSA_LOOKUPNAMES4:
1316 48 : check_policy = false;
1317 48 : break;
1318 4 : case NDR_LSA_LOOKUPNAMES3:
1319 : default:
1320 4 : check_policy = true;
1321 : }
1322 :
1323 52 : if (num_entries > MAX_LOOKUP_SIDS) {
1324 0 : num_entries = MAX_LOOKUP_SIDS;
1325 0 : DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
1326 : }
1327 :
1328 52 : flags = lsa_lookup_level_to_flags(r->in.level);
1329 :
1330 52 : domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
1331 52 : if (!domains) {
1332 0 : return NT_STATUS_NO_MEMORY;
1333 : }
1334 :
1335 52 : if (num_entries) {
1336 28 : trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
1337 : num_entries);
1338 28 : if (!trans_sids) {
1339 0 : return NT_STATUS_NO_MEMORY;
1340 : }
1341 : } else {
1342 24 : trans_sids = NULL;
1343 : }
1344 :
1345 52 : if (check_policy) {
1346 :
1347 4 : handle = find_policy_by_hnd(p,
1348 : r->in.handle,
1349 : LSA_HANDLE_POLICY_TYPE,
1350 : struct lsa_info,
1351 0 : &status);
1352 4 : if (!NT_STATUS_IS_OK(status)) {
1353 0 : status = NT_STATUS_INVALID_HANDLE;
1354 0 : goto done;
1355 : }
1356 :
1357 : /* check if the user has enough rights */
1358 4 : if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
1359 0 : status = NT_STATUS_ACCESS_DENIED;
1360 0 : goto done;
1361 : }
1362 : }
1363 :
1364 : /* set up the LSA Lookup SIDs response */
1365 52 : become_root(); /* lookup_name can require root privs */
1366 52 : status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
1367 : names, flags, &mapped_count);
1368 52 : unbecome_root();
1369 :
1370 52 : done:
1371 :
1372 52 : if (NT_STATUS_IS_OK(status)) {
1373 52 : if (mapped_count == 0) {
1374 24 : status = NT_STATUS_NONE_MAPPED;
1375 28 : } else if (mapped_count != num_entries) {
1376 0 : status = STATUS_SOME_UNMAPPED;
1377 : }
1378 : }
1379 :
1380 52 : *r->out.count = mapped_count;
1381 52 : *r->out.domains = domains;
1382 52 : r->out.sids->sids = trans_sids;
1383 52 : r->out.sids->count = num_entries;
1384 :
1385 52 : return status;
1386 : }
1387 :
1388 : /***************************************************************************
1389 : _lsa_LookupNames3
1390 : ***************************************************************************/
1391 :
1392 4 : NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
1393 : struct lsa_LookupNames3 *r)
1394 : {
1395 4 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1396 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1397 0 : return NT_STATUS_ACCESS_DENIED;
1398 : }
1399 :
1400 4 : return _lsa_LookupNames_common(p, r);
1401 : }
1402 :
1403 : /***************************************************************************
1404 : _lsa_LookupNames4
1405 : ***************************************************************************/
1406 :
1407 52 : NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
1408 : struct lsa_LookupNames4 *r)
1409 : {
1410 52 : struct dcesrv_call_state *dce_call = p->dce_call;
1411 52 : enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1412 52 : enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
1413 0 : struct lsa_LookupNames3 q;
1414 :
1415 52 : if (p->transport != NCACN_IP_TCP) {
1416 2 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1417 2 : return NT_STATUS_ACCESS_DENIED;
1418 : }
1419 :
1420 50 : dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
1421 :
1422 : /* No policy handle on this call. Restrict to crypto connections. */
1423 50 : if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
1424 48 : auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1425 2 : DEBUG(1, ("_lsa_LookupNames4: The client %s is not using "
1426 : "a secure connection over netlogon\n",
1427 : get_remote_machine_name()));
1428 2 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1429 2 : return NT_STATUS_ACCESS_DENIED;
1430 : }
1431 :
1432 48 : q.in.handle = NULL;
1433 48 : q.in.num_names = r->in.num_names;
1434 48 : q.in.names = r->in.names;
1435 48 : q.in.level = r->in.level;
1436 48 : q.in.lookup_options = r->in.lookup_options;
1437 48 : q.in.client_revision = r->in.client_revision;
1438 48 : q.in.sids = r->in.sids;
1439 48 : q.in.count = r->in.count;
1440 :
1441 48 : q.out.domains = r->out.domains;
1442 48 : q.out.sids = r->out.sids;
1443 48 : q.out.count = r->out.count;
1444 :
1445 48 : return _lsa_LookupNames_common(p, &q);
1446 : }
1447 :
1448 : /***************************************************************************
1449 : _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
1450 : ***************************************************************************/
1451 :
1452 978 : NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
1453 : {
1454 0 : NTSTATUS status;
1455 :
1456 978 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
1457 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
1458 0 : return NT_STATUS_ACCESS_DENIED;
1459 : }
1460 :
1461 978 : (void)find_policy_by_hnd(p,
1462 : r->in.handle,
1463 : DCESRV_HANDLE_ANY,
1464 : struct lsa_info,
1465 0 : &status);
1466 978 : if (!NT_STATUS_IS_OK(status)) {
1467 26 : return NT_STATUS_INVALID_HANDLE;
1468 : }
1469 :
1470 952 : close_policy_hnd(p, r->in.handle);
1471 952 : ZERO_STRUCTP(r->out.handle);
1472 952 : return NT_STATUS_OK;
1473 : }
1474 :
1475 : /***************************************************************************
1476 : ***************************************************************************/
1477 :
1478 0 : static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
1479 : const struct dom_sid *sid,
1480 : struct trustdom_info **info)
1481 : {
1482 0 : NTSTATUS status;
1483 0 : uint32_t num_domains = 0;
1484 0 : struct trustdom_info **domains = NULL;
1485 0 : int i;
1486 :
1487 0 : status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
1488 0 : if (!NT_STATUS_IS_OK(status)) {
1489 0 : return status;
1490 : }
1491 :
1492 0 : for (i=0; i < num_domains; i++) {
1493 0 : if (dom_sid_equal(&domains[i]->sid, sid)) {
1494 0 : break;
1495 : }
1496 : }
1497 :
1498 0 : if (i == num_domains) {
1499 0 : return NT_STATUS_INVALID_PARAMETER;
1500 : }
1501 :
1502 0 : *info = domains[i];
1503 :
1504 0 : return NT_STATUS_OK;
1505 : }
1506 :
1507 : /***************************************************************************
1508 : ***************************************************************************/
1509 :
1510 0 : static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
1511 : const char *netbios_domain_name,
1512 : struct trustdom_info **info_p)
1513 : {
1514 0 : NTSTATUS status;
1515 0 : struct trustdom_info *info;
1516 0 : struct pdb_trusted_domain *td;
1517 :
1518 0 : status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
1519 0 : if (!NT_STATUS_IS_OK(status)) {
1520 0 : return status;
1521 : }
1522 :
1523 0 : info = talloc(mem_ctx, struct trustdom_info);
1524 0 : if (!info) {
1525 0 : return NT_STATUS_NO_MEMORY;
1526 : }
1527 :
1528 0 : info->name = talloc_strdup(info, netbios_domain_name);
1529 0 : NT_STATUS_HAVE_NO_MEMORY(info->name);
1530 :
1531 0 : sid_copy(&info->sid, &td->security_identifier);
1532 :
1533 0 : *info_p = info;
1534 :
1535 0 : return NT_STATUS_OK;
1536 : }
1537 :
1538 : /***************************************************************************
1539 : _lsa_OpenSecret
1540 : ***************************************************************************/
1541 :
1542 8 : NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
1543 : struct lsa_OpenSecret *r)
1544 : {
1545 8 : struct dcesrv_call_state *dce_call = p->dce_call;
1546 0 : struct auth_session_info *session_info =
1547 8 : dcesrv_call_session_info(dce_call);
1548 0 : struct security_descriptor *psd;
1549 0 : NTSTATUS status;
1550 0 : uint32_t acc_granted;
1551 :
1552 8 : (void)find_policy_by_hnd(p,
1553 : r->in.handle,
1554 : LSA_HANDLE_POLICY_TYPE,
1555 : struct lsa_info,
1556 0 : &status);
1557 8 : if (!NT_STATUS_IS_OK(status)) {
1558 0 : return NT_STATUS_INVALID_HANDLE;
1559 : }
1560 :
1561 8 : if (!r->in.name.string) {
1562 0 : return NT_STATUS_INVALID_PARAMETER;
1563 : }
1564 :
1565 : /* Work out max allowed. */
1566 8 : map_max_allowed_access(session_info->security_token,
1567 8 : session_info->unix_token,
1568 : &r->in.access_mask);
1569 :
1570 : /* map the generic bits to the lsa policy ones */
1571 8 : se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
1572 :
1573 8 : status = pdb_get_secret(p->mem_ctx, r->in.name.string,
1574 : NULL,
1575 : NULL,
1576 : NULL,
1577 : NULL,
1578 : &psd);
1579 8 : if (!NT_STATUS_IS_OK(status)) {
1580 4 : return status;
1581 : }
1582 :
1583 4 : status = access_check_object(psd, session_info->security_token,
1584 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1585 : r->in.access_mask,
1586 : &acc_granted, "_lsa_OpenSecret");
1587 4 : if (!NT_STATUS_IS_OK(status)) {
1588 0 : return status;
1589 : }
1590 :
1591 4 : status = create_lsa_policy_handle(p->mem_ctx, p,
1592 : LSA_HANDLE_SECRET_TYPE,
1593 : acc_granted,
1594 : NULL,
1595 : r->in.name.string,
1596 : psd,
1597 : r->out.sec_handle);
1598 4 : if (!NT_STATUS_IS_OK(status)) {
1599 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1600 : }
1601 :
1602 4 : return NT_STATUS_OK;
1603 : }
1604 :
1605 : /***************************************************************************
1606 : _lsa_OpenTrustedDomain_base
1607 : ***************************************************************************/
1608 :
1609 0 : static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
1610 : uint32_t access_mask,
1611 : struct trustdom_info *info,
1612 : struct policy_handle *handle)
1613 : {
1614 0 : struct dcesrv_call_state *dce_call = p->dce_call;
1615 0 : struct auth_session_info *session_info =
1616 0 : dcesrv_call_session_info(dce_call);
1617 0 : struct security_descriptor *psd = NULL;
1618 0 : size_t sd_size;
1619 0 : uint32_t acc_granted;
1620 0 : NTSTATUS status;
1621 :
1622 : /* des_access is for the account here, not the policy
1623 : * handle - so don't check against policy handle. */
1624 :
1625 : /* Work out max allowed. */
1626 0 : map_max_allowed_access(session_info->security_token,
1627 0 : session_info->unix_token,
1628 : &access_mask);
1629 :
1630 : /* map the generic bits to the lsa account ones */
1631 0 : se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
1632 :
1633 : /* get the generic lsa account SD until we store it */
1634 0 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1635 : &lsa_trusted_domain_mapping,
1636 : NULL, 0);
1637 0 : if (!NT_STATUS_IS_OK(status)) {
1638 0 : return status;
1639 : }
1640 :
1641 0 : status = access_check_object(psd, session_info->security_token,
1642 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1643 : access_mask, &acc_granted,
1644 : "_lsa_OpenTrustedDomain");
1645 0 : if (!NT_STATUS_IS_OK(status)) {
1646 0 : return status;
1647 : }
1648 :
1649 0 : status = create_lsa_policy_handle(p->mem_ctx, p,
1650 : LSA_HANDLE_TRUST_TYPE,
1651 : acc_granted,
1652 : &info->sid,
1653 0 : info->name,
1654 : psd,
1655 : handle);
1656 0 : if (!NT_STATUS_IS_OK(status)) {
1657 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1658 : }
1659 :
1660 0 : return NT_STATUS_OK;
1661 : }
1662 :
1663 : /***************************************************************************
1664 : _lsa_OpenTrustedDomain
1665 : ***************************************************************************/
1666 :
1667 0 : NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
1668 : struct lsa_OpenTrustedDomain *r)
1669 : {
1670 0 : struct trustdom_info *info = NULL;
1671 0 : NTSTATUS status;
1672 :
1673 0 : (void)find_policy_by_hnd(p,
1674 : r->in.handle,
1675 : LSA_HANDLE_POLICY_TYPE,
1676 : struct lsa_info,
1677 0 : &status);
1678 0 : if (!NT_STATUS_IS_OK(status)) {
1679 0 : return NT_STATUS_INVALID_HANDLE;
1680 : }
1681 :
1682 0 : status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
1683 0 : r->in.sid,
1684 : &info);
1685 0 : if (!NT_STATUS_IS_OK(status)) {
1686 0 : return status;
1687 : }
1688 :
1689 0 : return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1690 : r->out.trustdom_handle);
1691 : }
1692 :
1693 : /***************************************************************************
1694 : _lsa_OpenTrustedDomainByName
1695 : ***************************************************************************/
1696 :
1697 0 : NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
1698 : struct lsa_OpenTrustedDomainByName *r)
1699 : {
1700 0 : struct trustdom_info *info = NULL;
1701 0 : NTSTATUS status;
1702 :
1703 0 : (void)find_policy_by_hnd(p,
1704 : r->in.handle,
1705 : LSA_HANDLE_POLICY_TYPE,
1706 : struct lsa_info,
1707 0 : &status);
1708 0 : if (!NT_STATUS_IS_OK(status)) {
1709 0 : return NT_STATUS_INVALID_HANDLE;
1710 : }
1711 :
1712 0 : status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
1713 : r->in.name.string,
1714 : &info);
1715 0 : if (!NT_STATUS_IS_OK(status)) {
1716 0 : return status;
1717 : }
1718 :
1719 0 : return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
1720 : r->out.trustdom_handle);
1721 : }
1722 :
1723 0 : static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
1724 : TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
1725 : struct trustDomainPasswords *auth_struct)
1726 : {
1727 0 : struct dcesrv_call_state *dce_call = p->dce_call;
1728 0 : struct auth_session_info *session_info =
1729 0 : dcesrv_call_session_info(dce_call);
1730 0 : enum ndr_err_code ndr_err;
1731 0 : DATA_BLOB lsession_key;
1732 0 : gnutls_cipher_hd_t cipher_hnd = NULL;
1733 0 : gnutls_datum_t my_session_key;
1734 0 : NTSTATUS status;
1735 0 : int rc;
1736 0 : bool encrypted;
1737 :
1738 0 : encrypted = dcerpc_is_transport_encrypted(session_info);
1739 0 : if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
1740 0 : !encrypted) {
1741 0 : return NT_STATUS_ACCESS_DENIED;
1742 : }
1743 :
1744 0 : status = session_extract_session_key(
1745 : session_info, &lsession_key, KEY_USE_16BYTES);
1746 0 : if (!NT_STATUS_IS_OK(status)) {
1747 0 : return NT_STATUS_INVALID_PARAMETER;
1748 : }
1749 :
1750 0 : my_session_key = (gnutls_datum_t) {
1751 0 : .data = lsession_key.data,
1752 0 : .size = lsession_key.length,
1753 : };
1754 :
1755 0 : GNUTLS_FIPS140_SET_LAX_MODE();
1756 0 : rc = gnutls_cipher_init(&cipher_hnd,
1757 : GNUTLS_CIPHER_ARCFOUR_128,
1758 : &my_session_key,
1759 : NULL);
1760 0 : if (rc < 0) {
1761 0 : GNUTLS_FIPS140_SET_STRICT_MODE();
1762 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
1763 0 : goto out;
1764 : }
1765 :
1766 0 : rc = gnutls_cipher_decrypt(cipher_hnd,
1767 0 : auth_blob->data,
1768 : auth_blob->length);
1769 0 : gnutls_cipher_deinit(cipher_hnd);
1770 0 : GNUTLS_FIPS140_SET_STRICT_MODE();
1771 0 : if (rc < 0) {
1772 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
1773 0 : goto out;
1774 : }
1775 :
1776 0 : ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
1777 : auth_struct,
1778 : (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
1779 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1780 0 : status = NT_STATUS_INVALID_PARAMETER;
1781 0 : goto out;
1782 : }
1783 :
1784 0 : status = NT_STATUS_OK;
1785 0 : out:
1786 0 : return status;
1787 : }
1788 :
1789 0 : static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
1790 : struct trustAuthInOutBlob *iopw,
1791 : DATA_BLOB *trustauth_blob)
1792 : {
1793 0 : enum ndr_err_code ndr_err;
1794 :
1795 0 : if (iopw->current.count != iopw->count) {
1796 0 : return NT_STATUS_INVALID_PARAMETER;
1797 : }
1798 :
1799 0 : if (iopw->previous.count > iopw->current.count) {
1800 0 : return NT_STATUS_INVALID_PARAMETER;
1801 : }
1802 :
1803 0 : if (iopw->previous.count == 0) {
1804 : /*
1805 : * If the previous credentials are not present
1806 : * we need to make a copy.
1807 : */
1808 0 : iopw->previous = iopw->current;
1809 : }
1810 :
1811 0 : if (iopw->previous.count < iopw->current.count) {
1812 0 : struct AuthenticationInformationArray *c = &iopw->current;
1813 0 : struct AuthenticationInformationArray *p = &iopw->previous;
1814 :
1815 : /*
1816 : * The previous array needs to have the same size
1817 : * as the current one.
1818 : *
1819 : * We may have to fill with TRUST_AUTH_TYPE_NONE
1820 : * elements.
1821 : */
1822 0 : p->array = talloc_realloc(mem_ctx, p->array,
1823 : struct AuthenticationInformation,
1824 : c->count);
1825 0 : if (p->array == NULL) {
1826 0 : return NT_STATUS_NO_MEMORY;
1827 : }
1828 :
1829 0 : while (p->count < c->count) {
1830 0 : struct AuthenticationInformation *a =
1831 0 : &p->array[p->count++];
1832 :
1833 0 : *a = (struct AuthenticationInformation) {
1834 0 : .LastUpdateTime = p->array[0].LastUpdateTime,
1835 : .AuthType = TRUST_AUTH_TYPE_NONE,
1836 : };
1837 : }
1838 : }
1839 :
1840 0 : ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
1841 : iopw,
1842 : (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
1843 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1844 0 : return NT_STATUS_INVALID_PARAMETER;
1845 : }
1846 :
1847 0 : return NT_STATUS_OK;
1848 : }
1849 :
1850 : /***************************************************************************
1851 : _lsa_CreateTrustedDomainEx2
1852 : ***************************************************************************/
1853 :
1854 0 : NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
1855 : struct lsa_CreateTrustedDomainEx2 *r)
1856 : {
1857 0 : struct dcesrv_call_state *dce_call = p->dce_call;
1858 0 : struct auth_session_info *session_info =
1859 0 : dcesrv_call_session_info(dce_call);
1860 0 : struct lsa_info *policy;
1861 0 : NTSTATUS status;
1862 0 : uint32_t acc_granted;
1863 0 : struct security_descriptor *psd;
1864 0 : size_t sd_size;
1865 0 : struct pdb_trusted_domain td;
1866 0 : struct trustDomainPasswords auth_struct;
1867 0 : DATA_BLOB auth_blob;
1868 :
1869 0 : if (!IS_DC) {
1870 0 : return NT_STATUS_NOT_SUPPORTED;
1871 : }
1872 :
1873 0 : policy = find_policy_by_hnd(p,
1874 : r->in.policy_handle,
1875 : LSA_HANDLE_POLICY_TYPE,
1876 : struct lsa_info,
1877 0 : &status);
1878 0 : if (!NT_STATUS_IS_OK(status)) {
1879 0 : return NT_STATUS_INVALID_HANDLE;
1880 : }
1881 :
1882 0 : if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
1883 0 : return NT_STATUS_ACCESS_DENIED;
1884 : }
1885 :
1886 0 : if (session_info->unix_token->uid != sec_initial_uid() &&
1887 0 : !nt_token_check_domain_rid(
1888 : session_info->security_token, DOMAIN_RID_ADMINS)) {
1889 0 : return NT_STATUS_ACCESS_DENIED;
1890 : }
1891 :
1892 : /* Work out max allowed. */
1893 0 : map_max_allowed_access(session_info->security_token,
1894 0 : session_info->unix_token,
1895 : &r->in.access_mask);
1896 :
1897 : /* map the generic bits to the lsa policy ones */
1898 0 : se_map_generic(&r->in.access_mask, &lsa_account_mapping);
1899 :
1900 0 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
1901 : &lsa_trusted_domain_mapping,
1902 : NULL, 0);
1903 0 : if (!NT_STATUS_IS_OK(status)) {
1904 0 : return status;
1905 : }
1906 :
1907 0 : status = access_check_object(psd, session_info->security_token,
1908 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
1909 : r->in.access_mask, &acc_granted,
1910 : "_lsa_CreateTrustedDomainEx2");
1911 0 : if (!NT_STATUS_IS_OK(status)) {
1912 0 : return status;
1913 : }
1914 :
1915 0 : ZERO_STRUCT(td);
1916 :
1917 0 : td.domain_name = talloc_strdup(p->mem_ctx,
1918 0 : r->in.info->domain_name.string);
1919 0 : if (td.domain_name == NULL) {
1920 0 : return NT_STATUS_NO_MEMORY;
1921 : }
1922 0 : td.netbios_name = talloc_strdup(p->mem_ctx,
1923 0 : r->in.info->netbios_name.string);
1924 0 : if (td.netbios_name == NULL) {
1925 0 : return NT_STATUS_NO_MEMORY;
1926 : }
1927 0 : sid_copy(&td.security_identifier, r->in.info->sid);
1928 0 : td.trust_direction = r->in.info->trust_direction;
1929 0 : td.trust_type = r->in.info->trust_type;
1930 0 : td.trust_attributes = r->in.info->trust_attributes;
1931 :
1932 0 : if (r->in.auth_info_internal->auth_blob.size != 0) {
1933 0 : auth_blob.length = r->in.auth_info_internal->auth_blob.size;
1934 0 : auth_blob.data = r->in.auth_info_internal->auth_blob.data;
1935 :
1936 0 : status = get_trustdom_auth_blob(p, p->mem_ctx, &auth_blob, &auth_struct);
1937 0 : if (!NT_STATUS_IS_OK(status)) {
1938 0 : return NT_STATUS_UNSUCCESSFUL;
1939 : }
1940 :
1941 0 : status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.incoming, &td.trust_auth_incoming);
1942 0 : if (!NT_STATUS_IS_OK(status)) {
1943 0 : return NT_STATUS_UNSUCCESSFUL;
1944 : }
1945 :
1946 0 : status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.outgoing, &td.trust_auth_outgoing);
1947 0 : if (!NT_STATUS_IS_OK(status)) {
1948 0 : return NT_STATUS_UNSUCCESSFUL;
1949 : }
1950 : } else {
1951 0 : td.trust_auth_incoming.data = NULL;
1952 0 : td.trust_auth_incoming.length = 0;
1953 0 : td.trust_auth_outgoing.data = NULL;
1954 0 : td.trust_auth_outgoing.length = 0;
1955 : }
1956 :
1957 0 : status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
1958 0 : if (!NT_STATUS_IS_OK(status)) {
1959 0 : return status;
1960 : }
1961 :
1962 0 : status = create_lsa_policy_handle(p->mem_ctx, p,
1963 : LSA_HANDLE_TRUST_TYPE,
1964 : acc_granted,
1965 0 : r->in.info->sid,
1966 0 : r->in.info->netbios_name.string,
1967 : psd,
1968 : r->out.trustdom_handle);
1969 0 : if (!NT_STATUS_IS_OK(status)) {
1970 0 : pdb_del_trusted_domain(r->in.info->netbios_name.string);
1971 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1972 : }
1973 :
1974 0 : return NT_STATUS_OK;
1975 : }
1976 :
1977 : /***************************************************************************
1978 : _lsa_CreateTrustedDomainEx
1979 : ***************************************************************************/
1980 :
1981 0 : NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
1982 : struct lsa_CreateTrustedDomainEx *r)
1983 : {
1984 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1985 0 : return NT_STATUS_NOT_IMPLEMENTED;
1986 : }
1987 :
1988 : /***************************************************************************
1989 : _lsa_CreateTrustedDomain
1990 : ***************************************************************************/
1991 :
1992 0 : NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
1993 : struct lsa_CreateTrustedDomain *r)
1994 : {
1995 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1996 0 : return NT_STATUS_NOT_IMPLEMENTED;
1997 : }
1998 :
1999 : /***************************************************************************
2000 : _lsa_DeleteTrustedDomain
2001 : ***************************************************************************/
2002 :
2003 0 : NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
2004 : struct lsa_DeleteTrustedDomain *r)
2005 : {
2006 0 : NTSTATUS status;
2007 0 : struct lsa_info *handle;
2008 0 : struct pdb_trusted_domain *td;
2009 :
2010 : /* find the connection policy handle. */
2011 0 : handle = find_policy_by_hnd(p,
2012 : r->in.handle,
2013 : LSA_HANDLE_POLICY_TYPE,
2014 : struct lsa_info,
2015 0 : &status);
2016 0 : if (!NT_STATUS_IS_OK(status)) {
2017 0 : return NT_STATUS_INVALID_HANDLE;
2018 : }
2019 :
2020 0 : if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
2021 0 : return NT_STATUS_ACCESS_DENIED;
2022 : }
2023 :
2024 0 : status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
2025 0 : if (!NT_STATUS_IS_OK(status)) {
2026 0 : return status;
2027 : }
2028 :
2029 0 : if (td->netbios_name == NULL || *td->netbios_name == '\0') {
2030 0 : struct dom_sid_buf buf;
2031 0 : DEBUG(10, ("Missing netbios name for trusted domain %s.\n",
2032 : dom_sid_str_buf(r->in.dom_sid, &buf)));
2033 0 : return NT_STATUS_UNSUCCESSFUL;
2034 : }
2035 :
2036 0 : status = pdb_del_trusted_domain(td->netbios_name);
2037 0 : if (!NT_STATUS_IS_OK(status)) {
2038 0 : return status;
2039 : }
2040 :
2041 0 : return NT_STATUS_OK;
2042 : }
2043 :
2044 : /***************************************************************************
2045 : _lsa_CloseTrustedDomainEx
2046 : ***************************************************************************/
2047 :
2048 0 : NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
2049 : struct lsa_CloseTrustedDomainEx *r)
2050 : {
2051 0 : return NT_STATUS_NOT_IMPLEMENTED;
2052 : }
2053 :
2054 : /***************************************************************************
2055 : _lsa_QueryTrustedDomainInfo
2056 : ***************************************************************************/
2057 :
2058 0 : static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
2059 : struct pdb_trusted_domain *td,
2060 : struct lsa_TrustDomainInfoInfoEx *info_ex)
2061 : {
2062 0 : if (td->domain_name == NULL ||
2063 0 : td->netbios_name == NULL ||
2064 0 : is_null_sid(&td->security_identifier)) {
2065 0 : return NT_STATUS_INVALID_PARAMETER;
2066 : }
2067 :
2068 0 : info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
2069 0 : info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
2070 0 : info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
2071 0 : if (info_ex->domain_name.string == NULL ||
2072 0 : info_ex->netbios_name.string == NULL ||
2073 0 : info_ex->sid == NULL) {
2074 0 : return NT_STATUS_NO_MEMORY;
2075 : }
2076 :
2077 0 : info_ex->trust_direction = td->trust_direction;
2078 0 : info_ex->trust_type = td->trust_type;
2079 0 : info_ex->trust_attributes = td->trust_attributes;
2080 :
2081 0 : return NT_STATUS_OK;
2082 : }
2083 :
2084 0 : NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
2085 : struct lsa_QueryTrustedDomainInfo *r)
2086 : {
2087 0 : NTSTATUS status;
2088 0 : struct lsa_info *handle;
2089 0 : union lsa_TrustedDomainInfo *info;
2090 0 : struct pdb_trusted_domain *td;
2091 0 : uint32_t acc_required;
2092 :
2093 : /* find the connection policy handle. */
2094 0 : handle = find_policy_by_hnd(p,
2095 : r->in.trustdom_handle,
2096 : LSA_HANDLE_TRUST_TYPE,
2097 : struct lsa_info,
2098 0 : &status);
2099 0 : if (!NT_STATUS_IS_OK(status)) {
2100 0 : return NT_STATUS_INVALID_HANDLE;
2101 : }
2102 :
2103 0 : switch (r->in.level) {
2104 0 : case LSA_TRUSTED_DOMAIN_INFO_NAME:
2105 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2106 0 : break;
2107 0 : case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2108 0 : acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
2109 0 : break;
2110 0 : case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2111 0 : acc_required = LSA_TRUSTED_QUERY_POSIX;
2112 0 : break;
2113 0 : case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2114 0 : acc_required = LSA_TRUSTED_QUERY_AUTH;
2115 0 : break;
2116 0 : case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2117 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2118 0 : break;
2119 0 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2120 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2121 0 : break;
2122 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2123 0 : acc_required = LSA_TRUSTED_QUERY_AUTH;
2124 0 : break;
2125 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2126 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2127 : LSA_TRUSTED_QUERY_POSIX |
2128 : LSA_TRUSTED_QUERY_AUTH;
2129 0 : break;
2130 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2131 0 : acc_required = LSA_TRUSTED_QUERY_AUTH;
2132 0 : break;
2133 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2134 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2135 : LSA_TRUSTED_QUERY_POSIX |
2136 : LSA_TRUSTED_QUERY_AUTH;
2137 0 : break;
2138 0 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2139 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
2140 0 : break;
2141 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2142 0 : acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
2143 : LSA_TRUSTED_QUERY_POSIX |
2144 : LSA_TRUSTED_QUERY_AUTH;
2145 0 : break;
2146 0 : case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2147 0 : acc_required = LSA_TRUSTED_QUERY_POSIX;
2148 0 : break;
2149 0 : default:
2150 0 : return NT_STATUS_INVALID_PARAMETER;
2151 : }
2152 :
2153 0 : if (!(handle->access & acc_required)) {
2154 0 : return NT_STATUS_ACCESS_DENIED;
2155 : }
2156 :
2157 0 : status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
2158 0 : if (!NT_STATUS_IS_OK(status)) {
2159 0 : return status;
2160 : }
2161 :
2162 0 : info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
2163 0 : if (!info) {
2164 0 : return NT_STATUS_NO_MEMORY;
2165 : }
2166 :
2167 0 : switch (r->in.level) {
2168 0 : case LSA_TRUSTED_DOMAIN_INFO_NAME:
2169 0 : init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
2170 0 : break;
2171 0 : case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2172 0 : return NT_STATUS_INVALID_PARAMETER;
2173 0 : case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2174 0 : info->posix_offset.posix_offset = *td->trust_posix_offset;
2175 0 : break;
2176 0 : case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
2177 0 : return NT_STATUS_INVALID_INFO_CLASS;
2178 0 : case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2179 0 : return NT_STATUS_INVALID_PARAMETER;
2180 0 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2181 0 : status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
2182 0 : if (!NT_STATUS_IS_OK(status)) {
2183 0 : return status;
2184 : }
2185 0 : break;
2186 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
2187 0 : return NT_STATUS_INVALID_INFO_CLASS;
2188 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2189 0 : status = pdb_trusted_domain_2_info_ex(info, td,
2190 : &info->full_info.info_ex);
2191 0 : if (!NT_STATUS_IS_OK(status)) {
2192 0 : return status;
2193 : }
2194 0 : info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
2195 0 : status = auth_blob_2_auth_info(p->mem_ctx,
2196 0 : td->trust_auth_incoming,
2197 0 : td->trust_auth_outgoing,
2198 : &info->full_info.auth_info);
2199 0 : if (!NT_STATUS_IS_OK(status)) {
2200 0 : return status;
2201 : }
2202 0 : break;
2203 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
2204 0 : return NT_STATUS_INVALID_INFO_CLASS;
2205 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
2206 0 : return NT_STATUS_INVALID_INFO_CLASS;
2207 0 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2208 0 : return NT_STATUS_INVALID_PARAMETER;
2209 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2210 0 : info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
2211 0 : status = auth_blob_2_auth_info(p->mem_ctx,
2212 0 : td->trust_auth_incoming,
2213 0 : td->trust_auth_outgoing,
2214 : &info->full_info2_internal.auth_info);
2215 0 : if (!NT_STATUS_IS_OK(status)) {
2216 0 : return status;
2217 : }
2218 0 : break;
2219 0 : case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2220 0 : info->enc_types.enc_types = *td->supported_enc_type;
2221 0 : break;
2222 0 : default:
2223 0 : return NT_STATUS_INVALID_PARAMETER;
2224 : }
2225 :
2226 0 : *r->out.info = info;
2227 :
2228 0 : return NT_STATUS_OK;
2229 : }
2230 :
2231 : /***************************************************************************
2232 : _lsa_QueryTrustedDomainInfoBySid
2233 : ***************************************************************************/
2234 :
2235 0 : NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
2236 : struct lsa_QueryTrustedDomainInfoBySid *r)
2237 : {
2238 0 : NTSTATUS status;
2239 0 : struct policy_handle trustdom_handle;
2240 0 : struct lsa_OpenTrustedDomain o;
2241 0 : struct lsa_QueryTrustedDomainInfo q;
2242 0 : struct lsa_Close c;
2243 :
2244 0 : o.in.handle = r->in.handle;
2245 0 : o.in.sid = r->in.dom_sid;
2246 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2247 0 : o.out.trustdom_handle = &trustdom_handle;
2248 :
2249 0 : status = _lsa_OpenTrustedDomain(p, &o);
2250 0 : if (!NT_STATUS_IS_OK(status)) {
2251 0 : return status;
2252 : }
2253 :
2254 0 : q.in.trustdom_handle = &trustdom_handle;
2255 0 : q.in.level = r->in.level;
2256 0 : q.out.info = r->out.info;
2257 :
2258 0 : status = _lsa_QueryTrustedDomainInfo(p, &q);
2259 0 : if (!NT_STATUS_IS_OK(status)) {
2260 0 : return status;
2261 : }
2262 :
2263 0 : c.in.handle = &trustdom_handle;
2264 0 : c.out.handle = &trustdom_handle;
2265 :
2266 0 : return _lsa_Close(p, &c);
2267 : }
2268 :
2269 : /***************************************************************************
2270 : _lsa_QueryTrustedDomainInfoByName
2271 : ***************************************************************************/
2272 :
2273 0 : NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
2274 : struct lsa_QueryTrustedDomainInfoByName *r)
2275 : {
2276 0 : NTSTATUS status;
2277 0 : struct policy_handle trustdom_handle;
2278 0 : struct lsa_OpenTrustedDomainByName o;
2279 0 : struct lsa_QueryTrustedDomainInfo q;
2280 0 : struct lsa_Close c;
2281 :
2282 0 : o.in.handle = r->in.handle;
2283 0 : o.in.name.string = r->in.trusted_domain->string;
2284 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2285 0 : o.out.trustdom_handle = &trustdom_handle;
2286 :
2287 0 : status = _lsa_OpenTrustedDomainByName(p, &o);
2288 0 : if (!NT_STATUS_IS_OK(status)) {
2289 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
2290 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2291 : }
2292 0 : return status;
2293 : }
2294 :
2295 0 : q.in.trustdom_handle = &trustdom_handle;
2296 0 : q.in.level = r->in.level;
2297 0 : q.out.info = r->out.info;
2298 :
2299 0 : status = _lsa_QueryTrustedDomainInfo(p, &q);
2300 0 : if (!NT_STATUS_IS_OK(status)) {
2301 0 : return status;
2302 : }
2303 :
2304 0 : c.in.handle = &trustdom_handle;
2305 0 : c.out.handle = &trustdom_handle;
2306 :
2307 0 : return _lsa_Close(p, &c);
2308 : }
2309 :
2310 : /***************************************************************************
2311 : _lsa_CreateSecret
2312 : ***************************************************************************/
2313 :
2314 632 : NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
2315 : struct lsa_CreateSecret *r)
2316 : {
2317 632 : struct dcesrv_call_state *dce_call = p->dce_call;
2318 0 : struct auth_session_info *session_info =
2319 632 : dcesrv_call_session_info(dce_call);
2320 0 : NTSTATUS status;
2321 0 : struct lsa_info *handle;
2322 0 : uint32_t acc_granted;
2323 0 : struct security_descriptor *psd;
2324 0 : size_t sd_size;
2325 :
2326 : /* find the connection policy handle. */
2327 632 : handle = find_policy_by_hnd(p,
2328 : r->in.handle,
2329 : LSA_HANDLE_POLICY_TYPE,
2330 : struct lsa_info,
2331 0 : &status);
2332 632 : if (!NT_STATUS_IS_OK(status)) {
2333 0 : return NT_STATUS_INVALID_HANDLE;
2334 : }
2335 :
2336 : /* check if the user has enough rights */
2337 :
2338 632 : if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
2339 0 : return NT_STATUS_ACCESS_DENIED;
2340 : }
2341 :
2342 : /* Work out max allowed. */
2343 632 : map_max_allowed_access(session_info->security_token,
2344 632 : session_info->unix_token,
2345 : &r->in.access_mask);
2346 :
2347 : /* map the generic bits to the lsa policy ones */
2348 632 : se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
2349 :
2350 632 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2351 : &lsa_secret_mapping,
2352 : NULL, 0);
2353 632 : if (!NT_STATUS_IS_OK(status)) {
2354 0 : return status;
2355 : }
2356 :
2357 632 : status = access_check_object(psd, session_info->security_token,
2358 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
2359 : r->in.access_mask,
2360 : &acc_granted, "_lsa_CreateSecret");
2361 632 : if (!NT_STATUS_IS_OK(status)) {
2362 0 : return status;
2363 : }
2364 :
2365 632 : if (!r->in.name.string) {
2366 0 : return NT_STATUS_INVALID_PARAMETER;
2367 : }
2368 :
2369 632 : if (strlen(r->in.name.string) > 128) {
2370 0 : return NT_STATUS_NAME_TOO_LONG;
2371 : }
2372 :
2373 632 : status = pdb_get_secret(p->mem_ctx, r->in.name.string,
2374 : NULL, NULL, NULL, NULL, NULL);
2375 632 : if (NT_STATUS_IS_OK(status)) {
2376 4 : return NT_STATUS_OBJECT_NAME_COLLISION;
2377 : }
2378 :
2379 628 : status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
2380 628 : if (!NT_STATUS_IS_OK(status)) {
2381 0 : return status;
2382 : }
2383 :
2384 628 : status = create_lsa_policy_handle(p->mem_ctx, p,
2385 : LSA_HANDLE_SECRET_TYPE,
2386 : acc_granted,
2387 : NULL,
2388 : r->in.name.string,
2389 : psd,
2390 : r->out.sec_handle);
2391 628 : if (!NT_STATUS_IS_OK(status)) {
2392 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2393 : }
2394 :
2395 628 : return NT_STATUS_OK;
2396 : }
2397 :
2398 : /***************************************************************************
2399 : _lsa_SetSecret
2400 : ***************************************************************************/
2401 :
2402 848 : NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
2403 : struct lsa_SetSecret *r)
2404 : {
2405 848 : struct dcesrv_call_state *dce_call = p->dce_call;
2406 0 : struct auth_session_info *session_info =
2407 848 : dcesrv_call_session_info(dce_call);
2408 0 : NTSTATUS status;
2409 848 : struct lsa_info *info = NULL;
2410 0 : DATA_BLOB blob_new, blob_old;
2411 848 : DATA_BLOB cleartext_blob_new = data_blob_null;
2412 848 : DATA_BLOB cleartext_blob_old = data_blob_null;
2413 848 : DATA_BLOB *cleartext_blob_new_p = NULL;
2414 848 : DATA_BLOB *cleartext_blob_old_p = NULL;
2415 0 : DATA_BLOB session_key;
2416 :
2417 848 : info = find_policy_by_hnd(p,
2418 : r->in.sec_handle,
2419 : LSA_HANDLE_SECRET_TYPE,
2420 : struct lsa_info,
2421 0 : &status);
2422 848 : if (!NT_STATUS_IS_OK(status)) {
2423 0 : return NT_STATUS_INVALID_HANDLE;
2424 : }
2425 :
2426 848 : if (!(info->access & LSA_SECRET_SET_VALUE)) {
2427 0 : return NT_STATUS_ACCESS_DENIED;
2428 : }
2429 :
2430 848 : status = session_extract_session_key(
2431 : session_info, &session_key, KEY_USE_16BYTES);
2432 848 : if(!NT_STATUS_IS_OK(status)) {
2433 0 : return status;
2434 : }
2435 :
2436 848 : if (r->in.new_val) {
2437 844 : blob_new = data_blob_const(r->in.new_val->data,
2438 844 : r->in.new_val->length);
2439 :
2440 844 : status = sess_decrypt_blob(p->mem_ctx, &blob_new,
2441 : &session_key,
2442 : &cleartext_blob_new);
2443 844 : if (!NT_STATUS_IS_OK(status)) {
2444 420 : return status;
2445 : }
2446 :
2447 424 : cleartext_blob_new_p = &cleartext_blob_new;
2448 : }
2449 :
2450 428 : if (r->in.old_val) {
2451 4 : blob_old = data_blob_const(r->in.old_val->data,
2452 4 : r->in.old_val->length);
2453 :
2454 4 : status = sess_decrypt_blob(p->mem_ctx, &blob_old,
2455 : &session_key,
2456 : &cleartext_blob_old);
2457 4 : if (!NT_STATUS_IS_OK(status)) {
2458 0 : return status;
2459 : }
2460 :
2461 4 : cleartext_blob_old_p = &cleartext_blob_old;
2462 : }
2463 :
2464 428 : status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
2465 428 : if (!NT_STATUS_IS_OK(status)) {
2466 0 : return status;
2467 : }
2468 :
2469 : #ifdef DEBUG_PASSWORD
2470 428 : DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
2471 428 : dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
2472 428 : DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
2473 428 : dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
2474 : #endif
2475 :
2476 428 : return NT_STATUS_OK;
2477 : }
2478 :
2479 : /***************************************************************************
2480 : _lsa_QuerySecret
2481 : ***************************************************************************/
2482 :
2483 428 : NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
2484 : struct lsa_QuerySecret *r)
2485 : {
2486 428 : struct dcesrv_call_state *dce_call = p->dce_call;
2487 0 : struct auth_session_info *session_info =
2488 428 : dcesrv_call_session_info(dce_call);
2489 428 : struct lsa_info *info = NULL;
2490 0 : DATA_BLOB blob_new, blob_old;
2491 0 : DATA_BLOB blob_new_crypt, blob_old_crypt;
2492 0 : DATA_BLOB session_key;
2493 0 : NTTIME nttime_new, nttime_old;
2494 0 : NTSTATUS status;
2495 :
2496 428 : info = find_policy_by_hnd(p,
2497 : r->in.sec_handle,
2498 : LSA_HANDLE_SECRET_TYPE,
2499 : struct lsa_info,
2500 0 : &status);
2501 428 : if (!NT_STATUS_IS_OK(status)) {
2502 0 : return NT_STATUS_INVALID_HANDLE;
2503 : }
2504 :
2505 428 : if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
2506 0 : return NT_STATUS_ACCESS_DENIED;
2507 : }
2508 :
2509 428 : status = pdb_get_secret(p->mem_ctx, info->name,
2510 : &blob_new, &nttime_new,
2511 : &blob_old, &nttime_old,
2512 : NULL);
2513 428 : if (!NT_STATUS_IS_OK(status)) {
2514 0 : return status;
2515 : }
2516 :
2517 428 : status = session_extract_session_key(
2518 : session_info, &session_key, KEY_USE_16BYTES);
2519 428 : if(!NT_STATUS_IS_OK(status)) {
2520 0 : return status;
2521 : }
2522 :
2523 428 : if (r->in.new_val) {
2524 428 : if (blob_new.length) {
2525 424 : if (!r->out.new_val->buf) {
2526 424 : r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2527 : }
2528 424 : if (!r->out.new_val->buf) {
2529 0 : return NT_STATUS_NO_MEMORY;
2530 : }
2531 :
2532 424 : blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
2533 : &session_key);
2534 424 : if (!blob_new_crypt.length) {
2535 0 : return NT_STATUS_NO_MEMORY;
2536 : }
2537 :
2538 424 : r->out.new_val->buf->data = blob_new_crypt.data;
2539 424 : r->out.new_val->buf->length = blob_new_crypt.length;
2540 424 : r->out.new_val->buf->size = blob_new_crypt.length;
2541 : }
2542 : }
2543 :
2544 428 : if (r->in.old_val) {
2545 8 : if (blob_old.length) {
2546 8 : if (!r->out.old_val->buf) {
2547 8 : r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
2548 : }
2549 8 : if (!r->out.old_val->buf) {
2550 0 : return NT_STATUS_NO_MEMORY;
2551 : }
2552 :
2553 8 : blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
2554 : &session_key);
2555 8 : if (!blob_old_crypt.length) {
2556 0 : return NT_STATUS_NO_MEMORY;
2557 : }
2558 :
2559 8 : r->out.old_val->buf->data = blob_old_crypt.data;
2560 8 : r->out.old_val->buf->length = blob_old_crypt.length;
2561 8 : r->out.old_val->buf->size = blob_old_crypt.length;
2562 : }
2563 : }
2564 :
2565 428 : if (r->out.new_mtime) {
2566 428 : *r->out.new_mtime = nttime_new;
2567 : }
2568 :
2569 428 : if (r->out.old_mtime) {
2570 8 : *r->out.old_mtime = nttime_old;
2571 : }
2572 :
2573 428 : return NT_STATUS_OK;
2574 : }
2575 :
2576 : /***************************************************************************
2577 : _lsa_DeleteObject
2578 : ***************************************************************************/
2579 :
2580 636 : NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
2581 : struct lsa_DeleteObject *r)
2582 : {
2583 0 : NTSTATUS status;
2584 636 : struct lsa_info *info = NULL;
2585 :
2586 636 : info = find_policy_by_hnd(p,
2587 : r->in.handle,
2588 : DCESRV_HANDLE_ANY,
2589 : struct lsa_info,
2590 0 : &status);
2591 636 : if (!NT_STATUS_IS_OK(status)) {
2592 0 : return NT_STATUS_INVALID_HANDLE;
2593 : }
2594 :
2595 636 : if (!(info->access & SEC_STD_DELETE)) {
2596 0 : return NT_STATUS_ACCESS_DENIED;
2597 : }
2598 :
2599 636 : switch (info->type) {
2600 4 : case LSA_HANDLE_ACCOUNT_TYPE:
2601 4 : status = privilege_delete_account(&info->sid);
2602 4 : if (!NT_STATUS_IS_OK(status)) {
2603 0 : DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
2604 : nt_errstr(status)));
2605 4 : return status;
2606 : }
2607 4 : break;
2608 0 : case LSA_HANDLE_TRUST_TYPE:
2609 0 : if (!pdb_del_trusteddom_pw(info->name)) {
2610 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2611 : }
2612 0 : status = NT_STATUS_OK;
2613 0 : break;
2614 632 : case LSA_HANDLE_SECRET_TYPE:
2615 632 : status = pdb_delete_secret(info->name);
2616 632 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2617 4 : return NT_STATUS_INVALID_HANDLE;
2618 : }
2619 628 : break;
2620 0 : default:
2621 0 : return NT_STATUS_INVALID_HANDLE;
2622 : }
2623 :
2624 632 : close_policy_hnd(p, r->in.handle);
2625 632 : ZERO_STRUCTP(r->out.handle);
2626 :
2627 632 : return status;
2628 : }
2629 :
2630 : /***************************************************************************
2631 : _lsa_EnumPrivs
2632 : ***************************************************************************/
2633 :
2634 2 : NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
2635 : struct lsa_EnumPrivs *r)
2636 : {
2637 0 : struct lsa_info *handle;
2638 0 : uint32_t i;
2639 2 : uint32_t enum_context = *r->in.resume_handle;
2640 2 : int num_privs = num_privileges_in_short_list();
2641 2 : struct lsa_PrivEntry *entries = NULL;
2642 0 : NTSTATUS status;
2643 :
2644 : /* remember that the enum_context starts at 0 and not 1 */
2645 :
2646 2 : if ( enum_context >= num_privs )
2647 0 : return NT_STATUS_NO_MORE_ENTRIES;
2648 :
2649 2 : DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
2650 : enum_context, num_privs));
2651 :
2652 2 : handle = find_policy_by_hnd(p,
2653 : r->in.handle,
2654 : LSA_HANDLE_POLICY_TYPE,
2655 : struct lsa_info,
2656 0 : &status);
2657 2 : if (!NT_STATUS_IS_OK(status)) {
2658 0 : return NT_STATUS_INVALID_HANDLE;
2659 : }
2660 :
2661 : /* check if the user has enough rights
2662 : I don't know if it's the right one. not documented. */
2663 :
2664 2 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2665 0 : return NT_STATUS_ACCESS_DENIED;
2666 :
2667 2 : if (num_privs) {
2668 2 : entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
2669 2 : if (!entries) {
2670 0 : return NT_STATUS_NO_MEMORY;
2671 : }
2672 : } else {
2673 0 : entries = NULL;
2674 : }
2675 :
2676 20 : for (i = 0; i < num_privs; i++) {
2677 18 : if( i < enum_context) {
2678 :
2679 0 : init_lsa_StringLarge(&entries[i].name, NULL);
2680 :
2681 0 : entries[i].luid.low = 0;
2682 0 : entries[i].luid.high = 0;
2683 : } else {
2684 :
2685 18 : init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
2686 :
2687 18 : entries[i].luid.low = sec_privilege_from_index(i);
2688 18 : entries[i].luid.high = 0;
2689 : }
2690 : }
2691 :
2692 2 : enum_context = num_privs;
2693 :
2694 2 : *r->out.resume_handle = enum_context;
2695 2 : r->out.privs->count = num_privs;
2696 2 : r->out.privs->privs = entries;
2697 :
2698 2 : return NT_STATUS_OK;
2699 : }
2700 :
2701 : /***************************************************************************
2702 : _lsa_LookupPrivDisplayName
2703 : ***************************************************************************/
2704 :
2705 18 : NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
2706 : struct lsa_LookupPrivDisplayName *r)
2707 : {
2708 0 : struct lsa_info *handle;
2709 0 : const char *description;
2710 0 : struct lsa_StringLarge *lsa_name;
2711 0 : NTSTATUS status;
2712 :
2713 18 : handle = find_policy_by_hnd(p,
2714 : r->in.handle,
2715 : LSA_HANDLE_POLICY_TYPE,
2716 : struct lsa_info,
2717 0 : &status);
2718 18 : if (!NT_STATUS_IS_OK(status)) {
2719 0 : return NT_STATUS_INVALID_HANDLE;
2720 : }
2721 :
2722 : /* check if the user has enough rights */
2723 :
2724 : /*
2725 : * I don't know if it's the right one. not documented.
2726 : */
2727 18 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2728 0 : return NT_STATUS_ACCESS_DENIED;
2729 :
2730 18 : DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
2731 :
2732 18 : description = get_privilege_dispname(r->in.name->string);
2733 18 : if (!description) {
2734 0 : DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
2735 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
2736 : }
2737 :
2738 18 : DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
2739 :
2740 18 : lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
2741 18 : if (!lsa_name) {
2742 0 : return NT_STATUS_NO_MEMORY;
2743 : }
2744 :
2745 18 : init_lsa_StringLarge(lsa_name, description);
2746 :
2747 18 : *r->out.returned_language_id = r->in.language_id;
2748 18 : *r->out.disp_name = lsa_name;
2749 :
2750 18 : return NT_STATUS_OK;
2751 : }
2752 :
2753 : /***************************************************************************
2754 : _lsa_EnumAccounts
2755 : ***************************************************************************/
2756 :
2757 10 : NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
2758 : struct lsa_EnumAccounts *r)
2759 : {
2760 0 : struct lsa_info *handle;
2761 0 : struct dom_sid *sid_list;
2762 0 : int i, j, num_entries;
2763 0 : NTSTATUS status;
2764 10 : struct lsa_SidPtr *sids = NULL;
2765 :
2766 10 : handle = find_policy_by_hnd(p,
2767 : r->in.handle,
2768 : LSA_HANDLE_POLICY_TYPE,
2769 : struct lsa_info,
2770 0 : &status);
2771 10 : if (!NT_STATUS_IS_OK(status)) {
2772 0 : return NT_STATUS_INVALID_HANDLE;
2773 : }
2774 :
2775 10 : if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
2776 0 : return NT_STATUS_ACCESS_DENIED;
2777 :
2778 10 : sid_list = NULL;
2779 10 : num_entries = 0;
2780 :
2781 : /* The only way we can currently find out all the SIDs that have been
2782 : privileged is to scan all privileges */
2783 :
2784 10 : status = privilege_enumerate_accounts(&sid_list, &num_entries);
2785 10 : if (!NT_STATUS_IS_OK(status)) {
2786 0 : return status;
2787 : }
2788 :
2789 10 : if (*r->in.resume_handle >= num_entries) {
2790 2 : return NT_STATUS_NO_MORE_ENTRIES;
2791 : }
2792 :
2793 8 : if (num_entries - *r->in.resume_handle) {
2794 8 : sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
2795 : num_entries - *r->in.resume_handle);
2796 8 : if (!sids) {
2797 0 : talloc_free(sid_list);
2798 0 : return NT_STATUS_NO_MEMORY;
2799 : }
2800 :
2801 60 : for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
2802 52 : sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
2803 52 : if (!sids[j].sid) {
2804 0 : talloc_free(sid_list);
2805 0 : return NT_STATUS_NO_MEMORY;
2806 : }
2807 : }
2808 : }
2809 :
2810 8 : talloc_free(sid_list);
2811 :
2812 8 : *r->out.resume_handle = num_entries;
2813 8 : r->out.sids->num_sids = num_entries;
2814 8 : r->out.sids->sids = sids;
2815 :
2816 8 : return NT_STATUS_OK;
2817 : }
2818 :
2819 : /***************************************************************************
2820 : _lsa_GetUserName
2821 : ***************************************************************************/
2822 :
2823 394 : NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
2824 : struct lsa_GetUserName *r)
2825 : {
2826 394 : struct dcesrv_call_state *dce_call = p->dce_call;
2827 0 : struct auth_session_info *session_info =
2828 394 : dcesrv_call_session_info(dce_call);
2829 0 : const char *username, *domname;
2830 394 : struct lsa_String *account_name = NULL;
2831 394 : struct lsa_String *authority_name = NULL;
2832 :
2833 394 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
2834 0 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
2835 0 : return NT_STATUS_ACCESS_DENIED;
2836 : }
2837 :
2838 394 : if (r->in.account_name &&
2839 394 : *r->in.account_name) {
2840 0 : return NT_STATUS_INVALID_PARAMETER;
2841 : }
2842 :
2843 394 : if (r->in.authority_name &&
2844 384 : *r->in.authority_name) {
2845 0 : return NT_STATUS_INVALID_PARAMETER;
2846 : }
2847 :
2848 394 : if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
2849 : /*
2850 : * I'm 99% sure this is not the right place to do this,
2851 : * global_sid_Anonymous should probably be put into the token
2852 : * instead of the guest id -- vl
2853 : */
2854 142 : if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
2855 : &domname, &username, NULL)) {
2856 0 : return NT_STATUS_NO_MEMORY;
2857 : }
2858 : } else {
2859 252 : username = session_info->unix_info->sanitized_username;
2860 252 : domname = session_info->info->domain_name;
2861 : }
2862 :
2863 394 : account_name = talloc(p->mem_ctx, struct lsa_String);
2864 394 : if (!account_name) {
2865 0 : return NT_STATUS_NO_MEMORY;
2866 : }
2867 394 : init_lsa_String(account_name, username);
2868 :
2869 394 : if (r->out.authority_name) {
2870 384 : authority_name = talloc(p->mem_ctx, struct lsa_String);
2871 384 : if (!authority_name) {
2872 0 : return NT_STATUS_NO_MEMORY;
2873 : }
2874 384 : init_lsa_String(authority_name, domname);
2875 : }
2876 :
2877 394 : *r->out.account_name = account_name;
2878 394 : if (r->out.authority_name) {
2879 384 : *r->out.authority_name = authority_name;
2880 : }
2881 :
2882 394 : return NT_STATUS_OK;
2883 : }
2884 :
2885 : /***************************************************************************
2886 : _lsa_CreateAccount
2887 : ***************************************************************************/
2888 :
2889 2 : NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
2890 : struct lsa_CreateAccount *r)
2891 : {
2892 2 : struct dcesrv_call_state *dce_call = p->dce_call;
2893 0 : struct auth_session_info *session_info =
2894 2 : dcesrv_call_session_info(dce_call);
2895 0 : NTSTATUS status;
2896 0 : struct lsa_info *handle;
2897 0 : uint32_t acc_granted;
2898 0 : struct security_descriptor *psd;
2899 0 : size_t sd_size;
2900 2 : uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2901 : ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2902 : LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2903 : SEC_STD_DELETE));
2904 :
2905 : /* find the connection policy handle. */
2906 2 : handle = find_policy_by_hnd(p,
2907 : r->in.handle,
2908 : LSA_HANDLE_POLICY_TYPE,
2909 : struct lsa_info,
2910 0 : &status);
2911 2 : if (!NT_STATUS_IS_OK(status)) {
2912 0 : return NT_STATUS_INVALID_HANDLE;
2913 : }
2914 :
2915 : /* check if the user has enough rights */
2916 :
2917 2 : if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
2918 0 : return NT_STATUS_ACCESS_DENIED;
2919 : }
2920 :
2921 : /* Work out max allowed. */
2922 2 : map_max_allowed_access(session_info->security_token,
2923 2 : session_info->unix_token,
2924 : &r->in.access_mask);
2925 :
2926 : /* map the generic bits to the lsa policy ones */
2927 2 : se_map_generic(&r->in.access_mask, &lsa_account_mapping);
2928 :
2929 2 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
2930 : &lsa_account_mapping,
2931 : r->in.sid, owner_access);
2932 2 : if (!NT_STATUS_IS_OK(status)) {
2933 0 : return status;
2934 : }
2935 :
2936 2 : status = access_check_object(psd, session_info->security_token,
2937 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
2938 : &acc_granted, "_lsa_CreateAccount");
2939 2 : if (!NT_STATUS_IS_OK(status)) {
2940 0 : return status;
2941 : }
2942 :
2943 2 : if ( is_privileged_sid( r->in.sid ) )
2944 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
2945 :
2946 2 : status = create_lsa_policy_handle(p->mem_ctx, p,
2947 : LSA_HANDLE_ACCOUNT_TYPE,
2948 : acc_granted,
2949 : r->in.sid,
2950 : NULL,
2951 : psd,
2952 : r->out.acct_handle);
2953 2 : if (!NT_STATUS_IS_OK(status)) {
2954 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2955 : }
2956 :
2957 2 : return privilege_create_account(r->in.sid);
2958 : }
2959 :
2960 : /***************************************************************************
2961 : _lsa_OpenAccount
2962 : ***************************************************************************/
2963 :
2964 16 : NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
2965 : struct lsa_OpenAccount *r)
2966 : {
2967 16 : struct dcesrv_call_state *dce_call = p->dce_call;
2968 0 : struct auth_session_info *session_info =
2969 16 : dcesrv_call_session_info(dce_call);
2970 16 : struct security_descriptor *psd = NULL;
2971 0 : size_t sd_size;
2972 16 : uint32_t des_access = r->in.access_mask;
2973 0 : uint32_t acc_granted;
2974 16 : uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
2975 : ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
2976 : LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
2977 : SEC_STD_DELETE));
2978 0 : NTSTATUS status;
2979 :
2980 : /* find the connection policy handle. */
2981 16 : (void)find_policy_by_hnd(p,
2982 : r->in.handle,
2983 : LSA_HANDLE_POLICY_TYPE,
2984 : struct lsa_info,
2985 0 : &status);
2986 16 : if (!NT_STATUS_IS_OK(status)) {
2987 0 : return NT_STATUS_INVALID_HANDLE;
2988 : }
2989 :
2990 : /* des_access is for the account here, not the policy
2991 : * handle - so don't check against policy handle. */
2992 :
2993 : /* Work out max allowed. */
2994 16 : map_max_allowed_access(session_info->security_token,
2995 16 : session_info->unix_token,
2996 : &des_access);
2997 :
2998 : /* map the generic bits to the lsa account ones */
2999 16 : se_map_generic(&des_access, &lsa_account_mapping);
3000 :
3001 : /* get the generic lsa account SD until we store it */
3002 16 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3003 : &lsa_account_mapping,
3004 : r->in.sid, owner_access);
3005 16 : if (!NT_STATUS_IS_OK(status)) {
3006 0 : return status;
3007 : }
3008 :
3009 16 : status = access_check_object(psd, session_info->security_token,
3010 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
3011 : &acc_granted, "_lsa_OpenAccount" );
3012 16 : if (!NT_STATUS_IS_OK(status)) {
3013 0 : return status;
3014 : }
3015 :
3016 : /* TODO: Fis the parsing routine before reenabling this check! */
3017 : #if 0
3018 : if (!lookup_sid(&handle->sid, dom_name, name, &type))
3019 : return NT_STATUS_ACCESS_DENIED;
3020 : #endif
3021 :
3022 16 : status = create_lsa_policy_handle(p->mem_ctx, p,
3023 : LSA_HANDLE_ACCOUNT_TYPE,
3024 : acc_granted,
3025 : r->in.sid,
3026 : NULL,
3027 : psd,
3028 : r->out.acct_handle);
3029 16 : if (!NT_STATUS_IS_OK(status)) {
3030 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3031 : }
3032 :
3033 16 : return NT_STATUS_OK;
3034 : }
3035 :
3036 : /***************************************************************************
3037 : _lsa_EnumPrivsAccount
3038 : For a given SID, enumerate all the privilege this account has.
3039 : ***************************************************************************/
3040 :
3041 28 : NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
3042 : struct lsa_EnumPrivsAccount *r)
3043 : {
3044 28 : NTSTATUS status = NT_STATUS_OK;
3045 28 : struct lsa_info *info=NULL;
3046 0 : PRIVILEGE_SET *privileges;
3047 28 : struct lsa_PrivilegeSet *priv_set = NULL;
3048 0 : struct dom_sid_buf buf;
3049 :
3050 : /* find the connection policy handle. */
3051 28 : info = find_policy_by_hnd(p,
3052 : r->in.handle,
3053 : LSA_HANDLE_ACCOUNT_TYPE,
3054 : struct lsa_info,
3055 0 : &status);
3056 28 : if (!NT_STATUS_IS_OK(status)) {
3057 0 : return NT_STATUS_INVALID_HANDLE;
3058 : }
3059 :
3060 28 : if (!(info->access & LSA_ACCOUNT_VIEW))
3061 0 : return NT_STATUS_ACCESS_DENIED;
3062 :
3063 28 : status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
3064 28 : if (!NT_STATUS_IS_OK(status)) {
3065 0 : return status;
3066 : }
3067 :
3068 28 : *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
3069 28 : if (!priv_set) {
3070 0 : return NT_STATUS_NO_MEMORY;
3071 : }
3072 :
3073 28 : DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
3074 : dom_sid_str_buf(&info->sid, &buf),
3075 : privileges->count));
3076 :
3077 28 : priv_set->count = privileges->count;
3078 28 : priv_set->unknown = 0;
3079 28 : priv_set->set = talloc_move(priv_set, &privileges->set);
3080 :
3081 28 : return status;
3082 : }
3083 :
3084 : /***************************************************************************
3085 : _lsa_GetSystemAccessAccount
3086 : ***************************************************************************/
3087 :
3088 16 : NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
3089 : struct lsa_GetSystemAccessAccount *r)
3090 : {
3091 0 : NTSTATUS status;
3092 16 : struct lsa_info *info = NULL;
3093 0 : struct lsa_EnumPrivsAccount e;
3094 0 : struct lsa_PrivilegeSet *privset;
3095 :
3096 : /* find the connection policy handle. */
3097 :
3098 16 : info = find_policy_by_hnd(p,
3099 : r->in.handle,
3100 : LSA_HANDLE_ACCOUNT_TYPE,
3101 : struct lsa_info,
3102 0 : &status);
3103 16 : if (!NT_STATUS_IS_OK(status)) {
3104 0 : return NT_STATUS_INVALID_HANDLE;
3105 : }
3106 :
3107 16 : if (!(info->access & LSA_ACCOUNT_VIEW))
3108 0 : return NT_STATUS_ACCESS_DENIED;
3109 :
3110 16 : privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
3111 16 : if (!privset) {
3112 0 : return NT_STATUS_NO_MEMORY;
3113 : }
3114 :
3115 16 : e.in.handle = r->in.handle;
3116 16 : e.out.privs = &privset;
3117 :
3118 16 : status = _lsa_EnumPrivsAccount(p, &e);
3119 16 : if (!NT_STATUS_IS_OK(status)) {
3120 0 : DEBUG(10,("_lsa_GetSystemAccessAccount: "
3121 : "failed to call _lsa_EnumPrivsAccount(): %s\n",
3122 : nt_errstr(status)));
3123 0 : return status;
3124 : }
3125 :
3126 : /* Samba4 would iterate over the privset to merge the policy mode bits,
3127 : * not sure samba3 can do the same here, so just return what we did in
3128 : * the past - gd */
3129 :
3130 : /*
3131 : 0x01 -> Log on locally
3132 : 0x02 -> Access this computer from network
3133 : 0x04 -> Log on as a batch job
3134 : 0x10 -> Log on as a service
3135 :
3136 : they can be ORed together
3137 : */
3138 :
3139 16 : *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
3140 : LSA_POLICY_MODE_NETWORK;
3141 :
3142 16 : return NT_STATUS_OK;
3143 : }
3144 :
3145 : /***************************************************************************
3146 : update the systemaccount information
3147 : ***************************************************************************/
3148 :
3149 0 : NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
3150 : struct lsa_SetSystemAccessAccount *r)
3151 : {
3152 0 : struct lsa_info *info=NULL;
3153 0 : NTSTATUS status;
3154 0 : GROUP_MAP *map;
3155 :
3156 : /* find the connection policy handle. */
3157 0 : info = find_policy_by_hnd(p,
3158 : r->in.handle,
3159 : LSA_HANDLE_ACCOUNT_TYPE,
3160 : struct lsa_info,
3161 0 : &status);
3162 0 : if (!NT_STATUS_IS_OK(status)) {
3163 0 : return NT_STATUS_INVALID_HANDLE;
3164 : }
3165 :
3166 0 : if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
3167 0 : return NT_STATUS_ACCESS_DENIED;
3168 : }
3169 :
3170 0 : map = talloc_zero(p->mem_ctx, GROUP_MAP);
3171 0 : if (!map) {
3172 0 : return NT_STATUS_NO_MEMORY;
3173 : }
3174 :
3175 0 : if (!pdb_getgrsid(map, info->sid)) {
3176 0 : TALLOC_FREE(map);
3177 0 : return NT_STATUS_NO_SUCH_GROUP;
3178 : }
3179 :
3180 0 : status = pdb_update_group_mapping_entry(map);
3181 0 : TALLOC_FREE(map);
3182 0 : return status;
3183 : }
3184 :
3185 : /***************************************************************************
3186 : _lsa_AddPrivilegesToAccount
3187 : For a given SID, add some privileges.
3188 : ***************************************************************************/
3189 :
3190 2 : NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
3191 : struct lsa_AddPrivilegesToAccount *r)
3192 : {
3193 2 : struct lsa_info *info = NULL;
3194 2 : struct lsa_PrivilegeSet *set = NULL;
3195 0 : NTSTATUS status;
3196 :
3197 : /* find the connection policy handle. */
3198 2 : info = find_policy_by_hnd(p,
3199 : r->in.handle,
3200 : LSA_HANDLE_ACCOUNT_TYPE,
3201 : struct lsa_info,
3202 0 : &status);
3203 2 : if (!NT_STATUS_IS_OK(status)) {
3204 0 : return NT_STATUS_INVALID_HANDLE;
3205 : }
3206 :
3207 2 : if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3208 0 : return NT_STATUS_ACCESS_DENIED;
3209 : }
3210 :
3211 2 : set = r->in.privs;
3212 :
3213 2 : if ( !grant_privilege_set( &info->sid, set ) ) {
3214 0 : struct dom_sid_buf buf;
3215 0 : DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
3216 : dom_sid_str_buf(&info->sid, &buf)));
3217 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3218 : }
3219 :
3220 2 : return NT_STATUS_OK;
3221 : }
3222 :
3223 : /***************************************************************************
3224 : _lsa_RemovePrivilegesFromAccount
3225 : For a given SID, remove some privileges.
3226 : ***************************************************************************/
3227 :
3228 2 : NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
3229 : struct lsa_RemovePrivilegesFromAccount *r)
3230 : {
3231 2 : struct lsa_info *info = NULL;
3232 2 : struct lsa_PrivilegeSet *set = NULL;
3233 0 : NTSTATUS status;
3234 :
3235 : /* find the connection policy handle. */
3236 2 : info = find_policy_by_hnd(p,
3237 : r->in.handle,
3238 : LSA_HANDLE_ACCOUNT_TYPE,
3239 : struct lsa_info,
3240 0 : &status);
3241 2 : if (!NT_STATUS_IS_OK(status)) {
3242 0 : return NT_STATUS_INVALID_HANDLE;
3243 : }
3244 :
3245 2 : if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
3246 0 : return NT_STATUS_ACCESS_DENIED;
3247 : }
3248 :
3249 2 : set = r->in.privs;
3250 :
3251 2 : if ( !revoke_privilege_set( &info->sid, set) ) {
3252 0 : struct dom_sid_buf buf;
3253 0 : DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
3254 : dom_sid_str_buf(&info->sid, &buf)));
3255 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3256 : }
3257 :
3258 2 : return NT_STATUS_OK;
3259 : }
3260 :
3261 : /***************************************************************************
3262 : _lsa_LookupPrivName
3263 : ***************************************************************************/
3264 :
3265 50 : NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
3266 : struct lsa_LookupPrivName *r)
3267 : {
3268 50 : struct lsa_info *info = NULL;
3269 0 : const char *name;
3270 0 : struct lsa_StringLarge *lsa_name;
3271 0 : NTSTATUS status;
3272 :
3273 : /* find the connection policy handle. */
3274 50 : info = find_policy_by_hnd(p,
3275 : r->in.handle,
3276 : LSA_HANDLE_POLICY_TYPE,
3277 : struct lsa_info,
3278 0 : &status);
3279 50 : if (!NT_STATUS_IS_OK(status)) {
3280 0 : return NT_STATUS_INVALID_HANDLE;
3281 : }
3282 :
3283 50 : if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
3284 0 : return NT_STATUS_ACCESS_DENIED;
3285 : }
3286 :
3287 50 : if (r->in.luid->high != 0) {
3288 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3289 : }
3290 :
3291 50 : name = sec_privilege_name(r->in.luid->low);
3292 50 : if (!name) {
3293 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3294 : }
3295 :
3296 50 : lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
3297 50 : if (!lsa_name) {
3298 0 : return NT_STATUS_NO_MEMORY;
3299 : }
3300 :
3301 50 : lsa_name->string = talloc_strdup(lsa_name, name);
3302 50 : if (!lsa_name->string) {
3303 0 : TALLOC_FREE(lsa_name);
3304 0 : return NT_STATUS_NO_MEMORY;
3305 : }
3306 :
3307 50 : *r->out.name = lsa_name;
3308 :
3309 50 : return NT_STATUS_OK;
3310 : }
3311 :
3312 : /***************************************************************************
3313 : _lsa_QuerySecurity
3314 : ***************************************************************************/
3315 :
3316 12 : NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
3317 : struct lsa_QuerySecurity *r)
3318 : {
3319 12 : struct lsa_info *handle=NULL;
3320 12 : struct security_descriptor *psd = NULL;
3321 12 : size_t sd_size = 0;
3322 0 : NTSTATUS status;
3323 :
3324 : /* find the connection policy handle. */
3325 12 : handle = find_policy_by_hnd(p,
3326 : r->in.handle,
3327 : DCESRV_HANDLE_ANY,
3328 : struct lsa_info,
3329 0 : &status);
3330 12 : if (!NT_STATUS_IS_OK(status)) {
3331 0 : return NT_STATUS_INVALID_HANDLE;
3332 : }
3333 :
3334 12 : switch (handle->type) {
3335 12 : case LSA_HANDLE_POLICY_TYPE:
3336 : case LSA_HANDLE_ACCOUNT_TYPE:
3337 : case LSA_HANDLE_TRUST_TYPE:
3338 : case LSA_HANDLE_SECRET_TYPE:
3339 12 : psd = handle->sd;
3340 12 : sd_size = ndr_size_security_descriptor(psd, 0);
3341 12 : status = NT_STATUS_OK;
3342 12 : break;
3343 0 : default:
3344 0 : status = NT_STATUS_INVALID_HANDLE;
3345 0 : break;
3346 : }
3347 :
3348 12 : if (!NT_STATUS_IS_OK(status)) {
3349 0 : return status;
3350 : }
3351 :
3352 12 : *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
3353 12 : if (!*r->out.sdbuf) {
3354 0 : return NT_STATUS_NO_MEMORY;
3355 : }
3356 :
3357 12 : return status;
3358 : }
3359 :
3360 : /***************************************************************************
3361 : _lsa_AddAccountRights
3362 : ***************************************************************************/
3363 :
3364 26 : NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
3365 : struct lsa_AddAccountRights *r)
3366 : {
3367 26 : struct dcesrv_call_state *dce_call = p->dce_call;
3368 0 : struct auth_session_info *session_info =
3369 26 : dcesrv_call_session_info(dce_call);
3370 26 : int i = 0;
3371 26 : uint32_t acc_granted = 0;
3372 26 : struct security_descriptor *psd = NULL;
3373 0 : size_t sd_size;
3374 0 : struct dom_sid sid;
3375 0 : NTSTATUS status;
3376 :
3377 : /* find the connection policy handle. */
3378 26 : (void)find_policy_by_hnd(p,
3379 : r->in.handle,
3380 : LSA_HANDLE_POLICY_TYPE,
3381 : struct lsa_info,
3382 0 : &status);
3383 26 : if (!NT_STATUS_IS_OK(status)) {
3384 0 : return NT_STATUS_INVALID_HANDLE;
3385 : }
3386 :
3387 : /* get the generic lsa account SD for this SID until we store it */
3388 26 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3389 : &lsa_account_mapping,
3390 : NULL, 0);
3391 26 : if (!NT_STATUS_IS_OK(status)) {
3392 0 : return status;
3393 : }
3394 :
3395 : /*
3396 : * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
3397 : * on the policy handle. If it does, ask for
3398 : * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3399 : * on the account sid. We don't check here so just use the latter. JRA.
3400 : */
3401 :
3402 26 : status = access_check_object(psd, session_info->security_token,
3403 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3404 : LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
3405 : &acc_granted, "_lsa_AddAccountRights" );
3406 26 : if (!NT_STATUS_IS_OK(status)) {
3407 0 : return status;
3408 : }
3409 :
3410 : /* according to an NT4 PDC, you can add privileges to SIDs even without
3411 : call_lsa_create_account() first. And you can use any arbitrary SID. */
3412 :
3413 26 : sid_copy( &sid, r->in.sid );
3414 :
3415 50 : for ( i=0; i < r->in.rights->count; i++ ) {
3416 :
3417 26 : const char *privname = r->in.rights->names[i].string;
3418 :
3419 : /* only try to add non-null strings */
3420 :
3421 26 : if ( !privname )
3422 0 : continue;
3423 :
3424 26 : if ( !grant_privilege_by_name( &sid, privname ) ) {
3425 2 : DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
3426 : privname ));
3427 2 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3428 : }
3429 : }
3430 :
3431 24 : return NT_STATUS_OK;
3432 : }
3433 :
3434 : /***************************************************************************
3435 : _lsa_RemoveAccountRights
3436 : ***************************************************************************/
3437 :
3438 20 : NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
3439 : struct lsa_RemoveAccountRights *r)
3440 : {
3441 20 : struct dcesrv_call_state *dce_call = p->dce_call;
3442 0 : struct auth_session_info *session_info =
3443 20 : dcesrv_call_session_info(dce_call);
3444 20 : int i = 0;
3445 20 : struct security_descriptor *psd = NULL;
3446 0 : size_t sd_size;
3447 0 : struct dom_sid sid;
3448 20 : const char *privname = NULL;
3449 20 : uint32_t acc_granted = 0;
3450 0 : NTSTATUS status;
3451 :
3452 : /* find the connection policy handle. */
3453 20 : (void)find_policy_by_hnd(p,
3454 : r->in.handle,
3455 : LSA_HANDLE_POLICY_TYPE,
3456 : struct lsa_info,
3457 0 : &status);
3458 20 : if (!NT_STATUS_IS_OK(status)) {
3459 0 : return NT_STATUS_INVALID_HANDLE;
3460 : }
3461 :
3462 : /* get the generic lsa account SD for this SID until we store it */
3463 20 : status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
3464 : &lsa_account_mapping,
3465 : NULL, 0);
3466 20 : if (!NT_STATUS_IS_OK(status)) {
3467 0 : return status;
3468 : }
3469 :
3470 : /*
3471 : * From the MS DOCs. We need
3472 : * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
3473 : * and DELETE on the account sid.
3474 : */
3475 :
3476 20 : status = access_check_object(psd, session_info->security_token,
3477 : SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
3478 : LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
3479 : LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
3480 : &acc_granted, "_lsa_RemoveAccountRights");
3481 20 : if (!NT_STATUS_IS_OK(status)) {
3482 0 : return status;
3483 : }
3484 :
3485 20 : sid_copy( &sid, r->in.sid );
3486 :
3487 20 : if ( r->in.remove_all ) {
3488 0 : if ( !revoke_all_privileges( &sid ) )
3489 0 : return NT_STATUS_ACCESS_DENIED;
3490 :
3491 0 : return NT_STATUS_OK;
3492 : }
3493 :
3494 40 : for ( i=0; i < r->in.rights->count; i++ ) {
3495 :
3496 20 : privname = r->in.rights->names[i].string;
3497 :
3498 : /* only try to add non-null strings */
3499 :
3500 20 : if ( !privname )
3501 0 : continue;
3502 :
3503 20 : if ( !revoke_privilege_by_name( &sid, privname ) ) {
3504 0 : DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
3505 : privname ));
3506 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3507 : }
3508 : }
3509 :
3510 20 : return NT_STATUS_OK;
3511 : }
3512 :
3513 : /*******************************************************************
3514 : ********************************************************************/
3515 :
3516 16 : static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
3517 : struct lsa_RightSet *r,
3518 : PRIVILEGE_SET *privileges)
3519 : {
3520 0 : uint32_t i;
3521 0 : const char *privname;
3522 16 : const char **privname_array = NULL;
3523 16 : size_t num_priv = 0;
3524 :
3525 70 : for (i=0; i<privileges->count; i++) {
3526 54 : if (privileges->set[i].luid.high) {
3527 0 : continue;
3528 : }
3529 54 : privname = sec_privilege_name(privileges->set[i].luid.low);
3530 54 : if (privname) {
3531 54 : if (!add_string_to_array(mem_ctx, privname,
3532 : &privname_array, &num_priv)) {
3533 0 : return NT_STATUS_NO_MEMORY;
3534 : }
3535 : }
3536 : }
3537 :
3538 16 : if (num_priv) {
3539 :
3540 6 : r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
3541 : num_priv);
3542 6 : if (!r->names) {
3543 0 : return NT_STATUS_NO_MEMORY;
3544 : }
3545 :
3546 60 : for (i=0; i<num_priv; i++) {
3547 54 : init_lsa_StringLarge(&r->names[i], privname_array[i]);
3548 : }
3549 :
3550 6 : r->count = num_priv;
3551 : }
3552 :
3553 16 : return NT_STATUS_OK;
3554 : }
3555 :
3556 : /***************************************************************************
3557 : _lsa_EnumAccountRights
3558 : ***************************************************************************/
3559 :
3560 116 : NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
3561 : struct lsa_EnumAccountRights *r)
3562 : {
3563 0 : NTSTATUS status;
3564 116 : struct lsa_info *info = NULL;
3565 0 : PRIVILEGE_SET *privileges;
3566 0 : struct dom_sid_buf buf;
3567 :
3568 : /* find the connection policy handle. */
3569 :
3570 116 : info = find_policy_by_hnd(p,
3571 : r->in.handle,
3572 : LSA_HANDLE_POLICY_TYPE,
3573 : struct lsa_info,
3574 0 : &status);
3575 116 : if (!NT_STATUS_IS_OK(status)) {
3576 0 : return NT_STATUS_INVALID_HANDLE;
3577 : }
3578 :
3579 116 : if (!(info->access & LSA_ACCOUNT_VIEW)) {
3580 0 : return NT_STATUS_ACCESS_DENIED;
3581 : }
3582 :
3583 : /* according to an NT4 PDC, you can add privileges to SIDs even without
3584 : call_lsa_create_account() first. And you can use any arbitrary SID. */
3585 :
3586 : /* according to MS-LSAD 3.1.4.5.10 it is required to return
3587 : * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
3588 : * the lsa database */
3589 :
3590 116 : status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
3591 116 : if (!NT_STATUS_IS_OK(status)) {
3592 100 : return status;
3593 : }
3594 :
3595 16 : DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
3596 : dom_sid_str_buf(r->in.sid, &buf),
3597 : privileges->count));
3598 :
3599 16 : status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
3600 :
3601 16 : return status;
3602 : }
3603 :
3604 : /***************************************************************************
3605 : _lsa_LookupPrivValue
3606 : ***************************************************************************/
3607 :
3608 20 : NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
3609 : struct lsa_LookupPrivValue *r)
3610 : {
3611 20 : struct lsa_info *info = NULL;
3612 20 : const char *name = NULL;
3613 0 : NTSTATUS status;
3614 :
3615 : /* find the connection policy handle. */
3616 :
3617 20 : info = find_policy_by_hnd(p,
3618 : r->in.handle,
3619 : LSA_HANDLE_POLICY_TYPE,
3620 : struct lsa_info,
3621 0 : &status);
3622 20 : if (!NT_STATUS_IS_OK(status)) {
3623 0 : return NT_STATUS_INVALID_HANDLE;
3624 : }
3625 :
3626 20 : if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
3627 0 : return NT_STATUS_ACCESS_DENIED;
3628 :
3629 20 : name = r->in.name->string;
3630 :
3631 20 : DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
3632 :
3633 20 : r->out.luid->low = sec_privilege_id(name);
3634 20 : r->out.luid->high = 0;
3635 20 : if (r->out.luid->low == SEC_PRIV_INVALID) {
3636 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3637 : }
3638 20 : return NT_STATUS_OK;
3639 : }
3640 :
3641 : /***************************************************************************
3642 : _lsa_EnumAccountsWithUserRight
3643 : ***************************************************************************/
3644 :
3645 18 : NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
3646 : struct lsa_EnumAccountsWithUserRight *r)
3647 : {
3648 0 : NTSTATUS status;
3649 18 : struct lsa_info *info = NULL;
3650 18 : struct dom_sid *sids = NULL;
3651 18 : int num_sids = 0;
3652 0 : uint32_t i;
3653 0 : enum sec_privilege privilege;
3654 :
3655 18 : info = find_policy_by_hnd(p,
3656 : r->in.handle,
3657 : LSA_HANDLE_POLICY_TYPE,
3658 : struct lsa_info,
3659 0 : &status);
3660 18 : if (!NT_STATUS_IS_OK(status)) {
3661 0 : return NT_STATUS_INVALID_HANDLE;
3662 : }
3663 :
3664 18 : if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
3665 0 : return NT_STATUS_ACCESS_DENIED;
3666 : }
3667 :
3668 18 : if (!r->in.name || !r->in.name->string) {
3669 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3670 : }
3671 :
3672 18 : privilege = sec_privilege_id(r->in.name->string);
3673 18 : if (privilege == SEC_PRIV_INVALID) {
3674 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3675 : }
3676 :
3677 18 : status = privilege_enum_sids(privilege, p->mem_ctx,
3678 : &sids, &num_sids);
3679 18 : if (!NT_STATUS_IS_OK(status)) {
3680 0 : return status;
3681 : }
3682 :
3683 18 : r->out.sids->num_sids = num_sids;
3684 18 : r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
3685 : r->out.sids->num_sids);
3686 :
3687 36 : for (i=0; i < r->out.sids->num_sids; i++) {
3688 36 : r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
3689 18 : &sids[i]);
3690 18 : if (!r->out.sids->sids[i].sid) {
3691 0 : TALLOC_FREE(r->out.sids->sids);
3692 0 : r->out.sids->num_sids = 0;
3693 0 : return NT_STATUS_NO_MEMORY;
3694 : }
3695 : }
3696 :
3697 18 : return NT_STATUS_OK;
3698 : }
3699 :
3700 : /***************************************************************************
3701 : _lsa_Delete
3702 : ***************************************************************************/
3703 :
3704 8 : NTSTATUS _lsa_Delete(struct pipes_struct *p,
3705 : struct lsa_Delete *r)
3706 : {
3707 8 : return NT_STATUS_NOT_SUPPORTED;
3708 : }
3709 :
3710 0 : static NTSTATUS info_ex_2_pdb_trusted_domain(
3711 : struct lsa_TrustDomainInfoInfoEx *info_ex,
3712 : struct pdb_trusted_domain *td)
3713 : {
3714 0 : if (info_ex->domain_name.string == NULL ||
3715 0 : info_ex->netbios_name.string == NULL ||
3716 0 : info_ex->sid == NULL) {
3717 0 : return NT_STATUS_INVALID_PARAMETER;
3718 : }
3719 :
3720 0 : td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
3721 0 : td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
3722 0 : sid_copy(&td->security_identifier, info_ex->sid);
3723 0 : if (td->domain_name == NULL ||
3724 0 : td->netbios_name == NULL ||
3725 0 : is_null_sid(&td->security_identifier)) {
3726 0 : return NT_STATUS_NO_MEMORY;
3727 : }
3728 0 : td->trust_direction = info_ex->trust_direction;
3729 0 : td->trust_type = info_ex->trust_type;
3730 0 : td->trust_attributes = info_ex->trust_attributes;
3731 :
3732 0 : return NT_STATUS_OK;
3733 : }
3734 :
3735 0 : static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
3736 : TALLOC_CTX *mem_ctx,
3737 : struct lsa_info *policy,
3738 : enum lsa_TrustDomInfoEnum level,
3739 : union lsa_TrustedDomainInfo *info)
3740 : {
3741 0 : struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
3742 0 : DATA_BLOB auth_blob;
3743 0 : struct trustDomainPasswords auth_struct;
3744 0 : NTSTATUS nt_status;
3745 :
3746 0 : struct pdb_trusted_domain *td;
3747 0 : struct pdb_trusted_domain *orig_td;
3748 :
3749 0 : td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
3750 0 : if (td == NULL) {
3751 0 : return NT_STATUS_NO_MEMORY;
3752 : }
3753 :
3754 0 : switch (level) {
3755 0 : case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
3756 0 : if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3757 0 : return NT_STATUS_ACCESS_DENIED;
3758 : }
3759 0 : td->trust_posix_offset = &info->posix_offset.posix_offset;
3760 0 : break;
3761 0 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
3762 0 : if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3763 0 : return NT_STATUS_ACCESS_DENIED;
3764 : }
3765 0 : nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
3766 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3767 0 : return nt_status;
3768 : }
3769 0 : break;
3770 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
3771 0 : if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3772 0 : return NT_STATUS_ACCESS_DENIED;
3773 : }
3774 0 : nt_status = auth_info_2_auth_blob(td, &info->auth_info,
3775 : &td->trust_auth_incoming,
3776 : &td->trust_auth_outgoing);
3777 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3778 0 : return nt_status;
3779 : }
3780 0 : break;
3781 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
3782 0 : if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3783 0 : return NT_STATUS_ACCESS_DENIED;
3784 : }
3785 0 : td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
3786 0 : nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
3787 : td);
3788 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3789 0 : return nt_status;
3790 : }
3791 0 : nt_status = auth_info_2_auth_blob(td,
3792 : &info->full_info.auth_info,
3793 : &td->trust_auth_incoming,
3794 : &td->trust_auth_outgoing);
3795 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3796 0 : return nt_status;
3797 : }
3798 0 : break;
3799 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
3800 0 : if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
3801 0 : return NT_STATUS_ACCESS_DENIED;
3802 : }
3803 0 : auth_info_int = &info->auth_info_internal;
3804 0 : break;
3805 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
3806 0 : if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
3807 0 : return NT_STATUS_ACCESS_DENIED;
3808 : }
3809 0 : td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
3810 0 : nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
3811 : td);
3812 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3813 0 : return nt_status;
3814 : }
3815 0 : auth_info_int = &info->full_info_internal.auth_info;
3816 0 : break;
3817 0 : case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
3818 0 : if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
3819 0 : return NT_STATUS_ACCESS_DENIED;
3820 : }
3821 0 : td->supported_enc_type = &info->enc_types.enc_types;
3822 0 : break;
3823 0 : default:
3824 0 : return NT_STATUS_INVALID_PARAMETER;
3825 : }
3826 :
3827 : /* decode auth_info_int if set */
3828 0 : if (auth_info_int) {
3829 :
3830 : /* now decrypt blob */
3831 0 : auth_blob = data_blob_const(auth_info_int->auth_blob.data,
3832 0 : auth_info_int->auth_blob.size);
3833 :
3834 0 : nt_status = get_trustdom_auth_blob(p, mem_ctx,
3835 : &auth_blob, &auth_struct);
3836 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3837 0 : return nt_status;
3838 : }
3839 : } else {
3840 0 : memset(&auth_struct, 0, sizeof(auth_struct));
3841 : }
3842 :
3843 : /* TODO: verify only one object matches the dns/netbios/sid triplet and that
3844 : * this is the one we already have */
3845 :
3846 : /* TODO: check if the trust direction is changed and we need to add or remove
3847 : * auth data */
3848 :
3849 : /* TODO: check if trust type shall be changed and return an error in this case
3850 : * */
3851 0 : nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
3852 : &orig_td);
3853 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3854 0 : return nt_status;
3855 : }
3856 :
3857 :
3858 : /* TODO: should we fetch previous values from the existing entry
3859 : * and append them ? */
3860 0 : if (auth_struct.incoming.count) {
3861 0 : nt_status = get_trustauth_inout_blob(mem_ctx,
3862 : &auth_struct.incoming,
3863 : &td->trust_auth_incoming);
3864 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3865 0 : return nt_status;
3866 : }
3867 : } else {
3868 0 : ZERO_STRUCT(td->trust_auth_incoming);
3869 : }
3870 :
3871 0 : if (auth_struct.outgoing.count) {
3872 0 : nt_status = get_trustauth_inout_blob(mem_ctx,
3873 : &auth_struct.outgoing,
3874 : &td->trust_auth_outgoing);
3875 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3876 0 : return nt_status;
3877 : }
3878 : } else {
3879 0 : ZERO_STRUCT(td->trust_auth_outgoing);
3880 : }
3881 :
3882 0 : nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
3883 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3884 0 : return nt_status;
3885 : }
3886 :
3887 0 : return NT_STATUS_OK;
3888 : }
3889 :
3890 0 : NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
3891 : struct lsa_SetTrustedDomainInfo *r)
3892 : {
3893 0 : NTSTATUS status;
3894 0 : struct policy_handle trustdom_handle;
3895 0 : struct lsa_OpenTrustedDomain o;
3896 0 : struct lsa_SetInformationTrustedDomain s;
3897 0 : struct lsa_Close c;
3898 :
3899 0 : o.in.handle = r->in.handle;
3900 0 : o.in.sid = r->in.dom_sid;
3901 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3902 0 : o.out.trustdom_handle = &trustdom_handle;
3903 :
3904 0 : status = _lsa_OpenTrustedDomain(p, &o);
3905 0 : if (!NT_STATUS_IS_OK(status)) {
3906 0 : return status;
3907 : }
3908 :
3909 0 : s.in.trustdom_handle = &trustdom_handle;
3910 0 : s.in.level = r->in.level;
3911 0 : s.in.info = r->in.info;
3912 :
3913 0 : status = _lsa_SetInformationTrustedDomain(p, &s);
3914 0 : if (!NT_STATUS_IS_OK(status)) {
3915 0 : return status;
3916 : }
3917 :
3918 0 : c.in.handle = &trustdom_handle;
3919 0 : c.out.handle = &trustdom_handle;
3920 :
3921 0 : return _lsa_Close(p, &c);
3922 : }
3923 :
3924 0 : NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
3925 : struct lsa_SetTrustedDomainInfoByName *r)
3926 : {
3927 0 : NTSTATUS status;
3928 0 : struct policy_handle trustdom_handle;
3929 0 : struct lsa_OpenTrustedDomainByName o;
3930 0 : struct lsa_SetInformationTrustedDomain s;
3931 0 : struct lsa_Close c;
3932 :
3933 0 : o.in.handle = r->in.handle;
3934 0 : o.in.name.string = r->in.trusted_domain->string;
3935 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3936 0 : o.out.trustdom_handle = &trustdom_handle;
3937 :
3938 0 : status = _lsa_OpenTrustedDomainByName(p, &o);
3939 0 : if (!NT_STATUS_IS_OK(status)) {
3940 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
3941 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3942 : }
3943 0 : return status;
3944 : }
3945 :
3946 0 : s.in.trustdom_handle = &trustdom_handle;
3947 0 : s.in.level = r->in.level;
3948 0 : s.in.info = r->in.info;
3949 :
3950 0 : status = _lsa_SetInformationTrustedDomain(p, &s);
3951 0 : if (!NT_STATUS_IS_OK(status)) {
3952 0 : return status;
3953 : }
3954 :
3955 0 : c.in.handle = &trustdom_handle;
3956 0 : c.out.handle = &trustdom_handle;
3957 :
3958 0 : return _lsa_Close(p, &c);
3959 : }
3960 :
3961 0 : NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
3962 : struct lsa_SetInformationTrustedDomain *r)
3963 : {
3964 0 : struct lsa_info *policy;
3965 0 : NTSTATUS status;
3966 :
3967 0 : policy = find_policy_by_hnd(p,
3968 : r->in.trustdom_handle,
3969 : LSA_HANDLE_TRUST_TYPE,
3970 : struct lsa_info,
3971 0 : &status);
3972 0 : if (!NT_STATUS_IS_OK(status)) {
3973 0 : return NT_STATUS_INVALID_HANDLE;
3974 : }
3975 :
3976 0 : return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
3977 : r->in.level, r->in.info);
3978 : }
3979 :
3980 :
3981 : /*
3982 : * From here on the server routines are just dummy ones to make smbd link with
3983 : * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
3984 : * pulling the server stubs across one by one.
3985 : */
3986 :
3987 0 : NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
3988 : {
3989 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3990 0 : return NT_STATUS_NOT_IMPLEMENTED;
3991 : }
3992 :
3993 0 : NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
3994 : struct lsa_ChangePassword *r)
3995 : {
3996 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
3997 0 : return NT_STATUS_NOT_IMPLEMENTED;
3998 : }
3999 :
4000 0 : NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
4001 : {
4002 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4003 0 : return NT_STATUS_NOT_IMPLEMENTED;
4004 : }
4005 :
4006 0 : NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
4007 : {
4008 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4009 0 : return NT_STATUS_NOT_IMPLEMENTED;
4010 : }
4011 :
4012 0 : NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
4013 : struct lsa_GetQuotasForAccount *r)
4014 : {
4015 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4016 0 : return NT_STATUS_NOT_IMPLEMENTED;
4017 : }
4018 :
4019 0 : NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
4020 : struct lsa_SetQuotasForAccount *r)
4021 : {
4022 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4023 0 : return NT_STATUS_NOT_IMPLEMENTED;
4024 : }
4025 :
4026 0 : NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
4027 : struct lsa_StorePrivateData *r)
4028 : {
4029 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4030 0 : return NT_STATUS_NOT_IMPLEMENTED;
4031 : }
4032 :
4033 0 : NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
4034 : struct lsa_RetrievePrivateData *r)
4035 : {
4036 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4037 0 : return NT_STATUS_NOT_IMPLEMENTED;
4038 : }
4039 :
4040 0 : NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
4041 : struct lsa_SetInfoPolicy2 *r)
4042 : {
4043 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4044 0 : return NT_STATUS_NOT_IMPLEMENTED;
4045 : }
4046 :
4047 0 : NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
4048 : struct lsa_EnumTrustedDomainsEx *r)
4049 : {
4050 0 : struct lsa_info *info;
4051 0 : uint32_t count;
4052 0 : struct pdb_trusted_domain **domains;
4053 0 : struct lsa_TrustDomainInfoInfoEx *entries;
4054 0 : int i;
4055 0 : NTSTATUS nt_status;
4056 :
4057 : /* bail out early if pdb backend is not capable of ex trusted domains,
4058 : * if we don't do that, the client might not call
4059 : * _lsa_EnumTrustedDomains() afterwards - gd */
4060 :
4061 0 : if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
4062 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4063 0 : return NT_STATUS_NOT_IMPLEMENTED;
4064 : }
4065 :
4066 0 : info = find_policy_by_hnd(p,
4067 : r->in.handle,
4068 : LSA_HANDLE_POLICY_TYPE,
4069 : struct lsa_info,
4070 0 : &nt_status);
4071 0 : if (!NT_STATUS_IS_OK(nt_status)) {
4072 0 : return NT_STATUS_INVALID_HANDLE;
4073 : }
4074 :
4075 : /* check if the user has enough rights */
4076 0 : if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
4077 0 : return NT_STATUS_ACCESS_DENIED;
4078 :
4079 0 : become_root();
4080 0 : nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
4081 0 : unbecome_root();
4082 :
4083 0 : if (!NT_STATUS_IS_OK(nt_status)) {
4084 0 : return nt_status;
4085 : }
4086 :
4087 0 : entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
4088 : count);
4089 0 : if (!entries) {
4090 0 : return NT_STATUS_NO_MEMORY;
4091 : }
4092 :
4093 0 : for (i=0; i<count; i++) {
4094 0 : init_lsa_StringLarge(&entries[i].domain_name,
4095 0 : domains[i]->domain_name);
4096 0 : init_lsa_StringLarge(&entries[i].netbios_name,
4097 0 : domains[i]->netbios_name);
4098 0 : entries[i].sid = &domains[i]->security_identifier;
4099 0 : entries[i].trust_direction = domains[i]->trust_direction;
4100 0 : entries[i].trust_type = domains[i]->trust_type;
4101 0 : entries[i].trust_attributes = domains[i]->trust_attributes;
4102 : }
4103 :
4104 0 : if (*r->in.resume_handle >= count) {
4105 0 : *r->out.resume_handle = -1;
4106 0 : TALLOC_FREE(entries);
4107 0 : return NT_STATUS_NO_MORE_ENTRIES;
4108 : }
4109 :
4110 : /* return the rest, limit by max_size. Note that we
4111 : use the w2k3 element size value of 60 */
4112 0 : r->out.domains->count = count - *r->in.resume_handle;
4113 0 : r->out.domains->count = MIN(r->out.domains->count,
4114 : (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
4115 :
4116 0 : r->out.domains->domains = entries + *r->in.resume_handle;
4117 :
4118 0 : if (r->out.domains->count < count - *r->in.resume_handle) {
4119 0 : *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
4120 0 : return STATUS_MORE_ENTRIES;
4121 : }
4122 :
4123 : /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
4124 : * always be larger than the previous input resume handle, in
4125 : * particular when hitting the last query it is vital to set the
4126 : * resume handle correctly to avoid infinite client loops, as
4127 : * seen e.g. with Windows XP SP3 when resume handle is 0 and
4128 : * status is NT_STATUS_OK - gd */
4129 :
4130 0 : *r->out.resume_handle = (uint32_t)-1;
4131 :
4132 0 : return NT_STATUS_OK;
4133 : }
4134 :
4135 0 : NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
4136 : struct lsa_QueryDomainInformationPolicy *r)
4137 : {
4138 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4139 0 : return NT_STATUS_NOT_IMPLEMENTED;
4140 : }
4141 :
4142 0 : NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
4143 : struct lsa_SetDomainInformationPolicy *r)
4144 : {
4145 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4146 0 : return NT_STATUS_NOT_IMPLEMENTED;
4147 : }
4148 :
4149 0 : NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
4150 : {
4151 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4152 0 : return NT_STATUS_NOT_IMPLEMENTED;
4153 : }
4154 :
4155 0 : NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
4156 : {
4157 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4158 0 : return NT_STATUS_NOT_IMPLEMENTED;
4159 : }
4160 :
4161 0 : NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
4162 : {
4163 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4164 0 : return NT_STATUS_NOT_IMPLEMENTED;
4165 : }
4166 :
4167 0 : NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
4168 : {
4169 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4170 0 : return NT_STATUS_NOT_IMPLEMENTED;
4171 : }
4172 :
4173 0 : NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
4174 : struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4175 : {
4176 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4177 0 : return NT_STATUS_NOT_IMPLEMENTED;
4178 : }
4179 :
4180 0 : NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
4181 : struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4182 : {
4183 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4184 0 : return NT_STATUS_NOT_IMPLEMENTED;
4185 : }
4186 :
4187 0 : NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
4188 : {
4189 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4190 0 : return NT_STATUS_NOT_IMPLEMENTED;
4191 : }
4192 :
4193 0 : NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
4194 : struct lsa_CREDRGETTARGETINFO *r)
4195 : {
4196 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4197 0 : return NT_STATUS_NOT_IMPLEMENTED;
4198 : }
4199 :
4200 0 : NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
4201 : struct lsa_CREDRPROFILELOADED *r)
4202 : {
4203 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4204 0 : return NT_STATUS_NOT_IMPLEMENTED;
4205 : }
4206 :
4207 0 : NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
4208 : struct lsa_CREDRGETSESSIONTYPES *r)
4209 : {
4210 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4211 0 : return NT_STATUS_NOT_IMPLEMENTED;
4212 : }
4213 :
4214 0 : NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
4215 : struct lsa_LSARREGISTERAUDITEVENT *r)
4216 : {
4217 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4218 0 : return NT_STATUS_NOT_IMPLEMENTED;
4219 : }
4220 :
4221 0 : NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
4222 : struct lsa_LSARGENAUDITEVENT *r)
4223 : {
4224 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4225 0 : return NT_STATUS_NOT_IMPLEMENTED;
4226 : }
4227 :
4228 0 : NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
4229 : struct lsa_LSARUNREGISTERAUDITEVENT *r)
4230 : {
4231 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4232 0 : return NT_STATUS_NOT_IMPLEMENTED;
4233 : }
4234 :
4235 0 : NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
4236 : struct lsa_lsaRQueryForestTrustInformation *r)
4237 : {
4238 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4239 0 : return NT_STATUS_NOT_IMPLEMENTED;
4240 : }
4241 :
4242 : #define DNS_CMP_MATCH 0
4243 : #define DNS_CMP_FIRST_IS_CHILD 1
4244 : #define DNS_CMP_SECOND_IS_CHILD 2
4245 : #define DNS_CMP_NO_MATCH 3
4246 :
4247 : /* this function assumes names are well formed DNS names.
4248 : * it doesn't validate them */
4249 0 : static int dns_cmp(const char *s1, size_t l1,
4250 : const char *s2, size_t l2)
4251 : {
4252 0 : const char *p1, *p2;
4253 0 : size_t t1, t2;
4254 0 : int cret;
4255 :
4256 0 : if (l1 == l2) {
4257 0 : if (strcasecmp_m(s1, s2) == 0) {
4258 0 : return DNS_CMP_MATCH;
4259 : }
4260 0 : return DNS_CMP_NO_MATCH;
4261 : }
4262 :
4263 0 : if (l1 > l2) {
4264 0 : p1 = s1;
4265 0 : p2 = s2;
4266 0 : t1 = l1;
4267 0 : t2 = l2;
4268 0 : cret = DNS_CMP_FIRST_IS_CHILD;
4269 : } else {
4270 0 : p1 = s2;
4271 0 : p2 = s1;
4272 0 : t1 = l2;
4273 0 : t2 = l1;
4274 0 : cret = DNS_CMP_SECOND_IS_CHILD;
4275 : }
4276 :
4277 0 : if (p1[t1 - t2 - 1] != '.') {
4278 0 : return DNS_CMP_NO_MATCH;
4279 : }
4280 :
4281 0 : if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
4282 0 : return cret;
4283 : }
4284 :
4285 0 : return DNS_CMP_NO_MATCH;
4286 : }
4287 :
4288 0 : static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
4289 : struct lsa_ForestTrustInformation *lfti,
4290 : struct ForestTrustInfo *fti)
4291 : {
4292 0 : struct lsa_ForestTrustRecord *lrec;
4293 0 : struct ForestTrustInfoRecord *rec;
4294 0 : struct lsa_StringLarge *tln;
4295 0 : struct lsa_ForestTrustDomainInfo *info;
4296 0 : uint32_t i;
4297 :
4298 0 : fti->version = 1;
4299 0 : fti->count = lfti->count;
4300 0 : fti->records = talloc_array(mem_ctx,
4301 : struct ForestTrustInfoRecordArmor,
4302 : fti->count);
4303 0 : if (!fti->records) {
4304 0 : return NT_STATUS_NO_MEMORY;
4305 : }
4306 0 : for (i = 0; i < fti->count; i++) {
4307 0 : lrec = lfti->entries[i];
4308 0 : rec = &fti->records[i].record;
4309 :
4310 0 : rec->flags = lrec->flags;
4311 0 : rec->timestamp = lrec->time;
4312 0 : rec->type = (enum ForestTrustInfoRecordType)lrec->type;
4313 :
4314 0 : switch (lrec->type) {
4315 0 : case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
4316 : case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4317 0 : tln = &lrec->forest_trust_data.top_level_name;
4318 0 : rec->data.name.string =
4319 0 : talloc_strdup(mem_ctx, tln->string);
4320 0 : if (!rec->data.name.string) {
4321 0 : return NT_STATUS_NO_MEMORY;
4322 : }
4323 0 : rec->data.name.size = strlen(rec->data.name.string);
4324 0 : break;
4325 0 : case LSA_FOREST_TRUST_DOMAIN_INFO:
4326 0 : info = &lrec->forest_trust_data.domain_info;
4327 0 : rec->data.info.sid = *info->domain_sid;
4328 0 : rec->data.info.dns_name.string =
4329 0 : talloc_strdup(mem_ctx,
4330 : info->dns_domain_name.string);
4331 0 : if (!rec->data.info.dns_name.string) {
4332 0 : return NT_STATUS_NO_MEMORY;
4333 : }
4334 0 : rec->data.info.dns_name.size =
4335 0 : strlen(rec->data.info.dns_name.string);
4336 0 : rec->data.info.netbios_name.string =
4337 0 : talloc_strdup(mem_ctx,
4338 : info->netbios_domain_name.string);
4339 0 : if (!rec->data.info.netbios_name.string) {
4340 0 : return NT_STATUS_NO_MEMORY;
4341 : }
4342 0 : rec->data.info.netbios_name.size =
4343 0 : strlen(rec->data.info.netbios_name.string);
4344 0 : break;
4345 0 : default:
4346 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
4347 : }
4348 : }
4349 :
4350 0 : return NT_STATUS_OK;
4351 : }
4352 :
4353 : static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4354 : uint32_t index, uint32_t collision_type,
4355 : uint32_t conflict_type, const char *tdo_name);
4356 :
4357 0 : static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
4358 : const char *tdo_name,
4359 : struct ForestTrustInfo *tdo_fti,
4360 : struct ForestTrustInfo *new_fti,
4361 : struct lsa_ForestTrustCollisionInfo *c_info)
4362 : {
4363 0 : struct ForestTrustInfoRecord *nrec;
4364 0 : struct ForestTrustInfoRecord *trec;
4365 0 : const char *dns_name;
4366 0 : const char *nb_name = NULL;
4367 0 : struct dom_sid *sid = NULL;
4368 0 : const char *tname = NULL;
4369 0 : size_t dns_len = 0;
4370 0 : size_t tlen = 0;
4371 0 : uint32_t new_fti_idx;
4372 0 : uint32_t i;
4373 : /* use always TDO type, until we understand when Xref can be used */
4374 0 : uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
4375 0 : bool tln_conflict;
4376 0 : bool sid_conflict;
4377 0 : bool nb_conflict;
4378 0 : bool exclusion;
4379 0 : bool ex_rule = false;
4380 0 : int ret;
4381 :
4382 0 : for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
4383 :
4384 0 : nrec = &new_fti->records[new_fti_idx].record;
4385 0 : dns_name = NULL;
4386 0 : tln_conflict = false;
4387 0 : sid_conflict = false;
4388 0 : nb_conflict = false;
4389 0 : exclusion = false;
4390 :
4391 0 : switch (nrec->type) {
4392 0 : case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
4393 : /* exclusions do not conflict by definition */
4394 0 : break;
4395 :
4396 0 : case FOREST_TRUST_TOP_LEVEL_NAME:
4397 0 : dns_name = nrec->data.name.string;
4398 0 : dns_len = nrec->data.name.size;
4399 0 : break;
4400 :
4401 0 : case LSA_FOREST_TRUST_DOMAIN_INFO:
4402 0 : dns_name = nrec->data.info.dns_name.string;
4403 0 : dns_len = nrec->data.info.dns_name.size;
4404 0 : nb_name = nrec->data.info.netbios_name.string;
4405 0 : sid = &nrec->data.info.sid;
4406 0 : break;
4407 : }
4408 :
4409 0 : if (!dns_name) continue;
4410 :
4411 : /* check if this is already taken and not excluded */
4412 0 : for (i = 0; i < tdo_fti->count; i++) {
4413 0 : trec = &tdo_fti->records[i].record;
4414 :
4415 0 : switch (trec->type) {
4416 0 : case FOREST_TRUST_TOP_LEVEL_NAME:
4417 0 : ex_rule = false;
4418 0 : tname = trec->data.name.string;
4419 0 : tlen = trec->data.name.size;
4420 0 : break;
4421 0 : case FOREST_TRUST_TOP_LEVEL_NAME_EX:
4422 0 : ex_rule = true;
4423 0 : tname = trec->data.name.string;
4424 0 : tlen = trec->data.name.size;
4425 0 : break;
4426 0 : case FOREST_TRUST_DOMAIN_INFO:
4427 0 : ex_rule = false;
4428 0 : tname = trec->data.info.dns_name.string;
4429 0 : tlen = trec->data.info.dns_name.size;
4430 0 : break;
4431 0 : default:
4432 0 : return NT_STATUS_INVALID_PARAMETER;
4433 : }
4434 0 : ret = dns_cmp(dns_name, dns_len, tname, tlen);
4435 0 : switch (ret) {
4436 0 : case DNS_CMP_MATCH:
4437 : /* if it matches exclusion,
4438 : * it doesn't conflict */
4439 0 : if (ex_rule) {
4440 0 : exclusion = true;
4441 0 : break;
4442 : }
4443 :
4444 0 : FALL_THROUGH;
4445 : case DNS_CMP_FIRST_IS_CHILD:
4446 : case DNS_CMP_SECOND_IS_CHILD:
4447 0 : tln_conflict = true;
4448 :
4449 : FALL_THROUGH;
4450 0 : default:
4451 0 : break;
4452 : }
4453 :
4454 : /* explicit exclusion, no dns name conflict here */
4455 0 : if (exclusion) {
4456 0 : tln_conflict = false;
4457 : }
4458 :
4459 0 : if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
4460 0 : continue;
4461 : }
4462 :
4463 : /* also test for domain info */
4464 0 : if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
4465 0 : dom_sid_compare(&trec->data.info.sid, sid) == 0) {
4466 0 : sid_conflict = true;
4467 : }
4468 0 : if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
4469 0 : strcasecmp_m(trec->data.info.netbios_name.string,
4470 : nb_name) == 0) {
4471 0 : nb_conflict = true;
4472 : }
4473 : }
4474 :
4475 0 : if (tln_conflict) {
4476 0 : (void)add_collision(c_info, new_fti_idx,
4477 : collision_type,
4478 : LSA_TLN_DISABLED_CONFLICT,
4479 : tdo_name);
4480 : }
4481 0 : if (sid_conflict) {
4482 0 : (void)add_collision(c_info, new_fti_idx,
4483 : collision_type,
4484 : LSA_SID_DISABLED_CONFLICT,
4485 : tdo_name);
4486 : }
4487 0 : if (nb_conflict) {
4488 0 : (void)add_collision(c_info, new_fti_idx,
4489 : collision_type,
4490 : LSA_NB_DISABLED_CONFLICT,
4491 : tdo_name);
4492 : }
4493 : }
4494 :
4495 0 : return NT_STATUS_OK;
4496 : }
4497 :
4498 0 : static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
4499 : uint32_t idx, uint32_t collision_type,
4500 : uint32_t conflict_type, const char *tdo_name)
4501 : {
4502 0 : struct lsa_ForestTrustCollisionRecord **es;
4503 0 : uint32_t i = c_info->count;
4504 :
4505 0 : es = talloc_realloc(c_info, c_info->entries,
4506 : struct lsa_ForestTrustCollisionRecord *, i + 1);
4507 0 : if (!es) {
4508 0 : return NT_STATUS_NO_MEMORY;
4509 : }
4510 0 : c_info->entries = es;
4511 0 : c_info->count = i + 1;
4512 :
4513 0 : es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
4514 0 : if (!es[i]) {
4515 0 : return NT_STATUS_NO_MEMORY;
4516 : }
4517 :
4518 0 : es[i]->index = idx;
4519 0 : es[i]->type = collision_type;
4520 0 : es[i]->flags = conflict_type;
4521 0 : es[i]->name.string = talloc_strdup(es[i], tdo_name);
4522 0 : if (!es[i]->name.string) {
4523 0 : return NT_STATUS_NO_MEMORY;
4524 : }
4525 0 : es[i]->name.size = strlen(es[i]->name.string);
4526 :
4527 0 : return NT_STATUS_OK;
4528 : }
4529 :
4530 0 : static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
4531 : struct pdb_trusted_domain *td,
4532 : struct ForestTrustInfo *info)
4533 : {
4534 0 : enum ndr_err_code ndr_err;
4535 :
4536 0 : if (td->trust_forest_trust_info.length == 0 ||
4537 0 : td->trust_forest_trust_info.data == NULL) {
4538 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4539 : }
4540 0 : ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
4541 : info,
4542 : (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
4543 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4544 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
4545 : }
4546 :
4547 0 : return NT_STATUS_OK;
4548 : }
4549 :
4550 0 : static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
4551 : struct ForestTrustInfo *fti)
4552 : {
4553 0 : struct ForestTrustDataDomainInfo *info;
4554 0 : struct ForestTrustInfoRecord *rec;
4555 :
4556 0 : fti->version = 1;
4557 0 : fti->count = 2;
4558 0 : fti->records = talloc_array(fti,
4559 : struct ForestTrustInfoRecordArmor, 2);
4560 0 : if (!fti->records) {
4561 0 : return NT_STATUS_NO_MEMORY;
4562 : }
4563 :
4564 : /* TLN info */
4565 0 : rec = &fti->records[0].record;
4566 :
4567 0 : rec->flags = 0;
4568 0 : rec->timestamp = 0;
4569 0 : rec->type = FOREST_TRUST_TOP_LEVEL_NAME;
4570 :
4571 0 : rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
4572 0 : if (!rec->data.name.string) {
4573 0 : return NT_STATUS_NO_MEMORY;
4574 : }
4575 0 : rec->data.name.size = strlen(rec->data.name.string);
4576 :
4577 : /* DOMAIN info */
4578 0 : rec = &fti->records[1].record;
4579 :
4580 0 : rec->flags = 0;
4581 0 : rec->timestamp = 0;
4582 0 : rec->type = FOREST_TRUST_DOMAIN_INFO;
4583 :
4584 0 : info = &rec->data.info;
4585 :
4586 0 : info->sid = dom_info->sid;
4587 0 : info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
4588 0 : if (!info->dns_name.string) {
4589 0 : return NT_STATUS_NO_MEMORY;
4590 : }
4591 0 : info->dns_name.size = strlen(info->dns_name.string);
4592 0 : info->netbios_name.string = talloc_strdup(fti, dom_info->name);
4593 0 : if (!info->netbios_name.string) {
4594 0 : return NT_STATUS_NO_MEMORY;
4595 : }
4596 0 : info->netbios_name.size = strlen(info->netbios_name.string);
4597 :
4598 0 : return NT_STATUS_OK;
4599 : }
4600 :
4601 0 : NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
4602 : struct lsa_lsaRSetForestTrustInformation *r)
4603 : {
4604 0 : NTSTATUS status;
4605 0 : int i;
4606 0 : int j;
4607 0 : struct lsa_info *handle;
4608 0 : uint32_t num_domains;
4609 0 : struct pdb_trusted_domain **domains;
4610 0 : struct ForestTrustInfo *nfti;
4611 0 : struct ForestTrustInfo *fti;
4612 0 : struct lsa_ForestTrustCollisionInfo *c_info;
4613 0 : struct pdb_domain_info *dom_info;
4614 0 : enum ndr_err_code ndr_err;
4615 :
4616 0 : if (!IS_DC) {
4617 0 : return NT_STATUS_NOT_SUPPORTED;
4618 : }
4619 :
4620 0 : handle = find_policy_by_hnd(p,
4621 : r->in.handle,
4622 : LSA_HANDLE_TRUST_TYPE,
4623 : struct lsa_info,
4624 0 : &status);
4625 0 : if (!NT_STATUS_IS_OK(status)) {
4626 0 : return NT_STATUS_INVALID_HANDLE;
4627 : }
4628 :
4629 0 : if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
4630 0 : return NT_STATUS_ACCESS_DENIED;
4631 : }
4632 :
4633 0 : status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
4634 0 : if (!NT_STATUS_IS_OK(status)) {
4635 0 : return status;
4636 : }
4637 0 : if (num_domains == 0) {
4638 0 : return NT_STATUS_NO_SUCH_DOMAIN;
4639 : }
4640 :
4641 0 : for (i = 0; i < num_domains; i++) {
4642 0 : if (domains[i]->domain_name == NULL) {
4643 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
4644 : }
4645 0 : if (strcasecmp_m(domains[i]->domain_name,
4646 0 : r->in.trusted_domain_name->string) == 0) {
4647 0 : break;
4648 : }
4649 : }
4650 0 : if (i >= num_domains) {
4651 0 : return NT_STATUS_NO_SUCH_DOMAIN;
4652 : }
4653 :
4654 0 : if (!(domains[i]->trust_attributes &
4655 : LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4656 0 : return NT_STATUS_INVALID_PARAMETER;
4657 : }
4658 :
4659 0 : if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4660 0 : return NT_STATUS_INVALID_PARAMETER;
4661 : }
4662 :
4663 : /* The following section until COPY_END is a copy from
4664 : * source4/rpmc_server/lsa/scesrc_lsa.c */
4665 0 : nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
4666 0 : if (!nfti) {
4667 0 : return NT_STATUS_NO_MEMORY;
4668 : }
4669 :
4670 0 : status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
4671 0 : if (!NT_STATUS_IS_OK(status)) {
4672 0 : return status;
4673 : }
4674 :
4675 0 : c_info = talloc_zero(r->out.collision_info,
4676 : struct lsa_ForestTrustCollisionInfo);
4677 0 : if (!c_info) {
4678 0 : return NT_STATUS_NO_MEMORY;
4679 : }
4680 :
4681 : /* first check own info, then other domains */
4682 0 : fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4683 0 : if (!fti) {
4684 0 : return NT_STATUS_NO_MEMORY;
4685 : }
4686 :
4687 0 : dom_info = pdb_get_domain_info(p->mem_ctx);
4688 :
4689 0 : status = own_ft_info(dom_info, fti);
4690 0 : if (!NT_STATUS_IS_OK(status)) {
4691 0 : return status;
4692 : }
4693 :
4694 0 : status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
4695 0 : if (!NT_STATUS_IS_OK(status)) {
4696 0 : return status;
4697 : }
4698 :
4699 0 : for (j = 0; j < num_domains; j++) {
4700 0 : fti = talloc(p->mem_ctx, struct ForestTrustInfo);
4701 0 : if (!fti) {
4702 0 : return NT_STATUS_NO_MEMORY;
4703 : }
4704 :
4705 0 : status = get_ft_info(p->mem_ctx, domains[j], fti);
4706 0 : if (!NT_STATUS_IS_OK(status)) {
4707 0 : if (NT_STATUS_EQUAL(status,
4708 : NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4709 0 : continue;
4710 : }
4711 0 : return status;
4712 : }
4713 :
4714 0 : if (domains[j]->domain_name == NULL) {
4715 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
4716 : }
4717 :
4718 0 : status = check_ft_info(c_info, domains[j]->domain_name,
4719 : fti, nfti, c_info);
4720 0 : if (!NT_STATUS_IS_OK(status)) {
4721 0 : return status;
4722 : }
4723 : }
4724 :
4725 0 : if (c_info->count != 0) {
4726 0 : *r->out.collision_info = c_info;
4727 : }
4728 :
4729 0 : if (r->in.check_only != 0) {
4730 0 : return NT_STATUS_OK;
4731 : }
4732 :
4733 : /* COPY_END */
4734 :
4735 0 : ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
4736 : p->mem_ctx, nfti,
4737 : (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4738 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4739 0 : return NT_STATUS_INVALID_PARAMETER;
4740 : }
4741 :
4742 0 : status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
4743 0 : if (!NT_STATUS_IS_OK(status)) {
4744 0 : return status;
4745 : }
4746 :
4747 0 : return NT_STATUS_OK;
4748 : }
4749 :
4750 0 : NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
4751 : struct lsa_CREDRRENAME *r)
4752 : {
4753 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4754 0 : return NT_STATUS_NOT_IMPLEMENTED;
4755 : }
4756 :
4757 0 : NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
4758 : struct lsa_LSAROPENPOLICYSCE *r)
4759 : {
4760 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4761 0 : return NT_STATUS_NOT_IMPLEMENTED;
4762 : }
4763 :
4764 0 : NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4765 : struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4766 : {
4767 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4768 0 : return NT_STATUS_NOT_IMPLEMENTED;
4769 : }
4770 :
4771 0 : NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
4772 : struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4773 : {
4774 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4775 0 : return NT_STATUS_NOT_IMPLEMENTED;
4776 : }
4777 :
4778 0 : NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
4779 : struct lsa_LSARADTREPORTSECURITYEVENT *r)
4780 : {
4781 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4782 0 : return NT_STATUS_NOT_IMPLEMENTED;
4783 : }
4784 :
4785 0 : void _lsa_Opnum82NotUsedOnWire(struct pipes_struct *p,
4786 : struct lsa_Opnum82NotUsedOnWire *r)
4787 : {
4788 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4789 0 : }
4790 :
4791 0 : void _lsa_Opnum83NotUsedOnWire(struct pipes_struct *p,
4792 : struct lsa_Opnum83NotUsedOnWire *r)
4793 : {
4794 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4795 0 : }
4796 :
4797 0 : void _lsa_Opnum84NotUsedOnWire(struct pipes_struct *p,
4798 : struct lsa_Opnum84NotUsedOnWire *r)
4799 : {
4800 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4801 0 : }
4802 :
4803 0 : void _lsa_Opnum85NotUsedOnWire(struct pipes_struct *p,
4804 : struct lsa_Opnum85NotUsedOnWire *r)
4805 : {
4806 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4807 0 : }
4808 :
4809 0 : void _lsa_Opnum86NotUsedOnWire(struct pipes_struct *p,
4810 : struct lsa_Opnum86NotUsedOnWire *r)
4811 : {
4812 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4813 0 : }
4814 :
4815 0 : void _lsa_Opnum87NotUsedOnWire(struct pipes_struct *p,
4816 : struct lsa_Opnum87NotUsedOnWire *r)
4817 : {
4818 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4819 0 : }
4820 :
4821 0 : void _lsa_Opnum88NotUsedOnWire(struct pipes_struct *p,
4822 : struct lsa_Opnum88NotUsedOnWire *r)
4823 : {
4824 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4825 0 : }
4826 :
4827 0 : void _lsa_Opnum89NotUsedOnWire(struct pipes_struct *p,
4828 : struct lsa_Opnum89NotUsedOnWire *r)
4829 : {
4830 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4831 0 : }
4832 :
4833 0 : void _lsa_Opnum90NotUsedOnWire(struct pipes_struct *p,
4834 : struct lsa_Opnum90NotUsedOnWire *r)
4835 : {
4836 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4837 0 : }
4838 :
4839 0 : void _lsa_Opnum91NotUsedOnWire(struct pipes_struct *p,
4840 : struct lsa_Opnum91NotUsedOnWire *r)
4841 : {
4842 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4843 0 : }
4844 :
4845 0 : void _lsa_Opnum92NotUsedOnWire(struct pipes_struct *p,
4846 : struct lsa_Opnum92NotUsedOnWire *r)
4847 : {
4848 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4849 0 : }
4850 :
4851 0 : void _lsa_Opnum93NotUsedOnWire(struct pipes_struct *p,
4852 : struct lsa_Opnum93NotUsedOnWire *r)
4853 : {
4854 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4855 0 : }
4856 :
4857 0 : void _lsa_Opnum94NotUsedOnWire(struct pipes_struct *p,
4858 : struct lsa_Opnum94NotUsedOnWire *r)
4859 : {
4860 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4861 0 : }
4862 :
4863 0 : void _lsa_Opnum95NotUsedOnWire(struct pipes_struct *p,
4864 : struct lsa_Opnum95NotUsedOnWire *r)
4865 : {
4866 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4867 0 : }
4868 :
4869 0 : void _lsa_Opnum96NotUsedOnWire(struct pipes_struct *p,
4870 : struct lsa_Opnum96NotUsedOnWire *r)
4871 : {
4872 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4873 0 : }
4874 :
4875 0 : void _lsa_Opnum97NotUsedOnWire(struct pipes_struct *p,
4876 : struct lsa_Opnum97NotUsedOnWire *r)
4877 : {
4878 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4879 0 : }
4880 :
4881 0 : void _lsa_Opnum98NotUsedOnWire(struct pipes_struct *p,
4882 : struct lsa_Opnum98NotUsedOnWire *r)
4883 : {
4884 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4885 0 : }
4886 :
4887 0 : void _lsa_Opnum99NotUsedOnWire(struct pipes_struct *p,
4888 : struct lsa_Opnum99NotUsedOnWire *r)
4889 : {
4890 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4891 0 : }
4892 :
4893 0 : void _lsa_Opnum100NotUsedOnWire(struct pipes_struct *p,
4894 : struct lsa_Opnum100NotUsedOnWire *r)
4895 : {
4896 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4897 0 : }
4898 :
4899 0 : void _lsa_Opnum101NotUsedOnWire(struct pipes_struct *p,
4900 : struct lsa_Opnum101NotUsedOnWire *r)
4901 : {
4902 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4903 0 : }
4904 :
4905 0 : void _lsa_Opnum102NotUsedOnWire(struct pipes_struct *p,
4906 : struct lsa_Opnum102NotUsedOnWire *r)
4907 : {
4908 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4909 0 : }
4910 :
4911 0 : void _lsa_Opnum103NotUsedOnWire(struct pipes_struct *p,
4912 : struct lsa_Opnum103NotUsedOnWire *r)
4913 : {
4914 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4915 0 : }
4916 :
4917 0 : void _lsa_Opnum104NotUsedOnWire(struct pipes_struct *p,
4918 : struct lsa_Opnum104NotUsedOnWire *r)
4919 : {
4920 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4921 0 : }
4922 :
4923 0 : void _lsa_Opnum105NotUsedOnWire(struct pipes_struct *p,
4924 : struct lsa_Opnum105NotUsedOnWire *r)
4925 : {
4926 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4927 0 : }
4928 :
4929 0 : void _lsa_Opnum106NotUsedOnWire(struct pipes_struct *p,
4930 : struct lsa_Opnum106NotUsedOnWire *r)
4931 : {
4932 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4933 0 : }
4934 :
4935 0 : void _lsa_Opnum107NotUsedOnWire(struct pipes_struct *p,
4936 : struct lsa_Opnum107NotUsedOnWire *r)
4937 : {
4938 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4939 0 : }
4940 :
4941 0 : void _lsa_Opnum108NotUsedOnWire(struct pipes_struct *p,
4942 : struct lsa_Opnum108NotUsedOnWire *r)
4943 : {
4944 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4945 0 : }
4946 :
4947 0 : void _lsa_Opnum109NotUsedOnWire(struct pipes_struct *p,
4948 : struct lsa_Opnum109NotUsedOnWire *r)
4949 : {
4950 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4951 0 : }
4952 :
4953 0 : void _lsa_Opnum110NotUsedOnWire(struct pipes_struct *p,
4954 : struct lsa_Opnum110NotUsedOnWire *r)
4955 : {
4956 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4957 0 : }
4958 :
4959 0 : void _lsa_Opnum111NotUsedOnWire(struct pipes_struct *p,
4960 : struct lsa_Opnum111NotUsedOnWire *r)
4961 : {
4962 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4963 0 : }
4964 :
4965 0 : void _lsa_Opnum112NotUsedOnWire(struct pipes_struct *p,
4966 : struct lsa_Opnum112NotUsedOnWire *r)
4967 : {
4968 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4969 0 : }
4970 :
4971 0 : void _lsa_Opnum113NotUsedOnWire(struct pipes_struct *p,
4972 : struct lsa_Opnum113NotUsedOnWire *r)
4973 : {
4974 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4975 0 : }
4976 :
4977 0 : void _lsa_Opnum114NotUsedOnWire(struct pipes_struct *p,
4978 : struct lsa_Opnum114NotUsedOnWire *r)
4979 : {
4980 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4981 0 : }
4982 :
4983 0 : void _lsa_Opnum115NotUsedOnWire(struct pipes_struct *p,
4984 : struct lsa_Opnum115NotUsedOnWire *r)
4985 : {
4986 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4987 0 : }
4988 :
4989 0 : void _lsa_Opnum116NotUsedOnWire(struct pipes_struct *p,
4990 : struct lsa_Opnum116NotUsedOnWire *r)
4991 : {
4992 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4993 0 : }
4994 :
4995 0 : void _lsa_Opnum117NotUsedOnWire(struct pipes_struct *p,
4996 : struct lsa_Opnum117NotUsedOnWire *r)
4997 : {
4998 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
4999 0 : }
5000 :
5001 0 : void _lsa_Opnum118NotUsedOnWire(struct pipes_struct *p,
5002 : struct lsa_Opnum118NotUsedOnWire *r)
5003 : {
5004 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5005 0 : }
5006 :
5007 0 : void _lsa_Opnum119NotUsedOnWire(struct pipes_struct *p,
5008 : struct lsa_Opnum119NotUsedOnWire *r)
5009 : {
5010 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5011 0 : }
5012 :
5013 0 : void _lsa_Opnum120NotUsedOnWire(struct pipes_struct *p,
5014 : struct lsa_Opnum120NotUsedOnWire *r)
5015 : {
5016 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5017 0 : }
5018 :
5019 0 : void _lsa_Opnum121NotUsedOnWire(struct pipes_struct *p,
5020 : struct lsa_Opnum121NotUsedOnWire *r)
5021 : {
5022 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5023 0 : }
5024 :
5025 0 : void _lsa_Opnum122NotUsedOnWire(struct pipes_struct *p,
5026 : struct lsa_Opnum122NotUsedOnWire *r)
5027 : {
5028 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5029 0 : }
5030 :
5031 0 : void _lsa_Opnum123NotUsedOnWire(struct pipes_struct *p,
5032 : struct lsa_Opnum123NotUsedOnWire *r)
5033 : {
5034 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5035 0 : }
5036 :
5037 0 : void _lsa_Opnum124NotUsedOnWire(struct pipes_struct *p,
5038 : struct lsa_Opnum124NotUsedOnWire *r)
5039 : {
5040 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5041 0 : }
5042 :
5043 0 : void _lsa_Opnum125NotUsedOnWire(struct pipes_struct *p,
5044 : struct lsa_Opnum125NotUsedOnWire *r)
5045 : {
5046 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5047 0 : }
5048 :
5049 0 : void _lsa_Opnum126NotUsedOnWire(struct pipes_struct *p,
5050 : struct lsa_Opnum126NotUsedOnWire *r)
5051 : {
5052 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5053 0 : }
5054 :
5055 0 : void _lsa_Opnum127NotUsedOnWire(struct pipes_struct *p,
5056 : struct lsa_Opnum127NotUsedOnWire *r)
5057 : {
5058 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5059 0 : }
5060 :
5061 0 : void _lsa_Opnum128NotUsedOnWire(struct pipes_struct *p,
5062 : struct lsa_Opnum128NotUsedOnWire *r)
5063 : {
5064 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5065 0 : }
5066 :
5067 : /***************************************************************************
5068 : _lsa_CreateTrustedDomainEx3
5069 : ***************************************************************************/
5070 :
5071 0 : NTSTATUS _lsa_CreateTrustedDomainEx3(struct pipes_struct *p,
5072 : struct lsa_CreateTrustedDomainEx3 *r)
5073 : {
5074 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5075 0 : return NT_STATUS_NOT_IMPLEMENTED;
5076 : }
5077 :
5078 : /***************************************************************************
5079 : _lsa_OpenPolicy3
5080 : ***************************************************************************/
5081 :
5082 68 : NTSTATUS _lsa_OpenPolicy3(struct pipes_struct *p,
5083 : struct lsa_OpenPolicy3 *r)
5084 : {
5085 68 : struct dcesrv_call_state *dce_call = p->dce_call;
5086 0 : struct auth_session_info *session_info =
5087 68 : dcesrv_call_session_info(dce_call);
5088 68 : struct security_descriptor *psd = NULL;
5089 0 : size_t sd_size;
5090 68 : uint32_t des_access = r->in.access_mask;
5091 0 : uint32_t acc_granted;
5092 0 : NTSTATUS status;
5093 :
5094 68 : if (p->transport != NCACN_NP && p->transport != NCALRPC) {
5095 2 : p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
5096 2 : return NT_STATUS_ACCESS_DENIED;
5097 : }
5098 :
5099 66 : ZERO_STRUCTP(r->out.handle);
5100 :
5101 : /*
5102 : * The attributes have no effect and MUST be ignored, except the
5103 : * root_dir which MUST be NULL.
5104 : */
5105 66 : if (r->in.attr != NULL && r->in.attr->root_dir != NULL) {
5106 0 : return NT_STATUS_INVALID_PARAMETER;
5107 : }
5108 :
5109 66 : switch (r->in.in_version) {
5110 66 : case 1:
5111 66 : *r->out.out_version = 1;
5112 :
5113 66 : r->out.out_revision_info->info1.revision = 1;
5114 : /* TODO: Enable as soon as we support it */
5115 : #if 0
5116 : r->out.out_revision_info->info1.supported_features =
5117 : LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER;
5118 : #endif
5119 :
5120 66 : break;
5121 0 : default:
5122 0 : return NT_STATUS_NOT_SUPPORTED;
5123 : }
5124 :
5125 : /* Work out max allowed. */
5126 66 : map_max_allowed_access(session_info->security_token,
5127 66 : session_info->unix_token,
5128 : &des_access);
5129 :
5130 : /* map the generic bits to the lsa policy ones */
5131 66 : se_map_generic(&des_access, &lsa_policy_mapping);
5132 :
5133 : /* get the generic lsa policy SD until we store it */
5134 66 : status = make_lsa_object_sd(p->mem_ctx,
5135 : &psd,
5136 : &sd_size,
5137 : &lsa_policy_mapping,
5138 : NULL,
5139 : 0);
5140 66 : if (!NT_STATUS_IS_OK(status)) {
5141 0 : return status;
5142 : }
5143 :
5144 66 : status = access_check_object(psd,
5145 : session_info->security_token,
5146 : SEC_PRIV_INVALID,
5147 : SEC_PRIV_INVALID,
5148 : 0,
5149 : des_access,
5150 : &acc_granted,
5151 : "_lsa_OpenPolicy2");
5152 66 : if (!NT_STATUS_IS_OK(status)) {
5153 0 : return status;
5154 : }
5155 :
5156 66 : status = create_lsa_policy_handle(p->mem_ctx,
5157 : p,
5158 : LSA_HANDLE_POLICY_TYPE,
5159 : acc_granted,
5160 : get_global_sam_sid(),
5161 : NULL,
5162 : psd,
5163 : r->out.handle);
5164 66 : if (!NT_STATUS_IS_OK(status)) {
5165 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5166 : }
5167 :
5168 66 : return NT_STATUS_OK;
5169 : }
5170 :
5171 0 : void _lsa_Opnum131NotUsedOnWire(struct pipes_struct *p,
5172 : struct lsa_Opnum131NotUsedOnWire *r)
5173 : {
5174 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5175 0 : }
5176 :
5177 0 : NTSTATUS _lsa_lsaRQueryForestTrustInformation2(struct pipes_struct *p,
5178 : struct lsa_lsaRQueryForestTrustInformation2 *r)
5179 : {
5180 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5181 0 : return NT_STATUS_NOT_IMPLEMENTED;
5182 : }
5183 :
5184 0 : NTSTATUS _lsa_lsaRSetForestTrustInformation2(struct pipes_struct *p,
5185 : struct lsa_lsaRSetForestTrustInformation2 *r)
5186 : {
5187 0 : p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
5188 0 : return NT_STATUS_NOT_IMPLEMENTED;
5189 : }
5190 :
5191 : #include "librpc/rpc/dcesrv_core.h"
5192 :
5193 : #define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
5194 : dcesrv_interface_lsarpc_bind(context, iface)
5195 :
5196 2795 : static NTSTATUS dcesrv_interface_lsarpc_bind(
5197 : struct dcesrv_connection_context *context,
5198 : const struct dcesrv_interface *iface)
5199 : {
5200 2795 : return dcesrv_interface_bind_reject_connect(context, iface);
5201 : }
5202 :
5203 : static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
5204 : const struct dcesrv_endpoint_server *ep_server);
5205 : static const struct dcesrv_interface dcesrv_lsarpc_interface;
5206 :
5207 : #define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]"
5208 : #define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]"
5209 :
5210 : #define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT \
5211 : NCACN_NP_PIPE_LSASS
5212 :
5213 : #define DCESRV_INTERFACE_LSARPC_INIT_SERVER \
5214 : dcesrv_interface_lsarpc_init_server
5215 :
5216 215 : static NTSTATUS dcesrv_interface_lsarpc_init_server(
5217 : struct dcesrv_context *dce_ctx,
5218 : const struct dcesrv_endpoint_server *ep_server)
5219 : {
5220 215 : NTSTATUS ret = dcesrv_interface_register(dce_ctx,
5221 : NCACN_NP_PIPE_NETLOGON,
5222 : NCACN_NP_PIPE_LSASS,
5223 : &dcesrv_lsarpc_interface,
5224 : NULL);
5225 215 : if (!NT_STATUS_IS_OK(ret)) {
5226 0 : DBG_ERR("Failed to register endpoint "
5227 : "'\\pipe\\netlogon'\n");
5228 0 : return ret;
5229 : }
5230 :
5231 215 : return lsarpc__op_init_server(dce_ctx, ep_server);
5232 : }
5233 :
5234 : /* include the generated boilerplate */
5235 : #include "librpc/gen_ndr/ndr_lsa_scompat.c"
|