Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header.
[samba.git] / source3 / utils / smbgroupedit.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-2000,
6  *  Copyright (C) Jean François Micouleau      1998-2001.
7  *  
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *  
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *  
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include "includes.h"
24
25 extern pstring global_myname;
26 extern DOM_SID global_sam_sid;
27
28 /*
29  * Next two lines needed for SunOS and don't
30  * hurt anything else...
31  */
32 extern char *optarg;
33 extern int optind;
34
35 /*********************************************************
36  Print command usage on stderr and die.
37 **********************************************************/
38 static void usage(void)
39 {
40         if (getuid() == 0) {
41                 printf("groupedit options\n");
42         } else {
43                 printf("You need to be root to use this tool!\n");
44         }
45         printf("options:\n");
46         printf("  -a group             create new group\n");
47         printf("    -n group           NT group name\n");
48         printf("    -p privilege       only local\n");
49         printf("  -v                   list groups\n");
50         printf("  -c SID               change group\n");
51         printf("     -u unix group\n");
52         printf("  -x group             delete this group\n");
53         printf("\n");
54         printf("    -t[b|d|l]          type: builtin, domain, local \n");
55         exit(1);
56 }
57
58 /*********************************************************
59  add a group.
60 **********************************************************/
61 int addgroup(char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *ntcomment, char *privilege)
62 {
63         uint32 se_priv;
64         gid_t gid;
65         DOM_SID sid;
66         fstring string_sid;
67         fstring name, comment;
68
69 /*      convert_priv_from_text(&se_priv, privilege);*/
70
71         se_priv=0x0;
72
73         gid=nametogid(group);
74         if (gid==-1)
75                 return -1;
76
77         local_gid_to_sid(&sid, gid);
78         sid_to_string(string_sid, &sid);
79
80         if (ntgroup==NULL)
81                 fstrcpy(name, group);
82         else
83                 fstrcpy(name, ntgroup);
84         
85         if (ntcomment==NULL)
86                 fstrcpy(comment, "Local Unix group");
87         else
88                 fstrcpy(comment, ntcomment);
89
90         if(!add_initial_entry(gid, string_sid, sid_type, name, comment, se_priv))
91                 return -1;
92
93         return 0;
94 }
95
96 /*********************************************************
97  Change a group.
98 **********************************************************/
99 int changegroup(char *sid_string, char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *groupdesc, char *privilege)
100 {
101         DOM_SID sid;
102         GROUP_MAP map;
103         gid_t gid;
104         uint32 se_priv;
105
106         string_to_sid(&sid, sid_string);
107
108         /* Get the current mapping from the database */
109         if(!get_group_map_from_sid(sid, &map)) {
110                 printf("This SID does not exist in the database\n");
111                 return -1;
112         }
113
114         /* If a new Unix group is specified, check and change */
115         if (group!=NULL) {
116                 gid=nametogid(group);
117                 if (gid==-1) {
118                         printf("The UNIX group does not exist\n");
119                         return -1;
120                 } else
121                         map.gid=gid;
122         }
123         
124         /*
125          * Allow changing of group type only between domain and local
126          * We disallow changing Builtin groups !!! (SID problem)
127          */ 
128         if (sid_type==SID_NAME_ALIAS || sid_type==SID_NAME_DOM_GRP)
129                 if (map.sid_name_use==SID_NAME_ALIAS || map.sid_name_use==SID_NAME_DOM_GRP)
130                         map.sid_name_use=sid_type;
131
132
133         if (ntgroup!=NULL)
134                 fstrcpy(map.nt_name, ntgroup);
135
136         /* Change comment if new one */
137         if (groupdesc!=NULL)
138                 fstrcpy(map.comment, groupdesc);
139
140         /* Change the privilege if new one */
141         if (privilege!=NULL) {
142                 convert_priv_from_text(&se_priv, privilege);
143                 map.privilege=se_priv;
144         }
145
146         if (!add_mapping_entry(&map, TDB_REPLACE)) {
147                 printf("Count not update group database\n");
148                 return -1;
149         }
150
151         return 0;
152 }
153
154 /*********************************************************
155  Delete the group.
156 **********************************************************/
157 BOOL deletegroup(char *group)
158 {
159         DOM_SID sid;
160         
161         string_to_sid(&sid, group);
162
163         if(!group_map_remove(sid))
164                 return False;
165
166         return True;
167 }
168
169 /*********************************************************
170  List the groups.
171 **********************************************************/
172 int listgroup(enum SID_NAME_USE sid_type)
173 {
174         int entries,i;
175         GROUP_MAP *map=NULL;
176         fstring string_sid;
177         fstring group_type;
178         fstring priv_text;
179
180         printf("Unix\tSID\ttype\tnt name\tnt comment\tprivilege\n");
181                 
182         if (!enum_group_mapping(sid_type, &map, &entries, ENUM_ALL_MAPPED))
183                 return -1;
184         
185         for (i=0; i<entries; i++) {
186                 decode_sid_name_use(group_type, (map[i]).sid_name_use);
187                 sid_to_string(string_sid, &map[i].sid);
188                 convert_priv_to_text(map[i].privilege, priv_text);
189
190                 printf("%s\t%s\t%s\n\t%s\t%s\t%s\n\n", gidtoname(map[i].gid), map[i].nt_name, string_sid, 
191                                                      group_type, map[i].comment, priv_text);
192         }
193
194         return 0;
195 }
196
197 /*********************************************************
198  Start here.
199 **********************************************************/
200 int main (int argc, char **argv)
201 {
202         int ch;
203         static pstring servicesf = CONFIGFILE;
204         BOOL add_group = False;
205         BOOL view_group = False;
206         BOOL change_group = False;
207         BOOL delete_group = False;
208         BOOL nt_group = False;
209         BOOL priv = False;
210         BOOL group_type = False;
211         
212         char *group = NULL;
213         char *sid = NULL;
214         char *ntgroup = NULL;
215         char *privilege = NULL;
216         char *groupt = NULL;
217         char *group_desc = NULL;
218
219         enum SID_NAME_USE sid_type;
220
221         TimeInit();
222         
223         setup_logging("groupedit", True);
224
225         if (argc < 2) {
226                 usage();
227                 return 0;
228         }
229         
230         if(!initialize_password_db(True)) {
231                 fprintf(stderr, "Can't setup password database vectors.\n");
232                 exit(1);
233         }
234         
235         if (!lp_load(servicesf,True,False,False)) {
236                 fprintf(stderr, "Can't load %s - run testparm to debug it\n", 
237                         servicesf);
238                 exit(1);
239         }
240         
241         while ((ch = getopt(argc, argv, "a:c:d:n:p:t:u:vx:")) != EOF) {
242                 switch(ch) {
243                 case 'a':
244                         add_group = True;
245                         group=optarg;
246                         break;
247                 case 'c':
248                         change_group = True;
249                         sid=optarg;
250                         break;
251                 case 'd':
252                         group_desc=optarg;
253                         break;
254                 case 'n':
255                         nt_group = True;
256                         ntgroup=optarg;
257                         break;
258                 case 'p':
259                         priv = True;
260                         privilege=optarg;
261                         break;
262                 case 't':
263                         group_type = True;
264                         groupt=optarg;
265                         break;
266                 case 'u':
267                         group=optarg;
268                         break;
269                 case 'v':
270                         view_group = True;
271                         break;
272                 case 'x':
273                         delete_group = True;
274                         group=optarg;
275                         break;
276                 /*default:
277                         usage();*/
278                 }
279         }
280         
281         
282         if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) > 1) {
283                 fprintf (stderr, "Incompatible options on command line!\n");
284                 usage();
285                 exit(1);
286         }
287
288         /* no option on command line -> list groups */  
289         if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) == 0)
290                 view_group = True;
291
292         
293         if (group_type==False)
294                 sid_type=SID_NAME_UNKNOWN;
295         else {
296                 switch (groupt[0]) {
297                         case 'l':
298                         case 'L':
299                                 sid_type=SID_NAME_ALIAS;
300                                 break;
301                         case 'd':
302                         case 'D':
303                                 sid_type=SID_NAME_DOM_GRP;
304                                 break;
305                         case 'b':
306                         case 'B':
307                                 sid_type=SID_NAME_WKN_GRP;
308                                 break;
309                         default:
310                                 sid_type=SID_NAME_UNKNOWN;
311                                 break;
312                 }
313         }
314                 
315         if (init_group_mapping()==False) {
316                 printf("Could not open tdb mapping file.\n");
317                 return 0;
318         }
319         
320         if(pdb_generate_sam_sid()==False) {
321                 printf("Can not read machine SID\n");
322                 return 0;
323         }
324
325         default_group_mapping();
326
327         if (add_group)
328                 return addgroup(group, sid_type, ntgroup, group_desc, privilege);
329
330         if (view_group)
331                 return listgroup(sid_type);
332
333         if (delete_group)
334                 return deletegroup(group);
335         
336         if (change_group) {             
337                 return changegroup(sid, group, sid_type, ntgroup, group_desc, privilege);
338         }
339         
340         usage();
341
342         return 0;
343 }