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_RPC_SRV
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 BOOL smbconf_store_values( const char *key, REGVAL_CTR *val )
46 int num_values = regval_ctr_numvals(val);
47 REGVAL_CTR *new_val_ctr;
50 * we build a second regval container and copy over the values,
51 * possibly changing names to the canonical name, because when
52 * canonicalizing parameter names and replacing the original parameter
53 * (with reval_ctr_deletevalue and regval_ctr_addvalue) in the original
54 * container, the order would change and that is not so good in the
57 new_val_ctr = TALLOC_ZERO_P(val, REGVAL_CTR);
58 if (new_val_ctr == NULL) {
59 DEBUG(1, ("out of memory\n"));
63 for (i=0; i < num_values; i++) {
64 REGISTRY_VALUE *theval = regval_ctr_specific_value(val, i);
65 const char *valname = regval_name(theval);
68 DEBUG(10, ("inspecting value '%s'\n", valname));
70 /* unfortunately, we can not reject names that are not
71 * valid parameter names here, since e.g. regedit first
72 * creates values as "New Value #1" and so on and then
73 * drops into rename. */
75 if (regval_type(theval) != REG_SZ) {
76 DEBUG(1, ("smbconf_store_values: only registry value "
77 "type REG_SZ currently allowed under key "
82 if (registry_smbconf_valname_forbidden(regval_name(theval))) {
83 DEBUG(1, ("smbconf_store_values: value '%s' forbidden "
84 "in registry.\n", valname));
88 if (lp_parameter_is_valid(valname) &&
89 !lp_parameter_is_canonical(valname))
93 const char *canon_valname;
94 const char *canon_valstr;
96 struct registry_value *value;
101 DEBUG(5, ("valid parameter '%s' given but it is a "
102 "synonym. going to canonicalize it.\n",
105 mem_ctx = talloc_new(val);
106 if (mem_ctx == NULL) {
107 DEBUG(1, ("out of memory...\n"));
111 err = registry_pull_value(mem_ctx, &value,
116 if (!W_ERROR_IS_OK(err)) {
117 TALLOC_FREE(mem_ctx);
121 valstr = (value->v.sz.str);
122 len = value->v.sz.len;
123 if (valstr[len - 1] != '\0') {
124 DEBUG(10, ("string is not '\\0'-terminated. "
126 valstr = TALLOC_REALLOC_ARRAY(mem_ctx, valstr,
128 if (valstr == NULL) {
129 DEBUG(1, ("out of memory\n"));
130 TALLOC_FREE(mem_ctx);
137 if (!lp_canonicalize_parameter(valname, &canon_valname,
140 DEBUG(5, ("Error: lp_canonicalize_parameter "
141 "failed after lp_parameter_is_valid. "
142 "This should not happen!\n"));
143 TALLOC_FREE(mem_ctx);
146 DEBUG(10, ("old value name: '%s', canonical value "
147 "name: '%s'\n", valname, canon_valname));
148 if (inverse && lp_string_is_valid_boolean(valstr)) {
149 lp_invert_boolean(valstr, &canon_valstr);
151 canon_valstr = valstr;
156 value->type = REG_SZ;
157 value->v.sz.str = CONST_DISCARD(char *, canon_valstr);
158 value->v.sz.len = strlen(canon_valstr) + 1;
160 err = registry_push_value(mem_ctx, value, &value_data);
161 if (!W_ERROR_IS_OK(err)) {
162 DEBUG(10, ("error calling registry_push_value."
164 TALLOC_FREE(mem_ctx);
168 DEBUG(10, ("adding canonicalized parameter to "
170 res = regval_ctr_addvalue(new_val_ctr, canon_valname,
172 (char *)value_data.data,
175 DEBUG(10, ("error calling regval_ctr_addvalue. "
177 TALLOC_FREE(mem_ctx);
180 DEBUG(10, ("parameter added. container now has %d "
183 TALLOC_FREE(mem_ctx);
185 DEBUG(10, ("%s parameter found, "
186 "copying it to new container...\n",
187 (lp_parameter_is_valid(valname)?
188 "valid":"unknown")));
189 res = regval_ctr_copyvalue(new_val_ctr, theval);
191 DEBUG(10, ("error calling regval_ctr_copyvalue."
195 DEBUG(10, ("parameter copied. container now has %d "
199 return regdb_ops.store_values(key, new_val_ctr);
202 static BOOL smbconf_reg_access_check(const char *keyname, uint32 requested,
204 const struct nt_user_token *token)
206 if (!(user_has_privileges(token, &se_disk_operators))) {
210 *granted = REG_KEY_ALL;
214 static WERROR smbconf_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
215 struct security_descriptor **psecdesc)
217 return regdb_ops.get_secdesc(mem_ctx, key, psecdesc);
220 static WERROR smbconf_set_secdesc(const char *key,
221 struct security_descriptor *secdesc)
223 return regdb_ops.set_secdesc(key, secdesc);
228 * Table of function pointers for accessing smb.conf data
231 REGISTRY_OPS smbconf_reg_ops = {
233 smbconf_fetch_values,
235 smbconf_store_values,
236 smbconf_reg_access_check,