svn commit: samba r24630 - in branches: SAMBA_3_2/source/registry SAMBA_3_2_0/source/registry

obnox at samba.org obnox at samba.org
Wed Aug 22 16:03:18 GMT 2007


Author: obnox
Date: 2007-08-22 16:03:17 +0000 (Wed, 22 Aug 2007)
New Revision: 24630

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24630

Log:
Store Samba configuratin options only under the default name, not as aliases.
This prevents creation of problematic configurations from registry editors
like regedit or "net rpc registry".

I will refactor the code to be somewhat more concise,
but I wanted to have this in the tree, now I got it working... :-)

Michael


Modified:
   branches/SAMBA_3_2/source/registry/reg_smbconf.c
   branches/SAMBA_3_2_0/source/registry/reg_smbconf.c


Changeset:
Modified: branches/SAMBA_3_2/source/registry/reg_smbconf.c
===================================================================
--- branches/SAMBA_3_2/source/registry/reg_smbconf.c	2007-08-22 13:51:44 UTC (rev 24629)
+++ branches/SAMBA_3_2/source/registry/reg_smbconf.c	2007-08-22 16:03:17 UTC (rev 24630)
@@ -43,18 +43,167 @@
 {
 	int i;
 	int num_values = regval_ctr_numvals(val);
+	REGVAL_CTR *new_val_ctr;
 
+	/*
+	 * we build a second regval container and copy over the values,
+	 * possibly changing names to the canonical name, because when
+	 * canonicalizing parameter names and replacing the original parameter
+	 * (with reval_ctr_deletevalue and regval_ctr_addvalue) in the original
+	 * container, the order would change and that is not so good in the
+	 * "for" loop...  :-o
+	 */
+	new_val_ctr = TALLOC_ZERO_P(val, REGVAL_CTR);
+	if (new_val_ctr == NULL) {
+		DEBUG(1, ("out of memory\n"));
+		return False;
+	}
+
 	for (i=0; i < num_values; i++) {
 		REGISTRY_VALUE *theval = regval_ctr_specific_value(val, i);
 		const char *valname = regval_name(theval);
+		int res;
 
-		if (registry_smbconf_valname_forbidden(valname)) {
-			DEBUG(0, ("smbconf_store_values: value '%s' forbidden "
+		DEBUG(10, ("inspecting value '%s'\n", valname));
+
+		/* unfortunately, we can not reject names that are not
+		 * valid parameter names here, since e.g. regedit first
+		 * creates values as "New Value #1" and so on and then
+		 * drops into rename. */
+
+		if (regval_type(theval) != REG_SZ) {
+			DEBUG(1, ("smbconf_store_values: only registry value "
+			      "type REG_SZ currently allowed under key "
+			      "smbconf\n"));
+			return False;
+		}
+
+		if (registry_smbconf_valname_forbidden(regval_name(theval))) {
+			DEBUG(1, ("smbconf_store_values: value '%s' forbidden "
 			      "in registry.\n", valname));
 			return False;
 		}
+
+		if (lp_parameter_is_valid(valname) &&
+		    !lp_parameter_is_canonical(valname))
+		{
+			char *valstr;
+			size_t len;
+			const char *canon_valname;
+			const char *canon_valstr;
+			BOOL inverse;
+			struct registry_value *value;
+			WERROR err;
+			DATA_BLOB value_data;
+			TALLOC_CTX *mem_ctx;
+
+			DEBUG(5, ("valid parameter '%s' given but it is a "
+				  "synonym. going to canonicalize it.\n",
+				  valname));
+
+			mem_ctx = talloc_new(val);
+			if (mem_ctx == NULL) {
+				DEBUG(1, ("out of memory...\n"));
+				return False;
+			}
+
+			err = registry_pull_value(mem_ctx, &value,
+						  theval->type,
+						  theval->data_p,
+						  theval->size,
+						  theval->size);
+			if (!W_ERROR_IS_OK(err)) {
+				TALLOC_FREE(mem_ctx);
+				return False;
+			}
+
+			valstr = (value->v.sz.str);
+			len = value->v.sz.len;
+			DEBUG(10, ("theval->size: %d, value->v.sz.len: %d, "
+				   "value->v.sz.str: '%s'\n",
+				   theval->size, value->v.sz.len,
+				   value->v.sz.str));
+			if (valstr[len - 1] != '\0') {
+				DEBUG(10, ("string is not '\\0'-terminated. "
+				      "adding '\\0'...\n"));
+				valstr = TALLOC_REALLOC_ARRAY(mem_ctx, valstr,
+							      char, len + 1);
+				if (valstr == NULL) {
+					DEBUG(1, ("out of memory\n"));
+					TALLOC_FREE(mem_ctx);
+					return False;
+				}
+				valstr[len] = '\0';
+				len++;
+			}
+
+			if (!lp_canonicalize_parameter(valname, &canon_valname,
+						       &inverse))
+			{
+				DEBUG(5, ("oops: lp_canonicalize_parameter "
+				      "failed after lp_parameter_is_valid. "
+				      "This should not happen!\n"));
+				TALLOC_FREE(mem_ctx);
+				return False;
+			}
+			DEBUG(10, ("old value name: '%s', canonical value "
+				   "name: '%s'\n", valname, canon_valname));
+			if (inverse && lp_string_is_valid_boolean(valstr)) {
+				lp_invert_boolean(valstr, &canon_valstr);
+			} else {
+				canon_valstr = valstr;
+			}
+
+			ZERO_STRUCTP(value);
+
+			value->type = REG_SZ;
+			value->v.sz.str = CONST_DISCARD(char *, canon_valstr);
+			value->v.sz.len = strlen(canon_valstr) + 1;
+
+			DEBUG(10, ("NEW: value->type: %d, value->v.sz.len: %d, "
+				   "value->v.sz.str: '%s'\n", value->type,
+				   value->v.sz.len, value->v.sz.str));
+
+			err = registry_push_value(mem_ctx, value, &value_data);
+			if (!W_ERROR_IS_OK(err)) {
+				DEBUG(10, ("error calling registry_push_value."
+				      "\n"));
+				TALLOC_FREE(mem_ctx);
+				return False;
+			}
+
+			DEBUG(10, ("adding canonicalized parameter to "
+				   "container.\n"));
+			res = regval_ctr_addvalue(new_val_ctr, canon_valname,
+						  value->type,
+						  (char *)value_data.data,
+						  value_data.length);
+			if (res == 0) {
+				DEBUG(10, ("error calling regval_ctr_addvalue. "
+				      "(no memory?)\n"));
+				TALLOC_FREE(mem_ctx);
+				return False;
+			}
+			DEBUG(10, ("parameter added. container now has %d "
+				   "values.\n", res));
+
+			TALLOC_FREE(mem_ctx);
+		} else {
+			DEBUG(10, ("%s parameter found, "
+				   "copying it to new container...\n",
+				   (lp_parameter_is_valid(valname)?
+				    "valid":"unknown")));
+			res = regval_ctr_copyvalue(new_val_ctr, theval);
+			if (res == 0) {
+				DEBUG(10, ("error calling regval_ctr_copyvalue."
+					   " (no memory?)\n"));
+				return False;
+			}
+			DEBUG(10, ("parameter copied. container now has %d "
+				   "values.\n", res));
+		}
 	}
-	return regdb_ops.store_values(key, val);
+	return regdb_ops.store_values(key, new_val_ctr);
 }
 
 static BOOL smbconf_reg_access_check(const char *keyname, uint32 requested,

Modified: branches/SAMBA_3_2_0/source/registry/reg_smbconf.c
===================================================================
--- branches/SAMBA_3_2_0/source/registry/reg_smbconf.c	2007-08-22 13:51:44 UTC (rev 24629)
+++ branches/SAMBA_3_2_0/source/registry/reg_smbconf.c	2007-08-22 16:03:17 UTC (rev 24630)
@@ -43,18 +43,167 @@
 {
 	int i;
 	int num_values = regval_ctr_numvals(val);
+	REGVAL_CTR *new_val_ctr;
 
+	/*
+	 * we build a second regval container and copy over the values,
+	 * possibly changing names to the canonical name, because when
+	 * canonicalizing parameter names and replacing the original parameter
+	 * (with reval_ctr_deletevalue and regval_ctr_addvalue) in the original
+	 * container, the order would change and that is not so good in the
+	 * "for" loop...  :-o
+	 */
+	new_val_ctr = TALLOC_ZERO_P(val, REGVAL_CTR);
+	if (new_val_ctr == NULL) {
+		DEBUG(1, ("out of memory\n"));
+		return False;
+	}
+
 	for (i=0; i < num_values; i++) {
 		REGISTRY_VALUE *theval = regval_ctr_specific_value(val, i);
 		const char *valname = regval_name(theval);
+		int res;
 
-		if (registry_smbconf_valname_forbidden(valname)) {
-			DEBUG(0, ("smbconf_store_values: value '%s' forbidden "
+		DEBUG(10, ("inspecting value '%s'\n", valname));
+
+		/* unfortunately, we can not reject names that are not
+		 * valid parameter names here, since e.g. regedit first
+		 * creates values as "New Value #1" and so on and then
+		 * drops into rename. */
+
+		if (regval_type(theval) != REG_SZ) {
+			DEBUG(1, ("smbconf_store_values: only registry value "
+			      "type REG_SZ currently allowed under key "
+			      "smbconf\n"));
+			return False;
+		}
+
+		if (registry_smbconf_valname_forbidden(regval_name(theval))) {
+			DEBUG(1, ("smbconf_store_values: value '%s' forbidden "
 			      "in registry.\n", valname));
 			return False;
 		}
+
+		if (lp_parameter_is_valid(valname) &&
+		    !lp_parameter_is_canonical(valname))
+		{
+			char *valstr;
+			size_t len;
+			const char *canon_valname;
+			const char *canon_valstr;
+			BOOL inverse;
+			struct registry_value *value;
+			WERROR err;
+			DATA_BLOB value_data;
+			TALLOC_CTX *mem_ctx;
+
+			DEBUG(5, ("valid parameter '%s' given but it is a "
+				  "synonym. going to canonicalize it.\n",
+				  valname));
+
+			mem_ctx = talloc_new(val);
+			if (mem_ctx == NULL) {
+				DEBUG(1, ("out of memory...\n"));
+				return False;
+			}
+
+			err = registry_pull_value(mem_ctx, &value,
+						  theval->type,
+						  theval->data_p,
+						  theval->size,
+						  theval->size);
+			if (!W_ERROR_IS_OK(err)) {
+				TALLOC_FREE(mem_ctx);
+				return False;
+			}
+
+			valstr = (value->v.sz.str);
+			len = value->v.sz.len;
+			DEBUG(10, ("theval->size: %d, value->v.sz.len: %d, "
+				   "value->v.sz.str: '%s'\n",
+				   theval->size, value->v.sz.len,
+				   value->v.sz.str));
+			if (valstr[len - 1] != '\0') {
+				DEBUG(10, ("string is not '\\0'-terminated. "
+				      "adding '\\0'...\n"));
+				valstr = TALLOC_REALLOC_ARRAY(mem_ctx, valstr,
+							      char, len + 1);
+				if (valstr == NULL) {
+					DEBUG(1, ("out of memory\n"));
+					TALLOC_FREE(mem_ctx);
+					return False;
+				}
+				valstr[len] = '\0';
+				len++;
+			}
+
+			if (!lp_canonicalize_parameter(valname, &canon_valname,
+						       &inverse))
+			{
+				DEBUG(5, ("oops: lp_canonicalize_parameter "
+				      "failed after lp_parameter_is_valid. "
+				      "This should not happen!\n"));
+				TALLOC_FREE(mem_ctx);
+				return False;
+			}
+			DEBUG(10, ("old value name: '%s', canonical value "
+				   "name: '%s'\n", valname, canon_valname));
+			if (inverse && lp_string_is_valid_boolean(valstr)) {
+				lp_invert_boolean(valstr, &canon_valstr);
+			} else {
+				canon_valstr = valstr;
+			}
+
+			ZERO_STRUCTP(value);
+
+			value->type = REG_SZ;
+			value->v.sz.str = CONST_DISCARD(char *, canon_valstr);
+			value->v.sz.len = strlen(canon_valstr) + 1;
+
+			DEBUG(10, ("NEW: value->type: %d, value->v.sz.len: %d, "
+				   "value->v.sz.str: '%s'\n", value->type,
+				   value->v.sz.len, value->v.sz.str));
+
+			err = registry_push_value(mem_ctx, value, &value_data);
+			if (!W_ERROR_IS_OK(err)) {
+				DEBUG(10, ("error calling registry_push_value."
+				      "\n"));
+				TALLOC_FREE(mem_ctx);
+				return False;
+			}
+
+			DEBUG(10, ("adding canonicalized parameter to "
+				   "container.\n"));
+			res = regval_ctr_addvalue(new_val_ctr, canon_valname,
+						  value->type,
+						  (char *)value_data.data,
+						  value_data.length);
+			if (res == 0) {
+				DEBUG(10, ("error calling regval_ctr_addvalue. "
+				      "(no memory?)\n"));
+				TALLOC_FREE(mem_ctx);
+				return False;
+			}
+			DEBUG(10, ("parameter added. container now has %d "
+				   "values.\n", res));
+
+			TALLOC_FREE(mem_ctx);
+		} else {
+			DEBUG(10, ("%s parameter found, "
+				   "copying it to new container...\n",
+				   (lp_parameter_is_valid(valname)?
+				    "valid":"unknown")));
+			res = regval_ctr_copyvalue(new_val_ctr, theval);
+			if (res == 0) {
+				DEBUG(10, ("error calling regval_ctr_copyvalue."
+					   " (no memory?)\n"));
+				return False;
+			}
+			DEBUG(10, ("parameter copied. container now has %d "
+				   "values.\n", res));
+		}
 	}
-	return regdb_ops.store_values(key, val);
+	return regdb_ops.store_values(key, new_val_ctr);
 }
 
 static BOOL smbconf_reg_access_check(const char *keyname, uint32 requested,



More information about the samba-cvs mailing list