1/* 2 * Unix SMB/CIFS implementation. 3 * RPC Pipe client / server routines 4 * Copyright (C) Andrew Tridgell 1992-2000, 5 * Copyright (C) Jean Fran��ois Micouleau 1998-2001. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22#include "includes.h" 23 24static TDB_CONTEXT *tdb; /* used for driver files */ 25 26#define DATABASE_VERSION_V1 1 /* native byte format. */ 27#define DATABASE_VERSION_V2 2 /* le format. */ 28 29#define GROUP_PREFIX "UNIXGROUP/" 30 31/* Alias memberships are stored reverse, as memberships. The performance 32 * critical operation is to determine the aliases a SID is member of, not 33 * listing alias members. So we store a list of alias SIDs a SID is member of 34 * hanging of the member as key. 35 */ 36#define MEMBEROF_PREFIX "MEMBEROF/" 37 38/**************************************************************************** 39dump the mapping group mapping to a text file 40****************************************************************************/ 41char *decode_sid_name_use(fstring group, enum SID_NAME_USE name_use) 42{ 43 static fstring group_type; 44 45 switch(name_use) { 46 case SID_NAME_USER: 47 fstrcpy(group_type,"User"); 48 break; 49 case SID_NAME_DOM_GRP: 50 fstrcpy(group_type,"Domain group"); 51 break; 52 case SID_NAME_DOMAIN: 53 fstrcpy(group_type,"Domain"); 54 break; 55 case SID_NAME_ALIAS: 56 fstrcpy(group_type,"Local group"); 57 break; 58 case SID_NAME_WKN_GRP: 59 fstrcpy(group_type,"Builtin group"); 60 break; 61 case SID_NAME_DELETED: 62 fstrcpy(group_type,"Deleted"); 63 break; 64 case SID_NAME_INVALID: 65 fstrcpy(group_type,"Invalid"); 66 break; 67 case SID_NAME_UNKNOWN: 68 default: 69 fstrcpy(group_type,"Unknown type"); 70 break; 71 } 72 73 fstrcpy(group, group_type); 74 return group_type; 75} 76 77/**************************************************************************** 78initialise first time the mapping list - called from init_group_mapping() 79****************************************************************************/ 80static BOOL default_group_mapping(void) 81{ 82 DOM_SID sid_admins; 83 DOM_SID sid_users; 84 DOM_SID sid_guests; 85 fstring str_admins; 86 fstring str_users; 87 fstring str_guests; 88 89 /* Add the Wellknown groups */ 90 91 add_initial_entry(-1, "S-1-5-32-544", SID_NAME_WKN_GRP, "Administrators", ""); 92 add_initial_entry(-1, "S-1-5-32-545", SID_NAME_WKN_GRP, "Users", ""); 93 add_initial_entry(-1, "S-1-5-32-546", SID_NAME_WKN_GRP, "Guests", ""); 94 add_initial_entry(-1, "S-1-5-32-547", SID_NAME_WKN_GRP, "Power Users", ""); 95 add_initial_entry(-1, "S-1-5-32-548", SID_NAME_WKN_GRP, "Account Operators", ""); 96 add_initial_entry(-1, "S-1-5-32-549", SID_NAME_WKN_GRP, "System Operators", ""); 97 add_initial_entry(-1, "S-1-5-32-550", SID_NAME_WKN_GRP, "Print Operators", ""); 98 add_initial_entry(-1, "S-1-5-32-551", SID_NAME_WKN_GRP, "Backup Operators", ""); 99 add_initial_entry(-1, "S-1-5-32-552", SID_NAME_WKN_GRP, "Replicators", ""); 100 101 /* Add the defaults domain groups */ 102 103 sid_copy(&sid_admins, get_global_sam_sid()); 104 sid_append_rid(&sid_admins, DOMAIN_GROUP_RID_ADMINS); 105 sid_to_string(str_admins, &sid_admins); 106 add_initial_entry(-1, str_admins, SID_NAME_DOM_GRP, "Domain Admins", ""); 107 108 sid_copy(&sid_users, get_global_sam_sid()); 109 sid_append_rid(&sid_users, DOMAIN_GROUP_RID_USERS); 110 sid_to_string(str_users, &sid_users); 111 add_initial_entry(-1, str_users, SID_NAME_DOM_GRP, "Domain Users", ""); 112 113 sid_copy(&sid_guests, get_global_sam_sid()); 114 sid_append_rid(&sid_guests, DOMAIN_GROUP_RID_GUESTS); 115 sid_to_string(str_guests, &sid_guests); 116 add_initial_entry(-1, str_guests, SID_NAME_DOM_GRP, "Domain Guests", ""); 117 118 return True; 119} 120 121/**************************************************************************** 122 Open the group mapping tdb. 123****************************************************************************/ 124 125static BOOL init_group_mapping(void) 126{ 127 const char *vstring = "INFO/version"; 128 int32 vers_id; 129 130 if (tdb) 131 return True; 132 tdb = tdb_open_log(lock_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); 133 if (!tdb) { 134 DEBUG(0,("Failed to open group mapping database\n")); 135 return False; 136 } 137 138 /* handle a Samba upgrade */ 139 tdb_lock_bystring(tdb, vstring, 0); 140 141 /* Cope with byte-reversed older versions of the db. */ 142 vers_id = tdb_fetch_int32(tdb, vstring); 143 if ((vers_id == DATABASE_VERSION_V1) || (IREV(vers_id) == DATABASE_VERSION_V1)) { 144 /* Written on a bigendian machine with old fetch_int code. Save as le. */ 145 tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2); 146 vers_id = DATABASE_VERSION_V2; 147 } 148 149 if (vers_id != DATABASE_VERSION_V2) { 150 tdb_traverse(tdb, tdb_traverse_delete_fn, NULL); 151 tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2); 152 } 153 154 tdb_unlock_bystring(tdb, vstring); 155 156 /* write a list of default groups */ 157 if(!default_group_mapping()) 158 return False; 159 160 return True; 161} 162 163/**************************************************************************** 164****************************************************************************/ 165static BOOL add_mapping_entry(GROUP_MAP *map, int flag) 166{ 167 TDB_DATA kbuf, dbuf; 168 pstring key, buf; 169 fstring string_sid=""; 170 int len; 171 172 if(!init_group_mapping()) { 173 DEBUG(0,("failed to initialize group mapping\n")); 174 return(False); 175 } 176 177 sid_to_string(string_sid, &map->sid); 178 179 len = tdb_pack(buf, sizeof(buf), "ddff", 180 map->gid, map->sid_name_use, map->nt_name, map->comment); 181 182 if (len > sizeof(buf)) 183 return False; 184 185 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid); 186 187 kbuf.dsize = strlen(key)+1; 188 kbuf.dptr = key; 189 dbuf.dsize = len; 190 dbuf.dptr = buf; 191 if (tdb_store(tdb, kbuf, dbuf, flag) != 0) return False; 192 193 return True; 194} 195 196/**************************************************************************** 197initialise first time the mapping list 198****************************************************************************/ 199BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_use, const char *nt_name, const char *comment) 200{ 201 GROUP_MAP map; 202 203 if(!init_group_mapping()) { 204 DEBUG(0,("failed to initialize group mapping\n")); 205 return(False); 206 } 207 208 map.gid=gid; 209 if (!string_to_sid(&map.sid, sid)) { 210 DEBUG(0, ("string_to_sid failed: %s", sid)); 211 return False; 212 } 213 214 map.sid_name_use=sid_name_use; 215 fstrcpy(map.nt_name, nt_name); 216 fstrcpy(map.comment, comment); 217 218 return pdb_add_group_mapping_entry(&map); 219} 220 221/**************************************************************************** 222 Return the sid and the type of the unix group. 223****************************************************************************/ 224 225static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map) 226{ 227 TDB_DATA kbuf, dbuf; 228 pstring key; 229 fstring string_sid; 230 int ret = 0; 231 232 if(!init_group_mapping()) { 233 DEBUG(0,("failed to initialize group mapping\n")); 234 return(False); 235 } 236 237 /* the key is the SID, retrieving is direct */ 238 239 sid_to_string(string_sid, &sid); 240 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid); 241 242 kbuf.dptr = key; 243 kbuf.dsize = strlen(key)+1; 244 245 dbuf = tdb_fetch(tdb, kbuf); 246 if (!dbuf.dptr) 247 return False; 248 249 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", 250 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); 251 252 SAFE_FREE(dbuf.dptr); 253 254 if ( ret == -1 ) { 255 DEBUG(3,("get_group_map_from_sid: tdb_unpack failure\n")); 256 return False; 257 } 258 259 sid_copy(&map->sid, &sid); 260 261 return True; 262} 263 264/**************************************************************************** 265 Return the sid and the type of the unix group. 266****************************************************************************/ 267 268static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map) 269{ 270 TDB_DATA kbuf, dbuf, newkey; 271 fstring string_sid; 272 int ret; 273 274 if(!init_group_mapping()) { 275 DEBUG(0,("failed to initialize group mapping\n")); 276 return(False); 277 } 278 279 /* we need to enumerate the TDB to find the GID */ 280 281 for (kbuf = tdb_firstkey(tdb); 282 kbuf.dptr; 283 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { 284 285 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue; 286 287 dbuf = tdb_fetch(tdb, kbuf); 288 if (!dbuf.dptr) 289 continue; 290 291 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX)); 292 293 string_to_sid(&map->sid, string_sid); 294 295 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", 296 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); 297 298 SAFE_FREE(dbuf.dptr); 299 300 if ( ret == -1 ) { 301 DEBUG(3,("get_group_map_from_gid: tdb_unpack failure\n")); 302 return False; 303 } 304 305 if (gid==map->gid) { 306 SAFE_FREE(kbuf.dptr); 307 return True; 308 } 309 } 310 311 return False; 312} 313 314/**************************************************************************** 315 Return the sid and the type of the unix group. 316****************************************************************************/ 317 318static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map) 319{ 320 TDB_DATA kbuf, dbuf, newkey; 321 fstring string_sid; 322 int ret; 323 324 if(!init_group_mapping()) { 325 DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping\n")); 326 return(False); 327 } 328 329 /* we need to enumerate the TDB to find the name */ 330 331 for (kbuf = tdb_firstkey(tdb); 332 kbuf.dptr; 333 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { 334 335 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue; 336 337 dbuf = tdb_fetch(tdb, kbuf); 338 if (!dbuf.dptr) 339 continue; 340 341 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX)); 342 343 string_to_sid(&map->sid, string_sid); 344 345 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", 346 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); 347 348 SAFE_FREE(dbuf.dptr); 349 350 if ( ret == -1 ) { 351 DEBUG(3,("get_group_map_from_ntname: tdb_unpack failure\n")); 352 return False; 353 } 354 355 if (StrCaseCmp(name, map->nt_name)==0) { 356 SAFE_FREE(kbuf.dptr); 357 return True; 358 } 359 } 360 361 return False; 362} 363 364/**************************************************************************** 365 Remove a group mapping entry. 366****************************************************************************/ 367 368static BOOL group_map_remove(DOM_SID sid) 369{ 370 TDB_DATA kbuf, dbuf; 371 pstring key; 372 fstring string_sid; 373 374 if(!init_group_mapping()) { 375 DEBUG(0,("failed to initialize group mapping\n")); 376 return(False); 377 } 378 379 /* the key is the SID, retrieving is direct */ 380 381 sid_to_string(string_sid, &sid); 382 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid); 383 384 kbuf.dptr = key; 385 kbuf.dsize = strlen(key)+1; 386 387 dbuf = tdb_fetch(tdb, kbuf); 388 if (!dbuf.dptr) 389 return False; 390 391 SAFE_FREE(dbuf.dptr); 392 393 if(tdb_delete(tdb, kbuf) != TDB_SUCCESS) 394 return False; 395 396 return True; 397} 398 399/**************************************************************************** 400 Enumerate the group mapping. 401****************************************************************************/ 402 403static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, 404 int *num_entries, BOOL unix_only) 405{ 406 TDB_DATA kbuf, dbuf, newkey; 407 fstring string_sid; 408 fstring group_type; 409 GROUP_MAP map; 410 GROUP_MAP *mapt; 411 int ret; 412 int entries=0; 413 414 if(!init_group_mapping()) { 415 DEBUG(0,("failed to initialize group mapping\n")); 416 return(False); 417 } 418 419 *num_entries=0; 420 *rmap=NULL; 421 422 for (kbuf = tdb_firstkey(tdb); 423 kbuf.dptr; 424 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { 425 426 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) 427 continue; 428 429 dbuf = tdb_fetch(tdb, kbuf); 430 if (!dbuf.dptr) 431 continue; 432 433 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX)); 434 435 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", 436 &map.gid, &map.sid_name_use, &map.nt_name, &map.comment); 437 438 SAFE_FREE(dbuf.dptr); 439 440 if ( ret == -1 ) { 441 DEBUG(3,("enum_group_mapping: tdb_unpack failure\n")); 442 continue; 443 } 444 445 /* list only the type or everything if UNKNOWN */ 446 if (sid_name_use!=SID_NAME_UNKNOWN && sid_name_use!=map.sid_name_use) { 447 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name)); 448 continue; 449 } 450 451 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) { 452 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name)); 453 continue; 454 } 455 456 string_to_sid(&map.sid, string_sid); 457 458 decode_sid_name_use(group_type, map.sid_name_use); 459 DEBUG(11,("enum_group_mapping: returning group %s of type %s\n", map.nt_name ,group_type)); 460 461 mapt= SMB_REALLOC_ARRAY((*rmap), GROUP_MAP, entries+1); 462 if (!mapt) { 463 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n")); 464 SAFE_FREE(*rmap); 465 return False; 466 } 467 else 468 (*rmap) = mapt; 469 470 mapt[entries].gid = map.gid; 471 sid_copy( &mapt[entries].sid, &map.sid); 472 mapt[entries].sid_name_use = map.sid_name_use; 473 fstrcpy(mapt[entries].nt_name, map.nt_name); 474 fstrcpy(mapt[entries].comment, map.comment); 475 476 entries++; 477 478 } 479 480 *num_entries=entries; 481 482 return True; 483} 484 485/* This operation happens on session setup, so it should better be fast. We 486 * store a list of aliases a SID is member of hanging off MEMBEROF/SID. */ 487 488static NTSTATUS one_alias_membership(const DOM_SID *member, 489 DOM_SID **sids, int *num) 490{ 491 fstring key, string_sid; 492 TDB_DATA kbuf, dbuf; 493 const char *p; 494 495 if (!init_group_mapping()) { 496 DEBUG(0,("failed to initialize group mapping\n")); 497 return NT_STATUS_ACCESS_DENIED; 498 } 499 500 sid_to_string(string_sid, member); 501 slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid); 502 503 kbuf.dsize = strlen(key)+1; 504 kbuf.dptr = key; 505 506 dbuf = tdb_fetch(tdb, kbuf); 507 508 if (dbuf.dptr == NULL) { 509 return NT_STATUS_OK; 510 } 511 512 p = dbuf.dptr; 513 514 while (next_token(&p, string_sid, " ", sizeof(string_sid))) { 515 516 DOM_SID alias; 517 518 if (!string_to_sid(&alias, string_sid)) 519 continue; 520 521 add_sid_to_array_unique(&alias, sids, num); 522 523 if (sids == NULL) 524 return NT_STATUS_NO_MEMORY; 525 } 526 527 SAFE_FREE(dbuf.dptr); 528 return NT_STATUS_OK; 529} 530 531static NTSTATUS alias_memberships(const DOM_SID *members, int num_members, 532 DOM_SID **sids, int *num) 533{ 534 int i; 535 536 *num = 0; 537 *sids = NULL; 538 539 for (i=0; i<num_members; i++) { 540 NTSTATUS status = one_alias_membership(&members[i], sids, num); 541 if (!NT_STATUS_IS_OK(status)) 542 return status; 543 } 544 return NT_STATUS_OK; 545} 546 547static BOOL is_aliasmem(const DOM_SID *alias, const DOM_SID *member) 548{ 549 DOM_SID *sids; 550 int i, num; 551 552 /* This feels the wrong way round, but the on-disk data structure 553 * dictates it this way. */ 554 if (!NT_STATUS_IS_OK(alias_memberships(member, 1, &sids, &num))) 555 return False; 556 557 for (i=0; i<num; i++) { 558 if (sid_compare(alias, &sids[i]) == 0) { 559 SAFE_FREE(sids); 560 return True; 561 } 562 } 563 SAFE_FREE(sids); 564 return False; 565} 566 567static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member) 568{ 569 GROUP_MAP map; 570 TDB_DATA kbuf, dbuf; 571 pstring key; 572 fstring string_sid; 573 char *new_memberstring; 574 int result; 575 576 if(!init_group_mapping()) { 577 DEBUG(0,("failed to initialize group mapping\n")); 578 return NT_STATUS_ACCESS_DENIED; 579 } 580 581 if (!get_group_map_from_sid(*alias, &map)) 582 return NT_STATUS_NO_SUCH_ALIAS; 583 584 if ( (map.sid_name_use != SID_NAME_ALIAS) && 585 (map.sid_name_use != SID_NAME_WKN_GRP) ) 586 return NT_STATUS_NO_SUCH_ALIAS; 587 588 if (is_aliasmem(alias, member)) 589 return NT_STATUS_MEMBER_IN_ALIAS; 590 591 sid_to_string(string_sid, member); 592 slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid); 593 594 kbuf.dsize = strlen(key)+1; 595 kbuf.dptr = key; 596 597 dbuf = tdb_fetch(tdb, kbuf); 598 599 sid_to_string(string_sid, alias); 600 601 if (dbuf.dptr != NULL) { 602 asprintf(&new_memberstring, "%s %s", (char *)(dbuf.dptr), 603 string_sid); 604 } else { 605 new_memberstring = SMB_STRDUP(string_sid); 606 } 607 608 if (new_memberstring == NULL) 609 return NT_STATUS_NO_MEMORY; 610 611 SAFE_FREE(dbuf.dptr); 612 dbuf.dsize = strlen(new_memberstring)+1; 613 dbuf.dptr = new_memberstring; 614 615 result = tdb_store(tdb, kbuf, dbuf, 0); 616 617 SAFE_FREE(new_memberstring); 618 619 return (result == 0 ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED); 620} 621 622struct aliasmem_closure { 623 const DOM_SID *alias; 624 DOM_SID **sids; 625 int *num; 626}; 627 628static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data, 629 void *state) 630{ 631 struct aliasmem_closure *closure = (struct aliasmem_closure *)state; 632 const char *p; 633 fstring alias_string; 634 635 if (strncmp(key.dptr, MEMBEROF_PREFIX, 636 strlen(MEMBEROF_PREFIX)) != 0) 637 return 0; 638 639 p = data.dptr; 640 641 while (next_token(&p, alias_string, " ", sizeof(alias_string))) { 642 643 DOM_SID alias, member; 644 const char *member_string; 645 646 647 if (!string_to_sid(&alias, alias_string)) 648 continue; 649 650 if (sid_compare(closure->alias, &alias) != 0) 651 continue; 652 653 /* Ok, we found the alias we're looking for in the membership 654 * list currently scanned. The key represents the alias 655 * member. Add that. */ 656 657 member_string = strchr(key.dptr, '/'); 658 659 /* Above we tested for MEMBEROF_PREFIX which includes the 660 * slash. */ 661 662 SMB_ASSERT(member_string != NULL); 663 member_string += 1; 664 665 if (!string_to_sid(&member, member_string)) 666 continue; 667 668 add_sid_to_array(&member, closure->sids, closure->num); 669 } 670 671 return 0; 672} 673 674static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num) 675{ 676 GROUP_MAP map; 677 struct aliasmem_closure closure; 678 679 if(!init_group_mapping()) { 680 DEBUG(0,("failed to initialize group mapping\n")); 681 return NT_STATUS_ACCESS_DENIED; 682 } 683 684 if (!get_group_map_from_sid(*alias, &map)) 685 return NT_STATUS_NO_SUCH_ALIAS; 686 687 if ( (map.sid_name_use != SID_NAME_ALIAS) && 688 (map.sid_name_use != SID_NAME_WKN_GRP) ) 689 return NT_STATUS_NO_SUCH_ALIAS; 690 691 *sids = NULL; 692 *num = 0; 693 694 closure.alias = alias; 695 closure.sids = sids; 696 closure.num = num; 697 698 tdb_traverse(tdb, collect_aliasmem, &closure); 699 return NT_STATUS_OK; 700} 701 702static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member) 703{ 704 NTSTATUS result; 705 DOM_SID *sids; 706 int i, num; 707 BOOL found = False; 708 char *member_string; 709 TDB_DATA kbuf, dbuf; 710 pstring key; 711 fstring sid_string; 712 713 result = alias_memberships(member, 1, &sids, &num); 714 715 if (!NT_STATUS_IS_OK(result)) 716 return result; 717 718 for (i=0; i<num; i++) { 719 if (sid_compare(&sids[i], alias) == 0) { 720 found = True; 721 break; 722 } 723 } 724 725 if (!found) { 726 SAFE_FREE(sids); 727 return NT_STATUS_MEMBER_NOT_IN_ALIAS; 728 } 729 730 if (i < num) 731 sids[i] = sids[num-1]; 732 733 num -= 1; 734 735 sid_to_string(sid_string, member); 736 slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, sid_string); 737 738 kbuf.dsize = strlen(key)+1; 739 kbuf.dptr = key; 740 741 if (num == 0) 742 return tdb_delete(tdb, kbuf) == 0 ? 743 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 744 745 member_string = SMB_STRDUP(""); 746 747 if (member_string == NULL) { 748 SAFE_FREE(sids); 749 return NT_STATUS_NO_MEMORY; 750 } 751 752 for (i=0; i<num; i++) { 753 char *s = member_string; 754 755 sid_to_string(sid_string, &sids[i]); 756 asprintf(&member_string, "%s %s", s, sid_string); 757 758 SAFE_FREE(s); 759 if (member_string == NULL) { 760 SAFE_FREE(sids); 761 return NT_STATUS_NO_MEMORY; 762 } 763 } 764 765 dbuf.dsize = strlen(member_string)+1; 766 dbuf.dptr = member_string; 767 768 result = tdb_store(tdb, kbuf, dbuf, 0) == 0 ? 769 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED; 770 771 SAFE_FREE(sids); 772 SAFE_FREE(member_string); 773 774 return result; 775} 776 777/* 778 * 779 * High level functions 780 * better to use them than the lower ones. 781 * 782 * we are checking if the group is in the mapping file 783 * and if the group is an existing unix group 784 * 785 */ 786 787/* get a domain group from it's SID */ 788 789BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map) 790{ 791 struct group *grp; 792 BOOL ret; 793 794 if(!init_group_mapping()) { 795 DEBUG(0,("failed to initialize group mapping\n")); 796 return(False); 797 } 798 799 DEBUG(10, ("get_domain_group_from_sid\n")); 800 801 /* if the group is NOT in the database, it CAN NOT be a domain group */ 802 803 become_root(); 804 ret = pdb_getgrsid(map, sid); 805 unbecome_root(); 806 807 if ( !ret ) 808 return False; 809 810 DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n")); 811 812 /* if it's not a domain group, continue */ 813 if (map->sid_name_use!=SID_NAME_DOM_GRP) { 814 return False; 815 } 816 817 DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n")); 818 819 if (map->gid==-1) { 820 return False; 821 } 822 823 DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%lu\n",(unsigned long)map->gid)); 824 825 grp = getgrgid(map->gid); 826 if ( !grp ) { 827 DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n")); 828 return False; 829 } 830 831 DEBUG(10, ("get_domain_group_from_sid: gid exists in UNIX security\n")); 832 833 return True; 834} 835 836 837/* get a local (alias) group from it's SID */ 838 839BOOL get_local_group_from_sid(DOM_SID *sid, GROUP_MAP *map) 840{ 841 BOOL ret; 842 843 if(!init_group_mapping()) { 844 DEBUG(0,("failed to initialize group mapping\n")); 845 return(False); 846 } 847 848 /* The group is in the mapping table */ 849 become_root(); 850 ret = pdb_getgrsid(map, *sid); 851 unbecome_root(); 852 853 if ( !ret ) 854 return False; 855 856 if ( ( (map->sid_name_use != SID_NAME_ALIAS) && 857 (map->sid_name_use != SID_NAME_WKN_GRP) ) 858 || (map->gid == -1) 859 || (getgrgid(map->gid) == NULL) ) 860 { 861 return False; 862 } 863 864#if 1 /* JERRY */ 865 /* local groups only exist in the group mapping DB so this 866 is not necessary */ 867 868 else { 869 /* the group isn't in the mapping table. 870 * make one based on the unix information */ 871 uint32 alias_rid; 872 struct group *grp; 873 874 sid_peek_rid(sid, &alias_rid); 875 map->gid=pdb_group_rid_to_gid(alias_rid); 876 877 grp = getgrgid(map->gid); 878 if ( !grp ) { 879 DEBUG(3,("get_local_group_from_sid: No unix group for [%ul]\n", map->gid)); 880 return False; 881 } 882 883 map->sid_name_use=SID_NAME_ALIAS; 884 885 fstrcpy(map->nt_name, grp->gr_name); 886 fstrcpy(map->comment, "Local Unix Group"); 887 888 sid_copy(&map->sid, sid); 889 } 890#endif 891 892 return True; 893} 894 895/* get a builtin group from it's SID */ 896 897BOOL get_builtin_group_from_sid(DOM_SID *sid, GROUP_MAP *map) 898{ 899 struct group *grp; 900 BOOL ret; 901 902 903 if(!init_group_mapping()) { 904 DEBUG(0,("failed to initialize group mapping\n")); 905 return(False); 906 } 907 908 become_root(); 909 ret = pdb_getgrsid(map, *sid); 910 unbecome_root(); 911 912 if ( !ret ) 913 return False; 914 915 if (map->sid_name_use!=SID_NAME_WKN_GRP) { 916 return False; 917 } 918 919 if (map->gid==-1) { 920 return False; 921 } 922 923 if ( (grp=getgrgid(map->gid)) == NULL) { 924 return False; 925 } 926 927 return True; 928} 929 930 931 932/**************************************************************************** 933Returns a GROUP_MAP struct based on the gid. 934****************************************************************************/ 935BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map) 936{ 937 struct group *grp; 938 BOOL ret; 939 940 if(!init_group_mapping()) { 941 DEBUG(0,("failed to initialize group mapping\n")); 942 return(False); 943 } 944 945 if ( (grp=getgrgid(gid)) == NULL) 946 return False; 947 948 become_root(); 949 ret = pdb_getgrgid(map, gid); 950 unbecome_root(); 951 952 if ( !ret ) { 953 return False; 954 } 955 956 return True; 957} 958 959 960/**************************************************************************** 961 Create a UNIX group on demand. 962****************************************************************************/ 963 964int smb_create_group(char *unix_group, gid_t *new_gid) 965{ 966 pstring add_script; 967 int ret = -1; 968 int fd = 0; 969 970 *new_gid = 0; 971 972 /* defer to scripts */ 973 974 if ( *lp_addgroup_script() ) { 975 pstrcpy(add_script, lp_addgroup_script()); 976 pstring_sub(add_script, "%g", unix_group); 977 ret = smbrun(add_script, (new_gid!=NULL) ? &fd : NULL); 978 DEBUG(ret ? 0 : 3,("smb_create_group: Running the command `%s' gave %d\n",add_script,ret)); 979 if (ret != 0) 980 return ret; 981 982 if (fd != 0) { 983 fstring output; 984 985 *new_gid = 0; 986 if (read(fd, output, sizeof(output)) > 0) { 987 *new_gid = (gid_t)strtoul(output, NULL, 10); 988 } 989 990 close(fd); 991 } 992 993 } else if ( winbind_create_group( unix_group, NULL ) ) { 994 995 DEBUG(3,("smb_create_group: winbindd created the group (%s)\n", 996 unix_group)); 997 ret = 0; 998 } 999 1000 if (*new_gid == 0) { 1001 struct group *grp = getgrnam(unix_group); 1002 1003 if (grp != NULL) 1004 *new_gid = grp->gr_gid; 1005 } 1006 1007 return ret; 1008} 1009 1010/**************************************************************************** 1011 Delete a UNIX group on demand. 1012****************************************************************************/ 1013 1014int smb_delete_group(char *unix_group) 1015{ 1016 pstring del_script; 1017 int ret; 1018 1019 /* defer to scripts */ 1020 1021 if ( *lp_delgroup_script() ) { 1022 pstrcpy(del_script, lp_delgroup_script()); 1023 pstring_sub(del_script, "%g", unix_group); 1024 ret = smbrun(del_script,NULL); 1025 DEBUG(ret ? 0 : 3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret)); 1026 return ret; 1027 } 1028 1029 if ( winbind_delete_group( unix_group ) ) { 1030 DEBUG(3,("smb_delete_group: winbindd deleted the group (%s)\n", 1031 unix_group)); 1032 return 0; 1033 } 1034 1035 return -1; 1036} 1037 1038/**************************************************************************** 1039 Set a user's primary UNIX group. 1040****************************************************************************/ 1041int smb_set_primary_group(const char *unix_group, const char* unix_user) 1042{ 1043 pstring add_script; 1044 int ret; 1045 1046 /* defer to scripts */ 1047 1048 if ( *lp_setprimarygroup_script() ) { 1049 pstrcpy(add_script, lp_setprimarygroup_script()); 1050 all_string_sub(add_script, "%g", unix_group, sizeof(add_script)); 1051 all_string_sub(add_script, "%u", unix_user, sizeof(add_script)); 1052 ret = smbrun(add_script,NULL); 1053 flush_pwnam_cache(); 1054 DEBUG(ret ? 0 : 3,("smb_set_primary_group: " 1055 "Running the command `%s' gave %d\n",add_script,ret)); 1056 return ret; 1057 } 1058 1059 /* Try winbindd */ 1060 1061 if ( winbind_set_user_primary_group( unix_user, unix_group ) ) { 1062 DEBUG(3,("smb_delete_group: winbindd set the group (%s) as the primary group for user (%s)\n", 1063 unix_group, unix_user)); 1064 flush_pwnam_cache(); 1065 return 0; 1066 } 1067 1068 return -1; 1069} 1070 1071/**************************************************************************** 1072 Add a user to a UNIX group. 1073****************************************************************************/ 1074 1075int smb_add_user_group(char *unix_group, char *unix_user) 1076{ 1077 pstring add_script; 1078 int ret; 1079 1080 /* defer to scripts */ 1081 1082 if ( *lp_addusertogroup_script() ) { 1083 pstrcpy(add_script, lp_addusertogroup_script()); 1084 pstring_sub(add_script, "%g", unix_group); 1085 pstring_sub(add_script, "%u", unix_user); 1086 ret = smbrun(add_script,NULL); 1087 DEBUG(ret ? 0 : 3,("smb_add_user_group: Running the command `%s' gave %d\n",add_script,ret)); 1088 return ret; 1089 } 1090 1091 /* Try winbindd */ 1092 1093 if ( winbind_add_user_to_group( unix_user, unix_group ) ) { 1094 DEBUG(3,("smb_delete_group: winbindd added user (%s) to the group (%s)\n", 1095 unix_user, unix_group)); 1096 return -1; 1097 } 1098 1099 return -1; 1100} 1101 1102/**************************************************************************** 1103 Delete a user from a UNIX group 1104****************************************************************************/ 1105 1106int smb_delete_user_group(const char *unix_group, const char *unix_user) 1107{ 1108 pstring del_script; 1109 int ret; 1110 1111 /* defer to scripts */ 1112 1113 if ( *lp_deluserfromgroup_script() ) { 1114 pstrcpy(del_script, lp_deluserfromgroup_script()); 1115 pstring_sub(del_script, "%g", unix_group); 1116 pstring_sub(del_script, "%u", unix_user); 1117 ret = smbrun(del_script,NULL); 1118 DEBUG(ret ? 0 : 3,("smb_delete_user_group: Running the command `%s' gave %d\n",del_script,ret)); 1119 return ret; 1120 } 1121 1122 /* Try winbindd */ 1123 1124 if ( winbind_remove_user_from_group( unix_user, unix_group ) ) { 1125 DEBUG(3,("smb_delete_group: winbindd removed user (%s) from the group (%s)\n", 1126 unix_user, unix_group)); 1127 return 0; 1128 } 1129 1130 return -1; 1131} 1132 1133 1134NTSTATUS pdb_default_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, 1135 DOM_SID sid) 1136{ 1137 return get_group_map_from_sid(sid, map) ? 1138 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 1139} 1140 1141NTSTATUS pdb_default_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, 1142 gid_t gid) 1143{ 1144 return get_group_map_from_gid(gid, map) ? 1145 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 1146} 1147 1148NTSTATUS pdb_default_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, 1149 const char *name) 1150{ 1151 return get_group_map_from_ntname(name, map) ? 1152 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 1153} 1154 1155NTSTATUS pdb_default_add_group_mapping_entry(struct pdb_methods *methods, 1156 GROUP_MAP *map) 1157{ 1158 return add_mapping_entry(map, TDB_INSERT) ? 1159 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 1160} 1161 1162NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods, 1163 GROUP_MAP *map) 1164{ 1165 return add_mapping_entry(map, TDB_REPLACE) ? 1166 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 1167} 1168 1169NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods, 1170 DOM_SID sid) 1171{ 1172 return group_map_remove(sid) ? 1173 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 1174} 1175 1176NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods, 1177 enum SID_NAME_USE sid_name_use, 1178 GROUP_MAP **rmap, int *num_entries, 1179 BOOL unix_only) 1180{ 1181 return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only) ? 1182 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 1183} 1184 1185NTSTATUS pdb_default_find_alias(struct pdb_methods *methods, 1186 const char *name, DOM_SID *sid) 1187{ 1188 GROUP_MAP map; 1189 1190 if (!pdb_getgrnam(&map, name)) 1191 return NT_STATUS_NO_SUCH_ALIAS; 1192 1193 if ((map.sid_name_use != SID_NAME_WKN_GRP) && 1194 (map.sid_name_use != SID_NAME_ALIAS)) 1195 return NT_STATUS_OBJECT_TYPE_MISMATCH; 1196 1197 sid_copy(sid, &map.sid); 1198 return NT_STATUS_OK; 1199} 1200 1201NTSTATUS pdb_default_create_alias(struct pdb_methods *methods, 1202 const char *name, uint32 *rid) 1203{ 1204 DOM_SID sid; 1205 enum SID_NAME_USE type; 1206 uint32 new_rid; 1207 gid_t gid; 1208 1209 GROUP_MAP map; 1210 1211 if (lookup_name(get_global_sam_name(), name, &sid, &type)) 1212 return NT_STATUS_ALIAS_EXISTS; 1213 1214 if (!winbind_allocate_rid(&new_rid)) 1215 return NT_STATUS_ACCESS_DENIED; 1216 1217 sid_copy(&sid, get_global_sam_sid()); 1218 sid_append_rid(&sid, new_rid); 1219 1220 /* Here we allocate the gid */ 1221 if (!winbind_sid_to_gid(&gid, &sid)) { 1222 DEBUG(0, ("Could not get gid for new RID\n")); 1223 return NT_STATUS_ACCESS_DENIED; 1224 } 1225 1226 map.gid = gid; 1227 sid_copy(&map.sid, &sid); 1228 map.sid_name_use = SID_NAME_ALIAS; 1229 fstrcpy(map.nt_name, name); 1230 fstrcpy(map.comment, ""); 1231 1232 if (!pdb_add_group_mapping_entry(&map)) { 1233 DEBUG(0, ("Could not add group mapping entry for alias %s\n", 1234 name)); 1235 return NT_STATUS_ACCESS_DENIED; 1236 } 1237 1238 *rid = new_rid; 1239 1240 return NT_STATUS_OK; 1241} 1242 1243NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods, 1244 const DOM_SID *sid) 1245{ 1246 return pdb_delete_group_mapping_entry(*sid) ? 1247 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED; 1248} 1249 1250NTSTATUS pdb_default_enum_aliases(struct pdb_methods *methods, 1251 const DOM_SID *sid, 1252 uint32 start_idx, uint32 max_entries, 1253 uint32 *num_aliases, 1254 struct acct_info **info) 1255{ 1256 extern DOM_SID global_sid_Builtin; 1257 1258 GROUP_MAP *map; 1259 int i, num_maps; 1260 enum SID_NAME_USE type = SID_NAME_UNKNOWN; 1261 1262 if (sid_compare(sid, get_global_sam_sid()) == 0) 1263 type = SID_NAME_ALIAS; 1264 1265 if (sid_compare(sid, &global_sid_Builtin) == 0) 1266 type = SID_NAME_WKN_GRP; 1267 1268 if (!pdb_enum_group_mapping(type, &map, &num_maps, False) || 1269 (num_maps == 0)) { 1270 *num_aliases = 0; 1271 *info = NULL; 1272 goto done; 1273 } 1274 1275 if (start_idx > num_maps) { 1276 *num_aliases = 0; 1277 *info = NULL; 1278 goto done; 1279 } 1280 1281 *num_aliases = num_maps - start_idx; 1282 1283 if (*num_aliases > max_entries) 1284 *num_aliases = max_entries; 1285 1286 *info = SMB_MALLOC_ARRAY(struct acct_info, *num_aliases); 1287 1288 for (i=0; i<*num_aliases; i++) { 1289 fstrcpy((*info)[i].acct_name, map[i+start_idx].nt_name); 1290 fstrcpy((*info)[i].acct_desc, map[i+start_idx].comment); 1291 sid_peek_rid(&map[i].sid, &(*info)[i+start_idx].rid); 1292 } 1293 1294 done: 1295 SAFE_FREE(map); 1296 return NT_STATUS_OK; 1297} 1298 1299NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods, 1300 const DOM_SID *sid, 1301 struct acct_info *info) 1302{ 1303 GROUP_MAP map; 1304 1305 if (!pdb_getgrsid(&map, *sid)) 1306 return NT_STATUS_NO_SUCH_ALIAS; 1307 1308 fstrcpy(info->acct_name, map.nt_name); 1309 fstrcpy(info->acct_desc, map.comment); 1310 sid_peek_rid(&map.sid, &info->rid); 1311 return NT_STATUS_OK; 1312} 1313 1314NTSTATUS pdb_default_set_aliasinfo(struct pdb_methods *methods, 1315 const DOM_SID *sid, 1316 struct acct_info *info) 1317{ 1318 GROUP_MAP map; 1319 1320 if (!pdb_getgrsid(&map, *sid)) 1321 return NT_STATUS_NO_SUCH_ALIAS; 1322 1323 fstrcpy(map.comment, info->acct_desc); 1324 1325 if (!pdb_update_group_mapping_entry(&map)) 1326 return NT_STATUS_ACCESS_DENIED; 1327 1328 return NT_STATUS_OK; 1329} 1330 1331NTSTATUS pdb_default_add_aliasmem(struct pdb_methods *methods, 1332 const DOM_SID *alias, const DOM_SID *member) 1333{ 1334 return add_aliasmem(alias, member); 1335} 1336 1337NTSTATUS pdb_default_del_aliasmem(struct pdb_methods *methods, 1338 const DOM_SID *alias, const DOM_SID *member) 1339{ 1340 return del_aliasmem(alias, member); 1341} 1342 1343NTSTATUS pdb_default_enum_aliasmem(struct pdb_methods *methods, 1344 const DOM_SID *alias, DOM_SID **members, 1345 int *num_members) 1346{ 1347 return enum_aliasmem(alias, members, num_members); 1348} 1349 1350NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods, 1351 const DOM_SID *members, 1352 int num_members, 1353 DOM_SID **aliases, int *num) 1354{ 1355 return alias_memberships(members, num_members, aliases, num); 1356} 1357 1358/********************************************************************** 1359 no ops for passdb backends that don't implement group mapping 1360 *********************************************************************/ 1361 1362NTSTATUS pdb_nop_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, 1363 DOM_SID sid) 1364{ 1365 return NT_STATUS_UNSUCCESSFUL; 1366} 1367 1368NTSTATUS pdb_nop_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, 1369 gid_t gid) 1370{ 1371 return NT_STATUS_UNSUCCESSFUL; 1372} 1373 1374NTSTATUS pdb_nop_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, 1375 const char *name) 1376{ 1377 return NT_STATUS_UNSUCCESSFUL; 1378} 1379 1380NTSTATUS pdb_nop_add_group_mapping_entry(struct pdb_methods *methods, 1381 GROUP_MAP *map) 1382{ 1383 return NT_STATUS_UNSUCCESSFUL; 1384} 1385 1386NTSTATUS pdb_nop_update_group_mapping_entry(struct pdb_methods *methods, 1387 GROUP_MAP *map) 1388{ 1389 return NT_STATUS_UNSUCCESSFUL; 1390} 1391 1392NTSTATUS pdb_nop_delete_group_mapping_entry(struct pdb_methods *methods, 1393 DOM_SID sid) 1394{ 1395 return NT_STATUS_UNSUCCESSFUL; 1396} 1397 1398NTSTATUS pdb_nop_enum_group_mapping(struct pdb_methods *methods, 1399 enum SID_NAME_USE sid_name_use, 1400 GROUP_MAP **rmap, int *num_entries, 1401 BOOL unix_only) 1402{ 1403 return NT_STATUS_UNSUCCESSFUL; 1404} 1405 1406