static int net_groupmap_cleanup(struct net_context *c, int argc, const char **argv) { GROUP_MAP **maps = NULL; size_t i, entries; if (c->display_usage) { d_printf( "%s\n" "net groupmap cleanup\n" " %s\n", _("Usage:"), _("Delete all group mappings")); return 0; } if (!pdb_enum_group_mapping(NULL, SID_NAME_UNKNOWN, &maps, &entries, ENUM_ALL_MAPPED)) { d_fprintf(stderr, _("Could not list group mappings\n")); return -1; } for (i=0; i<entries; i++) { if (maps[i]->gid == -1) printf(_("Group %s is not mapped\n"), maps[i]->nt_name); if (!sid_check_is_in_our_domain(&maps[i]->sid)) { printf(_("Deleting mapping for NT Group %s, sid %s\n"), maps[i]->nt_name, sid_string_tos(&maps[i]->sid)); pdb_delete_group_mapping_entry(maps[i]->sid); } } TALLOC_FREE(maps); return 0; }
/********************************************************* List the groups. **********************************************************/ static int net_groupmap_list(struct net_context *c, int argc, const char **argv) { size_t entries; bool long_list = false; size_t i; fstring ntgroup = ""; fstring sid_string = ""; const char list_usage_str[] = N_("net groupmap list [verbose] " "[ntgroup=NT group] [sid=SID]\n" " verbose\tPrint verbose list\n" " ntgroup\tNT group to list\n" " sid\tSID of group to list"); if (c->display_usage) { d_printf("%s\n%s\n", _("Usage: "), list_usage_str); return 0; } if (c->opt_verbose || c->opt_long_list_entries) long_list = true; /* get the options */ for ( i=0; i<argc; i++ ) { if ( !strcasecmp_m(argv[i], "verbose")) { long_list = true; } else if ( !strncasecmp_m(argv[i], "ntgroup", strlen("ntgroup")) ) { fstrcpy( ntgroup, get_string_param( argv[i] ) ); if ( !ntgroup[0] ) { d_fprintf(stderr, _("must supply a name\n")); return -1; } } else if ( !strncasecmp_m(argv[i], "sid", strlen("sid")) ) { fstrcpy( sid_string, get_string_param( argv[i] ) ); if ( !sid_string[0] ) { d_fprintf(stderr, _("must supply a SID\n")); return -1; } } else { d_fprintf(stderr, _("Bad option: %s\n"), argv[i]); d_printf("%s\n%s\n", _("Usage:"), list_usage_str); return -1; } } /* list a single group is given a name */ if ( ntgroup[0] || sid_string[0] ) { struct dom_sid sid; GROUP_MAP *map; if ( sid_string[0] ) strlcpy(ntgroup, sid_string, sizeof(ntgroup)); if (!get_sid_from_input(&sid, ntgroup)) { return -1; } map = talloc_zero(NULL, GROUP_MAP); if (!map) { return -1; } /* Get the current mapping from the database */ if(!pdb_getgrsid(map, sid)) { d_fprintf(stderr, _("Failure to local group SID in the " "database\n")); TALLOC_FREE(map); return -1; } print_map_entry(map, long_list ); TALLOC_FREE(map); } else { GROUP_MAP **maps = NULL; bool ok = false; /* enumerate all group mappings */ ok = pdb_enum_group_mapping(NULL, SID_NAME_UNKNOWN, &maps, &entries, ENUM_ALL_MAPPED); if (!ok) { return -1; } for (i=0; i<entries; i++) { print_map_entry(maps[i], long_list); } TALLOC_FREE(maps); } return 0; }
/******************************************************************* gets a domain user's groups ********************************************************************/ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SAM_ACCOUNT *sam_pass) { GROUP_MAP *map=NULL; int i, num, num_entries, cur_gid=0; struct group *grp; DOM_GID *gids; fstring user_name; uint32 grid; uint32 tmp_rid; BOOL ret; *numgroups= 0; fstrcpy(user_name, pdb_get_username(sam_pass)); grid=pdb_get_group_rid(sam_pass); DEBUG(10,("get_domain_user_groups: searching domain groups [%s] is a member of\n", user_name)); /* we must wrap this is become/unbecome root for ldap backends */ become_root(); /* first get the list of the domain groups */ ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED); unbecome_root(); /* end wrapper for group enumeration */ if ( !ret ) return False; DEBUG(10,("get_domain_user_groups: there are %d mapped groups\n", num_entries)); /* * alloc memory. In the worse case, we alloc memory for nothing. * but I prefer to alloc for nothing * than reallocing everytime. */ gids = (DOM_GID *)talloc(ctx, sizeof(DOM_GID) * num_entries); /* for each group, check if the user is a member of. Only include groups from this domain */ for(i=0; i<num_entries; i++) { if ( !sid_check_is_in_our_domain(&map[i].sid) ) { DEBUG(10,("get_domain_user_groups: skipping check of %s since it is not in our domain\n", map[i].nt_name)); continue; } if ((grp=sys_getgrgid(map[i].gid)) == NULL) { /* very weird !!! */ DEBUG(5,("get_domain_user_groups: gid %d doesn't exist anymore !\n", (int)map[i].gid)); continue; } for(num=0; grp->gr_mem[num]!=NULL; num++) { if(strcmp(grp->gr_mem[num], user_name)==0) { /* we found the user, add the group to the list */ sid_peek_rid(&map[i].sid, &(gids[cur_gid].g_rid)); gids[cur_gid].attr=7; DEBUG(10,("get_domain_user_groups: user found in group %s\n", map[i].nt_name)); cur_gid++; break; } } } /* we have checked the groups */ /* we must now check the gid of the user or the primary group rid, that's the same */ for (i=0; i<cur_gid && grid!=gids[i].g_rid; i++) ; /* the user's gid is already there */ if (i!=cur_gid) { /* * the primary group of the user but be the first one in the list * don't ask ! JFM. */ gids[i].g_rid=gids[0].g_rid; gids[0].g_rid=grid; goto done; } for(i=0; i<num_entries; i++) { sid_peek_rid(&map[i].sid, &tmp_rid); if (tmp_rid==grid) { /* * the primary group of the user but be the first one in the list * don't ask ! JFM. */ gids[cur_gid].g_rid=gids[0].g_rid; gids[0].g_rid=tmp_rid; gids[cur_gid].attr=7; DEBUG(10,("get_domain_user_groups: primary gid of user found in group %s\n", map[i].nt_name)); cur_gid++; goto done; /* leave the loop early */ } } DEBUG(0,("get_domain_user_groups: primary gid of user [%s] is not a Domain group !\n", user_name)); DEBUGADD(0,("get_domain_user_groups: You should fix it, NT doesn't like that\n")); done: *pgids=gids; *numgroups=cur_gid; SAFE_FREE(map); return True; }