Index: t3lib/class.t3lib_page.php
===================================================================
--- t3lib/class.t3lib_page.php	(Revision 2528)
+++ t3lib/class.t3lib_page.php	(Arbeitskopie)
@@ -977,6 +977,10 @@
 						$field = $table.'.'.$ctrl['enablecolumns']['fe_group'];
 						$query.= $this->getMultipleGroupsWhereClause($field, $table);
 					}
+					if ($ctrl['enablecolumns']['fe_rules'] && !$ignore_array['fe_rules']) {
+						$field = $table.'.'.$ctrl['enablecolumns']['fe_rules'];
+						$query.= $this->getMultipleGroupsWhereClause($field, $table, $GLOBALS['TSFE']->rulesActive);
+					}
 
 					// Call hook functions for additional enableColumns
 					// It is used by the extension ingmar_accessctrl which enables assigning more than one usergroup to content and page records
@@ -1005,17 +1009,20 @@
 	 *
 	 * @param	string		Field with group list
 	 * @param	string		Table name
+	 * @param	array		The groups to be processed
 	 * @return	string		AND sql-clause
 	 * @see enableFields()
 	 */
-	function getMultipleGroupsWhereClause($field, $table)	{
-		$memberGroups = t3lib_div::intExplode(',',$GLOBALS['TSFE']->gr_list);
+	function getMultipleGroupsWhereClause($field, $table, $groups=null)	{
+		if (!is_array($groups)) {
+			$groups = t3lib_div::intExplode(',',$GLOBALS['TSFE']->gr_list);
+		}
 		$orChecks=array();
 		$orChecks[]=$field.'=\'\'';	// If the field is empty, then OK
 		$orChecks[]=$field.' IS NULL';	// If the field is NULL, then OK
 		$orChecks[]=$field.'=\'0\'';	// If the field contsains zero, then OK
 
-		foreach($memberGroups as $value)	{
+		foreach($groups as $value)	{
 			$orChecks[] = $GLOBALS['TYPO3_DB']->listQuery($field, $value, $table);
 		}
 
Index: t3lib/class.t3lib_div.php
===================================================================
--- t3lib/class.t3lib_div.php	(Revision 2528)
+++ t3lib/class.t3lib_div.php	(Arbeitskopie)
@@ -1367,6 +1367,19 @@
 		return chr(10).htmlspecialchars($content);
 	}
 
+	/**
+	 * Convert a string with wildcards '*,?' to a regular expression,
+	 * e.g. '*something?' get converted to '.*something.'.
+	 *
+	 * @param	string		$string: The wildcard string to be converted to a regular expression
+	 * @return	string		The regular expression string
+	 */
+	function wildcard2regexp($string) {
+		$string = str_replace(array('*','?'), array('###MANY###','###ONE###'), $string);
+		$string = '/^'.preg_quote($string,'/').'$/';
+		$string = str_replace(array('###MANY###','###ONE###'), array('.*','.'), $string);	// Replace the marker with .* to match anything (wildcard)
+		return $string;
+	}
 
 
 
@@ -1378,6 +1391,7 @@
 
 
 
+
 	/*************************
 	 *
 	 * ARRAY FUNCTIONS
Index: typo3/sysext/lang/locallang_general.xml
===================================================================
--- typo3/sysext/lang/locallang_general.xml	(Revision 2528)
+++ typo3/sysext/lang/locallang_general.xml	(Arbeitskopie)
@@ -14,6 +14,7 @@
 			<label index="LGL.hidden">Hide:</label>
 			<label index="LGL.starttime">Start:</label>
 			<label index="LGL.fe_group">Access:</label>
+			<label index="LGL.fe_rules">Rules:</label>
 			<label index="LGL.hide_at_login">Hide at login</label>
 			<label index="LGL.any_login">Show at any login</label>
 			<label index="LGL.usergroups">__Usergroups:__</label>
Index: typo3/sysext/cms/ext_tables.php
===================================================================
--- typo3/sysext/cms/ext_tables.php	(Revision 2528)
+++ typo3/sysext/cms/ext_tables.php	(Arbeitskopie)
@@ -525,6 +525,7 @@
 			'starttime' => 'starttime',
 			'endtime' => 'endtime',
 			'fe_group' => 'fe_group',
+			'fe_rules' => 'fe_rules',
 		),
 		'typeicon_column' => 'CType',
 		'typeicons' => Array (
@@ -546,7 +547,7 @@
 			'div' => 'tt_content_div.gif',
 			'html' => 'tt_content_html.gif'
 		),
-		'mainpalette' => '1,15',
+		'mainpalette' => '1,15,16',
 		'thumbnail' => 'image',
 		'requestUpdate' => 'list_type',
 		'dynamicConfigFile' => t3lib_extMgm::extPath($_EXTKEY).'tbl_tt_content.php'
@@ -598,6 +599,25 @@
 );
 
 // ******************************************************************
+// fe_rules
+// ******************************************************************
+$TCA['fe_rules'] = Array (
+	'ctrl' => Array (
+		'label' => 'title',
+		'tstamp' => 'tstamp',
+		'delete' => 'deleted',
+		'type' => 'type',
+		'prependAtCopy' => 'LLL:EXT:lang/locallang_general.php:LGL.prependAtCopy',
+		'enablecolumns' => Array (
+			'disabled' => 'hidden'
+		),
+		'title' => 'LLL:EXT:cms/locallang_tca.php:fe_rules',
+		'dynamicConfigFile' => t3lib_extMgm::extPath($_EXTKEY).'tbl_cms.php',
+		'requestUpdate' => 'type',
+	)
+);
+
+// ******************************************************************
 // sys_domain
 // ******************************************************************
 $TCA['sys_domain'] = Array (
Index: typo3/sysext/cms/locallang_tca.xml
===================================================================
--- typo3/sysext/cms/locallang_tca.xml	(Revision 2528)
+++ typo3/sysext/cms/locallang_tca.xml	(Arbeitskopie)
@@ -70,6 +70,12 @@
 			<label index="fe_groups.title">Grouptitle:</label>
 			<label index="fe_groups.lockToDomain">Lock to domain:</label>
 			<label index="fe_groups.subgroup">Subgroups:</label>
+			<label index="fe_rules">Website rule</label>
+			<label index="fe_rules.type">Type:</label>
+			<label index="fe_rules.title">Rule title:</label>
+			<label index="fe_rules.allow">Allow/Deny expression:</label>
+			<label index="fe_rules.expression">Expression:</label>
+			<label index="fe_rules.subrules">Sub rules:</label>
 			<label index="sys_domain">Domain</label>
 			<label index="sys_domain.domainName">Domain:</label>
 			<label index="sys_domain.redirectTo">Redirect to:</label>
Index: typo3/sysext/cms/ext_tables.sql
===================================================================
--- typo3/sysext/cms/ext_tables.sql	(Revision 2528)
+++ typo3/sysext/cms/ext_tables.sql	(Arbeitskopie)
@@ -92,6 +92,25 @@
 
 
 #
+# Table structure for table 'fe_rules'
+#
+CREATE TABLE fe_rules (
+  uid int(11) unsigned NOT NULL auto_increment,
+  pid int(11) unsigned DEFAULT '0' NOT NULL,
+  tstamp int(11) unsigned DEFAULT '0' NOT NULL,
+  type varchar(16) DEFAULT '' NOT NULL,
+  title varchar(50) DEFAULT '' NOT NULL,
+  hidden tinyint(3) unsigned DEFAULT '0' NOT NULL,
+  deleted tinyint(3) unsigned DEFAULT '0' NOT NULL,
+  description text NOT NULL,
+  allow tinyint(1) unsigned DEFAULT '0' NOT NULL,
+  expression varchar(128) DEFAULT '' NOT NULL,
+  subrules tinyblob NOT NULL,
+  PRIMARY KEY (uid),
+  KEY parent (pid)
+);
+
+#
 # Table structure for table 'fe_session_data'
 #
 CREATE TABLE fe_session_data (
@@ -327,6 +346,7 @@
   spaceBefore tinyint(4) unsigned DEFAULT '0' NOT NULL,
   spaceAfter tinyint(4) unsigned DEFAULT '0' NOT NULL,
   fe_group varchar(100) DEFAULT '0' NOT NULL,
+  fe_rules varchar(100) DEFAULT '0' NOT NULL,
   header_link varchar(255) DEFAULT '' NOT NULL,
   imagecaption_position varchar(6) DEFAULT '' NOT NULL,
   image_link varchar(255) DEFAULT '' NOT NULL,
Index: typo3/sysext/cms/tbl_tt_content.php
===================================================================
--- typo3/sysext/cms/tbl_tt_content.php	(Revision 2528)
+++ typo3/sysext/cms/tbl_tt_content.php	(Arbeitskopie)
@@ -39,7 +39,7 @@
 	'ctrl' => $TCA['tt_content']['ctrl'],
 	'interface' => Array (
 		'always_description' => 0,
-		'showRecordFieldList' => 'CType,header,header_link,bodytext,image,imagewidth,imageorient,media,records,colPos,starttime,endtime,fe_group'
+		'showRecordFieldList' => 'CType,header,header_link,bodytext,image,imagewidth,imageorient,media,records,colPos,starttime,endtime,fe_group,fe_rules'
 	),
 	'columns' => Array (
 		'CType' => Array (
@@ -121,6 +121,18 @@
 				'foreign_table' => 'fe_groups'
 			)
 		),
+		'fe_rules' => Array (
+			'exclude' => 1,
+			'label' => 'LLL:EXT:lang/locallang_general.php:LGL.fe_rules',
+			'config' => Array (
+				'type' => 'select',
+				'size' => 5,
+				'maxitems' => 20,
+				'items' => Array (
+				),
+				'foreign_table' => 'fe_rules'
+			)
+		),
 		'sys_language_uid' => Array (
 			'exclude' => 1,
 			'label' => 'LLL:EXT:lang/locallang_general.php:LGL.language',
@@ -1021,6 +1033,7 @@
 	'palettes' => Array (
 		'1' => Array('showitem' => 'hidden, starttime, endtime'),
 		'15' => Array('showitem' => 'fe_group'),
+		'16' => Array('showitem' => 'fe_rules'),
 		'2' => Array('showitem' => 'imagecols, image_noRows, imageborder'),
 		'3' => Array('showitem' => 'header_position, header_layout, header_link, date'),
 		'4' => Array('showitem' => 'sys_language_uid, l18n_parent, colPos, spaceBefore, spaceAfter, section_frame, sectionIndex, linkToTop'),
Index: typo3/sysext/cms/tbl_cms.php
===================================================================
--- typo3/sysext/cms/tbl_cms.php	(Revision 2528)
+++ typo3/sysext/cms/tbl_cms.php	(Arbeitskopie)
@@ -372,6 +372,95 @@
 
 
 // ******************************************************************
+// fe_rules
+//
+// FrontEnd rules - determines visibility of elements
+// ******************************************************************
+$TCA['fe_rules'] = Array (
+	'ctrl' => $TCA['fe_rules']['ctrl'],
+	'interface' => Array (
+		'showRecordFieldList' => 'title,hidden,type,subrules,description,allow'
+	),
+	'columns' => Array (
+		'hidden' => Array (
+			'label' => 'LLL:EXT:lang/locallang_general.php:LGL.disable',
+			'exclude' => 1,
+			'config' => Array (
+				'type' => 'check',
+				'default' => '0'
+			)
+		),
+		'type' => array(
+			'label' => 'LLL:EXT:cms/locallang_tca.php:fe_rules.type',
+			'config' => array(
+				'type' => 'select',
+				'items' => Array (
+					Array('Domain', 'domain'),
+					Array('Group of rules', 'group'),
+				),
+				'default' => 'domain',
+			),
+		),
+		'title' => Array (
+			'label' => 'LLL:EXT:cms/locallang_tca.php:fe_rules.title',
+			'config' => Array (
+				'type' => 'input',
+				'size' => '20',
+				'max' => '50',
+				'eval' => 'trim,required'
+			)
+		),
+		'subrules' => Array (
+			'exclude' => 1,
+			'label' => 'LLL:EXT:cms/locallang_tca.php:fe_rules.subrules',
+			'config' => Array (
+				'type' => 'select',
+				'foreign_table' => 'fe_rules',
+				'foreign_table_where' => 'AND NOT(fe_rules.uid = ###THIS_UID###) AND fe_rules.hidden=0 ORDER BY fe_rules.title',
+				'size' => 4,
+				'autoSizeMax' => 10,
+				'minitems' => 0,
+				'maxitems' => 20
+			)
+		),
+		'allow' => array(
+			'label' => 'LLL:EXT:cms/locallang_tca.php:fe_rules.allow',
+			'config' => array(
+				'type' => 'select',
+				'items' => Array (
+					Array('Deny', '0'),
+					Array('Allow', '1'),
+				),
+				'default' => '1'
+			),
+		),
+		'expression' => array(
+			'label' => 'LLL:EXT:cms/locallang_tca.php:fe_rules.expression',
+			'config' => array(
+				'type' => 'input',
+				'size' => '20',
+				'max' => '50',
+				'eval' => 'trim,required'
+			),
+		),
+		'description' => Array (
+			'label' => 'LLL:EXT:lang/locallang_general.php:LGL.description',
+			'config' => Array (
+				'type' => 'text',
+				'rows' => 5,
+				'cols' => 48
+			)
+		),
+	),
+	'types' => Array (
+		'0' => Array('showitem' => 'hidden;;;;1-1-1,type, title;;;;2-2-2,description;;;;3-3-3, --div--, allow, expression'),
+		'domain' => Array('showitem' => 'hidden;;;;1-1-1,type, title;;;;2-2-2,description;;;;3-3-3, --div--, allow, expression'),
+		'group' => Array('showitem' => 'hidden;;;;1-1-1,type, title;;;;2-2-2,description;;;;3-3-3, --div--, allow, subrules'),
+	)
+);
+
+
+// ******************************************************************
 // sys_domain
 // ******************************************************************
 $TCA['sys_domain'] = Array (
Index: typo3/sysext/cms/tslib/class.tslib_fe.php
===================================================================
--- typo3/sysext/cms/tslib/class.tslib_fe.php	(Revision 2528)
+++ typo3/sysext/cms/tslib/class.tslib_fe.php	(Arbeitskopie)
@@ -237,6 +237,11 @@
 	var $page_cache_reg1=0;				// This can be set from applications as a way to tag cached versions of a page and later perform some external cache management, like clearing only a part of the cache of a page...
 	var $siteScript='';					// Contains the value of the current script path that activated the frontend. Typically "index.php" but by rewrite rules it could be something else! Used for Speaking Urls / Simulate Static Documents.
 
+		// RULES
+
+	var $rulesActive=array();			// FE rules that have positively passed the checks and thus are active
+	var $rulesProcessed=array();		// FE rules that were processed
+
 		// USER
 
 	/**
@@ -536,6 +541,75 @@
 
 
 	/**
+	 * Initialize the front-end rules.
+	 * 
+	 * @return	void
+	 */
+	function initFErules() {
+		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+			'*',
+			'fe_rules',
+			'hidden=0 AND deleted=0'
+		);
+		while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
+			$this->evaluateFErule($row);
+		}
+		$GLOBALS['TYPO3_DB']->sql_free_result($res);
+	}
+
+	/**
+	 * Evaluate a singe front-end rule and put the processed rules to $this->rulesProcessed.
+	 * The rules that were tested positive are stored in $this->rulesActive.
+	 *
+	 * @param	array		$row: A record row of table fe_rules
+	 * @return	boolean		Returns true if the rule matches the current sitation, otherwise false
+	 */
+	function evaluateFErule($row) {
+		$result = null;
+		$allow = (boolean)$row['allow'];
+		switch($row['type']) {
+			case 'domain':
+				$expression = trim($row['expression']);
+				if ($expression) {
+					$result = (boolean)preg_match(t3lib_div::wildcard2regexp($expression), t3lib_div::getIndpEnv('HTTP_HOST'));
+				}
+				break;
+			case 'group':
+				$subRules = t3lib_div::trimExplode(',', $row['subrules']);
+				echo $allow;
+				foreach ($subRules as $rule) {
+					if (isset($this->rulesProcessed[$rule])) {
+						$subResult = $this->rulesProcessed[$rule];
+					} else {
+						$subRows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'fe_rules', 'deleted=0 AND hidden=0 AND uid='.intval($rule));
+						$subResult = (count($subRows) ? $this->evaluateFErule($subRows[0]) : null);
+					}
+					if (isset($subResult) && $allow!=$subResult) {
+						$result = (!$allow && $subResult);
+						break;
+					}
+				}
+				if (!isset($result)) {
+					$result = $allow;
+				}
+				break;
+		}
+		if (isset($result)) {
+				// Invert result if this is a deny expresion:
+			if (!$allow) {
+				$result = ($result xor true);
+			}
+			if (!isset($this->rulesProcessed[$row['uid']])) {
+				$this->rulesProcessed[$row['uid']] = $result;
+				if ($result) {
+					$this->rulesActive[] = $row['uid'];
+				}
+			}
+		}
+		return $result;
+	}
+
+	/**
 	 * Initializes the front-end login user.
 	 *
 	 * @return	void
Index: typo3/sysext/cms/tslib/index_ts.php
===================================================================
--- typo3/sysext/cms/tslib/index_ts.php	(Revision 2528)
+++ typo3/sysext/cms/tslib/index_ts.php	(Arbeitskopie)
@@ -192,6 +192,13 @@
 }
 
 // *********
+// FE_RULES
+// *********
+$TT->push('Front End rules initialized','');
+	$TSFE->initFErules();
+$TT->pull();
+
+// *********
 // FE_USER
 // *********
 $TT->push('Front End user initialized','');
