r23746: Fix missing assignments to target string of asprintf in import function.
[ira/wip.git] / source / utils / net_conf.c
index 605ad3fdd2bcc6743fbe64af832450fce1b6baaa..febc8dc9e13cbb2777fc48465a68a9ed9b9fc420 100644 (file)
  */
 
 /*
- * This currently only an interface to the configuration
- * stored inside the samba registry. In the future there
- * might be support for other configuration backends as well.
- */
-
-/*
- * TODO:
- *
- *  - check uid 0 for write operations
- *  - check for valid parameter names and types (loadparm...) ???
- *  - check for correctness of shares (service_ok) ?
- *  - refactor to use _internal functions for pieces of code
- *
+ * This is an interface to the configuration stored inside the 
+ * samba registry. In the future there might be support for other 
+ * configuration backends as well.
  */
 
 #include "includes.h"
@@ -64,6 +54,12 @@ static int net_conf_listshares_usage(int argc, const char **argv)
        return -1;
 }
 
+static int net_conf_drop_usage(int argc, const char **argv)
+{
+       d_printf("USAGE: net conf drop\n");
+       return -1;
+}
+
 static int net_conf_showshare_usage(int argc, const char **argv)
 {
        d_printf("USAGE: net conf showshare <sharename>\n");
@@ -92,8 +88,7 @@ static int net_conf_delshare_usage(int argc, const char **argv)
 
 static int net_conf_setparm_usage(int argc, const char **argv)
 {
-       d_printf("USAGE: net conf setparm <section> <param> <type> <value>\n"
-                "\t(Supported types are 'dword' and 'sz' by now.)\n");
+       d_printf("USAGE: net conf setparm <section> <param> <value>\n");
        return -1;
 }
 
@@ -150,7 +145,7 @@ static char *format_value(TALLOC_CTX *mem_ctx, struct registry_value *value)
 /*
  * add a value to a key. 
  */
-static WERROR reg_setvalue_internal(struct registry_key *key, 
+static WERROR reg_setvalue_internal(struct registry_key *key,
                                    const char *valname,
                                    const char *valtype,
                                    const char *valstr)
@@ -170,7 +165,32 @@ static WERROR reg_setvalue_internal(struct registry_key *key,
                val.v.sz.len = strlen(valstr) + 1;
        }
        else {
-               d_fprintf(stderr, "Sorry, only value types DWORD and SZ implementd currently for setting values.\n");
+               d_fprintf(stderr, "Only value types DWORD and SZ are"
+                         "currently implemented for setting values.\n");
+               werr = WERR_INVALID_PARAM;
+               goto done;
+       }
+
+       if (!lp_parameter_is_valid(valname)) {
+               d_fprintf(stderr, "Invalid parameter '%s' given.\n", valname);
+               werr = WERR_INVALID_PARAM;
+               goto done;
+       }
+
+       if (registry_smbconf_valname_forbidden(valname)) {
+               d_fprintf(stderr, "Parameter '%s' not allowed in registry.\n",
+                         valname);
+               werr = WERR_INVALID_PARAM;
+               goto done;
+       }
+
+       if (!strequal(strrchr_m(key->key->name, '\\')+1, GLOBAL_NAME) &&
+           lp_parameter_is_global(valname))
+       {
+               d_fprintf(stderr, "Global paramter '%s' not allowed in "
+                         "service definition ('%s').\n", valname,
+                         strrchr_m(key->key->name, '\\')+1);
+               werr = WERR_INVALID_PARAM;
                goto done;
        }
 
@@ -261,7 +281,7 @@ static WERROR reg_delkey_internal(TALLOC_CTX *ctx, const char *keyname)
                goto done;
        }
 
-       werr = reg_deletekey(key, keyname);
+       werr = reg_deletekey_recursive(key, key, keyname);
        if (!W_ERROR_IS_OK(werr)) {
                d_fprintf(stderr, "Error deleting registry key %s\\%s: %s\n",
                          KEY_SMBCONF, keyname, dos_errstr(werr));
@@ -379,6 +399,56 @@ done:
        return werr; 
 }
 
+static WERROR drop_smbconf_internal(TALLOC_CTX *ctx)
+{
+       char *path, *p;
+       WERROR werr = WERR_OK;
+       NT_USER_TOKEN *token;
+       struct registry_key *parent_key = NULL;
+       struct registry_key *new_key = NULL;
+       TALLOC_CTX* tmp_ctx = NULL;
+       enum winreg_CreateAction action;
+
+       tmp_ctx = talloc_new(ctx);
+       if (tmp_ctx == NULL) {
+               werr = WERR_NOMEM;
+               goto done;
+       }
+
+       if (!(token = registry_create_admin_token(tmp_ctx))) {
+               /* what is the appropriate error code here? */
+               werr = WERR_CAN_NOT_COMPLETE; 
+               goto done;
+       }
+
+       path = talloc_strdup(tmp_ctx, KEY_SMBCONF);
+       if (path == NULL) {
+               d_fprintf(stderr, "ERROR: out of memory!\n");
+               werr = WERR_NOMEM;
+               goto done;
+       }
+       p = strrchr(path, '\\');
+       *p = '\0';
+       werr = reg_open_path(tmp_ctx, path, REG_KEY_WRITE, token, &parent_key);
+
+       if (!W_ERROR_IS_OK(werr)) {
+               goto done;
+       }
+
+       werr = reg_deletekey_recursive(tmp_ctx, parent_key, p+1);
+
+       if (!W_ERROR_IS_OK(werr)) {
+               goto done;
+       }
+       
+       werr = reg_createkey(tmp_ctx, parent_key, p+1, REG_KEY_WRITE, 
+                            &new_key, &action);
+
+done:
+       TALLOC_FREE(tmp_ctx);
+       return werr;
+}
+
 static int import_process_service(TALLOC_CTX *ctx, 
                                  struct share_params *share)
 {
@@ -457,7 +527,7 @@ static int import_process_service(TALLOC_CTX *ctx,
                        }
                        break;
                case P_OCTAL:
-                       talloc_asprintf(ctx, "%s", octal_string(*(int *)ptr));
+                       valstr = talloc_asprintf(ctx, "%s", octal_string(*(int *)ptr));
                        break;
                case P_LIST:
                        valstr = talloc_strdup(ctx, "");
@@ -483,7 +553,7 @@ static int import_process_service(TALLOC_CTX *ctx,
                        break;
                case P_INTEGER:
                        valtype = "dword";
-                       talloc_asprintf(ctx, "%d", *(int *)ptr);
+                       valstr = talloc_asprintf(ctx, "%d", *(int *)ptr);
                        break;
                case P_SEP:
                        break;
@@ -621,8 +691,6 @@ int net_conf_import(int argc, const char **argv)
        DEBUG(3,("net_conf_import: reading configuration from file %s.\n",
                filename));
 
-       /* TODO: check for existence and readability */
-
        if (!lp_load(filename, 
                     False,     /* global_only */
                     True,      /* save_defaults */
@@ -719,6 +787,29 @@ done:
        return ret;
 }
 
+int net_conf_drop(int argc, const char **argv)
+{
+       int ret = -1;
+       WERROR werr;
+
+       if (argc != 0) {
+               net_conf_drop_usage(argc, argv);
+               goto done;
+       }
+
+       werr = drop_smbconf_internal(NULL);
+       if (!W_ERROR_IS_OK(werr)) {
+               d_fprintf(stderr, "Error deleting configuration: %s\n",
+                         dos_errstr(werr));
+               goto done;
+       }
+
+       ret = 0;
+
+done:
+       return ret;
+}
+
 int net_conf_showshare(int argc, const char **argv)
 {
        int ret = -1;
@@ -928,20 +1019,18 @@ static int net_conf_setparm(int argc, const char **argv)
        struct registry_key *key = NULL;
        char *service = NULL;
        char *param = NULL;
-       char *type = NULL;
        const char *value_str = NULL;
        TALLOC_CTX *ctx;
 
        ctx = talloc_init("setparm");
 
-       if (argc != 4) {
+       if (argc != 3) {
                net_conf_setparm_usage(argc, argv);
                goto done;
        }
        service = strdup_lower(argv[0]);
        param = strdup_lower(argv[1]);
-       type = strdup_lower(argv[2]);
-       value_str = argv[3];
+       value_str = argv[2];
 
        if (!smbconf_key_exists(ctx, service)) {
                werr = reg_createkey_internal(ctx, service, &key);
@@ -953,7 +1042,7 @@ static int net_conf_setparm(int argc, const char **argv)
                goto done;
        }
 
-       werr = reg_setvalue_internal(key, param, type, value_str);
+       werr = reg_setvalue_internal(key, param, "sz", value_str);
        if (!W_ERROR_IS_OK(werr)) {
                d_fprintf(stderr, "Error setting value '%s': %s\n",
                          param, dos_errstr(werr));
@@ -1080,6 +1169,8 @@ int net_conf(int argc, const char **argv)
                 "Import configuration from file in smb.conf format."},
                {"listshares", net_conf_listshares, 
                 "List the registry shares."},
+               {"drop", net_conf_drop,
+                "Delete the complete configuration from registry."},
                {"showshare", net_conf_showshare, 
                 "Show the definition of a registry share."},
                {"addshare", net_conf_addshare,