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, 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 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 2 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program; if not, write to the Free Software 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 */ 27 28/* This is the implementation of the lsa server code. */ 29 30#include "includes.h" 31 32#undef DBGC_CLASS 33#define DBGC_CLASS DBGC_RPC_SRV 34 35extern PRIVS privs[]; 36 37struct lsa_info { 38 DOM_SID sid; 39 uint32 access; 40}; 41 42struct generic_mapping lsa_generic_mapping = { 43 POLICY_READ, 44 POLICY_WRITE, 45 POLICY_EXECUTE, 46 POLICY_ALL_ACCESS 47}; 48 49/******************************************************************* 50 Function to free the per handle data. 51 ********************************************************************/ 52 53static void free_lsa_info(void *ptr) 54{ 55 struct lsa_info *lsa = (struct lsa_info *)ptr; 56 57 SAFE_FREE(lsa); 58} 59 60/*************************************************************************** 61Init dom_query 62 ***************************************************************************/ 63 64static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_sid) 65{ 66 d_q->buffer_dom_name = (dom_name != NULL) ? 1 : 0; /* domain buffer pointer */ 67 d_q->buffer_dom_sid = (dom_sid != NULL) ? 1 : 0; /* domain sid pointer */ 68 69 /* this string is supposed to be non-null terminated. */ 70 /* But the maxlen in this UNISTR2 must include the terminating null. */ 71 init_unistr2(&d_q->uni_domain_name, dom_name, UNI_BROKEN_NON_NULL); 72 73 /* 74 * I'm not sure why this really odd combination of length 75 * values works, but it does appear to. I need to look at 76 * this *much* more closely - but at the moment leave alone 77 * until it's understood. This allows a W2k client to join 78 * a domain with both odd and even length names... JRA. 79 */ 80 81 /* 82 * IMPORTANT NOTE !!!! 83 * The two fields below probably are reversed in meaning, ie. 84 * the first field is probably the str_len, the second the max 85 * len. Both are measured in bytes anyway. 86 */ 87 88 d_q->uni_dom_str_len = d_q->uni_domain_name.uni_max_len * 2; 89 d_q->uni_dom_max_len = d_q->uni_domain_name.uni_str_len * 2; 90 91 if (dom_sid != NULL) 92 init_dom_sid2(&d_q->dom_sid, dom_sid); 93} 94 95/*************************************************************************** 96 init_dom_ref - adds a domain if it's not already in, returns the index. 97***************************************************************************/ 98 99static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid) 100{ 101 int num = 0; 102 103 if (dom_name != NULL) { 104 for (num = 0; num < ref->num_ref_doms_1; num++) { 105 fstring domname; 106 rpcstr_pull(domname, ref->ref_dom[num].uni_dom_name.buffer, sizeof(domname), -1, 0); 107 if (strequal(domname, dom_name)) 108 return num; 109 } 110 } else { 111 num = ref->num_ref_doms_1; 112 } 113 114 if (num >= MAX_REF_DOMAINS) { 115 /* index not found, already at maximum domain limit */ 116 return -1; 117 } 118 119 ref->num_ref_doms_1 = num+1; 120 ref->ptr_ref_dom = 1; 121 ref->max_entries = MAX_REF_DOMAINS; 122 ref->num_ref_doms_2 = num+1; 123 124 ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0; 125 126 init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, UNI_FLAGS_NONE); 127 init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, &ref->ref_dom[num].uni_dom_name); 128 129 init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid ); 130 131 return num; 132} 133 134/*************************************************************************** 135 init_lsa_rid2s 136 ***************************************************************************/ 137 138static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2, 139 int num_entries, UNISTR2 *name, 140 uint32 *mapped_count, BOOL endian) 141{ 142 int i; 143 int total = 0; 144 *mapped_count = 0; 145 146 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS); 147 148 become_root(); /* lookup_name can require root privs */ 149 150 for (i = 0; i < num_entries; i++) { 151 BOOL status = False; 152 DOM_SID sid; 153 uint32 rid = 0xffffffff; 154 int dom_idx = -1; 155 pstring full_name; 156 fstring dom_name, user; 157 enum SID_NAME_USE name_type = SID_NAME_UNKNOWN; 158 159 /* Split name into domain and user component */ 160 161 unistr2_to_ascii(full_name, &name[i], sizeof(full_name)); 162 split_domain_name(full_name, dom_name, user); 163 164 /* Lookup name */ 165 166 DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name)); 167 168 status = lookup_name(dom_name, user, &sid, &name_type); 169 170 if((name_type == SID_NAME_UNKNOWN) && (lp_server_role() == ROLE_DOMAIN_MEMBER) && (strncmp(dom_name, full_name, strlen(dom_name)) != 0)) { 171 DEBUG(5, ("init_lsa_rid2s: domain name not provided and local account not found, using member domain\n")); 172 fstrcpy(dom_name, lp_workgroup()); 173 status = lookup_name(dom_name, user, &sid, &name_type); 174 } 175 176#if 0 /* This is not true. */ 177 if (name_type == SID_NAME_WKN_GRP) { 178 /* BUILTIN aliases are still aliases :-) */ 179 name_type = SID_NAME_ALIAS; 180 } 181#endif 182 183 DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" : 184 "not found")); 185 186 if (status && name_type != SID_NAME_UNKNOWN) { 187 sid_split_rid(&sid, &rid); 188 dom_idx = init_dom_ref(ref, dom_name, &sid); 189 (*mapped_count)++; 190 } else { 191 dom_idx = -1; 192 rid = 0; 193 name_type = SID_NAME_UNKNOWN; 194 } 195 196 init_dom_rid2(&rid2[total], rid, name_type, dom_idx); 197 total++; 198 } 199 200 unbecome_root(); 201} 202 203/*************************************************************************** 204 init_reply_lookup_names 205 ***************************************************************************/ 206 207static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l, 208 DOM_R_REF *ref, uint32 num_entries, 209 DOM_RID2 *rid2, uint32 mapped_count) 210{ 211 r_l->ptr_dom_ref = 1; 212 r_l->dom_ref = ref; 213 214 r_l->num_entries = num_entries; 215 r_l->ptr_entries = 1; 216 r_l->num_entries2 = num_entries; 217 r_l->dom_rid = rid2; 218 219 r_l->mapped_count = mapped_count; 220} 221 222/*************************************************************************** 223 Init lsa_trans_names. 224 ***************************************************************************/ 225 226static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *trn, 227 int num_entries, DOM_SID2 *sid, 228 uint32 *mapped_count) 229{ 230 int i; 231 int total = 0; 232 *mapped_count = 0; 233 234 /* Allocate memory for list of names */ 235 236 if (num_entries > 0) { 237 if (!(trn->name = TALLOC_ARRAY(ctx, LSA_TRANS_NAME, num_entries))) { 238 DEBUG(0, ("init_lsa_trans_names(): out of memory\n")); 239 return; 240 } 241 242 if (!(trn->uni_name = TALLOC_ARRAY(ctx, UNISTR2, num_entries))) { 243 DEBUG(0, ("init_lsa_trans_names(): out of memory\n")); 244 return; 245 } 246 } 247 248 become_root(); /* Need root to get to passdb to for local sids */ 249 250 for (i = 0; i < num_entries; i++) { 251 BOOL status = False; 252 DOM_SID find_sid = sid[i].sid; 253 uint32 rid = 0xffffffff; 254 int dom_idx = -1; 255 fstring name, dom_name; 256 enum SID_NAME_USE sid_name_use = (enum SID_NAME_USE)0; 257 258 sid_to_string(name, &find_sid); 259 DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name)); 260 261 /* Lookup sid from winbindd */ 262 263 status = lookup_sid(&find_sid, dom_name, name, &sid_name_use); 264 265 DEBUG(5, ("init_lsa_trans_names: %s\n", status ? "found" : 266 "not found")); 267 268 if (!status) { 269 sid_name_use = SID_NAME_UNKNOWN; 270 memset(dom_name, '\0', sizeof(dom_name)); 271 sid_to_string(name, &find_sid); 272 dom_idx = -1; 273 274 DEBUG(10,("init_lsa_trans_names: added unknown user '%s' to " 275 "referenced list.\n", name )); 276 } else { 277 (*mapped_count)++; 278 /* Store domain sid in ref array */ 279 if (find_sid.num_auths == 5) { 280 sid_split_rid(&find_sid, &rid); 281 } 282 dom_idx = init_dom_ref(ref, dom_name, &find_sid); 283 284 DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' (%d) to referenced list.\n", 285 sid_type_lookup(sid_name_use), dom_name, name, sid_name_use )); 286 287 } 288 289 init_lsa_trans_name(&trn->name[total], &trn->uni_name[total], 290 sid_name_use, name, dom_idx); 291 total++; 292 } 293 294 unbecome_root(); 295 296 trn->num_entries = total; 297 trn->ptr_trans_names = 1; 298 trn->num_entries2 = total; 299} 300 301/*************************************************************************** 302 Init_reply_lookup_sids. 303 ***************************************************************************/ 304 305static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l, 306 DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names, 307 uint32 mapped_count) 308{ 309 r_l->ptr_dom_ref = 1; 310 r_l->dom_ref = ref; 311 r_l->names = names; 312 r_l->mapped_count = mapped_count; 313} 314 315static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size) 316{ 317 extern DOM_SID global_sid_World; 318 extern DOM_SID global_sid_Builtin; 319 DOM_SID local_adm_sid; 320 DOM_SID adm_sid; 321 322 SEC_ACE ace[3]; 323 SEC_ACCESS mask; 324 325 SEC_ACL *psa = NULL; 326 327 init_sec_access(&mask, POLICY_EXECUTE); 328 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); 329 330 sid_copy(&adm_sid, get_global_sam_sid()); 331 sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS); 332 init_sec_access(&mask, POLICY_ALL_ACCESS); 333 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); 334 335 sid_copy(&local_adm_sid, &global_sid_Builtin); 336 sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS); 337 init_sec_access(&mask, POLICY_ALL_ACCESS); 338 init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); 339 340 if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL) 341 return NT_STATUS_NO_MEMORY; 342 343 if((*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL, psa, sd_size)) == NULL) 344 return NT_STATUS_NO_MEMORY; 345 346 return NT_STATUS_OK; 347} 348 349#if 0 /* AD DC work in ongoing in Samba 4 */ 350 351/*************************************************************************** 352 Init_dns_dom_info. 353***************************************************************************/ 354 355static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name, 356 const char *dns_name, const char *forest_name, 357 struct uuid *dom_guid, DOM_SID *dom_sid) 358{ 359 if (nb_name && *nb_name) { 360 init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE); 361 init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name); 362 r_l->hdr_nb_dom_name.uni_max_len += 2; 363 r_l->uni_nb_dom_name.uni_max_len += 1; 364 } 365 366 if (dns_name && *dns_name) { 367 init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE); 368 init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name); 369 r_l->hdr_dns_dom_name.uni_max_len += 2; 370 r_l->uni_dns_dom_name.uni_max_len += 1; 371 } 372 373 if (forest_name && *forest_name) { 374 init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE); 375 init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name); 376 r_l->hdr_forest_name.uni_max_len += 2; 377 r_l->uni_forest_name.uni_max_len += 1; 378 } 379 380 /* how do we init the guid ? probably should write an init fn */ 381 if (dom_guid) { 382 memcpy(&r_l->dom_guid, dom_guid, sizeof(struct uuid)); 383 } 384 385 if (dom_sid) { 386 r_l->ptr_dom_sid = 1; 387 init_dom_sid2(&r_l->dom_sid, dom_sid); 388 } 389} 390#endif /* AD DC work in ongoing in Samba 4 */ 391 392 393/*************************************************************************** 394 _lsa_open_policy2. 395 ***************************************************************************/ 396 397NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u) 398{ 399 struct lsa_info *info; 400 SEC_DESC *psd = NULL; 401 size_t sd_size; 402 uint32 des_access=q_u->des_access; 403 uint32 acc_granted; 404 NTSTATUS status; 405 406 407 /* map the generic bits to the lsa policy ones */ 408 se_map_generic(&des_access, &lsa_generic_mapping); 409 410 /* get the generic lsa policy SD until we store it */ 411 lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size); 412 413 if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) { 414 if (geteuid() != 0) { 415 return status; 416 } 417 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n", 418 acc_granted, des_access)); 419 DEBUGADD(4,("but overwritten by euid == 0\n")); 420 } 421 422 /* This is needed for lsa_open_account and rpcclient .... :-) */ 423 424 if (geteuid() == 0) 425 acc_granted = POLICY_ALL_ACCESS; 426 427 /* associate the domain SID with the (unique) handle. */ 428 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL) 429 return NT_STATUS_NO_MEMORY; 430 431 ZERO_STRUCTP(info); 432 sid_copy(&info->sid,get_global_sam_sid()); 433 info->access = acc_granted; 434 435 /* set up the LSA QUERY INFO response */ 436 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info)) 437 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 438 439 return NT_STATUS_OK; 440} 441 442/*************************************************************************** 443 _lsa_open_policy 444 ***************************************************************************/ 445 446NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u) 447{ 448 struct lsa_info *info; 449 SEC_DESC *psd = NULL; 450 size_t sd_size; 451 uint32 des_access=q_u->des_access; 452 uint32 acc_granted; 453 NTSTATUS status; 454 455 456 /* map the generic bits to the lsa policy ones */ 457 se_map_generic(&des_access, &lsa_generic_mapping); 458 459 /* get the generic lsa policy SD until we store it */ 460 lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size); 461 462 if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) { 463 if (geteuid() != 0) { 464 return status; 465 } 466 DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n", 467 acc_granted, des_access)); 468 DEBUGADD(4,("but overwritten by euid == 0\n")); 469 acc_granted = des_access; 470 } 471 472 /* associate the domain SID with the (unique) handle. */ 473 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL) 474 return NT_STATUS_NO_MEMORY; 475 476 ZERO_STRUCTP(info); 477 sid_copy(&info->sid,get_global_sam_sid()); 478 info->access = acc_granted; 479 480 /* set up the LSA QUERY INFO response */ 481 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info)) 482 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 483 484 return NT_STATUS_OK; 485} 486 487/*************************************************************************** 488 _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA. 489 ufff, done :) mimir 490 ***************************************************************************/ 491 492NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENUM_TRUST_DOM *r_u) 493{ 494 struct lsa_info *info; 495 uint32 enum_context = q_u->enum_context; 496 497 /* 498 * preferred length is set to 5 as a "our" preferred length 499 * nt sets this parameter to 2 500 * update (20.08.2002): it's not preferred length, but preferred size! 501 * it needs further investigation how to optimally choose this value 502 */ 503 uint32 max_num_domains = q_u->preferred_len < 5 ? q_u->preferred_len : 10; 504 TRUSTDOM **trust_doms; 505 uint32 num_domains; 506 NTSTATUS nt_status; 507 508 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) 509 return NT_STATUS_INVALID_HANDLE; 510 511 /* check if the user have enough rights */ 512 if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION)) 513 return NT_STATUS_ACCESS_DENIED; 514 515 nt_status = secrets_get_trusted_domains(p->mem_ctx, (int *)&enum_context, max_num_domains, (int *)&num_domains, &trust_doms); 516 517 if (!NT_STATUS_IS_OK(nt_status) && 518 !NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES) && 519 !NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MORE_ENTRIES)) { 520 return nt_status; 521 } else { 522 r_u->status = nt_status; 523 } 524 525 /* set up the lsa_enum_trust_dom response */ 526 init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, max_num_domains, num_domains, trust_doms); 527 528 return r_u->status; 529} 530 531/*************************************************************************** 532 _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn. 533 ***************************************************************************/ 534 535NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u) 536{ 537 struct lsa_info *handle; 538 LSA_INFO_UNION *info = &r_u->dom; 539 DOM_SID domain_sid; 540 const char *name; 541 DOM_SID *sid = NULL; 542 543 r_u->status = NT_STATUS_OK; 544 545 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) 546 return NT_STATUS_INVALID_HANDLE; 547 548 switch (q_u->info_class) { 549 case 0x02: 550 { 551 unsigned int i; 552 /* check if the user have enough rights */ 553 if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION)) 554 return NT_STATUS_ACCESS_DENIED; 555 556 /* fake info: We audit everything. ;) */ 557 info->id2.auditing_enabled = 1; 558 info->id2.count1 = 7; 559 info->id2.count2 = 7; 560 if ((info->id2.auditsettings = TALLOC_ARRAY(p->mem_ctx,uint32, 7)) == NULL) 561 return NT_STATUS_NO_MEMORY; 562 for (i = 0; i < 7; i++) 563 info->id2.auditsettings[i] = 3; 564 break; 565 } 566 case 0x03: 567 /* check if the user have enough rights */ 568 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) 569 return NT_STATUS_ACCESS_DENIED; 570 571 /* Request PolicyPrimaryDomainInformation. */ 572 switch (lp_server_role()) { 573 case ROLE_DOMAIN_PDC: 574 case ROLE_DOMAIN_BDC: 575 name = get_global_sam_name(); 576 sid = get_global_sam_sid(); 577 break; 578 case ROLE_DOMAIN_MEMBER: 579 name = lp_workgroup(); 580 /* We need to return the Domain SID here. */ 581 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) 582 sid = &domain_sid; 583 else 584 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 585 break; 586 case ROLE_STANDALONE: 587 name = lp_workgroup(); 588 sid = NULL; 589 break; 590 default: 591 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 592 } 593 init_dom_query(&r_u->dom.id3, name, sid); 594 break; 595 case 0x05: 596 /* check if the user have enough rights */ 597 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) 598 return NT_STATUS_ACCESS_DENIED; 599 600 /* Request PolicyAccountDomainInformation. */ 601 name = get_global_sam_name(); 602 sid = get_global_sam_sid(); 603 init_dom_query(&r_u->dom.id5, name, sid); 604 break; 605 case 0x06: 606 /* check if the user have enough rights */ 607 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) 608 return NT_STATUS_ACCESS_DENIED; 609 610 switch (lp_server_role()) { 611 case ROLE_DOMAIN_BDC: 612 /* 613 * only a BDC is a backup controller 614 * of the domain, it controls. 615 */ 616 info->id6.server_role = 2; 617 break; 618 default: 619 /* 620 * any other role is a primary 621 * of the domain, it controls. 622 */ 623 info->id6.server_role = 3; 624 break; 625 } 626 break; 627 default: 628 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u->info_class)); 629 r_u->status = NT_STATUS_INVALID_INFO_CLASS; 630 break; 631 } 632 633 if (NT_STATUS_IS_OK(r_u->status)) { 634 r_u->undoc_buffer = 0x22000000; /* bizarre */ 635 r_u->info_class = q_u->info_class; 636 } 637 638 return r_u->status; 639} 640 641/*************************************************************************** 642 _lsa_lookup_sids 643 ***************************************************************************/ 644 645NTSTATUS _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SIDS *r_u) 646{ 647 struct lsa_info *handle; 648 DOM_SID2 *sid = q_u->sids.sid; 649 int num_entries = q_u->sids.num_entries; 650 DOM_R_REF *ref = NULL; 651 LSA_TRANS_NAME_ENUM *names = NULL; 652 uint32 mapped_count = 0; 653 654 if (num_entries > MAX_LOOKUP_SIDS) { 655 num_entries = 0; 656 DEBUG(5,("_lsa_lookup_sids: limit of %d exceeded, truncating SID lookup list to %d\n", MAX_LOOKUP_SIDS, num_entries)); 657 r_u->status = NT_STATUS_NONE_MAPPED; 658 } 659 660 ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); 661 names = TALLOC_ZERO_P(p->mem_ctx, LSA_TRANS_NAME_ENUM); 662 663 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) { 664 r_u->status = NT_STATUS_INVALID_HANDLE; 665 goto done; 666 } 667 668 /* check if the user have enough rights */ 669 if (!(handle->access & POLICY_LOOKUP_NAMES)) { 670 r_u->status = NT_STATUS_ACCESS_DENIED; 671 goto done; 672 } 673 if (!ref || !names) 674 return NT_STATUS_NO_MEMORY; 675 676done: 677 678 /* set up the LSA Lookup SIDs response */ 679 init_lsa_trans_names(p->mem_ctx, ref, names, num_entries, sid, &mapped_count); 680 if (NT_STATUS_IS_OK(r_u->status)) { 681 if (mapped_count == 0) 682 r_u->status = NT_STATUS_NONE_MAPPED; 683 else if (mapped_count != num_entries) 684 r_u->status = STATUS_SOME_UNMAPPED; 685 } 686 init_reply_lookup_sids(r_u, ref, names, mapped_count); 687 688 return r_u->status; 689} 690 691/*************************************************************************** 692lsa_reply_lookup_names 693 ***************************************************************************/ 694 695NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u) 696{ 697 struct lsa_info *handle; 698 UNISTR2 *names = q_u->uni_name; 699 int num_entries = q_u->num_entries; 700 DOM_R_REF *ref; 701 DOM_RID2 *rids; 702 uint32 mapped_count = 0; 703 704 if (num_entries > MAX_LOOKUP_SIDS) { 705 num_entries = MAX_LOOKUP_SIDS; 706 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries)); 707 } 708 709 ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); 710 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries); 711 712 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) { 713 r_u->status = NT_STATUS_INVALID_HANDLE; 714 goto done; 715 } 716 717 /* check if the user have enough rights */ 718 if (!(handle->access & POLICY_LOOKUP_NAMES)) { 719 r_u->status = NT_STATUS_ACCESS_DENIED; 720 goto done; 721 } 722 723 if (!ref || !rids) 724 return NT_STATUS_NO_MEMORY; 725 726done: 727 728 /* set up the LSA Lookup RIDs response */ 729 init_lsa_rid2s(ref, rids, num_entries, names, &mapped_count, p->endian); 730 if (NT_STATUS_IS_OK(r_u->status)) { 731 if (mapped_count == 0) 732 r_u->status = NT_STATUS_NONE_MAPPED; 733 else if (mapped_count != num_entries) 734 r_u->status = STATUS_SOME_UNMAPPED; 735 } 736 init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count); 737 738 return r_u->status; 739} 740 741/*************************************************************************** 742 _lsa_close. Also weird - needs to check if lsa handle is correct. JRA. 743 ***************************************************************************/ 744 745NTSTATUS _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u) 746{ 747 if (!find_policy_by_hnd(p, &q_u->pol, NULL)) 748 return NT_STATUS_INVALID_HANDLE; 749 750 close_policy_hnd(p, &q_u->pol); 751 return NT_STATUS_OK; 752} 753 754/*************************************************************************** 755 "No more secrets Marty...." :-). 756 ***************************************************************************/ 757 758NTSTATUS _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u) 759{ 760 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 761} 762 763/*************************************************************************** 764_lsa_enum_privs. 765 ***************************************************************************/ 766 767NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u) 768{ 769 struct lsa_info *handle; 770 uint32 i; 771 uint32 enum_context = q_u->enum_context; 772 int num_privs = count_all_privileges(); 773 LSA_PRIV_ENTRY *entries = NULL; 774 LUID_ATTR luid; 775 776 /* remember that the enum_context starts at 0 and not 1 */ 777 778 if ( enum_context >= num_privs ) 779 return NT_STATUS_NO_MORE_ENTRIES; 780 781 DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", 782 enum_context, num_privs)); 783 784 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) 785 return NT_STATUS_INVALID_HANDLE; 786 787 /* check if the user have enough rights 788 I don't know if it's the right one. not documented. */ 789 790 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) 791 return NT_STATUS_ACCESS_DENIED; 792 793 if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs )) ) 794 return NT_STATUS_NO_MEMORY; 795 796 for (i = 0; i < num_privs; i++) { 797 if( i < enum_context) { 798 init_unistr2(&entries[i].name, NULL, UNI_FLAGS_NONE); 799 init_uni_hdr(&entries[i].hdr_name, &entries[i].name); 800 801 entries[i].luid_low = 0; 802 entries[i].luid_high = 0; 803 } else { 804 init_unistr2(&entries[i].name, privs[i].name, UNI_FLAGS_NONE); 805 init_uni_hdr(&entries[i].hdr_name, &entries[i].name); 806 807 luid = get_privilege_luid( &privs[i].se_priv ); 808 809 entries[i].luid_low = luid.luid.low; 810 entries[i].luid_high = luid.luid.high; 811 } 812 } 813 814 enum_context = num_privs; 815 816 init_lsa_r_enum_privs(r_u, enum_context, num_privs, entries); 817 818 return NT_STATUS_OK; 819} 820 821/*************************************************************************** 822_lsa_priv_get_dispname. 823 ***************************************************************************/ 824 825NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u) 826{ 827 struct lsa_info *handle; 828 fstring name_asc; 829 const char *description; 830 831 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) 832 return NT_STATUS_INVALID_HANDLE; 833 834 /* check if the user have enough rights */ 835 836 /* 837 * I don't know if it's the right one. not documented. 838 */ 839 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) 840 return NT_STATUS_ACCESS_DENIED; 841 842 unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc)); 843 844 DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name_asc)); 845 846 description = get_privilege_dispname( name_asc ); 847 848 if ( description ) { 849 DEBUG(10,("_lsa_priv_get_dispname: display name = %s\n", description)); 850 851 init_unistr2(&r_u->desc, description, UNI_FLAGS_NONE); 852 init_uni_hdr(&r_u->hdr_desc, &r_u->desc); 853 854 r_u->ptr_info = 0xdeadbeef; 855 r_u->lang_id = q_u->lang_id; 856 857 return NT_STATUS_OK; 858 } else { 859 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n")); 860 861 r_u->ptr_info = 0; 862 863 return NT_STATUS_NO_SUCH_PRIVILEGE; 864 } 865} 866 867/*************************************************************************** 868_lsa_enum_accounts. 869 ***************************************************************************/ 870 871NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u) 872{ 873 struct lsa_info *handle; 874 DOM_SID *sid_list; 875 int i, j, num_entries; 876 LSA_SID_ENUM *sids=&r_u->sids; 877 NTSTATUS ret; 878 879 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) 880 return NT_STATUS_INVALID_HANDLE; 881 882 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) 883 return NT_STATUS_ACCESS_DENIED; 884 885 sid_list = NULL; 886 num_entries = 0; 887 888 /* The only way we can currently find out all the SIDs that have been 889 privileged is to scan all privileges */ 890 891 if (!NT_STATUS_IS_OK(ret = privilege_enumerate_accounts(&sid_list, &num_entries))) { 892 return ret; 893 } 894 895 if (q_u->enum_context >= num_entries) 896 return NT_STATUS_NO_MORE_ENTRIES; 897 898 sids->ptr_sid = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_entries-q_u->enum_context); 899 sids->sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_entries-q_u->enum_context); 900 901 if (sids->ptr_sid==NULL || sids->sid==NULL) { 902 SAFE_FREE(sid_list); 903 return NT_STATUS_NO_MEMORY; 904 } 905 906 for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) { 907 init_dom_sid2(&(*sids).sid[j], &sid_list[i]); 908 (*sids).ptr_sid[j] = 1; 909 } 910 911 SAFE_FREE(sid_list); 912 913 init_lsa_r_enum_accounts(r_u, num_entries); 914 915 return NT_STATUS_OK; 916} 917 918 919NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u) 920{ 921 fstring username, domname; 922 user_struct *vuser = get_valid_user_struct(p->vuid); 923 924 if (vuser == NULL) 925 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 926 927 fstrcpy(username, vuser->user.smb_name); 928 fstrcpy(domname, vuser->user.domain); 929 930 r_u->ptr_user_name = 1; 931 init_unistr2(&r_u->uni2_user_name, username, UNI_STR_TERMINATE); 932 init_uni_hdr(&r_u->hdr_user_name, &r_u->uni2_user_name); 933 934 r_u->unk1 = 1; 935 936 r_u->ptr_dom_name = 1; 937 init_unistr2(&r_u->uni2_dom_name, domname, UNI_STR_TERMINATE); 938 init_uni_hdr(&r_u->hdr_dom_name, &r_u->uni2_dom_name); 939 940 r_u->status = NT_STATUS_OK; 941 942 return r_u->status; 943} 944 945/*************************************************************************** 946 Lsa Create Account 947 ***************************************************************************/ 948 949NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CREATEACCOUNT *r_u) 950{ 951 struct lsa_info *handle; 952 struct lsa_info *info; 953 954 /* find the connection policy handle. */ 955 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) 956 return NT_STATUS_INVALID_HANDLE; 957 958 /* check if the user have enough rights */ 959 960 /* 961 * I don't know if it's the right one. not documented. 962 * but guessed with rpcclient. 963 */ 964 if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) 965 return NT_STATUS_ACCESS_DENIED; 966 967 /* check to see if the pipe_user is a Domain Admin since 968 account_pol.tdb was already opened as root, this is all we have */ 969 970 if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 971 return NT_STATUS_ACCESS_DENIED; 972 973 if ( is_privileged_sid( &q_u->sid.sid ) ) 974 return NT_STATUS_OBJECT_NAME_COLLISION; 975 976 /* associate the user/group SID with the (unique) handle. */ 977 978 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL) 979 return NT_STATUS_NO_MEMORY; 980 981 ZERO_STRUCTP(info); 982 info->sid = q_u->sid.sid; 983 info->access = q_u->access; 984 985 /* get a (unique) handle. open a policy on it. */ 986 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info)) 987 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 988 989 return privilege_create_account( &info->sid ); 990} 991 992 993/*************************************************************************** 994 Lsa Open Account 995 ***************************************************************************/ 996 997NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u) 998{ 999 struct lsa_info *handle; 1000 struct lsa_info *info; 1001 1002 /* find the connection policy handle. */ 1003 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) 1004 return NT_STATUS_INVALID_HANDLE; 1005 1006 /* check if the user have enough rights */ 1007 1008 /* 1009 * I don't know if it's the right one. not documented. 1010 * but guessed with rpcclient. 1011 */ 1012 if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) 1013 return NT_STATUS_ACCESS_DENIED; 1014 1015 /* TODO: Fis the parsing routine before reenabling this check! */ 1016 #if 0 1017 if (!lookup_sid(&handle->sid, dom_name, name, &type)) 1018 return NT_STATUS_ACCESS_DENIED; 1019 #endif 1020 /* associate the user/group SID with the (unique) handle. */ 1021 if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL) 1022 return NT_STATUS_NO_MEMORY; 1023 1024 ZERO_STRUCTP(info); 1025 info->sid = q_u->sid.sid; 1026 info->access = q_u->access; 1027 1028 /* get a (unique) handle. open a policy on it. */ 1029 if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info)) 1030 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 1031 1032 return NT_STATUS_OK; 1033} 1034 1035/*************************************************************************** 1036 For a given SID, enumerate all the privilege this account has. 1037 ***************************************************************************/ 1038 1039NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u) 1040{ 1041 struct lsa_info *info=NULL; 1042 SE_PRIV mask; 1043 PRIVILEGE_SET privileges; 1044 1045 /* find the connection policy handle. */ 1046 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) 1047 return NT_STATUS_INVALID_HANDLE; 1048 1049 if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) ) 1050 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 1051 1052 privilege_set_init( &privileges ); 1053 1054 if ( se_priv_to_privilege_set( &privileges, &mask ) ) { 1055 1056 DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n", 1057 sid_string_static(&info->sid), privileges.count)); 1058 1059 r_u->status = init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, privileges.set, privileges.count, 0); 1060 } 1061 else 1062 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE; 1063 1064 privilege_set_free( &privileges ); 1065 1066 return r_u->status; 1067} 1068 1069/*************************************************************************** 1070 1071 ***************************************************************************/ 1072 1073NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u) 1074{ 1075 struct lsa_info *info=NULL; 1076 fstring name, dom_name; 1077 enum SID_NAME_USE type; 1078 1079 /* find the connection policy handle. */ 1080 1081 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) 1082 return NT_STATUS_INVALID_HANDLE; 1083 1084 if (!lookup_sid(&info->sid, dom_name, name, &type)) 1085 return NT_STATUS_ACCESS_DENIED; 1086 1087 /* 1088 0x01 -> Log on locally 1089 0x02 -> Access this computer from network 1090 0x04 -> Log on as a batch job 1091 0x10 -> Log on as a service 1092 1093 they can be ORed together 1094 */ 1095 1096 r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK; 1097 1098 return NT_STATUS_OK; 1099} 1100 1101/*************************************************************************** 1102 update the systemaccount information 1103 ***************************************************************************/ 1104 1105NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA_R_SETSYSTEMACCOUNT *r_u) 1106{ 1107 struct lsa_info *info=NULL; 1108 GROUP_MAP map; 1109 r_u->status = NT_STATUS_OK; 1110 1111 /* find the connection policy handle. */ 1112 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) 1113 return NT_STATUS_INVALID_HANDLE; 1114 1115 /* check to see if the pipe_user is a Domain Admin since 1116 account_pol.tdb was already opened as root, this is all we have */ 1117 1118 if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 1119 return NT_STATUS_ACCESS_DENIED; 1120 1121 if (!pdb_getgrsid(&map, info->sid)) 1122 return NT_STATUS_NO_SUCH_GROUP; 1123 1124 if(!pdb_update_group_mapping_entry(&map)) 1125 return NT_STATUS_NO_SUCH_GROUP; 1126 1127 return r_u->status; 1128} 1129 1130/*************************************************************************** 1131 For a given SID, add some privileges. 1132 ***************************************************************************/ 1133 1134NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u) 1135{ 1136 struct lsa_info *info = NULL; 1137 SE_PRIV mask; 1138 PRIVILEGE_SET *set = NULL; 1139 struct current_user user; 1140 1141 /* find the connection policy handle. */ 1142 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) 1143 return NT_STATUS_INVALID_HANDLE; 1144 1145 /* check to see if the pipe_user is root or a Domain Admin since 1146 account_pol.tdb was already opened as root, this is all we have */ 1147 1148 get_current_user( &user, p ); 1149 if ( user.uid != sec_initial_uid() 1150 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 1151 { 1152 return NT_STATUS_ACCESS_DENIED; 1153 } 1154 1155 set = &q_u->set; 1156 1157 if ( !privilege_set_to_se_priv( &mask, set ) ) 1158 return NT_STATUS_NO_SUCH_PRIVILEGE; 1159 1160 if ( !grant_privilege( &info->sid, &mask ) ) { 1161 DEBUG(3,("_lsa_addprivs: grant_privilege(%s) failed!\n", 1162 sid_string_static(&info->sid) )); 1163 DEBUG(3,("Privilege mask:\n")); 1164 dump_se_priv( DBGC_ALL, 3, &mask ); 1165 return NT_STATUS_NO_SUCH_PRIVILEGE; 1166 } 1167 1168 return NT_STATUS_OK; 1169} 1170 1171/*************************************************************************** 1172 For a given SID, remove some privileges. 1173 ***************************************************************************/ 1174 1175NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u) 1176{ 1177 struct lsa_info *info = NULL; 1178 SE_PRIV mask; 1179 PRIVILEGE_SET *set = NULL; 1180 struct current_user user; 1181 1182 /* find the connection policy handle. */ 1183 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) 1184 return NT_STATUS_INVALID_HANDLE; 1185 1186 /* check to see if the pipe_user is root or a Domain Admin since 1187 account_pol.tdb was already opened as root, this is all we have */ 1188 1189 get_current_user( &user, p ); 1190 if ( user.uid != sec_initial_uid() 1191 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 1192 { 1193 return NT_STATUS_ACCESS_DENIED; 1194 } 1195 1196 set = &q_u->set; 1197 1198 if ( !privilege_set_to_se_priv( &mask, set ) ) 1199 return NT_STATUS_NO_SUCH_PRIVILEGE; 1200 1201 if ( !revoke_privilege( &info->sid, &mask ) ) { 1202 DEBUG(3,("_lsa_removeprivs: revoke_privilege(%s) failed!\n", 1203 sid_string_static(&info->sid) )); 1204 DEBUG(3,("Privilege mask:\n")); 1205 dump_se_priv( DBGC_ALL, 3, &mask ); 1206 return NT_STATUS_NO_SUCH_PRIVILEGE; 1207 } 1208 1209 return NT_STATUS_OK; 1210} 1211 1212/*************************************************************************** 1213 For a given SID, remove some privileges. 1214 ***************************************************************************/ 1215 1216NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUERY_SEC_OBJ *r_u) 1217{ 1218 struct lsa_info *handle=NULL; 1219 SEC_DESC *psd = NULL; 1220 size_t sd_size; 1221 NTSTATUS status; 1222 1223 r_u->status = NT_STATUS_OK; 1224 1225 /* find the connection policy handle. */ 1226 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) 1227 return NT_STATUS_INVALID_HANDLE; 1228 1229 /* check if the user have enough rights */ 1230 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) 1231 return NT_STATUS_ACCESS_DENIED; 1232 1233 1234 switch (q_u->sec_info) { 1235 case 1: 1236 /* SD contains only the owner */ 1237 1238 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size); 1239 if(!NT_STATUS_IS_OK(status)) 1240 return NT_STATUS_NO_MEMORY; 1241 1242 1243 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL) 1244 return NT_STATUS_NO_MEMORY; 1245 break; 1246 case 4: 1247 /* SD contains only the ACL */ 1248 1249 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size); 1250 if(!NT_STATUS_IS_OK(status)) 1251 return NT_STATUS_NO_MEMORY; 1252 1253 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL) 1254 return NT_STATUS_NO_MEMORY; 1255 break; 1256 default: 1257 return NT_STATUS_INVALID_LEVEL; 1258 } 1259 1260 r_u->ptr=1; 1261 1262 return r_u->status; 1263} 1264 1265#if 0 /* AD DC work in ongoing in Samba 4 */ 1266 1267/*************************************************************************** 1268 ***************************************************************************/ 1269 1270NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u) 1271{ 1272 struct lsa_info *handle; 1273 const char *nb_name; 1274 char *dns_name = NULL; 1275 char *forest_name = NULL; 1276 DOM_SID *sid = NULL; 1277 struct uuid guid; 1278 fstring dnsdomname; 1279 1280 ZERO_STRUCT(guid); 1281 r_u->status = NT_STATUS_OK; 1282 1283 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) 1284 return NT_STATUS_INVALID_HANDLE; 1285 1286 switch (q_u->info_class) { 1287 case 0x0c: 1288 /* check if the user have enough rights */ 1289 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) 1290 return NT_STATUS_ACCESS_DENIED; 1291 1292 /* Request PolicyPrimaryDomainInformation. */ 1293 switch (lp_server_role()) { 1294 case ROLE_DOMAIN_PDC: 1295 case ROLE_DOMAIN_BDC: 1296 nb_name = get_global_sam_name(); 1297 /* ugly temp hack for these next two */ 1298 1299 /* This should be a 'netbios domain -> DNS domain' mapping */ 1300 dnsdomname[0] = '\0'; 1301 get_mydnsdomname(dnsdomname); 1302 strlower_m(dnsdomname); 1303 1304 dns_name = dnsdomname; 1305 forest_name = dnsdomname; 1306 1307 sid = get_global_sam_sid(); 1308 secrets_fetch_domain_guid(lp_workgroup(), &guid); 1309 break; 1310 default: 1311 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 1312 } 1313 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name, 1314 forest_name,&guid,sid); 1315 break; 1316 default: 1317 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class)); 1318 r_u->status = NT_STATUS_INVALID_INFO_CLASS; 1319 break; 1320 } 1321 1322 if (NT_STATUS_IS_OK(r_u->status)) { 1323 r_u->ptr = 0x1; 1324 r_u->info_class = q_u->info_class; 1325 } 1326 1327 return r_u->status; 1328} 1329#endif /* AD DC work in ongoing in Samba 4 */ 1330 1331/*************************************************************************** 1332 ***************************************************************************/ 1333 1334NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u) 1335{ 1336 struct lsa_info *info = NULL; 1337 int i = 0; 1338 DOM_SID sid; 1339 fstring privname; 1340 UNISTR2_ARRAY *uni_privnames = &q_u->rights; 1341 struct current_user user; 1342 1343 1344 /* find the connection policy handle. */ 1345 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) 1346 return NT_STATUS_INVALID_HANDLE; 1347 1348 /* check to see if the pipe_user is a Domain Admin since 1349 account_pol.tdb was already opened as root, this is all we have */ 1350 1351 get_current_user( &user, p ); 1352 if ( user.uid != sec_initial_uid() 1353 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 1354 { 1355 return NT_STATUS_ACCESS_DENIED; 1356 } 1357 1358 /* according to an NT4 PDC, you can add privileges to SIDs even without 1359 call_lsa_create_account() first. And you can use any arbitrary SID. */ 1360 1361 sid_copy( &sid, &q_u->sid.sid ); 1362 1363 /* just a little sanity check */ 1364 1365 if ( q_u->count != uni_privnames->count ) { 1366 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n")); 1367 return NT_STATUS_INVALID_HANDLE; 1368 } 1369 1370 for ( i=0; i<q_u->count; i++ ) { 1371 unistr2_to_ascii( privname, &uni_privnames->strings[i].string, sizeof(fstring)-1 ); 1372 1373 /* only try to add non-null strings */ 1374 1375 if ( *privname && !grant_privilege_by_name( &sid, privname ) ) { 1376 DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname )); 1377 return NT_STATUS_NO_SUCH_PRIVILEGE; 1378 } 1379 } 1380 1381 return NT_STATUS_OK; 1382} 1383 1384/*************************************************************************** 1385 ***************************************************************************/ 1386 1387NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u) 1388{ 1389 struct lsa_info *info = NULL; 1390 int i = 0; 1391 DOM_SID sid; 1392 fstring privname; 1393 UNISTR2_ARRAY *uni_privnames = &q_u->rights; 1394 struct current_user user; 1395 1396 1397 /* find the connection policy handle. */ 1398 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) 1399 return NT_STATUS_INVALID_HANDLE; 1400 1401 /* check to see if the pipe_user is a Domain Admin since 1402 account_pol.tdb was already opened as root, this is all we have */ 1403 1404 get_current_user( &user, p ); 1405 if ( user.uid != sec_initial_uid() 1406 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 1407 { 1408 return NT_STATUS_ACCESS_DENIED; 1409 } 1410 1411 sid_copy( &sid, &q_u->sid.sid ); 1412 1413 if ( q_u->removeall ) { 1414 if ( !revoke_all_privileges( &sid ) ) 1415 return NT_STATUS_ACCESS_DENIED; 1416 1417 return NT_STATUS_OK; 1418 } 1419 1420 /* just a little sanity check */ 1421 1422 if ( q_u->count != uni_privnames->count ) { 1423 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n")); 1424 return NT_STATUS_INVALID_HANDLE; 1425 } 1426 1427 for ( i=0; i<q_u->count; i++ ) { 1428 unistr2_to_ascii( privname, &uni_privnames->strings[i].string, sizeof(fstring)-1 ); 1429 1430 /* only try to add non-null strings */ 1431 1432 if ( *privname && !revoke_privilege_by_name( &sid, privname ) ) { 1433 DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname )); 1434 return NT_STATUS_NO_SUCH_PRIVILEGE; 1435 } 1436 } 1437 1438 return NT_STATUS_OK; 1439} 1440 1441 1442NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u) 1443{ 1444 struct lsa_info *info = NULL; 1445 DOM_SID sid; 1446 PRIVILEGE_SET privileges; 1447 SE_PRIV mask; 1448 1449 1450 /* find the connection policy handle. */ 1451 1452 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) 1453 return NT_STATUS_INVALID_HANDLE; 1454 1455 /* according to an NT4 PDC, you can add privileges to SIDs even without 1456 call_lsa_create_account() first. And you can use any arbitrary SID. */ 1457 1458 sid_copy( &sid, &q_u->sid.sid ); 1459 1460 if ( !get_privileges_for_sids( &mask, &sid, 1 ) ) 1461 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 1462 1463 privilege_set_init( &privileges ); 1464 1465 if ( se_priv_to_privilege_set( &privileges, &mask ) ) { 1466 1467 DEBUG(10,("_lsa_enum_acct_rights: %s has %d privileges\n", 1468 sid_string_static(&sid), privileges.count)); 1469 1470 r_u->status = init_r_enum_acct_rights( r_u, &privileges ); 1471 } 1472 else 1473 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE; 1474 1475 privilege_set_free( &privileges ); 1476 1477 return r_u->status; 1478} 1479 1480 1481NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u) 1482{ 1483 struct lsa_info *info = NULL; 1484 fstring name; 1485 LUID_ATTR priv_luid; 1486 SE_PRIV mask; 1487 1488 /* find the connection policy handle. */ 1489 1490 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) 1491 return NT_STATUS_INVALID_HANDLE; 1492 1493 unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name)); 1494 1495 DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name)); 1496 1497 if ( !se_priv_from_name( name, &mask ) ) 1498 return NT_STATUS_NO_SUCH_PRIVILEGE; 1499 1500 priv_luid = get_privilege_luid( &mask ); 1501 1502 r_u->luid.low = priv_luid.luid.low; 1503 r_u->luid.high = priv_luid.luid.high; 1504 1505 1506 return NT_STATUS_OK; 1507} 1508 1509