Code, Explained

Apache (httpd) 403 errors & SELinux in RHLE5

The “targeted” policy confines certain network daemons to run in their own specific “security domain”. These daemons include dhcpd, httpd (apache), named, nscd, ntpd, portmap, snmpd, squid, and syslogd.

When I setup apache on a system where it wil be utilized, I have a habit of not using /var/www/html as my starting point for document roots, but rather create a dir at /home/websites and place my document roots in there. In the good ol’ days of Discretionary Access Controls (DAC) just making sure that apache had the perms it needed to read the documents in there was enough (using chmod, chown, and the like).

Not so with SELinux enabled. In addition to the regular DAC we’re all used to, we now have Mandatory Access Controls (MAC) that define security contexts for files/directories etc. Turns out it looks like by default, apache only has access to /var/www/html when it’s fired up…. I’m guessing that and probably /var/log/httpd (which is exactly as it should be). To enable apache to view my files in /home/websites, I had to apply a new security context to these files. The answer to this is the chcon command. To be brief, the full command I executed was:

chcon -R -t httpd_sys_content_t /home/websites

After executing this, apache could read my files.

I like where this SELinux thing is going. Permissions done right, for sure. This doesn’t come with out growing pains though. It’s complex (or so it seems to me after only working with it for a couple days) and will take some time to learn. I’m prepared for some frustration….

Now many of you are probably asking yourself why would anyone (let alone me) want to bother with this? Well I think a simple example of one of the cool things is that even though something like /etc/passwd has DAC octal perms of 644 (rw-r–r–), apache still can’t read it because that file is not with in apache’s security context. So any users on your system can’t write a little script that reads your /etc/passwd file and basically posts it on a web page for the world to see (giving potential crackers a list of valid user accounts on the system).

Actually this is a little bit extra security that provide by SELinux e.g. Security Enhanced!

Ohh, one more tips to change the direcotry live…

chcon --reference=/var/www <your website directory>
chcon --reference=/var/www/html <your public_html directory>

I suggest you to make a shell script to put it together… with following commands…

useradd <your website user name> #password and other necessary staff to point home directory
chmod --reference=/var/www /home/<your website user name>
mkdir /home/<your website user name>/public_html
# most probably the following line need not to execute
chmod --reference=/var/www/html /home/<your website user name>/public_html
# then do other necessary staff for your website suppose add virtual host, ftp user, database user etc.

nJoy…

Posted in linuxTagged , , , , , , , , , 2 Comments on Apache (httpd) 403 errors & SELinux in RHLE5

scope into smarty template

i’m very much fan of smarty templating. though it has many draw back but it tiny and strait froward for a small project. for smarty the varaible scope within template is very much complex. you cannot change a variable value from outside of the template.

let me explain the senario…

suppose i have a base template. named “main.tpl”

<html>
<head><title>title of the page</title></head>
<body>
<h1>your page head</h1>
{assign var="client_cur_location" value="You are now at home page."}
{include file="products.tpl" scope="global"}
<div id="pagloc">{$client_cur_location}</div>
</body>
</html>

now your products.tpl

{assign var="client_cur_location" value="<a href=\"index.php\">Home</a> &gt;&gt; Product"}
this is product listing page.

so you need to display the current location but from your included page. its not possible by smarty engin through included page. cause included page variable scope is totally local variable. here i found a solution from php mailing list. but unfortunatly it have bug when php function array_marge is changed for PHP 5

following is the complete modified, tested and working code…

/* Smarty_Compiler.class.php [near line # 950 ~ 975] */
 function _compile_include_tag($tag_args)
 {
 $attrs = $this->_parse_attrs($tag_args);

 // ADD NEXT LINE (default value of the param scope = local).
 $scope_action = "\$this->_tpl_vars = array_merge((array)\$_smarty_tpl_vars, (array)\$GLOBALS[\"_smarty_tpl_vars_temp\"]);\n";

 $arg_list = array();

 if (empty($attrs['file'])) {
 $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
 }

 foreach ($attrs as $arg_name => $arg_value) {
 if ($arg_name == 'file') {
 $include_file = $arg_value;
 continue;
 } else if ($arg_name == 'assign') {
 $assign_var = $arg_value;
 continue;
 }
 // ADD: Startin block
 else if( $arg_name == 'scope' )
 {
 $scope = @$this->_dequote($arg_value);
 if( $scope != 'local' &&
 $scope != 'parent' &&
 $scope != 'global')
 $this->_syntax_error("invalid 'scope' attribute value");
 if( $scope == 'parent' )
 $scope_action = "";
 if( $scope == 'global' )
 {
 $scope_action = "".
 "\$array_diff = array_diff( array_keys(\$this->_tpl_vars), array_keys(\$_smarty_tpl_vars) );".
 "foreach( \$array_diff as \$key=>\$value ){".
 "\$GLOBALS[\"_smarty_tpl_vars_temp\"][\$value] = \$this->_tpl_vars[\$value];\n".
 "}";
 }
 }
 // Ending block

 if (is_bool($arg_value))
 $arg_value = $arg_value ? 'true' : 'false';
 // REPLACE THIS LINE WITH THE NEXT TWO
 // $arg_list[] = "'$arg_name' => $arg_value";
 if( $arg_name != 'scope' )
 $arg_list[] = "'$arg_name' => $arg_value";

 }

 $output = '<?php ';

 if (isset($assign_var)) {
 $output .= "ob_start();\n";
 }

 $output .=
 "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";

 $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
 $output .= "\$this->_smarty_include($_params);\n" .

 // REPLACE THIS LINE WITH THE NEXT ONE
 // "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
 $scope_action."\n".

 "unset(\$_smarty_tpl_vars);\n";
/*        original code
 "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
 "unset(\$_smarty_tpl_vars);\n";        */

 if (isset($assign_var)) {
 $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
 }

 $output .= ' ?>';

 return $output;

 }

The value accepted for the *scope* param are: global|parent|local.
default value is *local*.

please add your valuable comment how can we improve our scope usability into our code.

please note, above php code originally is not mine. i just modified and fix the bug.

Posted in php, smarty, study, webdevelopmentTagged , , , , ,