Beispiel #1
0
/**
 * 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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
			   int argc, const char **argv)
{
	int ret = -1;
	const char *filename = NULL;
	const char *servicename = NULL;
	char *conf_source = NULL;
	TALLOC_CTX *mem_ctx;
	struct smbconf_ctx *txt_ctx;
	sbcErr err;

	if (c->display_usage)
		return net_conf_import_usage(c, argc, argv);

	mem_ctx = talloc_stackframe();

	switch (argc) {
		case 0:
		default:
			net_conf_import_usage(c, argc, argv);
			goto done;
		case 2:
			servicename = talloc_strdup(mem_ctx, argv[1]);
			if (servicename == NULL) {
				d_printf(_("error: out of memory!\n"));
				goto done;
			}

			FALL_THROUGH;
		case 1:
			filename = argv[0];
			break;
	}

	DEBUG(3,("net_conf_import: reading configuration from file %s.\n",
		filename));

	conf_source = talloc_asprintf(mem_ctx, "file:%s", filename);
	if (conf_source == NULL) {
		d_printf(_("error: out of memory!\n"));
		goto done;
	}

	err = smbconf_init(mem_ctx, &txt_ctx, conf_source);
	if (!SBC_ERROR_IS_OK(err)) {
		d_printf(_("error loading file '%s': %s\n"), filename,
			 sbcErrorString(err));
		goto done;
	}

	if (c->opt_testmode) {
		d_printf(_("\nTEST MODE - "
			 "would import the following configuration:\n\n"));
	}

	if (servicename != NULL) {
		struct smbconf_service *service = NULL;

		err = smbconf_get_share(txt_ctx, mem_ctx,
					servicename,
					&service);
		if (!SBC_ERROR_IS_OK(err)) {
			goto cancel;
		}

		err = smbconf_transaction_start(conf_ctx);
		if (!SBC_ERROR_IS_OK(err)) {
			d_printf(_("error starting transaction: %s\n"),
				 sbcErrorString(err));
			goto done;
		}

		err = import_process_service(c, conf_ctx, service);
		if (!SBC_ERROR_IS_OK(err)) {
			d_printf(_("error importing service %s: %s\n"),
				 servicename, sbcErrorString(err));
			goto cancel;
		}
	} else {
		struct smbconf_service **services = NULL;
		uint32_t num_shares, sidx;

		err = smbconf_get_config(txt_ctx, mem_ctx,
					  &num_shares,
					  &services);
		if (!SBC_ERROR_IS_OK(err)) {
			goto cancel;
		}
		if (!c->opt_testmode) {
			if (!SBC_ERROR_IS_OK(smbconf_drop(conf_ctx))) {
				goto cancel;
			}
		}

		/*
		 * Wrap the importing of shares into a transaction,
		 * but only 100 at a time, in order to save memory.
		 * The allocated memory accumulates across the actions
		 * within the transaction, and for me, some 1500
		 * imported shares, the MAX_TALLOC_SIZE of 256 MB
		 * was exceeded.
		 */
		err = smbconf_transaction_start(conf_ctx);
		if (!SBC_ERROR_IS_OK(err)) {
			d_printf(_("error starting transaction: %s\n"),
				 sbcErrorString(err));
			goto done;
		}

		for (sidx = 0; sidx < num_shares; sidx++) {
			err = import_process_service(c, conf_ctx,
						     services[sidx]);
			if (!SBC_ERROR_IS_OK(err)) {
				d_printf(_("error importing service %s: %s\n"),
					 services[sidx]->name,
					 sbcErrorString(err));
				goto cancel;
			}

			if (sidx % 100) {
				continue;
			}

			err = smbconf_transaction_commit(conf_ctx);
			if (!SBC_ERROR_IS_OK(err)) {
				d_printf(_("error committing transaction: "
					   "%s\n"),
					 sbcErrorString(err));
				goto done;
			}
			err = smbconf_transaction_start(conf_ctx);
			if (!SBC_ERROR_IS_OK(err)) {
				d_printf(_("error starting transaction: %s\n"),
					 sbcErrorString(err));
				goto done;
			}
		}
	}

	err = smbconf_transaction_commit(conf_ctx);
	if (!SBC_ERROR_IS_OK(err)) {
		d_printf(_("error committing transaction: %s\n"),
			 sbcErrorString(err));
	} else {
		ret = 0;
	}

	goto done;

cancel:
	err = smbconf_transaction_cancel(conf_ctx);
	if (!SBC_ERROR_IS_OK(err)) {
		d_printf(_("error cancelling transaction: %s\n"),
			 sbcErrorString(err));
	}

done:
	TALLOC_FREE(mem_ctx);
	return ret;
}