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