summaryrefslogtreecommitdiff
path: root/source4/utils/smbgroupedit.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/utils/smbgroupedit.c')
-rw-r--r--source4/utils/smbgroupedit.c410
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;
+}