import HEAD into svn+ssh://svn.samba.org/home/svn/samba/trunk
[metze/old/v3-2-winbind-ndr.git] / source / utils / net_privileges.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  *  Copyright (C) Gerald Carter                2003.
7  *  Copyright (C) Simo Sorce                   2003.
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24
25 #include "includes.h"
26 #include "../utils/net.h"
27
28 extern PRIVS privs[];
29
30 /*********************************************************
31  utility function to parse an integer parameter from 
32  "parameter = value"
33 **********************************************************/
34 static uint32 get_int_param( const char* param )
35 {
36         char *p;
37         
38         p = strchr( param, '=' );
39         if ( !p )
40                 return 0;
41                 
42         return atoi(p+1);
43 }
44
45 /*********************************************************
46  utility function to parse an integer parameter from 
47  "parameter = value"
48 **********************************************************/
49 static char* get_string_param( const char* param )
50 {
51         char *p;
52         
53         p = strchr( param, '=' );
54         if ( !p )
55                 return NULL;
56                 
57         return (p+1);
58 }
59
60 /*********************************************************
61  Dump a GROUP_MAP entry to stdout (long or short listing)
62 **********************************************************/
63
64 static void print_priv_entry(const char *privname, const char *description, const char *sid_list)
65 {
66         d_printf("%s\n", privname);
67
68         if (description) {
69                 d_printf("\tdescription: %s\n", description);
70         }
71
72         if (sid_list) {
73                 d_printf("\tSIDs: %s\n", sid_list);
74         } else {
75                 d_printf("\tNo SIDs in this privilege\n");
76         }
77 }
78
79 /*********************************************************
80  List the groups.
81 **********************************************************/
82 static int net_priv_list(int argc, const char **argv)
83 {
84         fstring privname = "";
85         fstring sid_string = "";
86         int i;
87         BOOL verbose = False;
88         
89         /* get the options */
90         for ( i=0; i<argc; i++ ) {
91                 if (StrnCaseCmp(argv[i], "privname", strlen("privname")) == 0) {
92                         fstrcpy(privname, get_string_param(argv[i]));
93                         if (!privname[0]) {
94                                 d_printf("must supply a name\n");
95                                 return -1;
96                         }
97                 }
98                 else if (StrnCaseCmp(argv[i], "sid", strlen("sid")) == 0) {
99                         fstrcpy(sid_string, get_string_param(argv[i]));
100                         if (!sid_string[0]) {
101                                 d_printf("must supply a SID\n");
102                                 return -1;
103                         }               
104                 }
105                 else if (StrnCaseCmp(argv[i], "verbose", strlen("verbose")) == 0) {
106                         verbose = True;
107                 }
108                 else {
109                         d_printf("Bad option: %s\n", argv[i]);
110                         return -1;
111                 }
112         }
113
114         if (sid_string[0] != '\0') {
115                 /* list all privileges of a single sid */
116                 
117         } else {
118                 char *sid_list = NULL;
119                 
120                 if (privname[0] != '\0') {
121                         const char *description = NULL;
122
123                         BOOL found = False;
124
125                         for (i=0; privs[i].se_priv != SE_ALL_PRIVS; i++) {
126                                 if (StrCaseCmp(privs[i].priv, privname) == 0) {
127                                         description = privs[i].description;
128                                         found = True;
129                                         break;
130                                 }
131                         }
132                         if (!found) {
133                                 d_printf("No such privilege!\n");
134                                 return -1;
135                         }
136                         
137                         /* Get the current privilege from the database */
138                         pdb_get_privilege_entry(privname, &sid_list);
139                         print_priv_entry(privname, description, sid_list);
140
141                         SAFE_FREE(sid_list);
142
143                 } else for (i=0; privs[i].se_priv != SE_ALL_PRIVS; i++) {
144
145                         if (!pdb_get_privilege_entry(privs[i].priv, &sid_list)) {
146                                 if (!verbose)
147                                         continue;
148
149                                 sid_list = NULL;
150                         }
151
152                         print_priv_entry(privs[i].priv, privs[i].description, sid_list);
153
154                         SAFE_FREE(sid_list);
155                 }
156         }
157
158         return 0;
159 }
160
161 /*********************************************************
162  Add a sid to a privilege entry
163 **********************************************************/
164
165 static int net_priv_add(int argc, const char **argv)
166 {
167         DOM_SID sid;
168         fstring privname = "";
169         fstring sid_string = "";
170         uint32 rid = 0; 
171         int i;
172         
173         /* get the options */
174         for ( i=0; i<argc; i++ ) {
175                 if (StrnCaseCmp(argv[i], "rid", strlen("rid")) == 0) {
176                         rid = get_int_param(argv[i]);
177                         if (rid < DOMAIN_GROUP_RID_ADMINS) {
178                                 d_printf("RID must be greater than %d\n", (uint32)DOMAIN_GROUP_RID_ADMINS-1);
179                                 return -1;
180                         }
181                 }
182                 else if (StrnCaseCmp(argv[i], "privilege", strlen("privilege")) == 0) {
183                         BOOL found = False;
184                         int j;
185
186                         fstrcpy(privname, get_string_param(argv[i]));
187                         if (!privname[0]) {
188                                 d_printf("must supply a name\n");
189                                 return -1;
190                         }               
191                         for (j=0; privs[j].se_priv != SE_ALL_PRIVS; j++) {
192                                 if (StrCaseCmp(privs[j].priv, privname) == 0) {
193                                         found = True;
194                                 }
195                         }
196                         if (!found) {
197                                 d_printf("unknown privilege name");
198                                 return -1;
199                         }
200                 }
201                 else if (StrnCaseCmp(argv[i], "sid", strlen("sid")) == 0) {
202                         fstrcpy(sid_string, get_string_param(argv[i]));
203                         if (!sid_string[0]) {
204                                 d_printf("must supply a SID\n");
205                                 return -1;
206                         }               
207                 }
208                 else {
209                         d_printf("Bad option: %s\n", argv[i]);
210                         return -1;
211                 }
212         }
213
214         if (privname[0] == '\0') {
215                 d_printf("Usage: net priv add {rid=<int>|sid=<string>} privilege=<string>\n");
216                 return -1;
217         }
218         
219         if ((rid == 0) && (sid_string[0] == '\0')) {
220                 d_printf("No rid or sid specified\n");
221                 d_printf("Usage: net priv add {rid=<int>|sid=<string>} privilege=<string>\n");
222                 return -1;
223         }
224
225         /* append the rid to our own domain/machine SID if we don't have a full SID */
226         if (sid_string[0] == '\0') {
227                 sid_copy(&sid, get_global_sam_sid());
228                 sid_append_rid(&sid, rid);
229                 sid_to_string(sid_string, &sid);
230         } else {
231                 string_to_sid(&sid, sid_string);
232         }
233
234         if (!pdb_add_sid_to_privilege(privname, &sid)) {
235                 d_printf("adding sid %s to privilege %s failed!\n", sid_string, privname);
236                 return -1;
237         }
238
239         d_printf("Successully added SID %s to privilege %s\n", sid_string, privname);
240         return 0;
241 }
242
243 /*********************************************************
244  Remove a SID froma privilege entry
245 **********************************************************/
246
247 static int net_priv_remove(int argc, const char **argv)
248 {
249         DOM_SID sid;
250         fstring privname = "";
251         fstring sid_string = "";
252         uint32 rid = 0; 
253         int i;
254         
255         /* get the options */
256         for ( i=0; i<argc; i++ ) {
257                 if (StrnCaseCmp(argv[i], "rid", strlen("rid")) == 0) {
258                         rid = get_int_param(argv[i]);
259                         if (rid < DOMAIN_GROUP_RID_ADMINS) {
260                                 d_printf("RID must be greater than %d\n", (uint32)DOMAIN_GROUP_RID_ADMINS-1);
261                                 return -1;
262                         }
263                 }
264                 else if (StrnCaseCmp(argv[i], "privilege", strlen("privilege")) == 0) {
265                         BOOL found = False;
266                         int j;
267
268                         fstrcpy(privname, get_string_param(argv[i]));
269                         if (!privname[0]) {
270                                 d_printf("must supply a name\n");
271                                 return -1;
272                         }               
273                         for (j=0; privs[j].se_priv != SE_ALL_PRIVS; j++) {
274                                 if (StrCaseCmp(privs[j].priv, privname) == 0) {
275                                         found = True;
276                                 }
277                         }
278                         if (!found) {
279                                 d_printf("unknown privilege name");
280                                 return -1;
281                         }
282                 }
283                 else if (StrnCaseCmp(argv[i], "sid", strlen("sid")) == 0) {
284                         fstrcpy(sid_string, get_string_param(argv[i]));
285                         if (!sid_string[0]) {
286                                 d_printf("must supply a SID\n");
287                                 return -1;
288                         }               
289                 }
290                 else {
291                         d_printf("Bad option: %s\n", argv[i]);
292                         return -1;
293                 }
294         }
295
296         if (privname[0] == '\0') {
297                 d_printf("Usage: net priv remove {rid=<int>|sid=<string>} privilege=<string>\n");
298                 return -1;
299         }
300         
301         if ((rid == 0) && (sid_string[0] == '\0')) {
302                 d_printf("No rid or sid specified\n");
303                 d_printf("Usage: net priv remove {rid=<int>|sid=<string>} privilege=<string>\n");
304                 return -1;
305         }
306
307         /* append the rid to our own domain/machine SID if we don't have a full SID */
308         if (sid_string[0] == '\0') {
309                 sid_copy(&sid, get_global_sam_sid());
310                 sid_append_rid(&sid, rid);
311                 sid_to_string(sid_string, &sid);
312         } else {
313                 string_to_sid(&sid, sid_string);
314         }
315
316         if (!pdb_remove_sid_from_privilege(privname, &sid)) {
317                 d_printf("removing sid %s from privilege %s failed!\n", sid_string, privname);
318                 return -1;
319         }
320
321         d_printf("Successully removed SID %s from privilege %s\n", sid_string, privname);
322         return 0;
323 }
324
325 int net_help_priv(int argc, const char **argv)
326 {
327         d_printf("net priv add sid\n" \
328                  "    Add sid to privilege\n");
329         d_printf("net priv remove sid\n"\
330                  "    Remove sid from privilege\n");
331         d_printf("net priv list\n"\
332                  "    List sids per privilege\n");
333         
334         return -1;
335 }
336
337
338 /***********************************************************
339  migrated functionality from smbgroupedit
340  **********************************************************/
341 int net_priv(int argc, const char **argv)
342 {
343         struct functable func[] = {
344                 {"add", net_priv_add},
345                 {"remove", net_priv_remove},
346                 {"list", net_priv_list},
347                 {"help", net_help_priv},
348                 {NULL, NULL}
349         };
350
351         /* we shouldn't have silly checks like this */
352         if (getuid() != 0) {
353                 d_printf("You must be root to edit privilege mappings.\nExiting...\n");
354                 return -1;
355         }
356         
357         if ( argc )
358                 return net_run_function(argc, argv, func, net_help_priv);
359
360         return net_help_priv(argc, argv);
361 }
362