static bool smbconf_txt_do_parameter(const char *param_name, const char *param_value, void *private_data) { WERROR werr; char **param_names, **param_values; uint32_t num_params; uint32_t idx; struct txt_private_data *tpd = (struct txt_private_data *)private_data; struct txt_cache *cache = tpd->cache; if (cache->num_shares == 0) { /* * not in any share yet, * initialize the "empty" section (NULL): * parameters without a previous [section] are stored here. */ if (!smbconf_txt_do_section(NULL, private_data)) { return false; } } param_names = cache->param_names[cache->current_share]; param_values = cache->param_values[cache->current_share]; num_params = cache->num_params[cache->current_share]; if (!(tpd->verbatim) && smbconf_find_in_array(param_name, param_names, num_params, &idx)) { talloc_free(param_values[idx]); param_values[idx] = talloc_strdup(cache, param_value); if (param_values[idx] == NULL) { return false; } return true; } werr = smbconf_add_string_to_array(cache, &(cache->param_names[cache->current_share]), num_params, param_name); if (!W_ERROR_IS_OK(werr)) { return false; } werr = smbconf_add_string_to_array(cache, &(cache->param_values[cache->current_share]), num_params, param_value); cache->num_params[cache->current_share]++; return W_ERROR_IS_OK(werr); }
static WERROR smbconf_txt_get_includes(struct smbconf_ctx *ctx, TALLOC_CTX *mem_ctx, const char *service, uint32_t *num_includes, char ***includes) { WERROR werr; bool found; uint32_t sidx, count; TALLOC_CTX *tmp_ctx = NULL; uint32_t tmp_num_includes = 0; char **tmp_includes = NULL; werr = smbconf_txt_load_file(ctx); if (!W_ERROR_IS_OK(werr)) { return werr; } found = smbconf_find_in_array(service, pd(ctx)->cache->share_names, pd(ctx)->cache->num_shares, &sidx); if (!found) { return WERR_NO_SUCH_SERVICE; } tmp_ctx = talloc_stackframe(); for (count = 0; count < pd(ctx)->cache->num_params[sidx]; count++) { if (strequal(pd(ctx)->cache->param_names[sidx][count], "include")) { werr = smbconf_add_string_to_array(tmp_ctx, &tmp_includes, tmp_num_includes, pd(ctx)->cache->param_values[sidx][count]); if (!W_ERROR_IS_OK(werr)) { goto done; } tmp_num_includes++; } } *num_includes = tmp_num_includes; if (*num_includes > 0) { *includes = talloc_move(mem_ctx, &tmp_includes); if (*includes == NULL) { werr = WERR_NOMEM; goto done; } } else { *includes = NULL; } werr = WERR_OK; done: talloc_free(tmp_ctx); return werr; }
static bool smbconf_txt_do_section(const char *section, void *private_data) { WERROR werr; uint32_t idx; struct txt_private_data *tpd = (struct txt_private_data *)private_data; struct txt_cache *cache = tpd->cache; if (smbconf_find_in_array(section, cache->share_names, cache->num_shares, &idx)) { cache->current_share = idx; return true; } werr = smbconf_add_string_to_array(cache, &(cache->share_names), cache->num_shares, section); if (!W_ERROR_IS_OK(werr)) { return false; } cache->current_share = cache->num_shares; cache->num_shares++; cache->param_names = TALLOC_REALLOC_ARRAY(cache, cache->param_names, char **, cache->num_shares); if (cache->param_names == NULL) { return false; } cache->param_names[cache->current_share] = NULL; cache->param_values = TALLOC_REALLOC_ARRAY(cache, cache->param_values, char **, cache->num_shares); if (cache->param_values == NULL) { return false; } cache->param_values[cache->current_share] = NULL; cache->num_params = TALLOC_REALLOC_ARRAY(cache, cache->num_params, uint32_t, cache->num_shares); if (cache->num_params == NULL) { return false; } cache->num_params[cache->current_share] = 0; return true; }
/** * get the list of share names defined in the configuration. * registry version. */ static sbcErr smbconf_reg_get_share_names(struct smbconf_ctx *ctx, TALLOC_CTX *mem_ctx, uint32_t *num_shares, char ***share_names) { uint32_t count; uint32_t added_count = 0; TALLOC_CTX *tmp_ctx = NULL; WERROR werr; sbcErr err = SBC_ERR_OK; char *subkey_name = NULL; char **tmp_share_names = NULL; if ((num_shares == NULL) || (share_names == NULL)) { return SBC_ERR_INVALID_PARAM; } tmp_ctx = talloc_stackframe(); /* if there are values in the base key, return NULL as share name */ if (smbconf_reg_key_has_values(rpd(ctx)->base_key)) { err = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, 0, NULL); if (!SBC_ERROR_IS_OK(err)) { goto done; } added_count++; } /* make sure "global" is always listed first */ if (smbconf_share_exists(ctx, GLOBAL_NAME)) { err = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, added_count, GLOBAL_NAME); if (!SBC_ERROR_IS_OK(err)) { goto done; } added_count++; } for (count = 0; werr = reg_enumkey(tmp_ctx, rpd(ctx)->base_key, count, &subkey_name, NULL), W_ERROR_IS_OK(werr); count++) { if (strequal(subkey_name, GLOBAL_NAME)) { continue; } err = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, added_count, subkey_name); if (!SBC_ERROR_IS_OK(err)) { goto done; } added_count++; } if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { err = SBC_ERR_NO_MORE_ITEMS; goto done; } err = SBC_ERR_OK; *num_shares = added_count; if (added_count > 0) { *share_names = talloc_move(mem_ctx, &tmp_share_names); } else { *share_names = NULL; } done: talloc_free(tmp_ctx); return err; }
/** * Get the values of a key as a list of value names * and a list of value strings (ordered) */ static sbcErr smbconf_reg_get_values(TALLOC_CTX *mem_ctx, struct registry_key *key, uint32_t *num_values, char ***value_names, char ***value_strings) { TALLOC_CTX *tmp_ctx = NULL; WERROR werr = WERR_OK; sbcErr err; uint32_t count; struct registry_value *valvalue = NULL; char *valname = NULL; uint32_t tmp_num_values = 0; char **tmp_valnames = NULL; char **tmp_valstrings = NULL; uint32_t num_includes = 0; char **includes = NULL; if ((num_values == NULL) || (value_names == NULL) || (value_strings == NULL)) { err = SBC_ERR_INVALID_PARAM; goto done; } tmp_ctx = talloc_stackframe(); for (count = 0; werr = reg_enumvalue(tmp_ctx, key, count, &valname, &valvalue), W_ERROR_IS_OK(werr); count++) { char *valstring; if (!smbconf_reg_valname_valid(valname)) { continue; } err = smbconf_add_string_to_array(tmp_ctx, &tmp_valnames, tmp_num_values, valname); if (!SBC_ERROR_IS_OK(err)) { goto done; } valstring = smbconf_format_registry_value(tmp_ctx, valvalue); err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings, tmp_num_values, valstring); if (!SBC_ERROR_IS_OK(err)) { goto done; } tmp_num_values++; } if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { err = SBC_ERR_NOMEM; goto done; } /* now add the includes at the end */ err = smbconf_reg_get_includes_internal(tmp_ctx, key, &num_includes, &includes); if (!SBC_ERROR_IS_OK(err)) { goto done; } for (count = 0; count < num_includes; count++) { err = smbconf_add_string_to_array(tmp_ctx, &tmp_valnames, tmp_num_values, "include"); if (!SBC_ERROR_IS_OK(err)) { goto done; } err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings, tmp_num_values, includes[count]); if (!SBC_ERROR_IS_OK(err)) { goto done; } tmp_num_values++; } *num_values = tmp_num_values; if (tmp_num_values > 0) { *value_names = talloc_move(mem_ctx, &tmp_valnames); *value_strings = talloc_move(mem_ctx, &tmp_valstrings); } else { *value_names = NULL; *value_strings = NULL; } done: talloc_free(tmp_ctx); return err; }
static sbcErr smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx, struct registry_key *key, uint32_t *num_includes, char ***includes) { WERROR werr; sbcErr err; uint32_t count; struct registry_value *value = NULL; char **tmp_includes = NULL; const char **array = NULL; TALLOC_CTX *tmp_ctx = talloc_stackframe(); if (!smbconf_value_exists(key, INCLUDES_VALNAME)) { /* no includes */ *num_includes = 0; *includes = NULL; err = SBC_ERR_OK; goto done; } werr = reg_queryvalue(tmp_ctx, key, INCLUDES_VALNAME, &value); if (!W_ERROR_IS_OK(werr)) { err = SBC_ERR_ACCESS_DENIED; goto done; } if (value->type != REG_MULTI_SZ) { /* wrong type -- ignore */ err = SBC_ERR_OK; goto done; } if (!pull_reg_multi_sz(tmp_ctx, &value->data, &array)) { err = SBC_ERR_NOMEM; goto done; } for (count = 0; array[count] != NULL; count++) { err = smbconf_add_string_to_array(tmp_ctx, &tmp_includes, count, array[count]); if (!SBC_ERROR_IS_OK(err)) { goto done; } } if (count > 0) { *includes = talloc_move(mem_ctx, &tmp_includes); if (*includes == NULL) { err = SBC_ERR_NOMEM; goto done; } *num_includes = count; } else { *num_includes = 0; *includes = NULL; } err = SBC_ERR_OK; done: talloc_free(tmp_ctx); return err; }
/** * get a definition of a share (service) from configuration. */ static WERROR smbconf_txt_get_share(struct smbconf_ctx *ctx, TALLOC_CTX *mem_ctx, const char *servicename, struct smbconf_service **service) { WERROR werr; uint32_t sidx, count; bool found; TALLOC_CTX *tmp_ctx = NULL; struct smbconf_service *tmp_service = NULL; werr = smbconf_txt_load_file(ctx); if (!W_ERROR_IS_OK(werr)) { return werr; } found = smbconf_find_in_array(servicename, pd(ctx)->cache->share_names, pd(ctx)->cache->num_shares, &sidx); if (!found) { return WERR_NO_SUCH_SERVICE; } tmp_ctx = talloc_stackframe(); tmp_service = TALLOC_ZERO_P(tmp_ctx, struct smbconf_service); if (tmp_service == NULL) { werr = WERR_NOMEM; goto done; } if (servicename != NULL) { tmp_service->name = talloc_strdup(tmp_service, servicename); if (tmp_service->name == NULL) { werr = WERR_NOMEM; goto done; } } for (count = 0; count < pd(ctx)->cache->num_params[sidx]; count++) { werr = smbconf_add_string_to_array(tmp_service, &(tmp_service->param_names), count, pd(ctx)->cache->param_names[sidx][count]); if (!W_ERROR_IS_OK(werr)) { goto done; } werr = smbconf_add_string_to_array(tmp_service, &(tmp_service->param_values), count, pd(ctx)->cache->param_values[sidx][count]); if (!W_ERROR_IS_OK(werr)) { goto done; } } tmp_service->num_params = count; if (count > 0) { *service = talloc_move(mem_ctx, &tmp_service); } else { *service = NULL; } done: talloc_free(tmp_ctx); return werr; }
/** * get the list of share names defined in the configuration. */ static WERROR smbconf_txt_get_share_names(struct smbconf_ctx *ctx, TALLOC_CTX *mem_ctx, uint32_t *num_shares, char ***share_names) { uint32_t count; uint32_t added_count = 0; TALLOC_CTX *tmp_ctx = NULL; WERROR werr = WERR_OK; char **tmp_share_names = NULL; if ((num_shares == NULL) || (share_names == NULL)) { werr = WERR_INVALID_PARAM; goto done; } werr = smbconf_txt_load_file(ctx); if (!W_ERROR_IS_OK(werr)) { return werr; } tmp_ctx = talloc_stackframe(); /* make sure "global" is always listed first, * possibly after NULL section */ if (smbconf_share_exists(ctx, NULL)) { werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, 0, NULL); if (!W_ERROR_IS_OK(werr)) { goto done; } added_count++; } if (smbconf_share_exists(ctx, GLOBAL_NAME)) { werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, added_count, GLOBAL_NAME); if (!W_ERROR_IS_OK(werr)) { goto done; } added_count++; } for (count = 0; count < pd(ctx)->cache->num_shares; count++) { if (strequal(pd(ctx)->cache->share_names[count], GLOBAL_NAME) || (pd(ctx)->cache->share_names[count] == NULL)) { continue; } werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, added_count, pd(ctx)->cache->share_names[count]); if (!W_ERROR_IS_OK(werr)) { goto done; } added_count++; } *num_shares = added_count; if (added_count > 0) { *share_names = talloc_move(mem_ctx, &tmp_share_names); } else { *share_names = NULL; } done: talloc_free(tmp_ctx); return werr; }