summaryrefslogtreecommitdiff
path: root/source3/utils
diff options
context:
space:
mode:
Diffstat (limited to 'source3/utils')
-rw-r--r--source3/utils/net_privileges.c363
1 files changed, 363 insertions, 0 deletions
diff --git a/source3/utils/net_privileges.c b/source3/utils/net_privileges.c
new file mode 100644
index 0000000000..2e8bfe0c83
--- /dev/null
+++ b/source3/utils/net_privileges.c
@@ -0,0 +1,363 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Jean François Micouleau 1998-2001.
+ * Copyright (C) Gerald Carter 2003.
+ * Copyright (C) Simo Sorce 2003.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "../utils/net.h"
+
+extern PRIVS privs[];
+
+/*********************************************************
+ utility function to parse an integer parameter from
+ "parameter = value"
+**********************************************************/
+static uint32 get_int_param( const char* param )
+{
+ char *p;
+
+ p = strchr( param, '=' );
+ if ( !p )
+ return 0;
+
+ return atoi(p+1);
+}
+
+/*********************************************************
+ utility function to parse an integer parameter from
+ "parameter = value"
+**********************************************************/
+static char* get_string_param( const char* param )
+{
+ char *p;
+
+ p = strchr( param, '=' );
+ if ( !p )
+ return NULL;
+
+ return (p+1);
+}
+
+/*********************************************************
+ Dump a GROUP_MAP entry to stdout (long or short listing)
+**********************************************************/
+
+static void print_priv_entry(const char *privname, const char *description, const char *sid_list)
+{
+
+ if (!sid_list) {
+ d_printf("Error getting privilege list!\n");
+ return;
+ }
+
+ if (!description)
+ d_printf("%s\n", privname);
+ else {
+ d_printf("%s\n", privname);
+ d_printf("\tdescription: %s\n", description);
+ d_printf("\tSIDS: %s\n", sid_list);
+ }
+}
+
+/*********************************************************
+ List the groups.
+**********************************************************/
+static int net_priv_list(int argc, const char **argv)
+{
+ BOOL long_list = False;
+ fstring privname = "";
+ fstring sid_string = "";
+ int i;
+
+ /* get the options */
+ for ( i=0; i<argc; i++ ) {
+ if (!StrCaseCmp(argv[i], "verbose")) {
+ long_list = True;
+ }
+ else if (!StrnCaseCmp(argv[i], "privname", strlen("privname"))) {
+ fstrcpy(privname, get_string_param(argv[i]));
+ if (!privname[0]) {
+ d_printf("must supply a name\n");
+ return -1;
+ }
+ }
+ else if (!StrnCaseCmp(argv[i], "sid", strlen("sid"))) {
+ fstrcpy(sid_string, get_string_param(argv[i]));
+ if (!sid_string[0]) {
+ d_printf("must supply a SID\n");
+ return -1;
+ }
+ }
+ else {
+ d_printf("Bad option: %s\n", argv[i]);
+ return -1;
+ }
+ }
+
+ if (*sid_string) {
+ /* list all privileges of a single sid */
+
+ } else {
+ char *sid_list = NULL;
+
+ if (*privname) {
+ const char *description = NULL;
+
+ if (long_list) {
+ BOOL found = False;
+
+ for (i=0; privs[i].se_priv != SE_ALL_PRIVS; i++) {
+ if (!StrCaseCmp(privs[i].priv, privname)) {
+ description = privs[i].description;
+ found = True;
+ break;
+ }
+ }
+ if (!found) {
+ d_printf("No such privilege!\n");
+ return -1;
+ }
+ }
+
+ /* Get the current privilege from the database */
+ pdb_get_privilege_entry(privname, &sid_list);
+ print_priv_entry(privname, description, sid_list);
+
+ SAFE_FREE(sid_list);
+
+ } else for (i=0; privs[i].se_priv != SE_ALL_PRIVS; i++) {
+
+ if (!pdb_get_privilege_entry(privs[i].priv, &sid_list))
+ continue;
+ if (long_list) {
+ print_priv_entry(privs[i].priv, privs[i].description, sid_list);
+ } else {
+ print_priv_entry(privs[i].priv, NULL, sid_list);
+ }
+
+ SAFE_FREE(sid_list);
+ }
+ }
+
+ return 0;
+}
+
+/*********************************************************
+ Add a sid to a privilege entry
+**********************************************************/
+
+static int net_priv_add(int argc, const char **argv)
+{
+ DOM_SID sid;
+ fstring privname = "";
+ fstring sid_string = "";
+ uint32 rid = 0;
+ int i;
+
+ /* get the options */
+ for ( i=0; i<argc; i++ ) {
+ if (!StrnCaseCmp(argv[i], "rid", strlen("rid"))) {
+ rid = get_int_param(argv[i]);
+ if (rid < DOMAIN_GROUP_RID_ADMINS) {
+ d_printf("RID must be greater than %d\n", (uint32)DOMAIN_GROUP_RID_ADMINS-1);
+ return -1;
+ }
+ }
+ else if (!StrnCaseCmp(argv[i], "privilege", strlen("privilege"))) {
+ BOOL found;
+ int j;
+
+ fstrcpy(privname, get_string_param(argv[i]));
+ if (!privname[0]) {
+ d_printf("must supply a name\n");
+ return -1;
+ }
+ for (j=0; privs[j].se_priv != SE_ALL_PRIVS; j++) {
+ if (!StrCaseCmp(privs[j].priv, privname)) {
+ found = True;
+ break;
+ }
+ }
+ if (!found) {
+ d_printf("unknown privilege name");
+ return -1;
+ }
+ }
+ else if (!StrnCaseCmp(argv[i], "sid", strlen("sid"))) {
+ fstrcpy(sid_string, get_string_param(argv[i]));
+ if (!sid_string[0]) {
+ d_printf("must supply a SID\n");
+ return -1;
+ }
+ }
+ else {
+ d_printf("Bad option: %s\n", argv[i]);
+ return -1;
+ }
+ }
+
+ if (!privname[0]) {
+ d_printf("Usage: net print add {rid=<int>|sid=<string>} privilege=<string>\n");
+ return -1;
+ }
+
+ if ((rid == 0) && (sid_string[0] == '\0')) {
+ d_printf("No rid or sid specified\n");
+ d_printf("Usage: net print add {rid=<int>|sid=<string>} privilege=<string>\n");
+ return -1;
+ }
+
+ /* append the rid to our own domain/machine SID if we don't have a full SID */
+ if (!sid_string[0]) {
+ sid_copy(&sid, get_global_sam_sid());
+ sid_append_rid(&sid, rid);
+ sid_to_string(sid_string, &sid);
+ }
+
+ if (!pdb_add_sid_to_privilege(privname, &sid)) {
+ d_printf("adding sid %s to privilege %s failed!\n", sid_string, privname);
+ return -1;
+ }
+
+ d_printf("Successully added SID %s to privilege %s\n", sid_string, privname);
+ return 0;
+}
+
+/*********************************************************
+ Remove a SID froma privilege entry
+**********************************************************/
+
+static int net_priv_remove(int argc, const char **argv)
+{
+ DOM_SID sid;
+ fstring privname = "";
+ fstring sid_string = "";
+ uint32 rid = 0;
+ int i;
+
+ /* get the options */
+ for ( i=0; i<argc; i++ ) {
+ if (!StrnCaseCmp(argv[i], "rid", strlen("rid"))) {
+ rid = get_int_param(argv[i]);
+ if (rid < DOMAIN_GROUP_RID_ADMINS) {
+ d_printf("RID must be greater than %d\n", (uint32)DOMAIN_GROUP_RID_ADMINS-1);
+ return -1;
+ }
+ }
+ else if (!StrnCaseCmp(argv[i], "privilege", strlen("privilege"))) {
+ BOOL found;
+ int j;
+
+ fstrcpy(privname, get_string_param(argv[i]));
+ if (!privname[0]) {
+ d_printf("must supply a name\n");
+ return -1;
+ }
+ for (j=0; privs[j].se_priv != SE_ALL_PRIVS; j++) {
+ if (!StrCaseCmp(privs[j].priv, privname)) {
+ found = True;
+ break;
+ }
+ }
+ if (!found) {
+ d_printf("unknown privilege name");
+ return -1;
+ }
+ }
+ else if (!StrnCaseCmp(argv[i], "sid", strlen("sid"))) {
+ fstrcpy(sid_string, get_string_param(argv[i]));
+ if (!sid_string[0]) {
+ d_printf("must supply a SID\n");
+ return -1;
+ }
+ }
+ else {
+ d_printf("Bad option: %s\n", argv[i]);
+ return -1;
+ }
+ }
+
+ if (!privname[0]) {
+ d_printf("Usage: net print add {rid=<int>|sid=<string>} privilege=<string>\n");
+ return -1;
+ }
+
+ if ((rid == 0) && (sid_string[0] == '\0')) {
+ d_printf("No rid or sid specified\n");
+ d_printf("Usage: net print add {rid=<int>|sid=<string>} privilege=<string>\n");
+ return -1;
+ }
+
+ /* append the rid to our own domain/machine SID if we don't have a full SID */
+ if (!sid_string[0]) {
+ sid_copy(&sid, get_global_sam_sid());
+ sid_append_rid(&sid, rid);
+ sid_to_string(sid_string, &sid);
+ }
+
+ if (!pdb_remove_sid_from_privilege(privname, &sid)) {
+ d_printf("adding sid %s to privilege %s failed!\n", sid_string, privname);
+ return -1;
+ }
+
+ d_printf("Successully removed SID %s from privilege %s\n", sid_string, privname);
+ return 0;
+}
+
+int net_help_priv(int argc, const char **argv)
+{
+ d_printf("net priv add sid\n" \
+ " Add sid to privilege\n");
+ d_printf("net priv remove sid\n"\
+ " Remove sid from privilege\n");
+ d_printf("net priv list\n"\
+ " List sids per privilege\n");
+
+ return -1;
+}
+
+
+/***********************************************************
+ migrated functionality from smbgroupedit
+ **********************************************************/
+int net_priv(int argc, const char **argv)
+{
+ struct functable func[] = {
+ {"add", net_priv_add},
+ {"remove", net_priv_remove},
+ {"list", net_priv_list},
+ {"help", net_help_priv},
+ {NULL, NULL}
+ };
+
+ /* we shouldn't have silly checks like this */
+ if (getuid() != 0) {
+ d_printf("You must be root to edit privilege mappings.\nExiting...\n");
+ return -1;
+ }
+
+ if ( argc )
+ return net_run_function(argc, argv, func, net_help_priv);
+
+ return net_help_priv(argc, argv);
+}
+