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