Fairly large change to printing code.
[Samba.git] / source / utils / smbgroupedit.c
blob4358e6f08c99acc0c8911a24f24d6fff4609649c
1 /*
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.
6 *
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.
22 #include "includes.h"
24 extern pstring global_myname;
25 extern fstring global_myworkgroup;
28 * Next two lines needed for SunOS and don't
29 * hurt anything else...
31 extern char *optarg;
32 extern int optind;
34 /*********************************************************
35 Print command usage on stderr and die.
36 **********************************************************/
37 static void usage(void)
39 if (getuid() == 0) {
40 printf("smbgroupedit options\n");
41 } else {
42 printf("You need to be root to use this tool!\n");
44 printf("options:\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(" -x group delete this group\n");
56 printf("\n");
57 printf(" -t[b|d|l] type: builtin, domain, local \n");
58 exit(1);
61 /*********************************************************
62 Figure out if the input was an NT group or a SID string.
63 Return the SID.
64 **********************************************************/
65 static BOOL get_sid_from_input(DOM_SID *sid, char *input)
67 GROUP_MAP map;
69 if (StrnCaseCmp( input, "S-", 2)) {
70 /* Perhaps its the NT group name? */
71 if (!get_group_map_from_ntname(input, &map, MAPPING_WITHOUT_PRIV)) {
72 printf("NT Group %s doesn't exist in mapping DB\n", input);
73 return False;
74 } else {
75 *sid = map.sid;
77 } else {
78 if (!string_to_sid(sid, input)) {
79 printf("converting sid %s from a string failed!\n", input);
80 return False;
83 return True;
86 /*********************************************************
87 add a group.
88 **********************************************************/
89 static int addgroup(char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *ntcomment, char *privilege)
91 PRIVILEGE_SET se_priv;
92 gid_t gid;
93 DOM_SID sid;
94 fstring string_sid;
95 fstring name, comment;
97 gid=nametogid(group);
98 if (gid==-1) {
99 printf("unix group %s doesn't exist!\n", group);
100 return -1;
103 local_gid_to_sid(&sid, gid);
105 sid_to_string(string_sid, &sid);
107 if (ntgroup==NULL)
108 fstrcpy(name, group);
109 else
110 fstrcpy(name, ntgroup);
112 if (ntcomment==NULL)
113 fstrcpy(comment, "Local Unix group");
114 else
115 fstrcpy(comment, ntcomment);
117 init_privilege(&se_priv);
118 if (privilege!=NULL)
119 convert_priv_from_text(&se_priv, privilege);
121 if(!add_initial_entry(gid, string_sid, sid_type, name, comment, se_priv, PR_ACCESS_FROM_NETWORK)) {
122 printf("adding entry for group %s failed!\n", group);
123 free_privilege(&se_priv);
124 return -1;
127 free_privilege(&se_priv);
128 return 0;
131 /*********************************************************
132 Change a group.
133 **********************************************************/
134 static int changegroup(char *sid_string, char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *groupdesc, char *privilege)
136 DOM_SID sid;
137 GROUP_MAP map;
138 gid_t gid;
140 if (!get_sid_from_input(&sid, sid_string)) {
141 return -1;
144 /* Get the current mapping from the database */
145 if(!get_group_map_from_sid(sid, &map, MAPPING_WITH_PRIV)) {
146 printf("This SID does not exist in the database\n");
147 return -1;
150 /* If a new Unix group is specified, check and change */
151 if (group!=NULL) {
152 gid=nametogid(group);
153 if (gid==-1) {
154 printf("The UNIX group does not exist\n");
155 return -1;
156 } else
157 map.gid=gid;
161 * Allow changing of group type only between domain and local
162 * We disallow changing Builtin groups !!! (SID problem)
164 if (sid_type==SID_NAME_ALIAS
165 || sid_type==SID_NAME_DOM_GRP
166 || sid_type==SID_NAME_UNKNOWN) {
167 if (map.sid_name_use==SID_NAME_ALIAS
168 || map.sid_name_use==SID_NAME_DOM_GRP
169 || map.sid_name_use==SID_NAME_UNKNOWN) {
170 map.sid_name_use=sid_type;
171 } else {
172 printf("cannot change group type to builtin\n");
174 } else {
175 printf("cannot change group type from builtin\n");
178 if (ntgroup!=NULL)
179 fstrcpy(map.nt_name, ntgroup);
181 /* Change comment if new one */
182 if (groupdesc!=NULL)
183 fstrcpy(map.comment, groupdesc);
185 /* Change the privilege if new one */
186 if (privilege!=NULL)
187 convert_priv_from_text(&map.priv_set, privilege);
189 if (!add_mapping_entry(&map, TDB_REPLACE)) {
190 printf("Count not update group database\n");
191 free_privilege(&map.priv_set);
192 return -1;
195 free_privilege(&map.priv_set);
196 return 0;
199 /*********************************************************
200 Delete the group.
201 **********************************************************/
202 static int deletegroup(char *group)
204 DOM_SID sid;
206 if (!get_sid_from_input(&sid, group)) {
207 return -1;
210 if(!group_map_remove(sid)) {
211 printf("removing group %s from the mapping db failed!\n", group);
212 return -1;
215 return 0;
218 /*********************************************************
219 List the groups.
220 **********************************************************/
221 static int listgroup(enum SID_NAME_USE sid_type, BOOL long_list)
223 int entries,i;
224 GROUP_MAP *map=NULL;
225 fstring string_sid;
226 fstring group_type;
227 fstring priv_text;
229 if (!long_list)
230 printf("NT group (SID) -> Unix group\n");
232 if (!enum_group_mapping(sid_type, &map, &entries, ENUM_ALL_MAPPED, MAPPING_WITH_PRIV))
233 return -1;
235 for (i=0; i<entries; i++) {
236 decode_sid_name_use(group_type, (map[i]).sid_name_use);
237 sid_to_string(string_sid, &map[i].sid);
238 convert_priv_to_text(&(map[i].priv_set), priv_text);
239 free_privilege(&(map[i].priv_set));
241 if (!long_list)
242 printf("%s (%s) -> %s\n", map[i].nt_name, string_sid, gidtoname(map[i].gid));
243 else {
244 printf("%s\n", map[i].nt_name);
245 printf("\tSID : %s\n", string_sid);
246 printf("\tUnix group: %s\n", gidtoname(map[i].gid));
247 printf("\tGroup type: %s\n", group_type);
248 printf("\tComment : %s\n", map[i].comment);
249 printf("\tPrivilege : %s\n\n", priv_text);
253 return 0;
256 /*********************************************************
257 Start here.
258 **********************************************************/
259 int main (int argc, char **argv)
261 int ch;
262 BOOL add_group = False;
263 BOOL view_group = False;
264 BOOL change_group = False;
265 BOOL delete_group = False;
266 BOOL nt_group = False;
267 BOOL priv = False;
268 BOOL group_type = False;
269 BOOL long_list = False;
271 char *group = NULL;
272 char *sid = NULL;
273 char *ntgroup = NULL;
274 char *privilege = NULL;
275 char *groupt = NULL;
276 char *group_desc = NULL;
278 enum SID_NAME_USE sid_type;
280 setup_logging("groupedit", True);
282 if (argc < 2) {
283 usage();
284 return 0;
287 if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
288 fprintf(stderr, "Can't load %s - run testparm to debug it\n",
289 dyn_CONFIGFILE);
290 exit(1);
293 if (!*global_myname) {
294 char *p;
295 pstrcpy( global_myname, myhostname() );
296 p = strchr_m(global_myname, '.' );
297 if (p)
298 *p = 0;
301 strupper(global_myname);
303 fstrcpy(global_myworkgroup, lp_workgroup());
305 if(!initialize_password_db(True)) {
306 fprintf(stderr, "Can't setup password database vectors.\n");
307 exit(1);
310 if(get_global_sam_sid()==False) {
311 fprintf(stderr, "Can not read machine SID\n");
312 return 0;
315 while ((ch = getopt(argc, argv, "a:c:d:ln:p:st:u:vx:")) != EOF) {
316 switch(ch) {
317 case 'a':
318 add_group = True;
319 group=optarg;
320 break;
321 case 'c':
322 change_group = True;
323 sid=optarg;
324 break;
325 case 'd':
326 group_desc=optarg;
327 break;
328 case 'l':
329 long_list = True;
330 break;
331 case 'n':
332 nt_group = True;
333 ntgroup=optarg;
334 break;
335 case 'p':
336 priv = True;
337 privilege=optarg;
338 break;
339 case 's':
340 long_list = False;
341 break;
342 case 't':
343 group_type = True;
344 groupt=optarg;
345 break;
346 case 'u':
347 group=optarg;
348 break;
349 case 'v':
350 view_group = True;
351 break;
352 case 'x':
353 delete_group = True;
354 group=optarg;
355 break;
356 /*default:
357 usage();*/
362 if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) > 1) {
363 fprintf (stderr, "Incompatible options on command line!\n");
364 usage();
365 exit(1);
368 /* no option on command line -> list groups */
369 if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) == 0)
370 view_group = True;
373 if (group_type==False)
374 sid_type=SID_NAME_UNKNOWN;
375 else {
376 switch (groupt[0]) {
377 case 'l':
378 case 'L':
379 sid_type=SID_NAME_ALIAS;
380 break;
381 case 'd':
382 case 'D':
383 sid_type=SID_NAME_DOM_GRP;
384 break;
385 case 'b':
386 case 'B':
387 sid_type=SID_NAME_WKN_GRP;
388 break;
389 default:
390 sid_type=SID_NAME_UNKNOWN;
391 break;
395 if (add_group)
396 return addgroup(group, sid_type, ntgroup, group_desc, privilege);
398 if (view_group)
399 return listgroup(sid_type, long_list);
401 if (delete_group)
402 return deletegroup(group);
404 if (change_group) {
405 return changegroup(sid, group, sid_type, ntgroup, group_desc, privilege);
408 usage();
410 return 0;