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 fstring global_myworkgroup;
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(" -d description group description\n");
49 printf(" -v list groups\n");
50 printf(" -l long list (include details)\n");
51 printf(" -s short list (default)\n");
52 printf(" -c SID change group\n");
53 printf(" -u unix group\n");
54 printf(" -d description group description\n");
55 printf(" -r rid RID of new group\n");
56 printf(" -x group delete this group\n");
58 printf(" -t[b|d|l] type: builtin, domain, local \n");
62 /*********************************************************
63 Figure out if the input was an NT group or a SID string.
65 **********************************************************/
66 static BOOL get_sid_from_input(DOM_SID *sid, char *input)
70 if (StrnCaseCmp( input, "S-", 2)) {
71 /* Perhaps its the NT group name? */
72 if (!get_group_map_from_ntname(input, &map, MAPPING_WITHOUT_PRIV)) {
73 printf("NT Group %s doesn't exist in mapping DB\n", input);
79 if (!string_to_sid(sid, input)) {
80 printf("converting sid %s from a string failed!\n", input);
87 /*********************************************************
89 **********************************************************/
90 static int addgroup(gid_t gid, enum SID_NAME_USE sid_type, char *ntgroup, char *ntcomment, char *privilege, uint32 rid)
92 PRIVILEGE_SET se_priv;
97 sid_copy(&sid, get_global_sam_sid());
98 sid_append_rid(&sid, rid);
100 sid_to_string(string_sid, &sid);
103 fstrcpy(comment, "Local Unix group");
105 fstrcpy(comment, ntcomment);
107 init_privilege(&se_priv);
109 convert_priv_from_text(&se_priv, privilege);
111 if(!add_initial_entry(gid, string_sid, sid_type, ntgroup,
112 comment, se_priv, PR_ACCESS_FROM_NETWORK)) {
113 printf("adding entry for group %s failed!\n", ntgroup);
114 free_privilege(&se_priv);
118 free_privilege(&se_priv);
122 /*********************************************************
124 **********************************************************/
125 static int changegroup(char *sid_string, char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *groupdesc, char *privilege)
131 if (!get_sid_from_input(&sid, sid_string)) {
135 /* Get the current mapping from the database */
136 if(!get_group_map_from_sid(sid, &map, MAPPING_WITH_PRIV)) {
137 printf("This SID does not exist in the database\n");
141 /* If a new Unix group is specified, check and change */
143 gid=nametogid(group);
145 printf("The UNIX group does not exist\n");
152 * Allow changing of group type only between domain and local
153 * We disallow changing Builtin groups !!! (SID problem)
155 if (sid_type==SID_NAME_ALIAS
156 || sid_type==SID_NAME_DOM_GRP
157 || sid_type==SID_NAME_UNKNOWN) {
158 if (map.sid_name_use==SID_NAME_ALIAS
159 || map.sid_name_use==SID_NAME_DOM_GRP
160 || map.sid_name_use==SID_NAME_UNKNOWN) {
161 map.sid_name_use=sid_type;
163 printf("cannot change group type to builtin\n");
166 printf("cannot change group type from builtin\n");
170 fstrcpy(map.nt_name, ntgroup);
172 /* Change comment if new one */
174 fstrcpy(map.comment, groupdesc);
176 /* Change the privilege if new one */
178 convert_priv_from_text(&map.priv_set, privilege);
180 if (!add_mapping_entry(&map, TDB_REPLACE)) {
181 printf("Count not update group database\n");
182 free_privilege(&map.priv_set);
186 free_privilege(&map.priv_set);
190 /*********************************************************
192 **********************************************************/
193 static int deletegroup(char *group)
197 if (!get_sid_from_input(&sid, group)) {
201 if(!group_map_remove(sid)) {
202 printf("removing group %s from the mapping db failed!\n", group);
209 /*********************************************************
211 **********************************************************/
212 static int listgroup(enum SID_NAME_USE sid_type, BOOL long_list)
221 printf("NT group (SID) -> Unix group\n");
223 if (!enum_group_mapping(sid_type, &map, &entries, ENUM_ALL_MAPPED, MAPPING_WITH_PRIV))
226 for (i=0; i<entries; i++) {
227 decode_sid_name_use(group_type, (map[i]).sid_name_use);
228 sid_to_string(string_sid, &map[i].sid);
229 convert_priv_to_text(&(map[i].priv_set), priv_text);
230 free_privilege(&(map[i].priv_set));
233 printf("%s (%s) -> %s\n", map[i].nt_name, string_sid, gidtoname(map[i].gid));
235 printf("%s\n", map[i].nt_name);
236 printf("\tSID : %s\n", string_sid);
237 printf("\tUnix group: %s\n", gidtoname(map[i].gid));
238 printf("\tGroup type: %s\n", group_type);
239 printf("\tComment : %s\n", map[i].comment);
240 printf("\tPrivilege : %s\n\n", priv_text);
247 /*********************************************************
249 **********************************************************/
250 int main (int argc, char **argv)
253 BOOL add_group = False;
254 BOOL view_group = False;
255 BOOL change_group = False;
256 BOOL delete_group = False;
257 BOOL nt_group = False;
259 BOOL group_type = False;
260 BOOL long_list = False;
264 char *ntgroup = NULL;
265 char *privilege = NULL;
267 char *group_desc = NULL;
269 enum SID_NAME_USE sid_type;
272 setup_logging("groupedit", True);
279 if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
280 fprintf(stderr, "Can't load %s - run testparm to debug it\n",
285 if (!*global_myname) {
287 pstrcpy( global_myname, myhostname() );
288 p = strchr_m(global_myname, '.' );
293 strupper(global_myname);
295 fstrcpy(global_myworkgroup, lp_workgroup());
297 if(!initialize_password_db(True)) {
298 fprintf(stderr, "Can't setup password database vectors.\n");
302 if(get_global_sam_sid()==False) {
303 fprintf(stderr, "Can not read machine SID\n");
307 while ((ch = getopt(argc, argv, "a:c:d:ln:p:r:st:u:vx:")) != EOF) {
357 if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) > 1) {
358 fprintf (stderr, "Incompatible options on command line!\n");
363 /* no option on command line -> list groups */
364 if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) == 0)
368 if (group_type==False)
369 sid_type=SID_NAME_UNKNOWN;
374 sid_type=SID_NAME_ALIAS;
378 sid_type=SID_NAME_DOM_GRP;
382 sid_type=SID_NAME_WKN_GRP;
385 sid_type=SID_NAME_UNKNOWN;
391 gid_t gid=nametogid(group);
393 printf("unix group %s doesn't exist!\n", group);
398 rid = pdb_gid_to_group_rid(gid);
400 return addgroup(gid, sid_type, ntgroup?ntgroup:group,
401 group_desc, privilege, rid);
405 return listgroup(sid_type, long_list);
408 return deletegroup(group);
411 return changegroup(sid, group, sid_type, ntgroup, group_desc, privilege);