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.
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.
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.
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.
26 #include "../utils/net.h"
30 /*********************************************************
31 utility function to parse an integer parameter from
33 **********************************************************/
34 static uint32 get_int_param( const char* param )
38 p = strchr( param, '=' );
45 /*********************************************************
46 utility function to parse an integer parameter from
48 **********************************************************/
49 static char* get_string_param( const char* param )
53 p = strchr( param, '=' );
60 /*********************************************************
61 Dump a GROUP_MAP entry to stdout (long or short listing)
62 **********************************************************/
64 static void print_priv_entry(const char *privname, const char *description, const char *sid_list)
66 d_printf("%s\n", privname);
69 d_printf("\tdescription: %s\n", description);
73 d_printf("\tSIDs: %s\n", sid_list);
75 d_printf("\tNo SIDs in this privilege\n");
79 /*********************************************************
81 **********************************************************/
82 static int net_priv_list(int argc, const char **argv)
84 fstring privname = "";
85 fstring sid_string = "";
90 for ( i=0; i<argc; i++ ) {
91 if (StrnCaseCmp(argv[i], "privname", strlen("privname")) == 0) {
92 fstrcpy(privname, get_string_param(argv[i]));
94 d_printf("must supply a name\n");
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");
105 else if (StrnCaseCmp(argv[i], "verbose", strlen("verbose")) == 0) {
109 d_printf("Bad option: %s\n", argv[i]);
114 if (sid_string[0] != '\0') {
115 /* list all privileges of a single sid */
118 char *sid_list = NULL;
120 if (privname[0] != '\0') {
121 const char *description = NULL;
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;
133 d_printf("No such privilege!\n");
137 /* Get the current privilege from the database */
138 pdb_get_privilege_entry(privname, &sid_list);
139 print_priv_entry(privname, description, sid_list);
143 } else for (i=0; privs[i].se_priv != SE_ALL_PRIVS; i++) {
145 if (!pdb_get_privilege_entry(privs[i].priv, &sid_list)) {
152 print_priv_entry(privs[i].priv, privs[i].description, sid_list);
161 /*********************************************************
162 Add a sid to a privilege entry
163 **********************************************************/
165 static int net_priv_add(int argc, const char **argv)
168 fstring privname = "";
169 fstring sid_string = "";
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);
182 else if (StrnCaseCmp(argv[i], "privilege", strlen("privilege")) == 0) {
186 fstrcpy(privname, get_string_param(argv[i]));
188 d_printf("must supply a name\n");
191 for (j=0; privs[j].se_priv != SE_ALL_PRIVS; j++) {
192 if (StrCaseCmp(privs[j].priv, privname) == 0) {
197 d_printf("unknown privilege name");
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");
209 d_printf("Bad option: %s\n", argv[i]);
214 if (privname[0] == '\0') {
215 d_printf("Usage: net priv add {rid=<int>|sid=<string>} privilege=<string>\n");
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");
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);
231 string_to_sid(&sid, sid_string);
234 if (!pdb_add_sid_to_privilege(privname, &sid)) {
235 d_printf("adding sid %s to privilege %s failed!\n", sid_string, privname);
239 d_printf("Successully added SID %s to privilege %s\n", sid_string, privname);
243 /*********************************************************
244 Remove a SID froma privilege entry
245 **********************************************************/
247 static int net_priv_remove(int argc, const char **argv)
250 fstring privname = "";
251 fstring sid_string = "";
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);
264 else if (StrnCaseCmp(argv[i], "privilege", strlen("privilege")) == 0) {
268 fstrcpy(privname, get_string_param(argv[i]));
270 d_printf("must supply a name\n");
273 for (j=0; privs[j].se_priv != SE_ALL_PRIVS; j++) {
274 if (StrCaseCmp(privs[j].priv, privname) == 0) {
279 d_printf("unknown privilege name");
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");
291 d_printf("Bad option: %s\n", argv[i]);
296 if (privname[0] == '\0') {
297 d_printf("Usage: net priv remove {rid=<int>|sid=<string>} privilege=<string>\n");
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");
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);
313 string_to_sid(&sid, sid_string);
316 if (!pdb_remove_sid_from_privilege(privname, &sid)) {
317 d_printf("removing sid %s from privilege %s failed!\n", sid_string, privname);
321 d_printf("Successully removed SID %s from privilege %s\n", sid_string, privname);
325 int net_help_priv(int argc, const char **argv)
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");
338 /***********************************************************
339 migrated functionality from smbgroupedit
340 **********************************************************/
341 int net_priv(int argc, const char **argv)
343 struct functable func[] = {
344 {"add", net_priv_add},
345 {"remove", net_priv_remove},
346 {"list", net_priv_list},
347 {"help", net_help_priv},
351 /* we shouldn't have silly checks like this */
353 d_printf("You must be root to edit privilege mappings.\nExiting...\n");
358 return net_run_function(argc, argv, func, net_help_priv);
360 return net_help_priv(argc, argv);