static sbcErr smbconf_reg_get_includes(struct smbconf_ctx *ctx, TALLOC_CTX *mem_ctx, const char *service, uint32_t *num_includes, char ***includes) { sbcErr err; struct registry_key *key = NULL; TALLOC_CTX *tmp_ctx = talloc_stackframe(); err = smbconf_reg_open_service_key(tmp_ctx, ctx, service, REG_KEY_READ, &key); if (!SBC_ERROR_IS_OK(err)) { goto done; } err = smbconf_reg_get_includes_internal(mem_ctx, key, num_includes, includes); if (!SBC_ERROR_IS_OK(err)) { goto done; } done: talloc_free(tmp_ctx); return err; }
static bool test_set_get_includes(struct smbconf_ctx *ctx) { sbcErr err; uint32_t count; bool ret = false; const char *set_includes[] = { "/path/to/include1", "/path/to/include2" }; uint32_t set_num_includes = 2; char **get_includes = NULL; uint32_t get_num_includes = 0; TALLOC_CTX *mem_ctx = talloc_stackframe(); printf("TEST: set_get_includes\n"); err = smbconf_set_global_includes(ctx, set_num_includes, set_includes); if (!SBC_ERROR_IS_OK(err)) { printf("FAIL: get_set_includes (setting includes) - %s\n", sbcErrorString(err)); goto done; } err = smbconf_get_global_includes(ctx, mem_ctx, &get_num_includes, &get_includes); if (!SBC_ERROR_IS_OK(err)) { printf("FAIL: get_set_includes (getting includes) - %s\n", sbcErrorString(err)); goto done; } if (get_num_includes != set_num_includes) { printf("FAIL: get_set_includes - set %d includes, got %d\n", set_num_includes, get_num_includes); goto done; } for (count = 0; count < get_num_includes; count++) { if (!strequal(set_includes[count], get_includes[count])) { printf("expected: \n"); print_strings("* ", set_num_includes, (const char * const *)set_includes); printf("got: \n"); print_strings("* ", get_num_includes, (const char * const *)get_includes); printf("FAIL: get_set_includes - data mismatch:\n"); goto done; } } printf("OK: set_includes\n"); ret = true; done: talloc_free(mem_ctx); return ret; }
static bool test_delete_includes(struct smbconf_ctx *ctx) { sbcErr err; bool ret = false; const char *set_includes[] = { "/path/to/include", }; uint32_t set_num_includes = 1; char **get_includes = NULL; uint32_t get_num_includes = 0; TALLOC_CTX *mem_ctx = talloc_stackframe(); printf("TEST: delete_includes\n"); err = smbconf_set_global_includes(ctx, set_num_includes, set_includes); if (!SBC_ERROR_IS_OK(err)) { printf("FAIL: delete_includes (setting includes) - %s\n", sbcErrorString(err)); goto done; } err = smbconf_delete_global_includes(ctx); if (!SBC_ERROR_IS_OK(err)) { printf("FAIL: delete_includes (deleting includes) - %s\n", sbcErrorString(err)); goto done; } err = smbconf_get_global_includes(ctx, mem_ctx, &get_num_includes, &get_includes); if (!SBC_ERROR_IS_OK(err)) { printf("FAIL: delete_includes (getting includes) - %s\n", sbcErrorString(err)); goto done; } if (get_num_includes != 0) { printf("FAIL: delete_includes (not empty after delete)\n"); goto done; } err = smbconf_delete_global_includes(ctx); if (!SBC_ERROR_IS_OK(err)) { printf("FAIL: delete_includes (delete empty includes) - " "%s\n", sbcErrorString(err)); goto done; } printf("OK: delete_includes\n"); ret = true; done: talloc_free(mem_ctx); return ret; }
static WERROR NetServerSetInfo_l_1005(struct libnetapi_ctx *ctx, struct NetServerSetInfo *r) { WERROR werr = WERR_OK; sbcErr err; struct smbconf_ctx *conf_ctx; struct srvsvc_NetSrvInfo1005 *info1005; if (!r->in.buffer) { *r->out.parm_error = 1005; /* sure here ? */ return WERR_INVALID_PARAM; } info1005 = (struct srvsvc_NetSrvInfo1005 *)r->in.buffer; if (!info1005->comment) { *r->out.parm_error = 1005; return WERR_INVALID_PARAM; } #ifdef REGISTRY_BACKEND if (!lp_config_backend_is_registry()) #endif { libnetapi_set_error_string(ctx, "Configuration manipulation requested but not " "supported by backend"); return WERR_NOT_SUPPORTED; } err = smbconf_init_reg(ctx, &conf_ctx, NULL); if (!SBC_ERROR_IS_OK(err)) { libnetapi_set_error_string(ctx, "Could not initialize backend: %s", sbcErrorString(err)); werr = WERR_NO_SUCH_SERVICE; goto done; } err = smbconf_set_global_parameter(conf_ctx, "server string", info1005->comment); if (!SBC_ERROR_IS_OK(err)) { libnetapi_set_error_string(ctx, "Could not set global parameter: %s", sbcErrorString(err)); werr = WERR_NO_SUCH_SERVICE; goto done; } done: smbconf_shutdown(conf_ctx); return werr; }
static int net_conf_delshare(struct net_context *c, struct smbconf_ctx *conf_ctx, int argc, const char **argv) { int ret = -1; const char *sharename = NULL; sbcErr err; TALLOC_CTX *mem_ctx = talloc_stackframe(); if (argc != 1 || c->display_usage) { net_conf_delshare_usage(c, argc, argv); goto done; } sharename = talloc_strdup(mem_ctx, argv[0]); if (sharename == NULL) { d_printf(_("error: out of memory!\n")); goto done; } err = smbconf_delete_share(conf_ctx, sharename); if (!SBC_ERROR_IS_OK(err)) { d_fprintf(stderr, _("Error deleting share %s: %s\n"), sharename, sbcErrorString(err)); goto done; } ret = 0; done: TALLOC_FREE(mem_ctx); return ret; }
static bool torture_smbconf_reg(void) { sbcErr err; bool ret = true; struct smbconf_ctx *conf_ctx = NULL; TALLOC_CTX *mem_ctx = talloc_stackframe(); printf("test: registry backend\n"); printf("TEST: init\n"); err = smbconf_init_reg(mem_ctx, &conf_ctx, NULL); if (!SBC_ERROR_IS_OK(err)) { printf("FAIL: init failed: %s\n", sbcErrorString(err)); ret = false; goto done; } printf("OK: init\n"); ret &= test_get_includes(conf_ctx); ret &= test_set_get_includes(conf_ctx); ret &= test_delete_includes(conf_ctx); smbconf_shutdown(conf_ctx); done: printf("%s: registry backend\n", ret ? "success" : "failure"); talloc_free(mem_ctx); return ret; }
static bool test_get_includes(struct smbconf_ctx *ctx) { sbcErr err; bool ret = false; uint32_t num_includes = 0; char **includes = NULL; TALLOC_CTX *mem_ctx = talloc_stackframe(); printf("TEST: get_includes\n"); err = smbconf_get_global_includes(ctx, mem_ctx, &num_includes, &includes); if (!SBC_ERROR_IS_OK(err)) { printf("FAIL: get_includes - %s\n", sbcErrorString(err)); goto done; } printf("got %u includes%s\n", num_includes, (num_includes > 0) ? ":" : "."); print_strings("", num_includes, (const char **)includes); printf("OK: get_includes\n"); ret = true; done: talloc_free(mem_ctx); return ret; }
static int net_conf_listshares(struct net_context *c, struct smbconf_ctx *conf_ctx, int argc, const char **argv) { sbcErr err; int ret = -1; uint32_t count, num_shares = 0; char **share_names = NULL; TALLOC_CTX *mem_ctx; mem_ctx = talloc_stackframe(); if (argc != 0 || c->display_usage) { net_conf_listshares_usage(c, argc, argv); goto done; } err = smbconf_get_share_names(conf_ctx, mem_ctx, &num_shares, &share_names); if (!SBC_ERROR_IS_OK(err)) { goto done; } for (count = 0; count < num_shares; count++) { d_printf("%s\n", share_names[count]); } ret = 0; done: TALLOC_FREE(mem_ctx); return ret; }
/** * delete a parameter from configuration */ static sbcErr smbconf_reg_delete_parameter(struct smbconf_ctx *ctx, const char *service, const char *param) { struct registry_key *key = NULL; WERROR werr; sbcErr err; TALLOC_CTX *mem_ctx = talloc_stackframe(); err = smbconf_reg_open_service_key(mem_ctx, ctx, service, REG_KEY_ALL, &key); if (!SBC_ERROR_IS_OK(err)) { goto done; } if (!smbconf_reg_valname_valid(param)) { err = SBC_ERR_INVALID_PARAM; goto done; } if (!smbconf_value_exists(key, param)) { err = SBC_ERR_OK; goto done; } werr = reg_deletevalue(key, param); if (!W_ERROR_IS_OK(werr)) { err = SBC_ERR_ACCESS_DENIED; } done: talloc_free(mem_ctx); return err; }
/** * This functions process a service previously loaded with libsmbconf. */ static sbcErr import_process_service(struct net_context *c, struct smbconf_ctx *conf_ctx, struct smbconf_service *service) { sbcErr err = SBC_ERR_OK; if (c->opt_testmode) { uint32_t idx; const char *indent = ""; if (service->name != NULL) { d_printf("[%s]\n", service->name); indent = "\t"; } for (idx = 0; idx < service->num_params; idx++) { d_printf("%s%s = %s\n", indent, service->param_names[idx], service->param_values[idx]); } d_printf("\n"); goto done; } if (smbconf_share_exists(conf_ctx, service->name)) { err = smbconf_delete_share(conf_ctx, service->name); if (!SBC_ERROR_IS_OK(err)) { goto done; } } err = smbconf_create_set_share(conf_ctx, service); done: return err; }
static int net_conf_delincludes(struct net_context *c, struct smbconf_ctx *conf_ctx, int argc, const char **argv) { sbcErr err; char *service; int ret = -1; TALLOC_CTX *mem_ctx = talloc_stackframe(); if (argc != 1 || c->display_usage) { net_conf_delincludes_usage(c, argc, argv); goto done; } service = talloc_strdup(mem_ctx, argv[0]); if (service == NULL) { d_printf(_("error: out of memory!\n")); goto done; } err = smbconf_delete_includes(conf_ctx, service); if (!SBC_ERROR_IS_OK(err)) { d_printf(_("error deleting includes: %s\n"), sbcErrorString(err)); goto done; } ret = 0; done: TALLOC_FREE(mem_ctx); return ret; }
static sbcErr smbconf_reg_delete_includes(struct smbconf_ctx *ctx, const char *service) { WERROR werr; sbcErr err; struct registry_key *key = NULL; TALLOC_CTX *tmp_ctx = talloc_stackframe(); err = smbconf_reg_open_service_key(tmp_ctx, ctx, service, REG_KEY_ALL, &key); if (!SBC_ERROR_IS_OK(err)) { goto done; } if (!smbconf_value_exists(key, INCLUDES_VALNAME)) { err = SBC_ERR_OK; goto done; } werr = reg_deletevalue(key, INCLUDES_VALNAME); if (!W_ERROR_IS_OK(werr)) { err = SBC_ERR_ACCESS_DENIED; goto done; } err = SBC_ERR_OK; done: talloc_free(tmp_ctx); return err; }
/** * Initialize the configuration. * * This should be the first function in a sequence of calls to smbconf * functions: * * Upon success, this creates and returns the conf context * that should be passed around in subsequent calls to the other * smbconf functions. * * After the work with the configuration is completed, smbconf_shutdown() * should be called. */ sbcErr smbconf_init_internal(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx, const char *path, struct smbconf_ops *ops) { sbcErr err = SBC_ERR_OK; struct smbconf_ctx *ctx; if (conf_ctx == NULL) { return SBC_ERR_INVALID_PARAM; } ctx = talloc_zero(mem_ctx, struct smbconf_ctx); if (ctx == NULL) { return SBC_ERR_NOMEM; } ctx->ops = ops; err = ctx->ops->init(ctx, path); if (!SBC_ERROR_IS_OK(err)) { goto fail; } talloc_set_destructor(ctx, smbconf_destroy_ctx); *conf_ctx = ctx; return err; fail: talloc_free(ctx); return err; }
static int net_conf_getparm(struct net_context *c, struct smbconf_ctx *conf_ctx, int argc, const char **argv) { int ret = -1; sbcErr err; char *service = NULL; char *param = NULL; char *valstr = NULL; TALLOC_CTX *mem_ctx; mem_ctx = talloc_stackframe(); if (argc != 2 || c->display_usage) { net_conf_getparm_usage(c, argc, argv); goto done; } /* * NULL service name means "dangling parameters" to libsmbconf. * We use the empty string from the command line for this purpose. */ if (strlen(argv[0]) != 0) { service = talloc_strdup(mem_ctx, argv[0]); if (service == NULL) { d_printf(_("error: out of memory!\n")); goto done; } } param = strlower_talloc(mem_ctx, argv[1]); if (param == NULL) { d_printf(_("error: out of memory!\n")); goto done; } err = smbconf_get_parameter(conf_ctx, mem_ctx, service, param, &valstr); if (SBC_ERROR_EQUAL(err, SBC_ERR_NO_SUCH_SERVICE)) { d_fprintf(stderr, _("Error: given service '%s' does not exist.\n"), service); goto done; } else if (SBC_ERROR_EQUAL(err, SBC_ERR_INVALID_PARAM)) { d_fprintf(stderr, _("Error: given parameter '%s' is not set.\n"), param); goto done; } else if (!SBC_ERROR_IS_OK(err)) { d_fprintf(stderr, _("Error getting value '%s': %s.\n"), param, sbcErrorString(err)); goto done; } d_printf("%s\n", valstr); ret = 0; done: TALLOC_FREE(mem_ctx); return ret; }
/** * get a definition of a share (service) from configuration. */ static sbcErr smbconf_reg_get_share(struct smbconf_ctx *ctx, TALLOC_CTX *mem_ctx, const char *servicename, struct smbconf_service **service) { sbcErr err; struct registry_key *key = NULL; struct smbconf_service *tmp_service = NULL; TALLOC_CTX *tmp_ctx = talloc_stackframe(); err = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename, REG_KEY_READ, &key); if (!SBC_ERROR_IS_OK(err)) { goto done; } tmp_service = talloc_zero(tmp_ctx, struct smbconf_service); if (tmp_service == NULL) { err = SBC_ERR_NOMEM; goto done; } if (servicename != NULL) { tmp_service->name = talloc_strdup(tmp_service, servicename); if (tmp_service->name == NULL) { err = SBC_ERR_NOMEM; goto done; } } err = smbconf_reg_get_values(tmp_service, key, &(tmp_service->num_params), &(tmp_service->param_names), &(tmp_service->param_values)); if (SBC_ERROR_IS_OK(err)) { *service = talloc_move(mem_ctx, &tmp_service); } done: talloc_free(tmp_ctx); return err; }
/** * Get the change sequence number of the given service/parameter. * service and parameter strings may be NULL. */ static void smbconf_reg_get_csn(struct smbconf_ctx *ctx, struct smbconf_csn *csn, const char *service, const char *param) { if (csn == NULL) { return; } if (!SBC_ERROR_IS_OK(ctx->ops->open_conf(ctx))) { return; } csn->csn = (uint64_t)regdb_get_seqnum(); }
static sbcErr fss_conf_get_share_def(struct smbconf_ctx *fconf_ctx, struct smbconf_ctx *rconf_ctx, TALLOC_CTX *mem_ctx, char *share, struct smbconf_service **service_def) { sbcErr cerr; struct smbconf_service *def; *service_def = NULL; cerr = smbconf_get_share(fconf_ctx, mem_ctx, share, &def); if (SBC_ERROR_IS_OK(cerr)) { *service_def = def; return SBC_ERR_OK; } cerr = smbconf_get_share(rconf_ctx, mem_ctx, share, &def); if (SBC_ERROR_IS_OK(cerr)) { *service_def = def; return SBC_ERR_OK; } return cerr; }
/** * initialize the registry smbconf backend */ static sbcErr smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) { WERROR werr = WERR_OK; sbcErr err; struct security_token *token; if (path == NULL) { path = KEY_SMBCONF; } ctx->path = talloc_strdup(ctx, path); if (ctx->path == NULL) { err = SBC_ERR_NOMEM; goto done; } ctx->data = talloc_zero(ctx, struct reg_private_data); werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token)); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, ("Error creating admin token\n")); err = SBC_ERR_UNKNOWN_FAILURE; goto done; } rpd(ctx)->open = false; werr = registry_init_smbconf(path); if (!W_ERROR_IS_OK(werr)) { err = SBC_ERR_BADFILE; goto done; } err = ctx->ops->open_conf(ctx); if (!SBC_ERROR_IS_OK(err)) { DEBUG(1, ("Error opening the registry.\n")); goto done; } werr = reg_open_path(ctx, ctx->path, KEY_ENUMERATE_SUB_KEYS | REG_KEY_WRITE, token, &rpd(ctx)->base_key); if (!W_ERROR_IS_OK(werr)) { err = SBC_ERR_UNKNOWN_FAILURE; goto done; } done: return err; }
static int net_conf_list(struct net_context *c, struct smbconf_ctx *conf_ctx, int argc, const char **argv) { sbcErr err; int ret = -1; TALLOC_CTX *mem_ctx; uint32_t num_shares; uint32_t share_count, param_count; struct smbconf_service **shares = NULL; mem_ctx = talloc_stackframe(); if (argc != 0 || c->display_usage) { net_conf_list_usage(c, argc, argv); goto done; } err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &shares); if (!SBC_ERROR_IS_OK(err)) { d_fprintf(stderr, _("Error getting config: %s\n"), sbcErrorString(err)); goto done; } for (share_count = 0; share_count < num_shares; share_count++) { const char *indent = ""; if (shares[share_count]->name != NULL) { d_printf("[%s]\n", shares[share_count]->name); indent = "\t"; } for (param_count = 0; param_count < shares[share_count]->num_params; param_count++) { d_printf("%s%s = %s\n", indent, shares[share_count]->param_names[param_count], shares[share_count]->param_values[param_count]); } d_printf("\n"); } ret = 0; done: TALLOC_FREE(mem_ctx); return ret; }
/** * check if a share/service of a given name exists - registry version */ static bool smbconf_reg_share_exists(struct smbconf_ctx *ctx, const char *servicename) { bool ret = false; sbcErr err; TALLOC_CTX *mem_ctx = talloc_stackframe(); struct registry_key *key = NULL; err = smbconf_reg_open_service_key(mem_ctx, ctx, servicename, REG_KEY_READ, &key); if (SBC_ERROR_IS_OK(err)) { ret = true; } talloc_free(mem_ctx); return ret; }
static int net_conf_showshare(struct net_context *c, struct smbconf_ctx *conf_ctx, int argc, const char **argv) { int ret = -1; sbcErr err; const char *sharename = NULL; TALLOC_CTX *mem_ctx; uint32_t count; struct smbconf_service *service = NULL; mem_ctx = talloc_stackframe(); if (argc != 1 || c->display_usage) { net_conf_showshare_usage(c, argc, argv); goto done; } sharename = talloc_strdup(mem_ctx, argv[0]); if (sharename == NULL) { d_printf("error: out of memory!\n"); goto done; } err = smbconf_get_share(conf_ctx, mem_ctx, sharename, &service); if (!SBC_ERROR_IS_OK(err)) { d_printf(_("error getting share parameters: %s\n"), sbcErrorString(err)); goto done; } d_printf("[%s]\n", service->name); for (count = 0; count < service->num_params; count++) { d_printf("\t%s = %s\n", service->param_names[count], service->param_values[count]); } ret = 0; done: TALLOC_FREE(mem_ctx); return ret; }
/** * get the value of a configuration parameter as a string */ static sbcErr smbconf_reg_get_parameter(struct smbconf_ctx *ctx, TALLOC_CTX *mem_ctx, const char *service, const char *param, char **valstr) { WERROR werr = WERR_OK; sbcErr err; struct registry_key *key = NULL; struct registry_value *value = NULL; err = smbconf_reg_open_service_key(mem_ctx, ctx, service, REG_KEY_READ, &key); if (!SBC_ERROR_IS_OK(err)) { goto done; } if (!smbconf_reg_valname_valid(param)) { err = SBC_ERR_INVALID_PARAM; goto done; } if (!smbconf_value_exists(key, param)) { err = SBC_ERR_INVALID_PARAM; goto done; } werr = reg_queryvalue(mem_ctx, key, param, &value); if (!W_ERROR_IS_OK(werr)) { err = SBC_ERR_NOMEM; goto done; } *valstr = smbconf_format_registry_value(mem_ctx, value); if (*valstr == NULL) { err = SBC_ERR_NOMEM; } done: talloc_free(key); talloc_free(value); return err; }
static int net_conf_setincludes(struct net_context *c, struct smbconf_ctx *conf_ctx, int argc, const char **argv) { sbcErr err; char *service; uint32_t num_includes; const char **includes; int ret = -1; TALLOC_CTX *mem_ctx = talloc_stackframe(); if (argc < 1 || c->display_usage) { net_conf_setincludes_usage(c, argc, argv); goto done; } service = talloc_strdup(mem_ctx, argv[0]); if (service == NULL) { d_printf(_("error: out of memory!\n")); goto done; } num_includes = argc - 1; if (num_includes == 0) { includes = NULL; } else { includes = argv + 1; } err = smbconf_set_includes(conf_ctx, service, num_includes, includes); if (!SBC_ERROR_IS_OK(err)) { d_printf(_("error setting includes: %s\n"), sbcErrorString(err)); goto done; } ret = 0; done: TALLOC_FREE(mem_ctx); return ret; }
static bool torture_smbconf_txt(void) { sbcErr err; bool ret = true; const char *filename = "/tmp/smb.conf.smbconf_testsuite"; struct smbconf_ctx *conf_ctx = NULL; TALLOC_CTX *mem_ctx = talloc_stackframe(); printf("test: text backend\n"); if (!create_conf_file(filename)) { ret = false; goto done; } printf("TEST: init\n"); err = smbconf_init_txt(mem_ctx, &conf_ctx, filename); if (!SBC_ERROR_IS_OK(err)) { printf("FAIL: text backend failed: %s\n", sbcErrorString(err)); ret = false; goto done; } printf("OK: init\n"); ret &= test_get_includes(conf_ctx); smbconf_shutdown(conf_ctx); printf("TEST: unlink file\n"); if (unlink(filename) != 0) { printf("OK: unlink failed: %s\n", strerror(errno)); ret = false; goto done; } printf("OK: unlink file\n"); done: printf("%s: text backend\n", ret ? "success" : "failure"); talloc_free(mem_ctx); return ret; }
/** * set a configuration parameter to the value provided. */ static sbcErr smbconf_reg_set_parameter(struct smbconf_ctx *ctx, const char *service, const char *param, const char *valstr) { sbcErr err; struct registry_key *key = NULL; TALLOC_CTX *mem_ctx = talloc_stackframe(); err = smbconf_reg_open_service_key(mem_ctx, ctx, service, REG_KEY_WRITE, &key); if (!SBC_ERROR_IS_OK(err)) { goto done; } err = smbconf_reg_set_value(key, param, valstr); done: talloc_free(mem_ctx); return err; }
static int net_conf_getincludes(struct net_context *c, struct smbconf_ctx *conf_ctx, int argc, const char **argv) { sbcErr err; uint32_t num_includes; uint32_t count; char *service; char **includes = NULL; int ret = -1; TALLOC_CTX *mem_ctx = talloc_stackframe(); if (argc != 1 || c->display_usage) { net_conf_getincludes_usage(c, argc, argv); goto done; } service = talloc_strdup(mem_ctx, argv[0]); if (service == NULL) { d_printf(_("error: out of memory!\n")); goto done; } err = smbconf_get_includes(conf_ctx, mem_ctx, service, &num_includes, &includes); if (!SBC_ERROR_IS_OK(err)) { d_printf(_("error getting includes: %s\n"), sbcErrorString(err)); goto done; } for (count = 0; count < num_includes; count++) { d_printf("include = %s\n", includes[count]); } ret = 0; done: TALLOC_FREE(mem_ctx); return ret; }
static int net_conf_drop(struct net_context *c, struct smbconf_ctx *conf_ctx, int argc, const char **argv) { int ret = -1; sbcErr err; if (argc != 0 || c->display_usage) { net_conf_drop_usage(c, argc, argv); goto done; } err = smbconf_drop(conf_ctx); if (!SBC_ERROR_IS_OK(err)) { d_fprintf(stderr, _("Error deleting configuration: %s\n"), sbcErrorString(err)); goto done; } ret = 0; done: return ret; }
/** * Wrapper function to call the main conf functions. * The wrapper calls handles opening and closing of the * configuration. */ static int net_conf_wrap_function(struct net_context *c, int (*fn)(struct net_context *, struct smbconf_ctx *, int, const char **), int argc, const char **argv) { sbcErr err; TALLOC_CTX *mem_ctx = talloc_stackframe(); struct smbconf_ctx *conf_ctx; int ret = -1; err = smbconf_init(mem_ctx, &conf_ctx, "registry:"); if (!SBC_ERROR_IS_OK(err)) { talloc_free(mem_ctx); return -1; } ret = fn(c, conf_ctx, argc, argv); smbconf_shutdown(conf_ctx); talloc_free(mem_ctx); return ret; }
static NTSTATUS sc_smap_unexpose(struct messaging_context *msg_ctx, struct fss_sc_smap *sc_smap, bool delete_all) { NTSTATUS ret; struct smbconf_ctx *conf_ctx; sbcErr cerr; bool is_modified = false; TALLOC_CTX *tmp_ctx = talloc_new(sc_smap); if (tmp_ctx == NULL) { return NT_STATUS_NO_MEMORY; } cerr = smbconf_init(tmp_ctx, &conf_ctx, "registry"); if (!SBC_ERROR_IS_OK(cerr)) { DEBUG(0, ("failed registry smbconf init: %s\n", sbcErrorString(cerr))); ret = NT_STATUS_UNSUCCESSFUL; goto err_tmp; } /* registry IO must be done as root */ become_root(); cerr = smbconf_transaction_start(conf_ctx); if (!SBC_ERROR_IS_OK(cerr)) { DEBUG(0, ("error starting transaction: %s\n", sbcErrorString(cerr))); ret = NT_STATUS_UNSUCCESSFUL; goto err_conf; } while (sc_smap) { struct fss_sc_smap *sc_map_next = sc_smap->next; if (!smbconf_share_exists(conf_ctx, sc_smap->sc_share_name)) { DEBUG(2, ("no such share: %s\n", sc_smap->sc_share_name)); if (!delete_all) { ret = NT_STATUS_OK; goto err_cancel; } sc_smap = sc_map_next; continue; } cerr = smbconf_delete_share(conf_ctx, sc_smap->sc_share_name); if (!SBC_ERROR_IS_OK(cerr)) { DEBUG(0, ("error deleting share: %s\n", sbcErrorString(cerr))); ret = NT_STATUS_UNSUCCESSFUL; goto err_cancel; } is_modified = true; sc_smap->is_exposed = false; if (delete_all) { sc_smap = sc_map_next; } else { sc_smap = NULL; /* only process single sc_map entry */ } } if (is_modified) { cerr = smbconf_transaction_commit(conf_ctx); if (!SBC_ERROR_IS_OK(cerr)) { DEBUG(0, ("error committing transaction: %s\n", sbcErrorString(cerr))); ret = NT_STATUS_UNSUCCESSFUL; goto err_cancel; } message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL); } else { ret = NT_STATUS_OK; goto err_cancel; } ret = NT_STATUS_OK; err_conf: talloc_free(conf_ctx); unbecome_root(); err_tmp: talloc_free(tmp_ctx); return ret; err_cancel: smbconf_transaction_cancel(conf_ctx); talloc_free(conf_ctx); unbecome_root(); talloc_free(tmp_ctx); return ret; }
uint32_t _fss_ExposeShadowCopySet(struct pipes_struct *p, struct fss_ExposeShadowCopySet *r) { NTSTATUS status; struct fss_sc_set *sc_set; struct fss_sc *sc; uint32_t ret; struct smbconf_ctx *fconf_ctx; struct smbconf_ctx *rconf_ctx; sbcErr cerr; char *fconf_path; TALLOC_CTX *tmp_ctx = talloc_new(p->mem_ctx); if (tmp_ctx == NULL) { return HRES_ERROR_V(HRES_E_OUTOFMEMORY); } if (!fss_permitted(p)) { ret = HRES_ERROR_V(HRES_E_ACCESSDENIED); goto err_out; } sc_set = sc_set_lookup(fss_global.sc_sets, &r->in.ShadowCopySetId); if (sc_set == NULL) { ret = HRES_ERROR_V(HRES_E_INVALIDARG); goto err_out; } if (sc_set->state != FSS_SC_COMMITED) { ret = FSRVP_E_BAD_STATE; goto err_out; } /* stop message sequence timer */ TALLOC_FREE(fss_global.seq_tmr); /* * Prepare to clone the base share definition for the snapshot share. * Create both registry and file conf contexts, as the base share * definition may be located in either. The snapshot share definition * is always written to the registry. */ cerr = smbconf_init(tmp_ctx, &rconf_ctx, "registry"); if (!SBC_ERROR_IS_OK(cerr)) { DEBUG(0, ("failed registry smbconf init: %s\n", sbcErrorString(cerr))); ret = HRES_ERROR_V(HRES_E_FAIL); goto err_tmr_restart; } fconf_path = talloc_asprintf(tmp_ctx, "file:%s", get_dyn_CONFIGFILE()); if (fconf_path == NULL) { ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY); goto err_tmr_restart; } cerr = smbconf_init(tmp_ctx, &fconf_ctx, fconf_path); if (!SBC_ERROR_IS_OK(cerr)) { DEBUG(0, ("failed %s smbconf init: %s\n", fconf_path, sbcErrorString(cerr))); ret = HRES_ERROR_V(HRES_E_FAIL); goto err_tmr_restart; } /* registry IO must be done as root */ become_root(); cerr = smbconf_transaction_start(rconf_ctx); if (!SBC_ERROR_IS_OK(cerr)) { DEBUG(0, ("error starting transaction: %s\n", sbcErrorString(cerr))); ret = HRES_ERROR_V(HRES_E_FAIL); unbecome_root(); goto err_tmr_restart; } for (sc = sc_set->scs; sc; sc = sc->next) { ret = fss_sc_expose(fconf_ctx, rconf_ctx, tmp_ctx, sc); if (ret) { DEBUG(0,("failed to expose shadow copy of %s\n", sc->volume_name)); goto err_cancel; } } cerr = smbconf_transaction_commit(rconf_ctx); if (!SBC_ERROR_IS_OK(cerr)) { DEBUG(0, ("error committing transaction: %s\n", sbcErrorString(cerr))); ret = HRES_ERROR_V(HRES_E_FAIL); goto err_cancel; } unbecome_root(); message_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL); for (sc = sc_set->scs; sc; sc = sc->next) { struct fss_sc_smap *sm; for (sm = sc->smaps; sm; sm = sm->next) sm->is_exposed = true; } sc_set->state = FSS_SC_EXPOSED; become_root(); status = fss_state_store(fss_global.mem_ctx, fss_global.sc_sets, fss_global.sc_sets_count, fss_global.db_path); unbecome_root(); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("failed to store fss server state: %s\n", nt_errstr(status))); } /* start message sequence timer */ fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set, &fss_global.seq_tmr); talloc_free(tmp_ctx); return 0; err_cancel: smbconf_transaction_cancel(rconf_ctx); unbecome_root(); err_tmr_restart: fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set, &fss_global.seq_tmr); err_out: talloc_free(tmp_ctx); return ret; }