diff options
Diffstat (limited to 'source4/utils/smbgroupedit.c')
-rw-r--r-- | source4/utils/smbgroupedit.c | 410 |
1 files changed, 410 insertions, 0 deletions
diff --git a/source4/utils/smbgroupedit.c b/source4/utils/smbgroupedit.c new file mode 100644 index 0000000000..69f69aea5d --- /dev/null +++ b/source4/utils/smbgroupedit.c @@ -0,0 +1,410 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-2000, + * Copyright (C) Jean François Micouleau 1998-2001. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +/* + * Next two lines needed for SunOS and don't + * hurt anything else... + */ +extern char *optarg; +extern int optind; + +/********************************************************* + Print command usage on stderr and die. +**********************************************************/ +static void usage(void) +{ + if (getuid() == 0) { + printf("smbgroupedit options\n"); + } else { + printf("You need to be root to use this tool!\n"); + } + printf("options:\n"); + printf(" -a group create new group\n"); + printf(" -n group NT group name\n"); + printf(" -p privilege only local\n"); + printf(" -d description group description\n"); + printf(" -v list groups\n"); + printf(" -l long list (include details)\n"); + printf(" -s short list (default)\n"); + printf(" -c SID change group\n"); + printf(" -u unix group\n"); + printf(" -d description group description\n"); + printf(" -r rid RID of new group\n"); + printf(" -x group delete this group\n"); + printf("\n"); + printf(" -t[b|d|l] type: builtin, domain, local \n"); + exit(1); +} + +/********************************************************* + Figure out if the input was an NT group or a SID string. + Return the SID. +**********************************************************/ +static BOOL get_sid_from_input(DOM_SID *sid, char *input) +{ + GROUP_MAP map; + + if (StrnCaseCmp( input, "S-", 2)) { + /* Perhaps its the NT group name? */ + if (!pdb_getgrnam(&map, input, MAPPING_WITHOUT_PRIV)) { + printf("NT Group %s doesn't exist in mapping DB\n", input); + return False; + } else { + *sid = map.sid; + } + } else { + if (!string_to_sid(sid, input)) { + printf("converting sid %s from a string failed!\n", input); + return False; + } + } + return True; +} + +/********************************************************* + add a group. +**********************************************************/ +static int addgroup(gid_t gid, enum SID_NAME_USE sid_type, char *ntgroup, char *ntcomment, char *privilege, uint32 rid) +{ + PRIVILEGE_SET se_priv; + DOM_SID sid; + fstring string_sid; + fstring comment; + + sid_copy(&sid, get_global_sam_sid()); + sid_append_rid(&sid, rid); + + sid_to_string(string_sid, &sid); + + if (ntcomment==NULL) + fstrcpy(comment, "Local Unix group"); + else + fstrcpy(comment, ntcomment); + + init_privilege(&se_priv); + if (privilege!=NULL) + convert_priv_from_text(&se_priv, privilege); + + if(!add_initial_entry(gid, string_sid, sid_type, ntgroup, + comment, se_priv, PR_ACCESS_FROM_NETWORK)) { + printf("adding entry for group %s failed!\n", ntgroup); + free_privilege(&se_priv); + return -1; + } + + free_privilege(&se_priv); + return 0; +} + +/********************************************************* + Change a group. +**********************************************************/ +static int changegroup(char *sid_string, char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *groupdesc, char *privilege) +{ + DOM_SID sid; + GROUP_MAP map; + gid_t gid; + + if (!get_sid_from_input(&sid, sid_string)) { + return -1; + } + + /* Get the current mapping from the database */ + if(!pdb_getgrsid(&map, sid, MAPPING_WITH_PRIV)) { + printf("This SID does not exist in the database\n"); + return -1; + } + + /* If a new Unix group is specified, check and change */ + if (group!=NULL) { + gid=nametogid(group); + if (gid==-1) { + printf("The UNIX group does not exist\n"); + return -1; + } else + map.gid=gid; + } + + /* + * Allow changing of group type only between domain and local + * We disallow changing Builtin groups !!! (SID problem) + */ + if (sid_type==SID_NAME_ALIAS + || sid_type==SID_NAME_DOM_GRP + || sid_type==SID_NAME_UNKNOWN) { + if (map.sid_name_use==SID_NAME_ALIAS + || map.sid_name_use==SID_NAME_DOM_GRP + || map.sid_name_use==SID_NAME_UNKNOWN) { + map.sid_name_use=sid_type; + } else { + printf("cannot change group type to builtin\n"); + }; + } else { + printf("cannot change group type from builtin\n"); + } + + if (ntgroup!=NULL) + fstrcpy(map.nt_name, ntgroup); + + /* Change comment if new one */ + if (groupdesc!=NULL) + fstrcpy(map.comment, groupdesc); + + /* Change the privilege if new one */ + if (privilege!=NULL) + convert_priv_from_text(&map.priv_set, privilege); + + if (!pdb_update_group_mapping_entry(&map)) { + printf("Could not update group database\n"); + free_privilege(&map.priv_set); + return -1; + } + + free_privilege(&map.priv_set); + return 0; +} + +/********************************************************* + Delete the group. +**********************************************************/ +static int deletegroup(char *group) +{ + DOM_SID sid; + + if (!get_sid_from_input(&sid, group)) { + return -1; + } + + if(!pdb_delete_group_mapping_entry(sid)) { + printf("removing group %s from the mapping db failed!\n", group); + return -1; + } + + return 0; +} + +/********************************************************* + List the groups. +**********************************************************/ +static int listgroup(enum SID_NAME_USE sid_type, BOOL long_list) +{ + int entries,i; + TALLOC_CTX *mem_ctx; + GROUP_MAP *map=NULL; + fstring string_sid; + fstring group_type; + fstring priv_text; + + if (!long_list) + printf("NT group (SID) -> Unix group\n"); + + if (!pdb_enum_group_mapping(sid_type, &map, &entries, ENUM_ALL_MAPPED, MAPPING_WITH_PRIV)) + return -1; + + mem_ctx = talloc_init("smbgroupedit talloc"); + if (!mem_ctx) return -1; + for (i=0; i<entries; i++) { + decode_sid_name_use(group_type, (map[i]).sid_name_use); + sid_to_string(string_sid, &map[i].sid); + convert_priv_to_text(&(map[i].priv_set), priv_text); + free_privilege(&(map[i].priv_set)); + + if (!long_list) + printf("%s (%s) -> %s\n", map[i].nt_name, string_sid, + gidtoname(mem_ctx, map[i].gid)); + else { + printf("%s\n", map[i].nt_name); + printf("\tSID : %s\n", string_sid); + printf("\tUnix group: %s\n", gidtoname(mem_ctx, map[i].gid)); + printf("\tGroup type: %s\n", group_type); + printf("\tComment : %s\n", map[i].comment); + printf("\tPrivilege : %s\n\n", priv_text); + } + } + talloc_destroy(mem_ctx); + + return 0; +} + +/********************************************************* + Start here. +**********************************************************/ +int main (int argc, char **argv) +{ + int ch; + BOOL add_group = False; + BOOL view_group = False; + BOOL change_group = False; + BOOL delete_group = False; + BOOL nt_group = False; + BOOL priv = False; + BOOL group_type = False; + BOOL long_list = False; + + char *group = NULL; + char *sid = NULL; + char *ntgroup = NULL; + char *privilege = NULL; + char *groupt = NULL; + char *group_desc = NULL; + + enum SID_NAME_USE sid_type; + uint32 rid = -1; + + setup_logging("groupedit", True); + + if (argc < 2) { + usage(); + return 0; + } + + if (!lp_load(dyn_CONFIGFILE,True,False,False)) { + fprintf(stderr, "Can't load %s - run testparm to debug it\n", + dyn_CONFIGFILE); + exit(1); + } + + if (!init_names()) + exit(1); + + if(!initialize_password_db(True)) { + fprintf(stderr, "Can't setup password database vectors.\n"); + exit(1); + } + + if(get_global_sam_sid()==False) { + fprintf(stderr, "Can not read machine SID\n"); + return 0; + } + + while ((ch = getopt(argc, argv, "a:c:d:ln:p:r:st:u:vx:")) != EOF) { + switch(ch) { + case 'a': + add_group = True; + group=optarg; + break; + case 'c': + change_group = True; + sid=optarg; + break; + case 'd': + group_desc=optarg; + break; + case 'l': + long_list = True; + break; + case 'n': + nt_group = True; + ntgroup=optarg; + break; + case 'p': + priv = True; + privilege=optarg; + break; + case 'r': + rid = atoi(optarg); + break; + case 's': + long_list = False; + break; + case 't': + group_type = True; + groupt=optarg; + break; + case 'u': + group=optarg; + break; + case 'v': + view_group = True; + break; + case 'x': + delete_group = True; + group=optarg; + break; + /*default: + usage();*/ + } + } + + + if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) > 1) { + fprintf (stderr, "Incompatible options on command line!\n"); + usage(); + exit(1); + } + + /* no option on command line -> list groups */ + if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) == 0) + view_group = True; + + + if (group_type==False) + sid_type=SID_NAME_UNKNOWN; + else { + switch (groupt[0]) { + case 'l': + case 'L': + sid_type=SID_NAME_ALIAS; + break; + case 'd': + case 'D': + sid_type=SID_NAME_DOM_GRP; + break; + case 'b': + case 'B': + sid_type=SID_NAME_WKN_GRP; + break; + default: + sid_type=SID_NAME_UNKNOWN; + break; + } + } + + if (add_group) { + gid_t gid=nametogid(group); + if (gid==-1) { + printf("unix group %s doesn't exist!\n", group); + return -1; + } + + if (rid == -1) { + rid = pdb_gid_to_group_rid(gid); + } + return addgroup(gid, sid_type, ntgroup?ntgroup:group, + group_desc, privilege, rid); + } + + if (view_group) + return listgroup(sid_type, long_list); + + if (delete_group) + return deletegroup(group); + + if (change_group) { + return changegroup(sid, group, sid_type, ntgroup, group_desc, privilege); + } + + usage(); + + return 0; +} |