1/* 2 * Unix SMB/CIFS implementation. 3 * libsmbconf - Samba configuration library 4 * Copyright (C) Michael Adam 2007-2008 5 * Copyright (C) Guenther Deschner 2007 6 * 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. 11 * 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. 16 * 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/>. 19 */ 20 21#include "includes.h" 22#include "smbconf_private.h" 23 24/********************************************************************** 25 * 26 * internal helper functions 27 * 28 **********************************************************************/ 29 30static WERROR smbconf_global_check(struct smbconf_ctx *ctx) 31{ 32 if (!smbconf_share_exists(ctx, GLOBAL_NAME)) { 33 return smbconf_create_share(ctx, GLOBAL_NAME); 34 } 35 return WERR_OK; 36} 37 38 39/********************************************************************** 40 * 41 * The actual libsmbconf API functions that are exported. 42 * 43 **********************************************************************/ 44 45/** 46 * Tell whether the backend requires messaging to be set up 47 * for the backend to work correctly. 48 */ 49bool smbconf_backend_requires_messaging(struct smbconf_ctx *ctx) 50{ 51 return ctx->ops->requires_messaging(ctx); 52} 53 54/** 55 * Tell whether the source is writeable. 56 */ 57bool smbconf_is_writeable(struct smbconf_ctx *ctx) 58{ 59 return ctx->ops->is_writeable(ctx); 60} 61 62/** 63 * Close the configuration. 64 */ 65void smbconf_shutdown(struct smbconf_ctx *ctx) 66{ 67 talloc_free(ctx); 68} 69 70/** 71 * Detect changes in the configuration. 72 * The given csn struct is filled with the current csn. 73 * smbconf_changed() can also be used for initial retrieval 74 * of the csn. 75 */ 76bool smbconf_changed(struct smbconf_ctx *ctx, struct smbconf_csn *csn, 77 const char *service, const char *param) 78{ 79 struct smbconf_csn old_csn; 80 81 if (csn == NULL) { 82 return false; 83 } 84 85 old_csn = *csn; 86 87 ctx->ops->get_csn(ctx, csn, service, param); 88 return (csn->csn != old_csn.csn); 89} 90 91/** 92 * Drop the whole configuration (restarting empty). 93 */ 94WERROR smbconf_drop(struct smbconf_ctx *ctx) 95{ 96 return ctx->ops->drop(ctx); 97} 98 99/** 100 * Get the whole configuration as lists of strings with counts: 101 * 102 * num_shares : number of shares 103 * share_names : list of length num_shares of share names 104 * num_params : list of length num_shares of parameter counts for each share 105 * param_names : list of lists of parameter names for each share 106 * param_values : list of lists of parameter values for each share 107 */ 108WERROR smbconf_get_config(struct smbconf_ctx *ctx, 109 TALLOC_CTX *mem_ctx, 110 uint32_t *num_shares, 111 struct smbconf_service ***services) 112{ 113 WERROR werr = WERR_OK; 114 TALLOC_CTX *tmp_ctx = NULL; 115 uint32_t tmp_num_shares; 116 char **tmp_share_names; 117 struct smbconf_service **tmp_services; 118 uint32_t count; 119 120 if ((num_shares == NULL) || (services == NULL)) { 121 werr = WERR_INVALID_PARAM; 122 goto done; 123 } 124 125 tmp_ctx = talloc_stackframe(); 126 127 werr = smbconf_get_share_names(ctx, tmp_ctx, &tmp_num_shares, 128 &tmp_share_names); 129 if (!W_ERROR_IS_OK(werr)) { 130 goto done; 131 } 132 133 tmp_services = talloc_array(tmp_ctx, struct smbconf_service *, 134 tmp_num_shares); 135 136 if (tmp_services == NULL) { 137 werr = WERR_NOMEM; 138 goto done; 139 } 140 141 for (count = 0; count < tmp_num_shares; count++) { 142 werr = smbconf_get_share(ctx, tmp_services, 143 tmp_share_names[count], 144 &tmp_services[count]); 145 if (!W_ERROR_IS_OK(werr)) { 146 goto done; 147 } 148 } 149 150 werr = WERR_OK; 151 152 *num_shares = tmp_num_shares; 153 if (tmp_num_shares > 0) { 154 *services = talloc_move(mem_ctx, &tmp_services); 155 } else { 156 *services = NULL; 157 } 158 159done: 160 talloc_free(tmp_ctx); 161 return werr; 162} 163 164/** 165 * get the list of share names defined in the configuration. 166 */ 167WERROR smbconf_get_share_names(struct smbconf_ctx *ctx, 168 TALLOC_CTX *mem_ctx, 169 uint32_t *num_shares, 170 char ***share_names) 171{ 172 return ctx->ops->get_share_names(ctx, mem_ctx, num_shares, 173 share_names); 174} 175 176/** 177 * check if a share/service of a given name exists 178 */ 179bool smbconf_share_exists(struct smbconf_ctx *ctx, 180 const char *servicename) 181{ 182 return ctx->ops->share_exists(ctx, servicename); 183} 184 185/** 186 * Add a service if it does not already exist. 187 */ 188WERROR smbconf_create_share(struct smbconf_ctx *ctx, 189 const char *servicename) 190{ 191 if ((servicename != NULL) && smbconf_share_exists(ctx, servicename)) { 192 return WERR_FILE_EXISTS; 193 } 194 195 return ctx->ops->create_share(ctx, servicename); 196} 197 198/** 199 * get a definition of a share (service) from configuration. 200 */ 201WERROR smbconf_get_share(struct smbconf_ctx *ctx, 202 TALLOC_CTX *mem_ctx, 203 const char *servicename, 204 struct smbconf_service **service) 205{ 206 return ctx->ops->get_share(ctx, mem_ctx, servicename, service); 207} 208 209/** 210 * delete a service from configuration 211 */ 212WERROR smbconf_delete_share(struct smbconf_ctx *ctx, const char *servicename) 213{ 214 if (!smbconf_share_exists(ctx, servicename)) { 215 return WERR_NO_SUCH_SERVICE; 216 } 217 218 return ctx->ops->delete_share(ctx, servicename); 219} 220 221/** 222 * set a configuration parameter to the value provided. 223 */ 224WERROR smbconf_set_parameter(struct smbconf_ctx *ctx, 225 const char *service, 226 const char *param, 227 const char *valstr) 228{ 229 return ctx->ops->set_parameter(ctx, service, param, valstr); 230} 231 232/** 233 * Set a global parameter 234 * (i.e. a parameter in the [global] service). 235 * 236 * This also creates [global] when it does not exist. 237 */ 238WERROR smbconf_set_global_parameter(struct smbconf_ctx *ctx, 239 const char *param, const char *val) 240{ 241 WERROR werr; 242 243 werr = smbconf_global_check(ctx); 244 if (W_ERROR_IS_OK(werr)) { 245 werr = smbconf_set_parameter(ctx, GLOBAL_NAME, param, val); 246 } 247 248 return werr; 249} 250 251/** 252 * get the value of a configuration parameter as a string 253 */ 254WERROR smbconf_get_parameter(struct smbconf_ctx *ctx, 255 TALLOC_CTX *mem_ctx, 256 const char *service, 257 const char *param, 258 char **valstr) 259{ 260 if (valstr == NULL) { 261 return WERR_INVALID_PARAM; 262 } 263 264 return ctx->ops->get_parameter(ctx, mem_ctx, service, param, valstr); 265} 266 267/** 268 * Get the value of a global parameter. 269 * 270 * Create [global] if it does not exist. 271 */ 272WERROR smbconf_get_global_parameter(struct smbconf_ctx *ctx, 273 TALLOC_CTX *mem_ctx, 274 const char *param, 275 char **valstr) 276{ 277 WERROR werr; 278 279 werr = smbconf_global_check(ctx); 280 if (W_ERROR_IS_OK(werr)) { 281 werr = smbconf_get_parameter(ctx, mem_ctx, GLOBAL_NAME, param, 282 valstr); 283 } 284 285 return werr; 286} 287 288/** 289 * delete a parameter from configuration 290 */ 291WERROR smbconf_delete_parameter(struct smbconf_ctx *ctx, 292 const char *service, const char *param) 293{ 294 return ctx->ops->delete_parameter(ctx, service, param); 295} 296 297/** 298 * Delete a global parameter. 299 * 300 * Create [global] if it does not exist. 301 */ 302WERROR smbconf_delete_global_parameter(struct smbconf_ctx *ctx, 303 const char *param) 304{ 305 WERROR werr; 306 307 werr = smbconf_global_check(ctx); 308 if (W_ERROR_IS_OK(werr)) { 309 werr = smbconf_delete_parameter(ctx, GLOBAL_NAME, param); 310 } 311 312 return werr; 313} 314 315WERROR smbconf_get_includes(struct smbconf_ctx *ctx, 316 TALLOC_CTX *mem_ctx, 317 const char *service, 318 uint32_t *num_includes, char ***includes) 319{ 320 return ctx->ops->get_includes(ctx, mem_ctx, service, num_includes, 321 includes); 322} 323 324WERROR smbconf_get_global_includes(struct smbconf_ctx *ctx, 325 TALLOC_CTX *mem_ctx, 326 uint32_t *num_includes, char ***includes) 327{ 328 WERROR werr; 329 330 werr = smbconf_global_check(ctx); 331 if (W_ERROR_IS_OK(werr)) { 332 werr = smbconf_get_includes(ctx, mem_ctx, GLOBAL_NAME, 333 num_includes, includes); 334 } 335 336 return werr; 337} 338 339WERROR smbconf_set_includes(struct smbconf_ctx *ctx, 340 const char *service, 341 uint32_t num_includes, const char **includes) 342{ 343 return ctx->ops->set_includes(ctx, service, num_includes, includes); 344} 345 346WERROR smbconf_set_global_includes(struct smbconf_ctx *ctx, 347 uint32_t num_includes, 348 const char **includes) 349{ 350 WERROR werr; 351 352 werr = smbconf_global_check(ctx); 353 if (W_ERROR_IS_OK(werr)) { 354 werr = smbconf_set_includes(ctx, GLOBAL_NAME, 355 num_includes, includes); 356 } 357 358 return werr; 359} 360 361 362WERROR smbconf_delete_includes(struct smbconf_ctx *ctx, const char *service) 363{ 364 return ctx->ops->delete_includes(ctx, service); 365} 366 367WERROR smbconf_delete_global_includes(struct smbconf_ctx *ctx) 368{ 369 WERROR werr; 370 371 werr = smbconf_global_check(ctx); 372 if (W_ERROR_IS_OK(werr)) { 373 werr = smbconf_delete_includes(ctx, GLOBAL_NAME); 374 } 375 376 return werr; 377} 378 379WERROR smbconf_transaction_start(struct smbconf_ctx *ctx) 380{ 381 return ctx->ops->transaction_start(ctx); 382} 383 384WERROR smbconf_transaction_commit(struct smbconf_ctx *ctx) 385{ 386 return ctx->ops->transaction_commit(ctx); 387} 388 389WERROR smbconf_transaction_cancel(struct smbconf_ctx *ctx) 390{ 391 return ctx->ops->transaction_cancel(ctx); 392} 393