2 * Unix SMB/CIFS implementation.
3 * libsmbconf - Samba configuration library
4 * Copyright (C) Michael Adam 2007-2008
5 * Copyright (C) Guenther Deschner 2007
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "smbconf_private.h"
24 /**********************************************************************
26 * internal helper functions
28 **********************************************************************/
30 static WERROR smbconf_global_check(struct smbconf_ctx *ctx)
32 if (!smbconf_share_exists(ctx, GLOBAL_NAME)) {
33 return smbconf_create_share(ctx, GLOBAL_NAME);
39 /**********************************************************************
41 * The actual libsmbconf API functions that are exported.
43 **********************************************************************/
46 * Close the configuration.
48 void smbconf_shutdown(struct smbconf_ctx *ctx)
54 * Detect changes in the configuration.
55 * The given csn struct is filled with the current csn.
56 * smbconf_changed() can also be used for initial retrieval
59 bool smbconf_changed(struct smbconf_ctx *ctx, struct smbconf_csn *csn,
60 const char *service, const char *param)
62 struct smbconf_csn old_csn;
70 ctx->ops->get_csn(ctx, csn, service, param);
71 return (csn->csn != old_csn.csn);
75 * Drop the whole configuration (restarting empty).
77 WERROR smbconf_drop(struct smbconf_ctx *ctx)
79 return ctx->ops->drop(ctx);
83 * Get the whole configuration as lists of strings with counts:
85 * num_shares : number of shares
86 * share_names : list of length num_shares of share names
87 * num_params : list of length num_shares of parameter counts for each share
88 * param_names : list of lists of parameter names for each share
89 * param_values : list of lists of parameter values for each share
91 WERROR smbconf_get_config(struct smbconf_ctx *ctx,
94 char ***share_names, uint32_t **num_params,
95 char ****param_names, char ****param_values)
97 WERROR werr = WERR_OK;
98 TALLOC_CTX *tmp_ctx = NULL;
99 uint32_t tmp_num_shares;
100 char **tmp_share_names;
101 uint32_t *tmp_num_params;
102 char ***tmp_param_names;
103 char ***tmp_param_values;
106 if ((num_shares == NULL) || (share_names == NULL) ||
107 (num_params == NULL) || (param_names == NULL) ||
108 (param_values == NULL))
110 werr = WERR_INVALID_PARAM;
114 tmp_ctx = talloc_stackframe();
115 if (tmp_ctx == NULL) {
120 werr = smbconf_get_share_names(ctx, tmp_ctx, &tmp_num_shares,
122 if (!W_ERROR_IS_OK(werr)) {
126 tmp_num_params = TALLOC_ARRAY(tmp_ctx, uint32_t, tmp_num_shares);
127 tmp_param_names = TALLOC_ARRAY(tmp_ctx, char **, tmp_num_shares);
128 tmp_param_values = TALLOC_ARRAY(tmp_ctx, char **, tmp_num_shares);
130 if ((tmp_num_params == NULL) || (tmp_param_names == NULL) ||
131 (tmp_param_values == NULL))
137 for (count = 0; count < tmp_num_shares; count++) {
138 werr = smbconf_get_share(ctx, mem_ctx,
139 tmp_share_names[count],
140 &tmp_num_params[count],
141 &tmp_param_names[count],
142 &tmp_param_values[count]);
143 if (!W_ERROR_IS_OK(werr)) {
150 *num_shares = tmp_num_shares;
151 if (tmp_num_shares > 0) {
152 *share_names = talloc_move(mem_ctx, &tmp_share_names);
153 *num_params = talloc_move(mem_ctx, &tmp_num_params);
154 *param_names = talloc_move(mem_ctx, &tmp_param_names);
155 *param_values = talloc_move(mem_ctx, &tmp_param_values);
160 *param_values = NULL;
164 TALLOC_FREE(tmp_ctx);
169 * get the list of share names defined in the configuration.
171 WERROR smbconf_get_share_names(struct smbconf_ctx *ctx,
173 uint32_t *num_shares,
176 return ctx->ops->get_share_names(ctx, mem_ctx, num_shares,
181 * check if a share/service of a given name exists
183 bool smbconf_share_exists(struct smbconf_ctx *ctx,
184 const char *servicename)
186 return ctx->ops->share_exists(ctx, servicename);
190 * Add a service if it does not already exist.
192 WERROR smbconf_create_share(struct smbconf_ctx *ctx,
193 const char *servicename)
195 if ((servicename != NULL) && smbconf_share_exists(ctx, servicename)) {
196 return WERR_ALREADY_EXISTS;
199 return ctx->ops->create_share(ctx, servicename);
203 * get a definition of a share (service) from configuration.
205 WERROR smbconf_get_share(struct smbconf_ctx *ctx,
207 const char *servicename, uint32_t *num_params,
208 char ***param_names, char ***param_values)
210 if (!smbconf_share_exists(ctx, servicename)) {
211 return WERR_NO_SUCH_SERVICE;
214 return ctx->ops->get_share(ctx, mem_ctx, servicename, num_params,
215 param_names, param_values);
219 * delete a service from configuration
221 WERROR smbconf_delete_share(struct smbconf_ctx *ctx, const char *servicename)
223 if (!smbconf_share_exists(ctx, servicename)) {
224 return WERR_NO_SUCH_SERVICE;
227 return ctx->ops->delete_share(ctx, servicename);
231 * set a configuration parameter to the value provided.
233 WERROR smbconf_set_parameter(struct smbconf_ctx *ctx,
238 if (!smbconf_share_exists(ctx, service)) {
239 return WERR_NO_SUCH_SERVICE;
242 return ctx->ops->set_parameter(ctx, service, param, valstr);
246 * Set a global parameter
247 * (i.e. a parameter in the [global] service).
249 * This also creates [global] when it does not exist.
251 WERROR smbconf_set_global_parameter(struct smbconf_ctx *ctx,
252 const char *param, const char *val)
256 werr = smbconf_global_check(ctx);
257 if (W_ERROR_IS_OK(werr)) {
258 werr = smbconf_set_parameter(ctx, GLOBAL_NAME, param, val);
265 * get the value of a configuration parameter as a string
267 WERROR smbconf_get_parameter(struct smbconf_ctx *ctx,
273 if (valstr == NULL) {
274 return WERR_INVALID_PARAM;
277 if (!smbconf_share_exists(ctx, service)) {
278 return WERR_NO_SUCH_SERVICE;
281 return ctx->ops->get_parameter(ctx, mem_ctx, service, param, valstr);
285 * Get the value of a global parameter.
287 * Create [global] if it does not exist.
289 WERROR smbconf_get_global_parameter(struct smbconf_ctx *ctx,
296 werr = smbconf_global_check(ctx);
297 if (W_ERROR_IS_OK(werr)) {
298 werr = smbconf_get_parameter(ctx, mem_ctx, GLOBAL_NAME, param,
306 * delete a parameter from configuration
308 WERROR smbconf_delete_parameter(struct smbconf_ctx *ctx,
309 const char *service, const char *param)
311 if (!smbconf_share_exists(ctx, service)) {
312 return WERR_NO_SUCH_SERVICE;
315 return ctx->ops->delete_parameter(ctx, service, param);
319 * Delete a global parameter.
321 * Create [global] if it does not exist.
323 WERROR smbconf_delete_global_parameter(struct smbconf_ctx *ctx,
328 werr = smbconf_global_check(ctx);
329 if (W_ERROR_IS_OK(werr)) {
330 werr = smbconf_delete_parameter(ctx, GLOBAL_NAME, param);
336 WERROR smbconf_get_includes(struct smbconf_ctx *ctx,
339 uint32_t *num_includes, char ***includes)
341 if (!smbconf_share_exists(ctx, service)) {
342 return WERR_NO_SUCH_SERVICE;
345 return ctx->ops->get_includes(ctx, mem_ctx, service, num_includes,
349 WERROR smbconf_get_global_includes(struct smbconf_ctx *ctx,
351 uint32_t *num_includes, char ***includes)
355 werr = smbconf_global_check(ctx);
356 if (W_ERROR_IS_OK(werr)) {
357 werr = smbconf_get_includes(ctx, mem_ctx, GLOBAL_NAME,
358 num_includes, includes);
364 WERROR smbconf_set_includes(struct smbconf_ctx *ctx,
366 uint32_t num_includes, const char **includes)
368 if (!smbconf_share_exists(ctx, service)) {
369 return WERR_NO_SUCH_SERVICE;
372 return ctx->ops->set_includes(ctx, service, num_includes, includes);
375 WERROR smbconf_set_global_includes(struct smbconf_ctx *ctx,
376 uint32_t num_includes,
377 const char **includes)
381 werr = smbconf_global_check(ctx);
382 if (W_ERROR_IS_OK(werr)) {
383 werr = smbconf_set_includes(ctx, GLOBAL_NAME,
384 num_includes, includes);
391 WERROR smbconf_delete_includes(struct smbconf_ctx *ctx, const char *service)
393 if (!smbconf_share_exists(ctx, service)) {
394 return WERR_NO_SUCH_SERVICE;
397 return ctx->ops->delete_includes(ctx, service);
400 WERROR smbconf_delete_global_includes(struct smbconf_ctx *ctx)
404 werr = smbconf_global_check(ctx);
405 if (W_ERROR_IS_OK(werr)) {
406 werr = smbconf_delete_includes(ctx, GLOBAL_NAME);