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.
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.
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.
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.
24 extern pstring global_myname;
25 extern DOM_SID global_sam_sid;
28 * Next two lines needed for SunOS and don't
29 * hurt anything else...
34 /*********************************************************
35 Print command usage on stderr and die.
36 **********************************************************/
37 static void usage(void)
40 printf("smbgroupedit options\n");
42 printf("You need to be root to use this tool!\n");
45 printf(" -a group create new group\n");
46 printf(" -n group NT group name\n");
47 printf(" -p privilege only local\n");
48 printf(" -v list groups\n");
49 printf(" -l long list (include details)\n");
50 printf(" -s short list (default)\n");
51 printf(" -c SID change group\n");
52 printf(" -u unix group\n");
53 printf(" -x group delete this group\n");
55 printf(" -t[b|d|l] type: builtin, domain, local \n");
59 /*********************************************************
60 Figure out if the input was an NT group or a SID string.
62 **********************************************************/
63 static BOOL get_sid_from_input(DOM_SID *sid, char *input)
67 if (StrnCaseCmp( input, "S-", 2)) {
68 /* Perhaps its the NT group name? */
69 if (!get_group_map_from_ntname(input, &map, MAPPING_WITHOUT_PRIV)) {
70 printf("NT Group %s doesn't exist in mapping DB\n", input);
76 if (!string_to_sid(sid, input)) {
77 printf("converting sid %s from a string failed!\n", input);
84 /*********************************************************
86 **********************************************************/
87 static int addgroup(char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *ntcomment, char *privilege)
89 PRIVILEGE_SET se_priv;
93 fstring name, comment;
97 printf("unix group %s doesn't exist!\n", group);
101 local_gid_to_sid(&sid, gid);
103 sid_to_string(string_sid, &sid);
106 fstrcpy(name, group);
108 fstrcpy(name, ntgroup);
111 fstrcpy(comment, "Local Unix group");
113 fstrcpy(comment, ntcomment);
115 init_privilege(&se_priv);
117 convert_priv_from_text(&se_priv, privilege);
119 if(!add_initial_entry(gid, string_sid, sid_type, name, comment, se_priv, PR_ACCESS_FROM_NETWORK)) {
120 printf("adding entry for group %s failed!\n", group);
121 free_privilege(&se_priv);
125 free_privilege(&se_priv);
129 /*********************************************************
131 **********************************************************/
132 static int changegroup(char *sid_string, char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *groupdesc, char *privilege)
138 if (!get_sid_from_input(&sid, sid_string)) {
142 /* Get the current mapping from the database */
143 if(!get_group_map_from_sid(sid, &map, MAPPING_WITH_PRIV)) {
144 printf("This SID does not exist in the database\n");
148 /* If a new Unix group is specified, check and change */
150 gid=nametogid(group);
152 printf("The UNIX group does not exist\n");
159 * Allow changing of group type only between domain and local
160 * We disallow changing Builtin groups !!! (SID problem)
162 if (sid_type==SID_NAME_ALIAS
163 || sid_type==SID_NAME_DOM_GRP
164 || sid_type==SID_NAME_UNKNOWN) {
165 if (map.sid_name_use==SID_NAME_ALIAS
166 || map.sid_name_use==SID_NAME_DOM_GRP
167 || map.sid_name_use==SID_NAME_UNKNOWN) {
168 map.sid_name_use=sid_type;
170 printf("cannot change group type to builtin\n");
173 printf("cannot change group type from builtin\n");
177 fstrcpy(map.nt_name, ntgroup);
179 /* Change comment if new one */
181 fstrcpy(map.comment, groupdesc);
183 /* Change the privilege if new one */
185 convert_priv_from_text(&map.priv_set, privilege);
187 if (!add_mapping_entry(&map, TDB_REPLACE)) {
188 printf("Count not update group database\n");
189 free_privilege(&map.priv_set);
193 free_privilege(&map.priv_set);
197 /*********************************************************
199 **********************************************************/
200 static int deletegroup(char *group)
204 if (!get_sid_from_input(&sid, group)) {
208 if(!group_map_remove(sid)) {
209 printf("removing group %s from the mapping db failed!\n", group);
216 /*********************************************************
218 **********************************************************/
219 static int listgroup(enum SID_NAME_USE sid_type, BOOL long_list)
228 printf("NT group (SID) -> Unix group\n");
230 if (!enum_group_mapping(sid_type, &map, &entries, ENUM_ALL_MAPPED, MAPPING_WITH_PRIV))
233 for (i=0; i<entries; i++) {
234 decode_sid_name_use(group_type, (map[i]).sid_name_use);
235 sid_to_string(string_sid, &map[i].sid);
236 convert_priv_to_text(&(map[i].priv_set), priv_text);
237 free_privilege(&(map[i].priv_set));
240 printf("%s (%s) -> %s\n", map[i].nt_name, string_sid, gidtoname(map[i].gid));
242 printf("%s\n", map[i].nt_name);
243 printf("\tSID : %s\n", string_sid);
244 printf("\tUnix group: %s\n", gidtoname(map[i].gid));
245 printf("\tGroup type: %s\n", group_type);
246 printf("\tComment : %s\n", map[i].comment);
247 printf("\tPrivilege : %s\n\n", priv_text);
254 /*********************************************************
256 **********************************************************/
257 int main (int argc, char **argv)
260 BOOL add_group = False;
261 BOOL view_group = False;
262 BOOL change_group = False;
263 BOOL delete_group = False;
264 BOOL nt_group = False;
266 BOOL group_type = False;
267 BOOL long_list = False;
271 char *ntgroup = NULL;
272 char *privilege = NULL;
274 char *group_desc = NULL;
276 enum SID_NAME_USE sid_type;
278 setup_logging("groupedit", True);
285 if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
286 fprintf(stderr, "Can't load %s - run testparm to debug it\n",
291 if(!initialize_password_db(True)) {
292 fprintf(stderr, "Can't setup password database vectors.\n");
296 if(pdb_generate_sam_sid()==False) {
297 printf("Can not read machine SID\n");
301 while ((ch = getopt(argc, argv, "a:c:d:ln:p:st:u:vx:")) != EOF) {
348 if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) > 1) {
349 fprintf (stderr, "Incompatible options on command line!\n");
354 /* no option on command line -> list groups */
355 if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) == 0)
359 if (group_type==False)
360 sid_type=SID_NAME_UNKNOWN;
365 sid_type=SID_NAME_ALIAS;
369 sid_type=SID_NAME_DOM_GRP;
373 sid_type=SID_NAME_WKN_GRP;
376 sid_type=SID_NAME_UNKNOWN;
382 return addgroup(group, sid_type, ntgroup, group_desc, privilege);
385 return listgroup(sid_type, long_list);
388 return deletegroup(group);
391 return changegroup(sid, group, sid_type, ntgroup, group_desc, privilege);