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