Fix some "nexted extern" warnins
[Samba.git] / source / registry / reg_backend_smbconf.c
bloba6e478200f1afcd39d108fa3712f15a1beb77ebf
1 /*
2 * Unix SMB/CIFS implementation.
3 * Virtual Windows Registry Layer
4 * Copyright (C) Volker Lendecke 2006
5 * Copyright (C) Michael Adam 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/>.
21 #include "includes.h"
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_REGISTRY
26 extern REGISTRY_OPS regdb_ops; /* these are the default */
28 static int smbconf_fetch_keys( const char *key, REGSUBKEY_CTR *subkey_ctr )
30 return regdb_ops.fetch_subkeys(key, subkey_ctr);
33 static bool smbconf_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
35 return regdb_ops.store_subkeys(key, subkeys);
38 static int smbconf_fetch_values( const char *key, REGVAL_CTR *val )
40 return regdb_ops.fetch_values(key, val);
43 static WERROR regval_hilvl_to_lolvl(TALLOC_CTX *mem_ctx, const char *valname,
44 struct registry_value *src,
45 REGISTRY_VALUE **dst)
47 WERROR err;
48 DATA_BLOB value_data;
49 REGISTRY_VALUE *newval = NULL;
51 if (dst == NULL) {
52 return WERR_INVALID_PARAM;
55 err = registry_push_value(mem_ctx, src, &value_data);
56 if (!W_ERROR_IS_OK(err)) {
57 DEBUG(10, ("error calling registry_push_value.\n"));
58 return err;
61 newval = regval_compose(mem_ctx, valname, src->type,
62 (char *)value_data.data, value_data.length);
63 if (newval == NULL) {
64 DEBUG(10, ("error composing registry value. (no memory?)\n"));
65 return WERR_NOMEM;
68 *dst = newval;
69 return WERR_OK;
72 static WERROR regval_lolvl_to_hilvl(TALLOC_CTX *mem_ctx, REGISTRY_VALUE *src,
73 struct registry_value **dst)
75 if (dst == NULL) {
76 return WERR_INVALID_PARAM;
79 return registry_pull_value(mem_ctx, dst, regval_type(src),
80 regval_data_p(src), regval_size(src),
81 regval_size(src));
85 * Utility function used by smbconf_store_values to canonicalize
86 * a registry value.
87 * registry_pull_value / registry_push_value are used for (un)marshalling.
89 static REGISTRY_VALUE *smbconf_canonicalize_regval(TALLOC_CTX *mem_ctx,
90 REGISTRY_VALUE *theval)
92 char *valstr;
93 size_t len;
94 const char *canon_valname;
95 const char *canon_valstr;
96 bool inverse;
97 struct registry_value *value;
98 WERROR err;
99 TALLOC_CTX *tmp_ctx;
100 REGISTRY_VALUE *newval = NULL;
102 if (!lp_parameter_is_valid(regval_name(theval)) ||
103 lp_parameter_is_canonical(regval_name(theval)))
105 return theval;
108 tmp_ctx = talloc_stackframe();
109 if (tmp_ctx == NULL) {
110 DEBUG(1, ("out of memory...\n"));
111 goto done;
114 err = regval_lolvl_to_hilvl(tmp_ctx, theval, &value);
115 if (!W_ERROR_IS_OK(err)) {
116 goto done;
119 /* we need the value-string zero-terminated */
120 valstr = value->v.sz.str;
121 len = value->v.sz.len;
122 if (valstr[len - 1] != '\0') {
123 DEBUG(10, ("string is not '\\0'-terminated. adding '\\0'.\n"));
124 valstr = TALLOC_REALLOC_ARRAY(tmp_ctx, valstr, char, len + 1);
125 if (valstr == NULL) {
126 DEBUG(1, ("out of memory\n"));
127 goto done;
129 valstr[len] = '\0';
132 if (!lp_canonicalize_parameter(regval_name(theval), &canon_valname,
133 &inverse))
135 DEBUG(5, ("Error: lp_canonicalize_parameter failed after "
136 "lp_parameter_is_valid. This should not happen!\n"));
137 goto done;
139 DEBUG(10, ("old value name: '%s', canonical value name: '%s'\n",
140 regval_name(theval), canon_valname));
141 if (inverse && lp_string_is_valid_boolean(valstr)) {
142 lp_invert_boolean(valstr, &canon_valstr);
143 } else {
144 canon_valstr = valstr;
147 ZERO_STRUCTP(value);
148 value->type = REG_SZ;
149 value->v.sz.str = CONST_DISCARD(char *, canon_valstr);
150 value->v.sz.len = strlen(canon_valstr) + 1;
152 err = regval_hilvl_to_lolvl(mem_ctx, canon_valname, value, &newval);
153 if (!W_ERROR_IS_OK(err)) {
154 DEBUG(10, ("error calling regval_hilvl_to_lolvl.\n"));
155 goto done;
158 done:
159 TALLOC_FREE(tmp_ctx);
160 return newval;
163 static bool smbconf_store_values( const char *key, REGVAL_CTR *val )
165 int i;
166 int num_values = regval_ctr_numvals(val);
167 REGVAL_CTR *new_val_ctr;
170 * we build a second regval container and copy over the values,
171 * possibly changing names to the canonical name, because when
172 * canonicalizing parameter names and replacing the original parameter
173 * (with reval_ctr_deletevalue and regval_ctr_addvalue) in the original
174 * container, the order would change and that is not so good in the
175 * "for" loop... :-o
177 new_val_ctr = TALLOC_ZERO_P(val, REGVAL_CTR);
178 if (new_val_ctr == NULL) {
179 DEBUG(1, ("out of memory\n"));
180 return False;
183 for (i=0; i < num_values; i++) {
184 REGISTRY_VALUE *theval = regval_ctr_specific_value(val, i);
185 const char *valname = regval_name(theval);
186 int res;
188 DEBUG(10, ("inspecting value '%s'\n", valname));
190 /* unfortunately, we can not reject names that are not
191 * valid parameter names here, since e.g. regedit first
192 * creates values as "New Value #1" and so on and then
193 * drops into rename. */
195 if (regval_type(theval) != REG_SZ) {
196 DEBUG(1, ("smbconf_store_values: only registry value "
197 "type REG_SZ currently allowed under key "
198 "smbconf\n"));
199 return False;
202 if (registry_smbconf_valname_forbidden(valname)) {
203 DEBUG(1, ("smbconf_store_values: value '%s' forbidden "
204 "in registry.\n", valname));
205 return False;
208 if (lp_parameter_is_valid(valname) &&
209 !lp_parameter_is_canonical(valname))
211 DEBUG(5, ("valid parameter '%s' given but it is a "
212 "synonym. going to canonicalize it.\n",
213 valname));
214 theval = smbconf_canonicalize_regval(val, theval);
215 if (theval == NULL) {
216 DEBUG(10, ("error canonicalizing registry "
217 "value\n"));
218 return False;
220 } else {
221 DEBUG(10, ("%s parameter found, "
222 "copying it to new container...\n",
223 (lp_parameter_is_valid(valname)?
224 "valid":"unknown")));
226 res = regval_ctr_copyvalue(new_val_ctr, theval);
227 if (res == 0) {
228 DEBUG(10, ("error calling regval_ctr_copyvalue. "
229 "(no memory?)\n"));
230 return False;
232 DEBUG(10, ("parameter copied. container now has %d values.\n",
233 res));
235 return regdb_ops.store_values(key, new_val_ctr);
238 static bool smbconf_reg_access_check(const char *keyname, uint32 requested,
239 uint32 *granted,
240 const struct nt_user_token *token)
242 if (!(user_has_privileges(token, &se_disk_operators))) {
243 return False;
246 *granted = REG_KEY_ALL;
247 return True;
250 static WERROR smbconf_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
251 struct security_descriptor **psecdesc)
253 return regdb_ops.get_secdesc(mem_ctx, key, psecdesc);
256 static WERROR smbconf_set_secdesc(const char *key,
257 struct security_descriptor *secdesc)
259 return regdb_ops.set_secdesc(key, secdesc);
264 * Table of function pointers for accessing smb.conf data
267 REGISTRY_OPS smbconf_reg_ops = {
268 .fetch_subkeys = smbconf_fetch_keys,
269 .fetch_values = smbconf_fetch_values,
270 .store_subkeys = smbconf_store_keys,
271 .store_values = smbconf_store_values,
272 .reg_access_check = smbconf_reg_access_check,
273 .get_secdesc = smbconf_get_secdesc,
274 .set_secdesc = smbconf_set_secdesc,