only supporting the Net::LDAP module now
[Samba.git] / source / utils / smbgroupedit.c
blob0faa0513edb5f6967d3e339b78e3f120622fb315
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"
25 * Next two lines needed for SunOS and don't
26 * hurt anything else...
28 extern char *optarg;
29 extern int optind;
31 /*********************************************************
32 Print command usage on stderr and die.
33 **********************************************************/
34 static void usage(void)
36 if (getuid() == 0) {
37 printf("smbgroupedit options\n");
38 } else {
39 printf("You need to be root to use this tool!\n");
41 printf("options:\n");
42 printf(" -a group create new group\n");
43 printf(" -n group NT group name\n");
44 printf(" -p privilege only local\n");
45 printf(" -d description group description\n");
46 printf(" -v list groups\n");
47 printf(" -l long list (include details)\n");
48 printf(" -s short list (default)\n");
49 printf(" -c SID change group\n");
50 printf(" -u unix group\n");
51 printf(" -d description group description\n");
52 printf(" -r rid RID of new group\n");
53 printf(" -x group delete this group\n");
54 printf("\n");
55 printf(" -t[b|d|l] type: builtin, domain, local \n");
56 exit(1);
59 /*********************************************************
60 Figure out if the input was an NT group or a SID string.
61 Return the SID.
62 **********************************************************/
63 static BOOL get_sid_from_input(DOM_SID *sid, char *input)
65 GROUP_MAP map;
67 if (StrnCaseCmp( input, "S-", 2)) {
68 /* Perhaps its the NT group name? */
69 if (!pdb_getgrnam(&map, input, MAPPING_WITHOUT_PRIV)) {
70 printf("NT Group %s doesn't exist in mapping DB\n", input);
71 return False;
72 } else {
73 *sid = map.sid;
75 } else {
76 if (!string_to_sid(sid, input)) {
77 printf("converting sid %s from a string failed!\n", input);
78 return False;
81 return True;
84 /*********************************************************
85 add a group.
86 **********************************************************/
87 static int addgroup(gid_t gid, enum SID_NAME_USE sid_type, char *ntgroup, char *ntcomment, char *privilege, uint32 rid)
89 PRIVILEGE_SET se_priv;
90 DOM_SID sid;
91 fstring string_sid;
92 fstring comment;
94 sid_copy(&sid, get_global_sam_sid());
95 sid_append_rid(&sid, rid);
97 sid_to_string(string_sid, &sid);
99 if (ntcomment==NULL)
100 fstrcpy(comment, "Local Unix group");
101 else
102 fstrcpy(comment, ntcomment);
104 init_privilege(&se_priv);
105 if (privilege!=NULL)
106 convert_priv_from_text(&se_priv, privilege);
108 if(!add_initial_entry(gid, string_sid, sid_type, ntgroup,
109 comment, se_priv, PR_ACCESS_FROM_NETWORK)) {
110 printf("adding entry for group %s failed!\n", ntgroup);
111 free_privilege(&se_priv);
112 return -1;
115 free_privilege(&se_priv);
116 return 0;
119 /*********************************************************
120 Change a group.
121 **********************************************************/
122 static int changegroup(char *sid_string, char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *groupdesc, char *privilege)
124 DOM_SID sid;
125 GROUP_MAP map;
126 gid_t gid;
128 if (!get_sid_from_input(&sid, sid_string)) {
129 return -1;
132 /* Get the current mapping from the database */
133 if(!pdb_getgrsid(&map, sid, MAPPING_WITH_PRIV)) {
134 printf("This SID does not exist in the database\n");
135 return -1;
138 /* If a new Unix group is specified, check and change */
139 if (group!=NULL) {
140 gid=nametogid(group);
141 if (gid==-1) {
142 printf("The UNIX group does not exist\n");
143 return -1;
144 } else
145 map.gid=gid;
149 * Allow changing of group type only between domain and local
150 * We disallow changing Builtin groups !!! (SID problem)
152 if (sid_type==SID_NAME_ALIAS
153 || sid_type==SID_NAME_DOM_GRP
154 || sid_type==SID_NAME_UNKNOWN) {
155 if (map.sid_name_use==SID_NAME_ALIAS
156 || map.sid_name_use==SID_NAME_DOM_GRP
157 || map.sid_name_use==SID_NAME_UNKNOWN) {
158 map.sid_name_use=sid_type;
159 } else {
160 printf("cannot change group type to builtin\n");
162 } else {
163 printf("cannot change group type from builtin\n");
166 if (ntgroup!=NULL)
167 fstrcpy(map.nt_name, ntgroup);
169 /* Change comment if new one */
170 if (groupdesc!=NULL)
171 fstrcpy(map.comment, groupdesc);
173 /* Change the privilege if new one */
174 if (privilege!=NULL)
175 convert_priv_from_text(&map.priv_set, privilege);
177 if (!pdb_update_group_mapping_entry(&map)) {
178 printf("Could not update group database\n");
179 free_privilege(&map.priv_set);
180 return -1;
183 free_privilege(&map.priv_set);
184 return 0;
187 /*********************************************************
188 Delete the group.
189 **********************************************************/
190 static int deletegroup(char *group)
192 DOM_SID sid;
194 if (!get_sid_from_input(&sid, group)) {
195 return -1;
198 if(!pdb_delete_group_mapping_entry(sid)) {
199 printf("removing group %s from the mapping db failed!\n", group);
200 return -1;
203 return 0;
206 /*********************************************************
207 List the groups.
208 **********************************************************/
209 static int listgroup(enum SID_NAME_USE sid_type, BOOL long_list)
211 int entries,i;
212 GROUP_MAP *map=NULL;
213 fstring string_sid;
214 fstring group_type;
215 fstring priv_text;
217 if (!long_list)
218 printf("NT group (SID) -> Unix group\n");
220 if (!pdb_enum_group_mapping(sid_type, &map, &entries, ENUM_ALL_MAPPED, MAPPING_WITH_PRIV))
221 return -1;
223 for (i=0; i<entries; i++) {
224 decode_sid_name_use(group_type, (map[i]).sid_name_use);
225 sid_to_string(string_sid, &map[i].sid);
226 convert_priv_to_text(&(map[i].priv_set), priv_text);
227 free_privilege(&(map[i].priv_set));
229 if (!long_list)
230 printf("%s (%s) -> %s\n", map[i].nt_name, string_sid, gidtoname(map[i].gid));
231 else {
232 printf("%s\n", map[i].nt_name);
233 printf("\tSID : %s\n", string_sid);
234 printf("\tUnix group: %s\n", gidtoname(map[i].gid));
235 printf("\tGroup type: %s\n", group_type);
236 printf("\tComment : %s\n", map[i].comment);
237 printf("\tPrivilege : %s\n\n", priv_text);
241 return 0;
244 /*********************************************************
245 Start here.
246 **********************************************************/
247 int main (int argc, char **argv)
249 int ch;
250 BOOL add_group = False;
251 BOOL view_group = False;
252 BOOL change_group = False;
253 BOOL delete_group = False;
254 BOOL nt_group = False;
255 BOOL priv = False;
256 BOOL group_type = False;
257 BOOL long_list = False;
259 char *group = NULL;
260 char *sid = NULL;
261 char *ntgroup = NULL;
262 char *privilege = NULL;
263 char *groupt = NULL;
264 char *group_desc = NULL;
266 enum SID_NAME_USE sid_type;
267 uint32 rid = -1;
269 setup_logging("groupedit", True);
271 if (argc < 2) {
272 usage();
273 return 0;
276 if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
277 fprintf(stderr, "Can't load %s - run testparm to debug it\n",
278 dyn_CONFIGFILE);
279 exit(1);
282 if (!init_names())
283 exit(1);
285 if(!initialize_password_db(True)) {
286 fprintf(stderr, "Can't setup password database vectors.\n");
287 exit(1);
290 if(get_global_sam_sid()==False) {
291 fprintf(stderr, "Can not read machine SID\n");
292 return 0;
295 while ((ch = getopt(argc, argv, "a:c:d:ln:p:r:st:u:vx:")) != EOF) {
296 switch(ch) {
297 case 'a':
298 add_group = True;
299 group=optarg;
300 break;
301 case 'c':
302 change_group = True;
303 sid=optarg;
304 break;
305 case 'd':
306 group_desc=optarg;
307 break;
308 case 'l':
309 long_list = True;
310 break;
311 case 'n':
312 nt_group = True;
313 ntgroup=optarg;
314 break;
315 case 'p':
316 priv = True;
317 privilege=optarg;
318 break;
319 case 'r':
320 rid = atoi(optarg);
321 break;
322 case 's':
323 long_list = False;
324 break;
325 case 't':
326 group_type = True;
327 groupt=optarg;
328 break;
329 case 'u':
330 group=optarg;
331 break;
332 case 'v':
333 view_group = True;
334 break;
335 case 'x':
336 delete_group = True;
337 group=optarg;
338 break;
339 /*default:
340 usage();*/
345 if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) > 1) {
346 fprintf (stderr, "Incompatible options on command line!\n");
347 usage();
348 exit(1);
351 /* no option on command line -> list groups */
352 if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) == 0)
353 view_group = True;
356 if (group_type==False)
357 sid_type=SID_NAME_UNKNOWN;
358 else {
359 switch (groupt[0]) {
360 case 'l':
361 case 'L':
362 sid_type=SID_NAME_ALIAS;
363 break;
364 case 'd':
365 case 'D':
366 sid_type=SID_NAME_DOM_GRP;
367 break;
368 case 'b':
369 case 'B':
370 sid_type=SID_NAME_WKN_GRP;
371 break;
372 default:
373 sid_type=SID_NAME_UNKNOWN;
374 break;
378 if (add_group) {
379 gid_t gid=nametogid(group);
380 if (gid==-1) {
381 printf("unix group %s doesn't exist!\n", group);
382 return -1;
385 if (rid == -1) {
386 rid = pdb_gid_to_group_rid(gid);
388 return addgroup(gid, sid_type, ntgroup?ntgroup:group,
389 group_desc, privilege, rid);
392 if (view_group)
393 return listgroup(sid_type, long_list);
395 if (delete_group)
396 return deletegroup(group);
398 if (change_group) {
399 return changegroup(sid, group, sid_type, ntgroup, group_desc, privilege);
402 usage();
404 return 0;