Beispiel #1
0
/*
 * Expose a new share using libsmbconf, cloning the existing configuration
 * from the base share. The base share may be defined in either the registry
 * or smb.conf.
 * XXX this is called as root
 */
static uint32_t fss_sc_expose(struct smbconf_ctx *fconf_ctx,
			      struct smbconf_ctx *rconf_ctx,
			      TALLOC_CTX *mem_ctx,
			      struct fss_sc *sc)
{
	struct fss_sc_smap *sc_smap;
	uint32_t err = 0;

	for (sc_smap = sc->smaps; sc_smap; sc_smap = sc_smap->next) {
		sbcErr cerr;
		struct smbconf_service *base_service = NULL;
		struct security_descriptor *sd;
		size_t sd_size;

		cerr = fss_conf_get_share_def(fconf_ctx, rconf_ctx, mem_ctx,
					    sc_smap->share_name, &base_service);
		if (!SBC_ERROR_IS_OK(cerr)) {
			DEBUG(0, ("failed to get base share %s definition: "
				  "%s\n", sc_smap->share_name,
				  sbcErrorString(cerr)));
			err = HRES_ERROR_V(HRES_E_FAIL);
			break;
		}

		/* smap share name already defined when added */
		err = map_share_comment(sc_smap, sc);
		if (err) {
			DEBUG(0, ("failed to map share comment\n"));
			break;
		}

		base_service->name = sc_smap->sc_share_name;

		cerr = smbconf_create_set_share(rconf_ctx, base_service);
		if (!SBC_ERROR_IS_OK(cerr)) {
			DEBUG(0, ("failed to create share %s: %s\n",
				  base_service->name, sbcErrorString(cerr)));
			err = HRES_ERROR_V(HRES_E_FAIL);
			break;
		}
		cerr = smbconf_set_parameter(rconf_ctx, sc_smap->sc_share_name,
					     "path", sc->sc_path);
		if (!SBC_ERROR_IS_OK(cerr)) {
			DEBUG(0, ("failed to set path param: %s\n",
				  sbcErrorString(cerr)));
			err = HRES_ERROR_V(HRES_E_FAIL);
			break;
		}
		if (sc_smap->sc_share_comment != NULL) {
			cerr = smbconf_set_parameter(rconf_ctx,
						    sc_smap->sc_share_name,
						    "comment",
						    sc_smap->sc_share_comment);
			if (!SBC_ERROR_IS_OK(cerr)) {
				DEBUG(0, ("failed to set comment param: %s\n",
					  sbcErrorString(cerr)));
				err = HRES_ERROR_V(HRES_E_FAIL);
				break;
			}
		}
		talloc_free(base_service);

		/*
		 * Obtain the base share SD, which also needs to be cloned.
		 * Share SDs are stored in share_info.tdb, so are not covered by
		 * the registry transaction.
		 * The base share SD should be cloned at the time of exposure,
		 * rather than when the snapshot is taken. This matches Windows
		 * Server 2012 behaviour.
		 */
		sd = get_share_security(mem_ctx, sc_smap->share_name, &sd_size);
		if (sd == NULL) {
			DEBUG(2, ("no share SD to clone for %s snapshot\n",
				  sc_smap->share_name));
		} else {
			bool ok;
			ok = set_share_security(sc_smap->sc_share_name, sd);
			TALLOC_FREE(sd);
			if (!ok) {
				DEBUG(0, ("failed to set %s share SD\n",
					  sc_smap->sc_share_name));
				err = HRES_ERROR_V(HRES_E_FAIL);
				break;
			}
		}
	}

	return err;
}
Beispiel #2
0
static int net_conf_setparm(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;
	const char *value_str = NULL;
	TALLOC_CTX *mem_ctx = talloc_stackframe();

	if (argc != 3 || c->display_usage) {
		net_conf_setparm_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;
	}
	value_str = argv[2];

	if (!net_conf_param_valid(service,param, value_str)) {
		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;
	}

	if (!smbconf_share_exists(conf_ctx, service)) {
		err = smbconf_create_share(conf_ctx, service);
		if (!SBC_ERROR_IS_OK(err)) {
			d_fprintf(stderr, _("Error creating share '%s': %s\n"),
				  service, sbcErrorString(err));
			goto cancel;
		}
	}

	err = smbconf_set_parameter(conf_ctx, service, param, value_str);
	if (!SBC_ERROR_IS_OK(err)) {
		d_fprintf(stderr, _("Error setting value '%s': %s\n"),
			  param, sbcErrorString(err));
		goto cancel;
	}

	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;
}
Beispiel #3
0
							char *,
							num_includes+1);
			if (includes == NULL) {
				werr = WERR_NOMEM;
				goto done;
			}
			includes[num_includes] = talloc_strdup(includes,
						service->param_values[idx]);
			if (includes[num_includes] == NULL) {
				werr = WERR_NOMEM;
				goto done;
			}
			num_includes++;
		} else {
			werr = smbconf_set_parameter(conf_ctx,
						     service->name,
						     service->param_names[idx],
						     service->param_values[idx]);
			if (!W_ERROR_IS_OK(werr)) {
				goto done;
			}
		}
	}

	werr = smbconf_set_includes(conf_ctx, service->name, num_includes,
				    (const char **)includes);

done:
	TALLOC_FREE(mem_ctx);
	return werr;
}
Beispiel #4
0
/**
 * Add a share, with a couple of standard parameters, partly optional.
 *
 * This is a high level utility function of the net conf utility,
 * not a direct frontend to the smbconf API.
 */
static int net_conf_addshare(struct net_context *c,
			     struct smbconf_ctx *conf_ctx, int argc,
			     const char **argv)
{
	int ret = -1;
	sbcErr err;
	char *sharename = NULL;
	const char *path = NULL;
	const char *comment = NULL;
	const char *guest_ok = "no";
	const char *writeable = "no";
	TALLOC_CTX *mem_ctx = talloc_stackframe();

	if (c->display_usage) {
		net_conf_addshare_usage(c, argc, argv);
		ret = 0;
		goto done;
	}

	switch (argc) {
		case 0:
		case 1:
		default:
			net_conf_addshare_usage(c, argc, argv);
			goto done;
		case 5:
			comment = argv[4];

			FALL_THROUGH;
		case 4:
			if (!strnequal(argv[3], "guest_ok=", 9)) {
				net_conf_addshare_usage(c, argc, argv);
				goto done;
			}
			switch (argv[3][9]) {
				case 'y':
				case 'Y':
					guest_ok = "yes";
					break;
				case 'n':
				case 'N':
					guest_ok = "no";
					break;
				default:
					net_conf_addshare_usage(c, argc, argv);
					goto done;
			}

			FALL_THROUGH;
		case 3:
			if (!strnequal(argv[2], "writeable=", 10)) {
				net_conf_addshare_usage(c, argc, argv);
				goto done;
			}
			switch (argv[2][10]) {
				case 'y':
				case 'Y':
					writeable = "yes";
					break;
				case 'n':
				case 'N':
					writeable = "no";
					break;
				default:
					net_conf_addshare_usage(c, argc, argv);
					goto done;
			}

			FALL_THROUGH;
		case 2:
			path = argv[1];
			sharename = talloc_strdup(mem_ctx, argv[0]);
			if (sharename == NULL) {
				d_printf(_("error: out of memory!\n"));
				goto done;
			}

			break;
	}

	/*
	 * validate arguments
	 */

	/* validate share name */

	if (!validate_net_name(sharename, INVALID_SHARENAME_CHARS,
			       strlen(sharename)))
	{
		d_fprintf(stderr, _("ERROR: share name %s contains "
                        "invalid characters (any of %s)\n"),
                        sharename, INVALID_SHARENAME_CHARS);
		goto done;
	}

	if (strequal(sharename, GLOBAL_NAME)) {
		d_fprintf(stderr,
			  _("ERROR: 'global' is not a valid share name.\n"));
		goto done;
	}

	if (smbconf_share_exists(conf_ctx, sharename)) {
		d_fprintf(stderr, _("ERROR: share %s already exists.\n"),
			  sharename);
		goto done;
	}

	/* validate path */

	if (path[0] != '/') {
		d_fprintf(stderr,
			  _("Error: path '%s' is not an absolute path.\n"),
			  path);
		goto done;
	}

	/*
	 * start a transaction
	 */

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

	/*
	 * create the share
	 */

	err = smbconf_create_share(conf_ctx, sharename);
	if (!SBC_ERROR_IS_OK(err)) {
		d_fprintf(stderr, _("Error creating share %s: %s\n"),
			  sharename, sbcErrorString(err));
		goto cancel;
	}

	/*
	 * fill the share with parameters
	 */

	err = smbconf_set_parameter(conf_ctx, sharename, "path", path);
	if (!SBC_ERROR_IS_OK(err)) {
		d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
			  "path", sbcErrorString(err));
		goto cancel;
	}

	if (comment != NULL) {
		err = smbconf_set_parameter(conf_ctx, sharename, "comment",
					    comment);
		if (!SBC_ERROR_IS_OK(err)) {
			d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
				  "comment", sbcErrorString(err));
			goto cancel;
		}
	}

	err = smbconf_set_parameter(conf_ctx, sharename, "guest ok", guest_ok);
	if (!SBC_ERROR_IS_OK(err)) {
		d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
			  "'guest ok'", sbcErrorString(err));
		goto cancel;
	}

	err = smbconf_set_parameter(conf_ctx, sharename, "writeable",
				    writeable);
	if (!SBC_ERROR_IS_OK(err)) {
		d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
			  "writeable", sbcErrorString(err));
		goto cancel;
	}

	/*
	 * commit the whole thing
	 */

	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;
}