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 * Copyright (C) Gerald Carter 2003, 7 * Copyright (C) Volker Lendecke 2004 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 */ 23 24 25#include "includes.h" 26#include "utils/net.h" 27 28 29/********************************************************* 30 utility function to parse an integer parameter from 31 "parameter = value" 32**********************************************************/ 33static uint32 get_int_param( const char* param ) 34{ 35 char *p; 36 37 p = strchr( param, '=' ); 38 if ( !p ) 39 return 0; 40 41 return atoi(p+1); 42} 43 44/********************************************************* 45 utility function to parse an integer parameter from 46 "parameter = value" 47**********************************************************/ 48static char* get_string_param( const char* param ) 49{ 50 char *p; 51 52 p = strchr( param, '=' ); 53 if ( !p ) 54 return NULL; 55 56 return (p+1); 57} 58 59/********************************************************* 60 Figure out if the input was an NT group or a SID string. 61 Return the SID. 62**********************************************************/ 63static BOOL get_sid_from_input(DOM_SID *sid, char *input) 64{ 65 GROUP_MAP map; 66 67 if (StrnCaseCmp( input, "S-", 2)) { 68 /* Perhaps its the NT group name? */ 69 if (!pdb_getgrnam(&map, input)) { 70 printf("NT Group %s doesn't exist in mapping DB\n", input); 71 return False; 72 } else { 73 *sid = map.sid; 74 } 75 } else { 76 if (!string_to_sid(sid, input)) { 77 printf("converting sid %s from a string failed!\n", input); 78 return False; 79 } 80 } 81 return True; 82} 83 84/********************************************************* 85 Dump a GROUP_MAP entry to stdout (long or short listing) 86**********************************************************/ 87 88static void print_map_entry ( GROUP_MAP map, BOOL long_list ) 89{ 90 if (!long_list) 91 d_printf("%s (%s) -> %s\n", map.nt_name, 92 sid_string_static(&map.sid), gidtoname(map.gid)); 93 else { 94 d_printf("%s\n", map.nt_name); 95 d_printf("\tSID : %s\n", sid_string_static(&map.sid)); 96 d_printf("\tUnix gid : %d\n", map.gid); 97 d_printf("\tUnix group: %s\n", gidtoname(map.gid)); 98 d_printf("\tGroup type: %s\n", 99 sid_type_lookup(map.sid_name_use)); 100 d_printf("\tComment : %s\n", map.comment); 101 } 102 103} 104/********************************************************* 105 List the groups. 106**********************************************************/ 107static int net_groupmap_list(int argc, const char **argv) 108{ 109 size_t entries; 110 BOOL long_list = False; 111 size_t i; 112 fstring ntgroup = ""; 113 fstring sid_string = ""; 114 115 if (opt_verbose || opt_long_list_entries) 116 long_list = True; 117 118 /* get the options */ 119 for ( i=0; i<argc; i++ ) { 120 if ( !StrCaseCmp(argv[i], "verbose")) { 121 long_list = True; 122 } 123 else if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) { 124 fstrcpy( ntgroup, get_string_param( argv[i] ) ); 125 if ( !ntgroup[0] ) { 126 d_fprintf(stderr, "must supply a name\n"); 127 return -1; 128 } 129 } 130 else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) { 131 fstrcpy( sid_string, get_string_param( argv[i] ) ); 132 if ( !sid_string[0] ) { 133 d_fprintf(stderr, "must supply a SID\n"); 134 return -1; 135 } 136 } 137 else { 138 d_fprintf(stderr, "Bad option: %s\n", argv[i]); 139 return -1; 140 } 141 } 142 143 /* list a single group is given a name */ 144 if ( ntgroup[0] || sid_string[0] ) { 145 DOM_SID sid; 146 GROUP_MAP map; 147 148 if ( sid_string[0] ) 149 fstrcpy( ntgroup, sid_string); 150 151 if (!get_sid_from_input(&sid, ntgroup)) { 152 return -1; 153 } 154 155 /* Get the current mapping from the database */ 156 if(!pdb_getgrsid(&map, sid)) { 157 d_fprintf(stderr, "Failure to local group SID in the database\n"); 158 return -1; 159 } 160 161 print_map_entry( map, long_list ); 162 } 163 else { 164 GROUP_MAP *map=NULL; 165 /* enumerate all group mappings */ 166 if (!pdb_enum_group_mapping(NULL, SID_NAME_UNKNOWN, &map, &entries, ENUM_ALL_MAPPED)) 167 return -1; 168 169 for (i=0; i<entries; i++) { 170 print_map_entry( map[i], long_list ); 171 } 172 173 SAFE_FREE(map); 174 } 175 176 return 0; 177} 178 179/********************************************************* 180 Add a new group mapping entry 181**********************************************************/ 182 183static int net_groupmap_add(int argc, const char **argv) 184{ 185 DOM_SID sid; 186 fstring ntgroup = ""; 187 fstring unixgrp = ""; 188 fstring string_sid = ""; 189 fstring type = ""; 190 fstring ntcomment = ""; 191 enum lsa_SidType sid_type = SID_NAME_DOM_GRP; 192 uint32 rid = 0; 193 gid_t gid; 194 int i; 195 GROUP_MAP map; 196 197 const char *name_type; 198 199 ZERO_STRUCT(map); 200 201 /* Default is domain group. */ 202 map.sid_name_use = SID_NAME_DOM_GRP; 203 name_type = "domain group"; 204 205 /* get the options */ 206 for ( i=0; i<argc; i++ ) { 207 if ( !StrnCaseCmp(argv[i], "rid", strlen("rid")) ) { 208 rid = get_int_param(argv[i]); 209 if ( rid < DOMAIN_GROUP_RID_ADMINS ) { 210 d_fprintf(stderr, "RID must be greater than %d\n", (uint32)DOMAIN_GROUP_RID_ADMINS-1); 211 return -1; 212 } 213 } 214 else if ( !StrnCaseCmp(argv[i], "unixgroup", strlen("unixgroup")) ) { 215 fstrcpy( unixgrp, get_string_param( argv[i] ) ); 216 if ( !unixgrp[0] ) { 217 d_fprintf(stderr, "must supply a name\n"); 218 return -1; 219 } 220 } 221 else if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) { 222 fstrcpy( ntgroup, get_string_param( argv[i] ) ); 223 if ( !ntgroup[0] ) { 224 d_fprintf(stderr, "must supply a name\n"); 225 return -1; 226 } 227 } 228 else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) { 229 fstrcpy( string_sid, get_string_param( argv[i] ) ); 230 if ( !string_sid[0] ) { 231 d_fprintf(stderr, "must supply a SID\n"); 232 return -1; 233 } 234 } 235 else if ( !StrnCaseCmp(argv[i], "comment", strlen("comment")) ) { 236 fstrcpy( ntcomment, get_string_param( argv[i] ) ); 237 if ( !ntcomment[0] ) { 238 d_fprintf(stderr, "must supply a comment string\n"); 239 return -1; 240 } 241 } 242 else if ( !StrnCaseCmp(argv[i], "type", strlen("type")) ) { 243 fstrcpy( type, get_string_param( argv[i] ) ); 244 switch ( type[0] ) { 245 case 'b': 246 case 'B': 247 sid_type = SID_NAME_WKN_GRP; 248 name_type = "wellknown group"; 249 break; 250 case 'd': 251 case 'D': 252 sid_type = SID_NAME_DOM_GRP; 253 name_type = "domain group"; 254 break; 255 case 'l': 256 case 'L': 257 sid_type = SID_NAME_ALIAS; 258 name_type = "alias (local) group"; 259 break; 260 default: 261 d_fprintf(stderr, "unknown group type %s\n", type); 262 return -1; 263 } 264 } 265 else { 266 d_fprintf(stderr, "Bad option: %s\n", argv[i]); 267 return -1; 268 } 269 } 270 271 if ( !unixgrp[0] ) { 272 d_printf("Usage: net groupmap add {rid=<int>|sid=<string>} unixgroup=<string> [type=<domain|local|builtin>] [ntgroup=<string>] [comment=<string>]\n"); 273 return -1; 274 } 275 276 if ( (gid = nametogid(unixgrp)) == (gid_t)-1 ) { 277 d_fprintf(stderr, "Can't lookup UNIX group %s\n", unixgrp); 278 return -1; 279 } 280 281 { 282 if (pdb_getgrgid(&map, gid)) { 283 d_printf("Unix group %s already mapped to SID %s\n", 284 unixgrp, sid_string_static(&map.sid)); 285 return -1; 286 } 287 } 288 289 if ( (rid == 0) && (string_sid[0] == '\0') ) { 290 d_printf("No rid or sid specified, choosing a RID\n"); 291 if (pdb_rid_algorithm()) { 292 rid = algorithmic_pdb_gid_to_group_rid(gid); 293 } else { 294 if (!pdb_new_rid(&rid)) { 295 d_printf("Could not get new RID\n"); 296 } 297 } 298 d_printf("Got RID %d\n", rid); 299 } 300 301 /* append the rid to our own domain/machine SID if we don't have a full SID */ 302 if ( !string_sid[0] ) { 303 sid_copy(&sid, get_global_sam_sid()); 304 sid_append_rid(&sid, rid); 305 sid_to_string(string_sid, &sid); 306 } 307 308 if (!ntcomment[0]) { 309 switch (sid_type) { 310 case SID_NAME_WKN_GRP: 311 fstrcpy(ntcomment, "Wellknown Unix group"); 312 break; 313 case SID_NAME_DOM_GRP: 314 fstrcpy(ntcomment, "Domain Unix group"); 315 break; 316 case SID_NAME_ALIAS: 317 fstrcpy(ntcomment, "Local Unix group"); 318 break; 319 default: 320 fstrcpy(ntcomment, "Unix group"); 321 break; 322 } 323 } 324 325 if (!ntgroup[0] ) 326 fstrcpy( ntgroup, unixgrp ); 327 328 329 if (!NT_STATUS_IS_OK(add_initial_entry(gid, string_sid, sid_type, ntgroup, ntcomment))) { 330 d_fprintf(stderr, "adding entry for group %s failed!\n", ntgroup); 331 return -1; 332 } 333 334 d_printf("Successfully added group %s to the mapping db as a %s\n", 335 ntgroup, name_type); 336 return 0; 337} 338 339static int net_groupmap_modify(int argc, const char **argv) 340{ 341 DOM_SID sid; 342 GROUP_MAP map; 343 fstring ntcomment = ""; 344 fstring type = ""; 345 fstring ntgroup = ""; 346 fstring unixgrp = ""; 347 fstring sid_string = ""; 348 enum lsa_SidType sid_type = SID_NAME_UNKNOWN; 349 int i; 350 gid_t gid; 351 352 /* get the options */ 353 for ( i=0; i<argc; i++ ) { 354 if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) { 355 fstrcpy( ntgroup, get_string_param( argv[i] ) ); 356 if ( !ntgroup[0] ) { 357 d_fprintf(stderr, "must supply a name\n"); 358 return -1; 359 } 360 } 361 else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) { 362 fstrcpy( sid_string, get_string_param( argv[i] ) ); 363 if ( !sid_string[0] ) { 364 d_fprintf(stderr, "must supply a name\n"); 365 return -1; 366 } 367 } 368 else if ( !StrnCaseCmp(argv[i], "comment", strlen("comment")) ) { 369 fstrcpy( ntcomment, get_string_param( argv[i] ) ); 370 if ( !ntcomment[0] ) { 371 d_fprintf(stderr, "must supply a comment string\n"); 372 return -1; 373 } 374 } 375 else if ( !StrnCaseCmp(argv[i], "unixgroup", strlen("unixgroup")) ) { 376 fstrcpy( unixgrp, get_string_param( argv[i] ) ); 377 if ( !unixgrp[0] ) { 378 d_fprintf(stderr, "must supply a group name\n"); 379 return -1; 380 } 381 } 382 else if ( !StrnCaseCmp(argv[i], "type", strlen("type")) ) { 383 fstrcpy( type, get_string_param( argv[i] ) ); 384 switch ( type[0] ) { 385 case 'd': 386 case 'D': 387 sid_type = SID_NAME_DOM_GRP; 388 break; 389 case 'l': 390 case 'L': 391 sid_type = SID_NAME_ALIAS; 392 break; 393 } 394 } 395 else { 396 d_fprintf(stderr, "Bad option: %s\n", argv[i]); 397 return -1; 398 } 399 } 400 401 if ( !ntgroup[0] && !sid_string[0] ) { 402 d_printf("Usage: net groupmap modify {ntgroup=<string>|sid=<SID>} [comment=<string>] [unixgroup=<string>] [type=<domain|local>]\n"); 403 return -1; 404 } 405 406 /* give preference to the SID; if both the ntgroup name and SID 407 are defined, use the SID and assume that the group name could be a 408 new name */ 409 410 if ( sid_string[0] ) { 411 if (!get_sid_from_input(&sid, sid_string)) { 412 return -1; 413 } 414 } 415 else { 416 if (!get_sid_from_input(&sid, ntgroup)) { 417 return -1; 418 } 419 } 420 421 /* Get the current mapping from the database */ 422 if(!pdb_getgrsid(&map, sid)) { 423 d_fprintf(stderr, "Failure to local group SID in the database\n"); 424 return -1; 425 } 426 427 /* 428 * Allow changing of group type only between domain and local 429 * We disallow changing Builtin groups !!! (SID problem) 430 */ 431 if (sid_type == SID_NAME_UNKNOWN) { 432 d_fprintf(stderr, "Can't map to an unknown group type.\n"); 433 return -1; 434 } 435 436 if (map.sid_name_use == SID_NAME_WKN_GRP) { 437 d_fprintf(stderr, "You can only change between domain and local groups.\n"); 438 return -1; 439 } 440 441 map.sid_name_use=sid_type; 442 443 /* Change comment if new one */ 444 if ( ntcomment[0] ) 445 fstrcpy( map.comment, ntcomment ); 446 447 if ( ntgroup[0] ) 448 fstrcpy( map.nt_name, ntgroup ); 449 450 if ( unixgrp[0] ) { 451 gid = nametogid( unixgrp ); 452 if ( gid == -1 ) { 453 d_fprintf(stderr, "Unable to lookup UNIX group %s. Make sure the group exists.\n", 454 unixgrp); 455 return -1; 456 } 457 458 map.gid = gid; 459 } 460 461 if ( !NT_STATUS_IS_OK(pdb_update_group_mapping_entry(&map)) ) { 462 d_fprintf(stderr, "Could not update group database\n"); 463 return -1; 464 } 465 466 d_printf("Updated mapping entry for %s\n", map.nt_name); 467 468 return 0; 469} 470 471static int net_groupmap_delete(int argc, const char **argv) 472{ 473 DOM_SID sid; 474 fstring ntgroup = ""; 475 fstring sid_string = ""; 476 int i; 477 478 /* get the options */ 479 for ( i=0; i<argc; i++ ) { 480 if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) { 481 fstrcpy( ntgroup, get_string_param( argv[i] ) ); 482 if ( !ntgroup[0] ) { 483 d_fprintf(stderr, "must supply a name\n"); 484 return -1; 485 } 486 } 487 else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) { 488 fstrcpy( sid_string, get_string_param( argv[i] ) ); 489 if ( !sid_string[0] ) { 490 d_fprintf(stderr, "must supply a SID\n"); 491 return -1; 492 } 493 } 494 else { 495 d_fprintf(stderr, "Bad option: %s\n", argv[i]); 496 return -1; 497 } 498 } 499 500 if ( !ntgroup[0] && !sid_string[0]) { 501 d_printf("Usage: net groupmap delete {ntgroup=<string>|sid=<SID>}\n"); 502 return -1; 503 } 504 505 /* give preference to the SID if we have that */ 506 507 if ( sid_string[0] ) 508 fstrcpy( ntgroup, sid_string ); 509 510 if ( !get_sid_from_input(&sid, ntgroup) ) { 511 d_fprintf(stderr, "Unable to resolve group %s to a SID\n", ntgroup); 512 return -1; 513 } 514 515 if ( !NT_STATUS_IS_OK(pdb_delete_group_mapping_entry(sid)) ) { 516 d_fprintf(stderr, "Failed to removing group %s from the mapping db!\n", ntgroup); 517 return -1; 518 } 519 520 d_printf("Sucessfully removed %s from the mapping db\n", ntgroup); 521 522 return 0; 523} 524 525static int net_groupmap_set(int argc, const char **argv) 526{ 527 const char *ntgroup = NULL; 528 struct group *grp = NULL; 529 GROUP_MAP map; 530 BOOL have_map = False; 531 532 if ((argc < 1) || (argc > 2)) { 533 d_printf("Usage: net groupmap set \"NT Group\" " 534 "[\"unix group\"] [-C \"comment\"] [-L] [-D]\n"); 535 return -1; 536 } 537 538 if ( opt_localgroup && opt_domaingroup ) { 539 d_printf("Can only specify -L or -D, not both\n"); 540 return -1; 541 } 542 543 ntgroup = argv[0]; 544 545 if (argc == 2) { 546 grp = getgrnam(argv[1]); 547 548 if (grp == NULL) { 549 d_fprintf(stderr, "Could not find unix group %s\n", argv[1]); 550 return -1; 551 } 552 } 553 554 have_map = pdb_getgrnam(&map, ntgroup); 555 556 if (!have_map) { 557 DOM_SID sid; 558 have_map = ( (strncmp(ntgroup, "S-", 2) == 0) && 559 string_to_sid(&sid, ntgroup) && 560 pdb_getgrsid(&map, sid) ); 561 } 562 563 if (!have_map) { 564 565 /* Ok, add it */ 566 567 if (grp == NULL) { 568 d_fprintf(stderr, "Could not find group mapping for %s\n", 569 ntgroup); 570 return -1; 571 } 572 573 map.gid = grp->gr_gid; 574 575 if (opt_rid == 0) { 576 if ( pdb_rid_algorithm() ) 577 opt_rid = algorithmic_pdb_gid_to_group_rid(map.gid); 578 else { 579 if ( !pdb_new_rid((uint32*)&opt_rid) ) { 580 d_fprintf( stderr, "Could not allocate new RID\n"); 581 return -1; 582 } 583 } 584 } 585 586 sid_copy(&map.sid, get_global_sam_sid()); 587 sid_append_rid(&map.sid, opt_rid); 588 589 map.sid_name_use = SID_NAME_DOM_GRP; 590 fstrcpy(map.nt_name, ntgroup); 591 fstrcpy(map.comment, ""); 592 593 if (!NT_STATUS_IS_OK(pdb_add_group_mapping_entry(&map))) { 594 d_fprintf(stderr, "Could not add mapping entry for %s\n", 595 ntgroup); 596 return -1; 597 } 598 } 599 600 /* Now we have a mapping entry, update that stuff */ 601 602 if ( opt_localgroup || opt_domaingroup ) { 603 if (map.sid_name_use == SID_NAME_WKN_GRP) { 604 d_fprintf(stderr, "Can't change type of the BUILTIN group %s\n", 605 map.nt_name); 606 return -1; 607 } 608 } 609 610 if (opt_localgroup) 611 map.sid_name_use = SID_NAME_ALIAS; 612 613 if (opt_domaingroup) 614 map.sid_name_use = SID_NAME_DOM_GRP; 615 616 /* The case (opt_domaingroup && opt_localgroup) was tested for above */ 617 618 if (strlen(opt_comment) > 0) 619 fstrcpy(map.comment, opt_comment); 620 621 if (strlen(opt_newntname) > 0) 622 fstrcpy(map.nt_name, opt_newntname); 623 624 if (grp != NULL) 625 map.gid = grp->gr_gid; 626 627 if (!NT_STATUS_IS_OK(pdb_update_group_mapping_entry(&map))) { 628 d_fprintf(stderr, "Could not update group mapping for %s\n", ntgroup); 629 return -1; 630 } 631 632 return 0; 633} 634 635static int net_groupmap_cleanup(int argc, const char **argv) 636{ 637 GROUP_MAP *map = NULL; 638 size_t i, entries; 639 640 if (!pdb_enum_group_mapping(NULL, SID_NAME_UNKNOWN, &map, &entries, 641 ENUM_ALL_MAPPED)) { 642 d_fprintf(stderr, "Could not list group mappings\n"); 643 return -1; 644 } 645 646 for (i=0; i<entries; i++) { 647 648 if (map[i].gid == -1) 649 printf("Group %s is not mapped\n", map[i].nt_name); 650 651 if (!sid_check_is_in_our_domain(&map[i].sid)) { 652 printf("Deleting mapping for NT Group %s, sid %s\n", 653 map[i].nt_name, 654 sid_string_static(&map[i].sid)); 655 pdb_delete_group_mapping_entry(map[i].sid); 656 } 657 } 658 659 SAFE_FREE(map); 660 661 return 0; 662} 663 664static int net_groupmap_addmem(int argc, const char **argv) 665{ 666 DOM_SID alias, member; 667 668 if ( (argc != 2) || 669 !string_to_sid(&alias, argv[0]) || 670 !string_to_sid(&member, argv[1]) ) { 671 d_printf("Usage: net groupmap addmem alias-sid member-sid\n"); 672 return -1; 673 } 674 675 if (!NT_STATUS_IS_OK(pdb_add_aliasmem(&alias, &member))) { 676 d_fprintf(stderr, "Could not add sid %s to alias %s\n", 677 argv[1], argv[0]); 678 return -1; 679 } 680 681 return 0; 682} 683 684static int net_groupmap_delmem(int argc, const char **argv) 685{ 686 DOM_SID alias, member; 687 688 if ( (argc != 2) || 689 !string_to_sid(&alias, argv[0]) || 690 !string_to_sid(&member, argv[1]) ) { 691 d_printf("Usage: net groupmap delmem alias-sid member-sid\n"); 692 return -1; 693 } 694 695 if (!NT_STATUS_IS_OK(pdb_del_aliasmem(&alias, &member))) { 696 d_fprintf(stderr, "Could not delete sid %s from alias %s\n", 697 argv[1], argv[0]); 698 return -1; 699 } 700 701 return 0; 702} 703 704static int net_groupmap_listmem(int argc, const char **argv) 705{ 706 DOM_SID alias; 707 DOM_SID *members; 708 size_t i, num; 709 710 if ( (argc != 1) || 711 !string_to_sid(&alias, argv[0]) ) { 712 d_printf("Usage: net groupmap listmem alias-sid\n"); 713 return -1; 714 } 715 716 members = NULL; 717 num = 0; 718 719 if (!NT_STATUS_IS_OK(pdb_enum_aliasmem(&alias, &members, &num))) { 720 d_fprintf(stderr, "Could not list members for sid %s\n", argv[0]); 721 return -1; 722 } 723 724 for (i = 0; i < num; i++) { 725 printf("%s\n", sid_string_static(&(members[i]))); 726 } 727 728 SAFE_FREE(members); 729 730 return 0; 731} 732 733static BOOL print_alias_memberships(TALLOC_CTX *mem_ctx, 734 const DOM_SID *domain_sid, 735 const DOM_SID *member) 736{ 737 uint32 *alias_rids; 738 size_t i, num_alias_rids; 739 740 alias_rids = NULL; 741 num_alias_rids = 0; 742 743 if (!NT_STATUS_IS_OK(pdb_enum_alias_memberships( 744 mem_ctx, domain_sid, member, 1, 745 &alias_rids, &num_alias_rids))) { 746 d_fprintf(stderr, "Could not list memberships for sid %s\n", 747 sid_string_static(member)); 748 return False; 749 } 750 751 for (i = 0; i < num_alias_rids; i++) { 752 DOM_SID alias; 753 sid_copy(&alias, domain_sid); 754 sid_append_rid(&alias, alias_rids[i]); 755 printf("%s\n", sid_string_static(&alias)); 756 } 757 758 return True; 759} 760 761static int net_groupmap_memberships(int argc, const char **argv) 762{ 763 TALLOC_CTX *mem_ctx; 764 DOM_SID *domain_sid, *builtin_sid, member; 765 766 if ( (argc != 1) || 767 !string_to_sid(&member, argv[0]) ) { 768 d_printf("Usage: net groupmap memberof sid\n"); 769 return -1; 770 } 771 772 mem_ctx = talloc_init("net_groupmap_memberships"); 773 if (mem_ctx == NULL) { 774 d_fprintf(stderr, "talloc_init failed\n"); 775 return -1; 776 } 777 778 domain_sid = get_global_sam_sid(); 779 builtin_sid = string_sid_talloc(mem_ctx, "S-1-5-32"); 780 if ((domain_sid == NULL) || (builtin_sid == NULL)) { 781 d_fprintf(stderr, "Could not get domain sid\n"); 782 return -1; 783 } 784 785 if (!print_alias_memberships(mem_ctx, domain_sid, &member) || 786 !print_alias_memberships(mem_ctx, builtin_sid, &member)) 787 return -1; 788 789 talloc_destroy(mem_ctx); 790 791 return 0; 792} 793 794int net_help_groupmap(int argc, const char **argv) 795{ 796 d_printf("net groupmap add"\ 797 "\n Create a new group mapping\n"); 798 d_printf("net groupmap modify"\ 799 "\n Update a group mapping\n"); 800 d_printf("net groupmap delete"\ 801 "\n Remove a group mapping\n"); 802 d_printf("net groupmap addmem"\ 803 "\n Add a foreign alias member\n"); 804 d_printf("net groupmap delmem"\ 805 "\n Delete a foreign alias member\n"); 806 d_printf("net groupmap listmem"\ 807 "\n List foreign group members\n"); 808 d_printf("net groupmap memberships"\ 809 "\n List foreign group memberships\n"); 810 d_printf("net groupmap list"\ 811 "\n List current group map\n"); 812 d_printf("net groupmap set"\ 813 "\n Set group mapping\n"); 814 d_printf("net groupmap cleanup"\ 815 "\n Remove foreign group mapping entries\n"); 816 817 return -1; 818} 819 820 821/*********************************************************** 822 migrated functionality from smbgroupedit 823 **********************************************************/ 824int net_groupmap(int argc, const char **argv) 825{ 826 struct functable func[] = { 827 {"add", net_groupmap_add}, 828 {"modify", net_groupmap_modify}, 829 {"delete", net_groupmap_delete}, 830 {"set", net_groupmap_set}, 831 {"cleanup", net_groupmap_cleanup}, 832 {"addmem", net_groupmap_addmem}, 833 {"delmem", net_groupmap_delmem}, 834 {"listmem", net_groupmap_listmem}, 835 {"memberships", net_groupmap_memberships}, 836 {"list", net_groupmap_list}, 837 {"help", net_help_groupmap}, 838 {NULL, NULL} 839 }; 840 841 /* we shouldn't have silly checks like this */ 842 if (getuid() != 0) { 843 d_fprintf(stderr, "You must be root to edit group mappings.\n"); 844 return -1; 845 } 846 847 if ( argc ) 848 return net_run_function(argc, argv, func, net_help_groupmap); 849 850 return net_help_groupmap( argc, argv ); 851} 852 853