*** ./src/backend/utils/misc/guc.c.orig	2007-03-10 19:13:26.000000000 +0100
--- ./src/backend/utils/misc/guc.c	2007-03-10 20:21:27.000000000 +0100
***************
*** 3997,4002 ****
--- 3997,4010 ----
  			break;
  	}
  
+ 	/* protect armored custom variables */
+ 	if (record->group == CUSTOM_OPTIONS)
+ 		if (record->armored && !superuser())
+ 			ereport(elevel,
+ 					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ 					 errmsg("permission denied to set parameter \"%s\"",
+ 							name)));
+ 
  	/*
  	 * Should we set reset/stacked values?	(If so, the behavior is not
  	 * transactional.)
***************
*** 5031,5036 ****
--- 5039,5066 ----
  	end_tup_output(tstate);
  }
  
+ 
+ /*
+  * Allow protection of content custom variables
+  */
+ void 
+ ArmorCustomVariable(const char *name)
+ {
+ 	struct config_generic *cvar;
+ 
+ 	cvar = find_option(name, ERROR);
+ 	if (cvar == NULL)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_UNDEFINED_OBJECT),
+ 	    			   errmsg("unrecognized configuration parameter \"%s\"", name)));
+ 
+ 	if (cvar->group != CUSTOM_OPTIONS)
+ 		elog(ERROR, "only custom variables can be armored");
+ 
+ 	cvar->armored = true;
+ }
+ 
+ 
  /*
   * Return GUC variable value by name; optionally return canonical
   * form of name.  Return value is palloc'd.
*** ./src/include/utils/guc.h.orig	2007-03-10 19:12:47.000000000 +0100
--- ./src/include/utils/guc.h	2007-03-10 19:13:03.000000000 +0100
***************
*** 202,207 ****
--- 202,208 ----
  extern void GetPGVariable(const char *name, DestReceiver *dest);
  extern TupleDesc GetPGVariableResultDesc(const char *name);
  extern void ResetPGVariable(const char *name);
+ extern void ArmorCustomVariable(const char *name);
  
  extern char *flatten_set_variable_args(const char *name, List *args);
  
*** ./src/include/utils/guc_tables.h.orig	2007-03-10 19:09:28.000000000 +0100
--- ./src/include/utils/guc_tables.h	2007-03-10 19:10:40.000000000 +0100
***************
*** 116,121 ****
--- 116,122 ----
  	GucSource	tentative_source;		/* source of the tentative_value */
  	GucSource	source;			/* source of the current actual value */
  	GucStack   *stack;			/* stacked outside-of-transaction states */
+ 	bool	armored;		/* armored value can change only superuser */
  };
  
  /* bit values in flags field */

