<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arricc &#187; PHP</title>
	<atom:link href="http://www.arricc.net/tag/php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.arricc.net</link>
	<description>50% IT snippets that I couldn&#039;t readily find existing help on. 50% drivel.</description>
	<lastBuildDate>Wed, 02 Mar 2011 23:44:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Drupal HTTPS images</title>
		<link>http://www.arricc.net/drupal-https-images.php</link>
		<comments>http://www.arricc.net/drupal-https-images.php#comments</comments>
		<pubDate>Wed, 02 Mar 2011 23:44:34 +0000</pubDate>
		<dc:creator>Fizzgig</dc:creator>
				<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[module]]></category>

		<guid isPermaLink="false">http://www.arricc.net/?p=96</guid>
		<description><![CDATA[I was involved with a project for a while which was using Drupal as the CMS. The entire site was being served over HTTPS, which was quite annoying as a large pile of the images that were being posted were being served over HTTP from their respective webservers. Naturally, this resulted in everyone getting very [...]]]></description>
			<content:encoded><![CDATA[<p>I was involved with a project for a while which was using <a href="http://drupal.org">Drupal</a> as the CMS. The entire site was being served over HTTPS, which was quite annoying as a large pile of the images that were being posted were being served over HTTP from their respective webservers. Naturally, this resulted in everyone getting very annoyed at their browser warning about loading unsecured content on a secure page.</p>
<p>So, I came up with this module. I&#8217;ve been meaning to release it for ages, but as I need to clear down the server it was running on it&#8217;s made me take the five minutes to write this post. Still needs a bit of work, but does what it says on the tin.</p>
<p>It identifies non-local images in content, downloads them and serves them from a local cache.</p>
<p>Download the module here: <a href='http://www.arricc.net/wp-content/uploads/img_proxy.tar.gz'>img_proxy.tar.gz</a></p>
<p>If you use Drupal, you should already know the drill &#8211; extract the file to your modules directory and enable it in the modules page. The module is implemented as an input filter, so you will then have to add it to the appropriate input formats at http://your.site.com/admin/settings/filters </p>
<p><strong>Notes</strong></p>
<ul>
<li>Licenced under the GPL version 2.</li>
<li><strong>*** There is nothing in the code that verifies the file being proxied is an image!! ***</strong> (that&#8217;ll be in the next version!)</li>
<li>May not work with sites that check the referer of the request for images.</li>
<li>I&#8217;ve been meaning to release this for ages, but there is sill a lot of debug code thats just commented out.</li>
</ul>
<p>Hopefully I&#8217;m not the only webmaster that ever had this issue and somebody will find this handy.</p>
<p>Maybe one day I&#8217;ll tidy up the code and submit it to the Drupal Module repository!</p>
<p>Enjoy.</p>
<p class="buymebeer"><form action="https://www.paypal.com/cgi-bin/webscr" target="paypal" method="post"><input type="hidden" name="cmd" value="_xclick" /><input type="hidden" name="business" value="mark@arricc.net" /><input type="hidden" name="return" value="http://www.arricc.net/pp-thanks.php" /><input type="hidden" name="item_name" value="Buy Me a Beer for Drupal HTTPS images" /><input type="hidden" name="currency_code" value="GBP" /><input type="hidden" name="amount" value="5" /><input type="image" src="http://www.arricc.net/wp-content/plugins/buy-me-beer/icon_beer.gif" align="left" alt="" title="" hspace="3" /></form><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=mark@arricc.net&amp;currency_code=GBP&amp;amount=5&amp;return=http://www.arricc.net/pp-thanks.php&amp;item_name=Buy+Me+a+Beer+for+Drupal+HTTPS+images" target="paypal">If you find this article useful, buy me a beer!</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.arricc.net/drupal-https-images.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress Front Page Single Post</title>
		<link>http://www.arricc.net/wordpress-front-page-single-post.php</link>
		<comments>http://www.arricc.net/wordpress-front-page-single-post.php#comments</comments>
		<pubDate>Fri, 11 Sep 2009 13:03:03 +0000</pubDate>
		<dc:creator>Fizzgig</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[front page]]></category>

		<guid isPermaLink="false">http://www.arricc.net/?p=55</guid>
		<description><![CDATA[Well, I&#8217;ve rejigged my site theme, and I decided to play a bit with the layout. The look of the site seemed to be better with just the excerpt from a single post on the front page. Now, that sounds really straight forward and something that WordPress should be able to do out of the [...]]]></description>
			<content:encoded><![CDATA[<p>Well, I&#8217;ve rejigged my site theme, and I decided to play a bit with the layout.</p>
<p>The look of the site seemed to be better with just the excerpt from a single post on the front page.</p>
<p>Now, that sounds really straight forward and something that WordPress should be able to do out of the box. And it is. </p>
<p>However, if you want the &#8220;Older Entries&#8221; pages to then show, say, 10 posts you&#8217;re knackered as all subsequent pages will just show 1 entry. I tried the Custom Post Limits plugin, but it still didn&#8217;t work as page 2 started at post 6.</p>
<p>After reading a lot of entries on this topic (it seems I&#8217;m not the only person keen on this!) and getting nowhere fast. Lots of &#8220;read this link then work it out yourself&#8221; type replies I finally got something to work. Using both the offset AND paging attributes of the query_posts() function!</p>
<p>The only issue with this is that the last page wouldn&#8217;t show at all. This was due to the fact that the front page misses all but 1 of the entries, then the 2nd page starts at entry 2. In effect you&#8217;re missing a number of entries up to the usual number per page minus 1 &#8211; everything that would be on the last page. To get round this, I simply double the number of entries displayed on what WordPress believes is the final page.</p>
<p><span id="more-55"></span></p>
<p>To get this to work, add the following snippit to the top of the home.php file in your theme directory.<br />
If you don&#8217;t have a home.php file then copy your index.php in your theme directory to home.php which will then take precedence according to the <a href="http://codex.wordpress.org/Template_Hierarchy">WordPress Template Heirarcy</a>. I do not recommend adding this to your index.php file.</p>
<p><div class="codeblock"><code><span class="synSpecial">&lt;?php</span><br /><span class="synComment">//WATCH THAT LINE WRAP!</span><br /><span class="synStatement">if</span> <span class="synSpecial">(</span>is_home<span class="synSpecial">())</span> <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">page</span> <span class="synStatement">=</span> <span class="synSpecial">(</span>get_query_var<span class="synSpecial">(</span>'<span class="synConstant">paged</span>'<span class="synSpecial">))</span> <span class="synStatement">?</span> get_query_var<span class="synSpecial">(</span>'<span class="synConstant">paged</span>'<span class="synSpecial">)</span> <span class="synStatement">:</span> <span class="synConstant">1</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">page</span> <span class="synStatement">==</span> <span class="synConstant">1</span><span class="synSpecial">)</span> <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query_posts<span class="synSpecial">(</span>&quot;<span class="synConstant">showposts=1&amp;paged=</span><span class="synStatement">$</span><span class="synIdentifier">page</span>&quot;<span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span> <span class="synStatement">else</span> <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">numposts</span> <span class="synStatement">=</span> get_option<span class="synSpecial">(</span>'<span class="synConstant">posts_per_page</span>'<span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synComment">//Work out what posts to show first on the page.</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">offset</span> <span class="synStatement">=</span> <span class="synSpecial">((</span><span class="synStatement">$</span><span class="synIdentifier">page</span> <span class="synConstant">-1</span><span class="synSpecial">)</span> <span class="synStatement">*</span> <span class="synStatement">$</span><span class="synIdentifier">numposts</span><span class="synSpecial">)</span> <span class="synStatement">-</span> <span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">numposts</span> <span class="synConstant">-1</span><span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synComment">//Quick hack to display double the number of posts on the last page as the offset hides posts per page -1.</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">page</span> <span class="synStatement">==</span> <span class="synStatement">$</span><span class="synIdentifier">wp_query</span><span class="synType">-&gt;</span>max_num_pages<span class="synSpecial">)</span> <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">numposts</span> <span class="synStatement">=</span> <span class="synConstant">2</span><span class="synStatement">*</span> get_option<span class="synSpecial">(</span>'<span class="synConstant">posts_per_page</span>'<span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query_posts<span class="synSpecial">(</span>&quot;<span class="synConstant">offset=</span><span class="synStatement">$</span><span class="synIdentifier">offset</span><span class="synConstant">&amp;paged=</span><span class="synStatement">$</span><span class="synIdentifier">page</span><span class="synConstant">&amp;showposts=</span><span class="synStatement">$</span><span class="synIdentifier">numposts</span>&quot;<span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br /><span class="synSpecial">}</span><br /><span class="synSpecial">?&gt;</span><br /></code></div></p>
<p class="buymebeer"><form action="https://www.paypal.com/cgi-bin/webscr" target="paypal" method="post"><input type="hidden" name="cmd" value="_xclick" /><input type="hidden" name="business" value="mark@arricc.net" /><input type="hidden" name="return" value="http://www.arricc.net/pp-thanks.php" /><input type="hidden" name="item_name" value="Buy Me a Beer for WordPress Front Page Single Post" /><input type="hidden" name="currency_code" value="GBP" /><input type="hidden" name="amount" value="5" /><input type="image" src="http://www.arricc.net/wp-content/plugins/buy-me-beer/icon_beer.gif" align="left" alt="" title="" hspace="3" /></form><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=mark@arricc.net&amp;currency_code=GBP&amp;amount=5&amp;return=http://www.arricc.net/pp-thanks.php&amp;item_name=Buy+Me+a+Beer+for+Wordpress+Front+Page+Single+Post" target="paypal">If you find this article useful, buy me a beer!</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.arricc.net/wordpress-front-page-single-post.php/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Exchange Guid converter tool</title>
		<link>http://www.arricc.net/exchange-guid-converter-tool.php</link>
		<comments>http://www.arricc.net/exchange-guid-converter-tool.php#comments</comments>
		<pubDate>Tue, 18 Sep 2007 01:13:40 +0000</pubDate>
		<dc:creator>Fizzgig</dc:creator>
				<category><![CDATA[Exchange]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.arricc.net/exchange-guid-converter.php</guid>
		<description><![CDATA[In response to the amount of comments I&#8217;ve had (which are way way more than I was ever expecting!) on my Exchange Mailbox Recovery article, I&#8217;ve written a script to convert your guids from the bad format that exmerge gives you to the one thats required for updating the user account. You can access it [...]]]></description>
			<content:encoded><![CDATA[<p>In response to the amount of comments I&#8217;ve had (which are way way more than I was ever expecting!) on my <a href="/exchange-2003-mailbox-recovery.php">Exchange Mailbox Recovery</a> article, I&#8217;ve written a script to convert your guids from the bad format that exmerge gives you to the one thats required for updating the user account.</p>
<p>You can access it <a href="/exchange-guid-converter.php">here</a>. Please leave any feedback on this post.</p>
<p class="buymebeer"><form action="https://www.paypal.com/cgi-bin/webscr" target="paypal" method="post"><input type="hidden" name="cmd" value="_xclick" /><input type="hidden" name="business" value="mark@arricc.net" /><input type="hidden" name="return" value="http://www.arricc.net/pp-thanks.php" /><input type="hidden" name="item_name" value="Buy Me a Beer for Exchange Guid converter tool" /><input type="hidden" name="currency_code" value="GBP" /><input type="hidden" name="amount" value="5" /><input type="image" src="http://www.arricc.net/wp-content/plugins/buy-me-beer/icon_beer.gif" align="left" alt="" title="" hspace="3" /></form><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=mark@arricc.net&amp;currency_code=GBP&amp;amount=5&amp;return=http://www.arricc.net/pp-thanks.php&amp;item_name=Buy+Me+a+Beer+for+Exchange+Guid+converter+tool" target="paypal">If you find this article useful, buy me a beer!</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.arricc.net/exchange-guid-converter-tool.php/feed</wfw:commentRss>
		<slash:comments>99</slash:comments>
		</item>
		<item>
		<title>LastFM for Drupal</title>
		<link>http://www.arricc.net/lastfm-for-drupal.php</link>
		<comments>http://www.arricc.net/lastfm-for-drupal.php#comments</comments>
		<pubDate>Wed, 22 Aug 2007 23:51:54 +0000</pubDate>
		<dc:creator>Fizzgig</dc:creator>
				<category><![CDATA[Drupal]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[lastfm]]></category>
		<category><![CDATA[module]]></category>

		<guid isPermaLink="false">http://www.arricc.net/lastfm-for-drupal.php</guid>
		<description><![CDATA[So, I&#8217;ve been playing with Drupal recently. At first it did my head in, but then something sorta clicked. Not been near the Taxonomy module yet, but when I do I expect that process to reverse. Anyway, I decided I needed a module that will allow users to show their LastFM stuff on their profile [...]]]></description>
			<content:encoded><![CDATA[<p>So, I&#8217;ve been playing with <a href="http://www.drupal.org">Drupal</a> recently.</p>
<p>At first it did my head in, but then something sorta clicked. Not been near the Taxonomy module yet, but when I do I expect that process to reverse.</p>
<p>Anyway, I decided I needed a module that will allow users to show their LastFM stuff on their profile pages. I couldn&#8217;t find one so I wrote one.</p>
<p>I stared out with the <a href="http://drupal.org/project/onlinestatus">Onlinestatus</a> module as it did something very similar to what I was hoping to achieve.</p>
<p>Anyway, the module is attached should you feel so inclined. (Requires the profiles module I think. The one I based it on does anyway, so it probably does too.)</p>
<p>Download: <a id="p31" href="http://www.arricc.net/wp-content/uploads/lastfm.tar.gz">lastfm.tar.gz</a></p>
<p class="buymebeer"><form action="https://www.paypal.com/cgi-bin/webscr" target="paypal" method="post"><input type="hidden" name="cmd" value="_xclick" /><input type="hidden" name="business" value="mark@arricc.net" /><input type="hidden" name="return" value="http://www.arricc.net/pp-thanks.php" /><input type="hidden" name="item_name" value="Buy Me a Beer for LastFM for Drupal" /><input type="hidden" name="currency_code" value="GBP" /><input type="hidden" name="amount" value="5" /><input type="image" src="http://www.arricc.net/wp-content/plugins/buy-me-beer/icon_beer.gif" align="left" alt="" title="" hspace="3" /></form><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=mark@arricc.net&amp;currency_code=GBP&amp;amount=5&amp;return=http://www.arricc.net/pp-thanks.php&amp;item_name=Buy+Me+a+Beer+for+LastFM+for+Drupal" target="paypal">If you find this article useful, buy me a beer!</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.arricc.net/lastfm-for-drupal.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>User VHosting</title>
		<link>http://www.arricc.net/user-vhosting.php</link>
		<comments>http://www.arricc.net/user-vhosting.php#comments</comments>
		<pubDate>Tue, 29 Aug 2006 23:05:50 +0000</pubDate>
		<dc:creator>Fizzgig</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Wintermute]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.arricc.net/user-vhosting.php</guid>
		<description><![CDATA[So, previously, I detailed how to do web virtual hosting to directories on the file system. This is all well and good, but I want to have users pidgeon holed into their own directories, plus I want users own websites to be stored under their own directories in a similar format to that used in [...]]]></description>
			<content:encoded><![CDATA[<p>So, <a href="/vwebhosting.php">previously</a>, I detailed how to do web virtual hosting to directories on the file system. This is all well and good, but I want to have users pidgeon holed into their own directories, plus I want users own websites to be stored under their own directories in a similar format to that used in the previous article (eg. /home/user/web/example.org/subdomain)</p>
<p>The problem lies with mapping domain names (example.org) onto user accounts (Alice? Bob?). This is where Apache and mod_rewrite come to the rescue again. On Wintermute I&#8217;ve installed Apache 2, but this recipe will work just as well with Apache 1.3.<span id="more-24"></span></p>
<p>First, we create a file with domain names to username mappings:<br />
/etc/apache2/map.hosted<br />
<div class="codeblock"><code>wintermute:/etc/apache2# cat map.hosted<br />xeno-phon.co.uk: jimsin<br />starfallonline.co.uk: stillborn<br />ryanroberts.co.uk: stillborn<br />witchhunter.co.uk: stillborn<br />flushedphoenix.co.uk: flushedphoenix<br />shawree.co.uk: shawree<br />theballswinger.co.uk: the_ball_swinger<br />the-hearse.com: hobgoth<br /></code></div><br />
The pattern is &#8220;website.com: username&#8221; with one per line.<br />
Each of these usernames must also exist in the Xoops database (or as system users), but I&#8217;ll be covering the links to that DB in a later article.</p>
<p>Coming up with that file was the easy bit. The next bit was the major pain in the hole. I searched for aaaages to try and work out how to do this in php ( my php is significantly better than my Perl), but all the examples I could find were written in Perl. So, here are some keywords for search engines: how to write a mod_rewrite map in php not perl. php apache rewritemap.</p>
<p><div class="codeblock"><code>#!/usr/bin/php<br /><span class="synSpecial">&lt;?</span><br /><span class="synComment">//Optional log file.</span><br /><span class="synComment">#$log = fopen (&quot;/tmp/rwlist&quot;,'a');</span><br /><span class="synComment">//Map file</span><br /><span class="synStatement">$</span><span class="synIdentifier">mapIn</span> <span class="synStatement">=</span> <span class="synIdentifier">fopen</span><span class="synSpecial">(</span>&quot;<span class="synConstant">/etc/apache2/map.hosted</span>&quot;, &quot;<span class="synConstant">r</span>&quot;<span class="synSpecial">)</span>;<br /><span class="synComment">//Read in the file.</span><br /><span class="synComment">//NB: This is only done at startup, so if you change the file you have to reload Apache to get the changes recognised.</span><br /><span class="synStatement">while</span> <span class="synSpecial">((</span><span class="synStatement">$</span><span class="synIdentifier">data</span> <span class="synStatement">=</span> <span class="synIdentifier">fgetcsv</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">mapIn</span>, <span class="synConstant">1000</span>, &quot;<span class="synConstant">:</span>&quot;<span class="synSpecial">))</span> <span class="synStatement">!==</span> <span class="synConstant">FALSE</span><span class="synSpecial">)</span> <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">map</span><span class="synSpecial">[</span><span class="synStatement">$</span><span class="synIdentifier">data</span><span class="synSpecial">[</span><span class="synConstant">0</span><span class="synSpecial">]]</span> <span class="synStatement">=</span> <span class="synIdentifier">trim</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">data</span><span class="synSpecial">[</span><span class="synConstant">1</span><span class="synSpecial">])</span>;<br /><span class="synSpecial">}</span><br /><span class="synIdentifier">fclose</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">mapIn</span><span class="synSpecial">)</span>;<br /><span class="synComment">//Recursive function. Starts with the full domain name and gradually pops off segments until it finds an owner (or not).</span><br /><span class="synComment">//eg. www.sub.example.org - first checks for www.sub.example.org, then sub.example.org, then example.org and finally org.</span><br /><span class="synPreProc">function</span> checkUser<span class="synSpecial">(</span><span class="synStatement">&amp;$</span><span class="synIdentifier">url</span><span class="synSpecial">)</span><br /><span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synType">global</span> <span class="synStatement">$</span><span class="synIdentifier">map</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">uname</span> <span class="synStatement">=</span> <span class="synStatement">$</span><span class="synIdentifier">map</span><span class="synSpecial">[</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]]</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">uname</span> <span class="synStatement">&lt;&gt;</span> &quot;&quot;<span class="synSpecial">)</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">=</span> <span class="synStatement">$</span><span class="synIdentifier">uname</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">else</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">host</span> <span class="synStatement">=</span> <span class="synIdentifier">explode</span><span class="synSpecial">(</span>&quot;<span class="synConstant">.</span>&quot;,<span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">])</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">=</span> &quot;<span class="synConstant">/</span>&quot;<span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">host</span><span class="synSpecial">[</span><span class="synConstant">0</span><span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">unset</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">host</span><span class="synSpecial">[</span><span class="synConstant">0</span><span class="synSpecial">])</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">=</span> <span class="synIdentifier">implode</span><span class="synSpecial">(</span>&quot;<span class="synConstant">.</span>&quot;,<span class="synStatement">$</span><span class="synIdentifier">host</span><span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">&lt;&gt;</span> &quot;&quot;<span class="synSpecial">)</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; checkUser<span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br /><span class="synSpecial">}</span><br /><span class="synStatement">do</span><br /><span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">in</span> <span class="synStatement">=</span> <span class="synIdentifier">trim</span><span class="synSpecial">(</span><span class="synIdentifier">fgets</span><span class="synSpecial">(</span>STDIN,<span class="synConstant">8096</span><span class="synSpecial">))</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synIdentifier">strlen</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">in</span><span class="synSpecial">)</span> <span class="synStatement">&gt;</span><span class="synConstant">0</span><span class="synSpecial">)</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br /><span class="synComment">//Log request</span><br /><span class="synComment">#&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  fputs($log, &quot;$in\n&quot;);</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">unset</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">])</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synIdentifier">substr</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">in</span>,<span class="synConstant">0</span>,<span class="synConstant">1</span><span class="synSpecial">)</span> <span class="synStatement">&lt;&gt;</span> &quot;<span class="synConstant">/</span>&quot;<span class="synSpecial">)</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">in</span> <span class="synStatement">=</span> &quot;<span class="synConstant">http://</span><span class="synStatement">$</span><span class="synIdentifier">in</span>&quot;;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">url</span> <span class="synStatement">=</span> <span class="synIdentifier">parse_url</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">in</span><span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">path</span> <span class="synStatement">=</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">=</span> &quot;&quot;;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; checkUser<span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synComment">//If we find an owner</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span><span class="synSpecial">(</span><span class="synStatement">isset</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]))</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synComment">//This bit is slightly legacy before I moved the hosting files about a bit. Kept for posterity mainly.</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">out</span> <span class="synStatement">=</span> &quot;<span class="synConstant">/home/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span>&quot;<span class="synConstant">/web/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> &quot;<span class="synConstant">.elizium.net/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">path</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synIdentifier">file_exists</span><span class="synSpecial">(</span>&quot;<span class="synConstant">/home/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span>&quot;<span class="synConstant">/web/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">path</span><span class="synSpecial">))</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">out</span> <span class="synStatement">=</span> &quot;<span class="synConstant">/home/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span>&quot;<span class="synConstant">/web/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">path</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synComment">//Otherwise just return this file as 99% chance its some automated script looking for exploitable webapps.</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">else</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">out</span><span class="synStatement">=</span> &quot;<span class="synConstant">/var/www/monkey.txt</span>&quot;;<br /><span class="synComment">//Log resulting path</span><br /><span class="synComment">#&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  fputs($log, &quot;$out\n&quot;);</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synIdentifier">fputs</span><span class="synSpecial">(</span>STDOUT, &quot;<span class="synStatement">$</span><span class="synIdentifier">out</span><span class="synSpecial">\n</span>&quot;<span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br /><span class="synComment">//Just keep doing it forever.</span><br /><span class="synSpecial">}</span> <span class="synStatement">while</span> <span class="synSpecial">(</span><span class="synConstant">true</span><span class="synSpecial">)</span>;<br /><span class="synSpecial">?&gt;</span><br /></code></div></p>
<p>The only improvement I may make to that is to get the users home directory info as opposed to assuming its under /home.</p>
<p>Now we just need put that script somewhere, make it executable by the Apache user and tell Apache to use it. Thats done like so:<br />
<div class="codeblock"><code><span class="synIdentifier">RewriteEngine</span> <span class="synConstant">on</span><br /><span class="synComment">#Use this program to do the mappings</span><br /><span class="synIdentifier">RewriteMap</span>&nbsp; &nbsp; &nbsp; hosted&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prg:/etc/apache2/<span class="synConstant">map</span>.hosted.php<br /><span class="synComment">#This is for allowing www.user.elizium.net type urls as they're outwith the scope of the rewrite script as they're easy to map.</span><br /><span class="synComment">#See http://forum.modrewrite.com/viewtopic.php?t=1652&amp;postdays=0&amp;postorder=asc&amp;start=10</span><br /><span class="synIdentifier">RewriteCond</span> %{HTTP_HOST} !^(www\.)?elizium\.net$ [NC]<br /><span class="synIdentifier">RewriteCond</span> %{ENV:REDIRECT_STATUS} ^$<br /><span class="synIdentifier">RewriteCond</span> %{HTTP_HOST} ^([^\.]+\.)?([^.]+)\.elizium\.net$ [NC]<br /><span class="synIdentifier">RewriteRule</span> .*&nbsp; /home/%2/web/%2\.elizium.net%{REQUEST_URI}&nbsp; &nbsp; &nbsp; [QSA,L]<br /><span class="synComment">#Ignore *.elizium.net</span><br /><span class="synIdentifier">RewriteCond</span>&nbsp; &nbsp;  %{HTTP_HOST}&nbsp; &nbsp; !elizium.net$ [NC]<br /><span class="synComment">#Use the full request</span><br /><span class="synIdentifier">RewriteRule</span>&nbsp; &nbsp;  ^(.+)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  %{HTTP_HOST}$1&nbsp; [C]<br /><span class="synComment">#Throw the request through the map program</span><br /><span class="synIdentifier">RewriteRule</span>&nbsp; &nbsp;  ^(.*)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  ${hosted:$1}&nbsp; &nbsp; [L,C]<br /></code></div></p>
<p>I hope this is of use to people. Especially those folk looking for a php based rewrite script for Apache. Theres a lot of scope to expand the script. For example, the file data could be retrieved from a database and then stored in something like <a href="http://www.danga.com/memcached/">memcached</a> if you were performing this sort of thing on a larger scale. Much better than having a large webserver config file that means the webserver has to be reloaded for each change.</p>
<p>The only problem I have with this, and I know its not insurmountable, is that the webserver user has to be able to read the files that users are storing. To allow this I&#8217;ve made the www-data user a member of the group all the users are members of. This also means that users can read each others files. So if somebody was to hardcode a password in a php file (for example) then it would be open to being read by any other user.</p>
<p>I also want to mention <a href="http://www.suphp.org">suPHP</a>, it really does merit an article to itself, but as I&#8217;m not intending to cover it in depth (you can read all about it at the website) I&#8217;ll just say that I&#8217;ve enabled it on Wintermute to prevent users being able to do things like kill the web server processes via a php script. To do that, I installed the suphp-common Debian package. The default configs are all you need. For the non-Debian user, they look like this when taken together:<br />
<div class="codeblock"><code><span class="synIdentifier">LoadModule</span> suphp_module /usr/lib/apache2/modules/mod_suphp.so<br /><span class="synStatement">&lt;IfModule</span><span class="synConstant"> mod_suphp.c</span><span class="synStatement">&gt;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; suPHP_Engine <span class="synConstant">on</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synIdentifier">AddHandler</span> x-httpd-php .php .php3 .php4 .phtml<br /><span class="synComment"># # Use a specific php config file (a dir which contains a php.ini file)</span><br />&nbsp; &nbsp; &nbsp; &nbsp; suPHP_ConfigPath /etc/php4/cgi/<br /><span class="synStatement">&lt;/IfModule&gt;</span><br /></code></div></p>
<p>As usual comments on the above are most welcome. Especially quick links about solving my security issue!</p>
<p class="buymebeer"><form action="https://www.paypal.com/cgi-bin/webscr" target="paypal" method="post"><input type="hidden" name="cmd" value="_xclick" /><input type="hidden" name="business" value="mark@arricc.net" /><input type="hidden" name="return" value="http://www.arricc.net/pp-thanks.php" /><input type="hidden" name="item_name" value="Buy Me a Beer for User VHosting" /><input type="hidden" name="currency_code" value="GBP" /><input type="hidden" name="amount" value="5" /><input type="image" src="http://www.arricc.net/wp-content/plugins/buy-me-beer/icon_beer.gif" align="left" alt="" title="" hspace="3" /></form><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=mark@arricc.net&amp;currency_code=GBP&amp;amount=5&amp;return=http://www.arricc.net/pp-thanks.php&amp;item_name=Buy+Me+a+Beer+for+User+VHosting" target="paypal">If you find this article useful, buy me a beer!</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.arricc.net/user-vhosting.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

