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/>.
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
,
49 REGISTRY_VALUE
*newval
= 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"));
61 newval
= regval_compose(mem_ctx
, valname
, src
->type
,
62 (char *)value_data
.data
, value_data
.length
);
64 DEBUG(10, ("error composing registry value. (no memory?)\n"));
72 static WERROR
regval_lolvl_to_hilvl(TALLOC_CTX
*mem_ctx
, REGISTRY_VALUE
*src
,
73 struct registry_value
**dst
)
76 return WERR_INVALID_PARAM
;
79 return registry_pull_value(mem_ctx
, dst
, regval_type(src
),
80 regval_data_p(src
), regval_size(src
),
85 * Utility function used by smbconf_store_values to canonicalize
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
)
94 const char *canon_valname
;
95 const char *canon_valstr
;
97 struct registry_value
*value
;
100 REGISTRY_VALUE
*newval
= NULL
;
102 if (!lp_parameter_is_valid(regval_name(theval
)) ||
103 lp_parameter_is_canonical(regval_name(theval
)))
108 tmp_ctx
= talloc_stackframe();
109 if (tmp_ctx
== NULL
) {
110 DEBUG(1, ("out of memory...\n"));
114 err
= regval_lolvl_to_hilvl(tmp_ctx
, theval
, &value
);
115 if (!W_ERROR_IS_OK(err
)) {
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"));
132 if (!lp_canonicalize_parameter(regval_name(theval
), &canon_valname
,
135 DEBUG(5, ("Error: lp_canonicalize_parameter failed after "
136 "lp_parameter_is_valid. This should not happen!\n"));
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
);
144 canon_valstr
= valstr
;
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"));
159 TALLOC_FREE(tmp_ctx
);
163 static bool smbconf_store_values( const char *key
, REGVAL_CTR
*val
)
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
177 new_val_ctr
= TALLOC_ZERO_P(val
, REGVAL_CTR
);
178 if (new_val_ctr
== NULL
) {
179 DEBUG(1, ("out of memory\n"));
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
);
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 "
202 if (registry_smbconf_valname_forbidden(valname
)) {
203 DEBUG(1, ("smbconf_store_values: value '%s' forbidden "
204 "in registry.\n", valname
));
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",
214 theval
= smbconf_canonicalize_regval(val
, theval
);
215 if (theval
== NULL
) {
216 DEBUG(10, ("error canonicalizing registry "
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
);
228 DEBUG(10, ("error calling regval_ctr_copyvalue. "
232 DEBUG(10, ("parameter copied. container now has %d values.\n",
235 return regdb_ops
.store_values(key
, new_val_ctr
);
238 static bool smbconf_reg_access_check(const char *keyname
, uint32 requested
,
240 const struct nt_user_token
*token
)
242 if (!(user_has_privileges(token
, &se_disk_operators
))) {
246 *granted
= REG_KEY_ALL
;
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
= {
269 smbconf_fetch_values
,
271 smbconf_store_values
,
272 smbconf_reg_access_check
,