Nov 24, 2013

YouTube Full Screen Problem (video doesn't stretch)

Are you tired of seeing this shit on YouTube Full Screen Video?

When clicking on the fullscreen button, the video stretches to about 3/4 of the screen, and the rest is black, so it's not really full screen at all. The hiccup is just in the graphics, because the controls (X Y positions of the buttons) are correct - in the corner on the screen, not where they are displayed.

This problem occurs in Google Chrome, and it's a problem with the Flash Player. To fix it, you need to go to the URL chrome://plugins/ in Chrome, and disable this plugin:

Type:PPAPI (out-of-process)


Refresh the page and...

Et voilà!

Nov 20, 2013

Measuring RaspberryPI CPU, GPU temperature and CPU frequency on Raspbian Linux

We'll create bash script:
sudo nano

Paste this and save:
cpuTemp0=$(cat /sys/class/thermal/thermal_zone0/temp)
cpuTempM=$(($cpuTemp2 % $cpuTemp1))
cpuFreq=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq | sed 's/.\{3\}$//'`Mhz

echo CPU temp"="$cpuTemp1"."$cpuTempM"'C"
echo GPU $(/opt/vc/bin/vcgencmd measure_temp)
echo CPU frequency=$cpuFreq

Set permission and run it:
sudo chmod +x;./

Bash script domain expiration check tool Slovenian version

This script checks if domain has expired and also supports e-mail notice. 

Original script is from Matt (domain-check). I modifed already modified script from Vivek (

List of changes:

- Added support for Slovenian (.si) domains.

- Added VAR for "mail from:".
- Increased time between whois queries to 7 seconds (Slovenian whois only allows 10 queries per minute).
- Mail subject and mail data are translated to Slovene language.
- Changed default VAR path for mail (/bin/mail/ to /usr/bin/mail)

Get the script:
wget;mv domain-check;chmod +x

Usage: ./ [ -e email ] [ -x expir_days ] [ -q ] [ -a ] [ -h ]
          {[ -d domain_namee ]} || { -f domainfile}

  -a                                        : Send a warning message through email
  -d domain                            : Domain to analyze (interactive mode)
  -e email address                   : Email address to send expiration notices
  -f domain file                        : File with a list of domains
  -h                                         : Print this screen
  -s whois server                     : Whois sever to query for information
  -q                                         : Don't print anything on the console
  -x days                                 : Domain expiration interval (eg. if domain_date < days)

Check single domain:
./ -d

Check single domain and send e-mail notice if domain will expire in less than defined in WARNDAYS:

./ -a -d

You can also check multiple domains. Create a file domains.txt and add your domains like:

Check multiple domains:
./ -f domains.txt

Check multiple domains and send e-mail notice if any domain will expire in less than defined in WARNDAYS:

./ -a -f domains.txt

Set your own parameters from command line. Next command will check domains in domains.txt with expiration date less than 60 days and send e-mail notice to [email protected]

./ -a -f domains.txt -e [email protected] -x 60 

If you are going to use this script with cron, use -q option or change QUIET="FALSE" to QUIET="TRUE"

Let's say we want to run this script every day at 4 AM. Open crontab with crontab -e (Ubuntu) and add the following line:
0 4 * * * /path/to/your/script/ -q -a -f /path/to/your/list/domains.txt

Nov 15, 2013

Postfix SSL error when sending message in Thunderbird client

This is a repost from my old blog that is no longer available. (May 16th 2012)

I was trying to send an email with Thunderbird client and got SSL TLS error message. I instantly suspected my email server crashed, because I had to force reboot a day ago.

After tailing mail.log this error message appeared:

postfix/smtpd[1834]: warning: TLS library problem: 1834:error:14094417:SSL routines:SSL3_READ_BYTES:sslv3 alert illegal parameter:s3_pkt.c:1093:SSL alert number 47:

When investigating further I found out mail server was fine, the main reason for this error was on guest machine (where thunderbird was installed - windows 7), it was Avast antivirus. Disabling and re-enabling it was the solution.

Nov 14, 2013

Encoding Web Shells in PNG IDAT chunks

Roses are red,
violets are blue,
images contain code,
you're hacked.

I've just had the privilege to have my mind blown, while reading this article:
Encoding Web Shells in PNG IDAT chunks. All credits go to Phil for this one, an IT consultant and hacker from down under. You should check out his other articles. Fascinating stuff.

In layman's terms, let's say you have a web page that allows user upload of images. You're feeling pretty safe about it, because when the image is uploaded, you immediately open and manipulate it in GD, a PHP image library, before you save it on the server. If you can't open the file, it's not a valid image. That should destroy all malicious code stored within the image, right?

That's right. It should.

But what if an image appears normal, and after you resize it in GD, a PHP shell appears out of thin air?

An image that contains a PHP shell "<?=$_GET[0]($_POST[1]);?>" when resized to 32x32 with GD.

There's no way around it. You can't really prevent it. And to make things worse, you're not even checking the file extension.

If you reverse the process of how the image is generated, you can encode all sorts of data in the image. When the image is then manipulated with GD, it produces plain text data within the image.
Sounds simple enough, but there are a few hoops one needs to jump through, to engineer such an image.
First, PHP code must be compressed, then reverse the PNG filtering process and finally embedding the data as raw pixels.

Depending on what the server does with this image, there are a few more tricks to be done.
If the file is resized with imagecopyresampled(), the payload needs to be encoded in a series of rectangles or squares.

Et voilà! Your PHP shell.

Oh sh*t!
But what can I do about it?

Like I said, not much. Without getting in too much detail on how this sorcery is done (you can check the source article for that), all you can do is focus on the prerequisites that enable this hack to work. Just uploading the image is, thankfully, not enough.

If you're a developer, don't be stupid. Don't do stupid things. Validate user input. Sanitize data. Have total control over how and where the files get saved. Triple check file and directory permissions and file extensions. There are many image hosting services and with the cloud becoming more and more popular, there are things like Amazon S3 you can use, to host data on third party.

Also, having total control over the file extension is not foolproof. You see, if your script contains a Local File Inclusion vulnerability (LFI) as well as user image upload, then my friend, I have bad news for you.
An attacker can just as well exploit the LFI with the path to the .png on the server.

Oh, you have all your include()-s and require()-s prefixed and suffixed? Tell me all about it! But while you're at it, have a look at this stackexchange debate. [*sound of explosion*]

If you're a user innocently hosting your web page somewhere, you can hope that your hosting provider has tight security, but also check file and directory permissions. Anything that isn't specificaly meant for upload, shouldn't have write access for apache. That typically means 644 or -rw-r--r--, for you. If you have .htaccess enabled, you can disable PHP execution on directories with user upload. See how below. Make sure it's not writable by anyone else.

If you're a sysadmin, you can expect your users to run all kinds of outdated opensourcy mumbo jumbo, which is like magnets for abusers. But you can't just mess with their files and do as you please. You've g0t r00t, and that's your real power. Figure out which directories can be written to by the web server, and stop PHP execution on these directories.
For example, Wordpress:

<Directory /home/test/www/wordpress/wp-includes>
php_flag engine off

<Directory /home/test/www/wordpress/wp-content/uploads>
php_flag engine off

Even though these directories contain PHP scripts, they're never called directly by URL. They are require()-d or include()-d by index.php originally. However, this raises another issue - source code disclosure, if done sloppy. The example above is quick and dirty. Yes, sloppy. Do some work.
Also, you can use a Web Application Firewall, like mod_security or things like that. Unfortunately, they wouldn't help in this my-png-is-a-shell situation. But they can solve a lot of other potential problems.

Well thanks, Jean! You've *really* helped me out with this information! ...NOT!

I've said it once, I've said it twice, I'll say it again.
There is no standard solution for this.
You're gonna have to find every hole through which an attacker can crawl through, fix every sensitive information disclosure (don't display error messages on the page, don't display source code - with php_flag engine off it will be displayed!). Don't be sloppy, don't be stupid.

Feeling safe yet?
If not, you can give us a call, and we can do some penetration testing for you.

Convert coordinates to street address (reverse geocoding) via Google Maps API

Because most articles on this topic are quite outdated, here is a quick tip on how to do reverse geocoding with the help of Google Maps API v3.

In fact, you don't even need an API, this can be done manually via browser, or by fetching the url with some script and parsing the result.

The link is in this format:[LAT,LON]&sensor=true


The result can be in JSON or XML format.

JSON example result:
   "results" : [
         "address_components" : [
               "long_name" : "51",
               "short_name" : "51",
               "types" : [ "street_number" ]
               "long_name" : "Kolodvorska cesta",
               "short_name" : "Kolodvorska cesta",
               "types" : [ "route" ]
               "long_name" : "Pivka",
               "short_name" : "Pivka",
               "types" : [ "locality", "political" ]
               "long_name" : "Slovenia",
               "short_name" : "SI",
               "types" : [ "country", "political" ]
               "long_name" : "6257",
               "short_name" : "6257",
               "types" : [ "postal_code" ]
               "long_name" : "Pivka",
               "short_name" : "Pivka",
               "types" : [ "postal_town" ]
         "formatted_address" : "Kolodvorska cesta 51, 6257 Pivka, Slovenia",

Nov 10, 2013

PhpSysInfo loading slow on RaspberryPI (Linux Raspbian + Nginx + PHP5-fpm)

Default installation of PhpSysInfo on RaspberryPI takes a long time to load due some missing programs and hardware components.

My system info:

Hardware: RaspberryPI Model B with 512MB RAM
OS: Raspbian GNU/Linux 7
Nginx version: 1.2.1-2.2+wheezy1
PHP version: 5.4.4-14+deb7u5
PhpSysInfo version: 3.0.17-1

Enable debug mode in /etc/phpsysinfo/config.php

define('PSI_DEBUG', true);

Open http://yoursitephpsysinfo/xml.php

I found the following errors:

<Error Function="find_program(lsb_release)">
program not found on the machine ./xml.php on line 45 ./includes/output/ on line 138 in function run() ./includes/xml/ on line 456 in function getXml() ./includes/xml/ on line 435 in function _buildXml() ./includes/os/ on line 70 in function getSys() ./includes/os/ on line 576 in function build() ./includes/os/ on line 527 in function _distro() ./includes/ on line 117 in function executeProgram( "lsb_release", "-a 2>/dev/null", "", true )
<Error Function="/usr/bin/lspci">
pcilib: Cannot open /proc/bus/pci lspci: Cannot find any working access method. Return value: 1 ./xml.php on line 45 ./includes/output/ on line 138 in function run() ./includes/xml/ on line 456 in function getXml() ./includes/xml/ on line 435 in function _buildXml() ./includes/os/ on line 70 in function getSys() ./includes/os/ on line 583 in function build() ./includes/os/ on line 306 in function _pci() ./includes/ on line 36 in function lspci() ./includes/ on line 142 in function executeProgram( "lspci", "", "", true )
<Error Function="find_program(lsscsi)">
program not found on the machine ./xml.php on line 45 ./includes/output/ on line 138 in function run() ./includes/xml/ on line 456 in function getXml() ./includes/xml/ on line 435 in function _buildXml() ./includes/os/ on line 70 in function getSys() ./includes/os/ on line 585 in function build() ./includes/os/ on line 367 in function _scsi() ./includes/ on line 117 in function executeProgram( "lsscsi", "-c", "", true )
<Error Function="file_exists(/proc/scsi/scsi)">
the file does not exist on your machine ./xml.php on line 45 ./includes/output/ on line 138 in function run() ./includes/xml/ on line 456 in function getXml() ./includes/xml/ on line 435 in function _buildXml() ./includes/os/ on line 70 in function getSys() ./includes/os/ on line 585 in function build() ./includes/os/ on line 367 in function _scsi() ./includes/ on line 191 in function rfts( "/proc/scsi/scsi", "", 0, 4096, true )

First, third and fourth error are because some programs are not present on the system, let's install them.

sudo apt-get install lsb-release lsscsi -y

Second error is due missing PCI bus on raspberryPI.

# lspci
pcilib: Cannot open /proc/bus/pci
lspci: Cannot find any working access method.

We can't do anything about that but disable that function in PhpSysInfo PHP code. Open the file /your/path/to/phpsyinfo/includes/ and find the lspci function.

     * parsing the output of lspci command
     * @return Array
    public static function lspci()
        $arrResults = array();
        if (CommonFunctions::executeProgram("lspci", "", $strBuf, PSI_DEBUG)) {
            $arrLines = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY);
            foreach ($arrLines as $strLine) {
                list($strAddr, $strName) = preg_split('/ /', trim($strLine), 2);
                $strName = preg_replace('/\(.*\)/', '', $strName);
                $dev = new HWDevice();
                $arrResults[] = $dev;
        return $arrResults;

Change the code above to match the one bellow:

     * parsing the output of lspci command
     * @return Array
    public static function lspci()
        return array();
            $arrResults = array();
        if (CommonFunctions::executeProgram("lspci", "", $strBuf, PSI_DEBUG)) {
            $arrLines = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY);
            foreach ($arrLines as $strLine) {
                list($strAddr, $strName) = preg_split('/ /', trim($strLine), 2);
                $strName = preg_replace('/\(.*\)/', '', $strName);
                $dev = new HWDevice();
                $arrResults[] = $dev;
        return $arrResults;

Disable debug mode in phpsysinfo config, save, reload, drink beer.

Nov 8, 2013

Ubuntu Fail2ban fails to parse Apache access.log

I was trying to setup Fail2ban to block Wordpress login bruteforce attacks, but Fail2ban somehow failed to parse access.log

When parsing log file with command:
fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/apache-wp-login.conf
CPU rises to 100% usage until I kill the process. I made a quick fix - workaround with redirecting needed content from access.log to another log file.

My setup is as follows:

OS: Ubuntu Server 12.04 LTS
Fail2ban: 0.8.6-3wheezy2build0.12.04.1
Python: 2.7.3-0ubuntu2.2

Fail2ban configuration:

# Fail2Ban configuration file
# Author: Cyril Jaquier
# $Revision$
# Option:  loglevel
# Notes.:  Set the log level output.
#          1 = ERROR
#          2 = WARN
#          3 = INFO
#          4 = DEBUG
# Values:  NUM  Default:  3
loglevel = 4
# Option:  logtarget
# Notes.:  Set the log target. This could be a file, SYSLOG, STDERR or STDOUT.
#          Only one log target can be specified.
# Values:  STDOUT STDERR SYSLOG file  Default:  /var/log/fail2ban.log
logtarget = /var/log/fail2ban.log
# Option: socket
# Notes.: Set the socket file. This is used to communicate with the daemon. Do
#         not remove this file when Fail2ban runs. It will not be possible to
#         communicate with the server afterwards.
# Values: FILE  Default:  /var/run/fail2ban/fail2ban.sock
socket = /var/run/fail2ban/fail2ban.sock
We add new entry for Wordpress

Add configuration to /etc/fail2ban/jail.conf
enabled  = true
port     = http,https
filter   = apache-wp-login
logpath  = /var/log/apache2/apache-wp-login.log
maxretry = 3
findtime = 60
Now me make new filter for Wordpress. Some servers logs are in different format so we have to make different regex entries. These are two most common configurations:

Log format example 1: - - [08/Nov/2013:13:20:46 +0100] "POST /en/wp-login.php HTTP/1.1" 200 1784 "" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1623.0 Safari/537.36"
Log format example 2: - - [08/Nov/2013:13:40:12 +0000] "POST /wp-login.php HTTP/1.1" 200 1756 "" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0"
Create /etc/fail2ban/filter.d/apache-wp-login.conf

For log format example 1 use:
failregex = ^[^\:]+\:80 <HOST> .* "POST
ignoreregex =
ATTENTION! Don't apply this filter to default access.log, it would block all POST request, not only Wordpress. Only use it with modified log file we will create bellow.

For log format example 2 use:
failregex = <HOST>.*] "POST /wp-login.php
ATTENTION! Don't apply this filter to log format example 1, it would block your own server, because <HOST> regex would match your domain (

Now we create new log file for parsing (/var/log/apache2/apache-wp-login.log). We only want to filter out POST requests for wp-login.php and write them to new log file called apache-wp-login.log.
tail --follow=name /var/log/apache2/access.log | grep --line-buffered wp-login.php > /var/log/apache2/apache-wp-login.log &
Add this command to /etc/rc.local so it would run at reboot:
#!/bin/sh -e
# rc.local
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
# In order to enable or disable this script just change the execution
# bits.
# By default this script does nothing.

# Fail2ban Wordpress Login
tail -f /var/log/apache2/access.log | grep --line-buffered wp-login.php > /var/log/apache2/apache-wp-login.log &

exit 0
Restart Fail2ban and you're done.
/etc/init.d/fail2ban restart

Oct 10, 2013

Wordpress update - old jQuery warnings

With the recent Wordpress update, jQuery was also updated to version 1.10.

Blogs were now full of warning messages, somewhere along the lines of:

ATTENTION! (by Comprehensive Google Map Plugin)
Your blog/site theme or one of your plugins uses jQuery javascript library which is older than the version 1.3.0.
The Comprehensive Google Map plugin will not work with such outdated jQuery version.
The minimum jQuery requirement for Comprehensive Google Map plugin is version 1.3.0. Apologies for the inconvenience..

However, this is not true. Version 1.10.2 is greater than 1.3, but somehow it get's detected as 1.1, because silly programmers cast the version code into float. Ugh.

if (version < 1.3) { // WTF ?!?!?!?!?!
    return false;
Unfortunately, there's not much we can do about it, other than a quick hack of removing the version check or modifying it to 1.1.

Or wait for the plugin developers to FIX THE DAMN CODE.

Like that will happen anytime soon.

Oct 5, 2013

Restore panoramas (cubic tiles) from exported Pano2VR

With this simple little script you can restore the full size cubic faces of the panorama which was exported using Pano2VR.

Pretty useful, if you deleted the original by mistake ;)

To convert the cubic projection back to equirectangular, you can also use Pano2VR, but for the input source you choose "Cubic", load all six cube faces, and export transformation.

Pano2VR's panoramas are exported as tiles in a cubic projection. The file naming scheme is as follows:
for example:

The most detailed resolution level is "0", so that level is used, and other tiles are disregarded.
Cube faces range from 0 to 5, and X and Y are the row and column number.

The script is written in PHP, and should be run in a CLI.

ini_set('display_errors', 1);
ini_set('memory_limit', '2G');

$dir = 'tiles/';

foreach(range(0,5) as $c) {
 $i = 0;
 $tiles = array();
 $height = 0;
 do {
  $width = 0;
  $j = 0;
  do {
   $fn = fname($c,$i,$j);
   if(file_exists($fn)) {
    $tiles[$i][$j] = $fn;
    list($w, $h) = getimagesize($fn);
    $width += $w;
  } while(file_exists(fname($c,$i,$j)));
  $height += $h;
 } while(file_exists(fname($c,$i,$j)));
 echo $width.' '.$height."\n";
 $im = imagecreatetruecolor($width, $height);
 $y = 0;
 foreach($tiles as $row) {
  $x = 0;
  foreach($row as $tile) {
   $tile = imagecreatefromjpeg($tile);
   $src_w = imagesx($tile);
   $src_h = imagesy($tile);
   imagecopy($im, $tile, $x, $y, 0, 0, $src_w, $src_h);
   $x += $src_w;
  $y += $src_h;
 imagejpeg($im, "$c.jpg", 70);

function fname($c,$i,$j) {
 global $dir;
 return "{$dir}c{$c}_l0_{$i}_{$j}.jpg";


Restored cube faces

Restored panorama 

Sep 13, 2013

Embedding flash in Facebook link posts

If you want to have custom flash movies embeded in Facebook posts that link to your website, like these one from YouTube or SoundCloud:


It's fairly simple. 
BUT, it requires a SSL certificate, so that your website works over HTTPS, without browsers whining about security.

Here's what you do.
You've heard of OpenGraph protocol, right? Right. So, that's all there is to it. Proper metadata in the HTML of your website will instruct Facebook to include your flash movie, like this:
<meta property="og:title" content="Aljažev stolp | Triglav (2864m) | VR panorama"/>
<meta property="og:video" content=""/> 
<meta property="og:type" content="movie"/>
<meta property="og:url" content=""/>
<meta property="og:image" content=""/>
<meta property="og:description" content="VR (virtual reality) panorama pri Aljaževem stolpu na vrhu Triglava. Panorama je posneta brez stativa."/>
<meta property="og:video:type" content="application/x-shockwave-flash" />
<meta property="og:video:width" content="400" />
<meta property="og:video:height" content="300" />

The next part depends on what the flash movie actually does. If it's a movie/music player that fetches media from other sources, or even an other part of your website, you'll need to configure crossdomain.xml. You put that file on the root of your website.

Here's a very liberal example, but fine for testing:
<?xml version="1.0" ?>
<allow-access-from domain="*" />

Jul 31, 2013

Garmin Nüvi map files

Here are the Garmin NUVI Map File Naming Conventions:

  • gmapprom.img - primary mapset, factory installed USA or Europe or other country.
  • gmapprom1.img - secondary mapset, example: North American / European units
  • gmapsupp.img - supplemental mapset, located on the Nuvi drive
  • gmapsupp.img - supplemental mapset, located on the SD card
  • gmapoem.img -  OEM mapset, user accessible, cannot be unselected from the unit via Tools/Settings/Map/Map Info
    *Note, when using the following default system maps as user maps, you'll naturally lose their default map attributes.
  • gmapbmap.img - default basemap, configurable as a supplemental map; NOT selectable and does NOT show up under installed maps (Tools/Settings/Map/Map Info) but may be visible under Tools/Settings/System/About/Basemap
  • gmaptz.img - Timezone map, configurable as a supplemental map
  • gmap3d.img - 3D Buildings map, configurable as a supplemental map
  • gmap3d1.img - secondary 3D Buildings map, configurable as a supplemental map
Now, if you're wondering which files to delete from your Nuvi drive or SD card to clear up some space, this should provide some insight.

You can easily remove/replace the primary, secondary or supplemental mapset, however you should keep the timezone map. Basemap can be deleted, however it's only around 50 MB in size.

With an SD card in the Nuvi you can fit around 4 custom maps, with the following naming conventions: gmapprom.img, gmapsupp.img. You can even use gmapbmap.img, but note that it will not be selectable from the settings.

Maps on the SD card are located in the folder Garmin.
Maps on the Nuvi drive are located in the .System folder (with a dot) or in the Map folder.

If you can't see the .System folder, you might need to change the USB mode on the Nuvi from MTP to mass storage.

You can get free maps for Garmin from OpenStreetMaps:

or from Open MTB maps (Mountanbike and Hiking):

Garmin Nüvi connected as media device - disable MTP, enable mass storage

What is MTP mode and which automotive devices use it?

Some automotive devices use Media Transfer Protocol (MTP) for connecting to your computer. MTP provides a more secure environment for the important system files on your device.
MTP connectivity requires the following:
  • Windows XP with service pack 3 or later
  • Windows Media Player 11 or later
The following devices use MTP  mode:
  • dezl 760
  • nuvi 2405 series
  • nuvi 2407 series
  • nuvi 2408 series
  • nuvi 2505 series
  • nuvi 2507 series
  • nuvi 2508 series
  • nuvi 2707 series
  • nuvi 2708 series
  • nuvi 3400 series
  • nuvi 3500 series
  • nuvi 3507 series
  • nuvi 3508 series
  • RV 760
  • zumo 350
If the above system requirements are not met, or you are using the device on a Mac, the device will connect to the computer using standard mass storage mode instead of MTP mode.
Make NUVI DIR & Files visible for Backup

1. To make all of Nuvi files visible you must unhide protected files via Win7 like any other HD.
2. Start NUVI by itself and go to Volume Screen.
3. Press the upper right hand corner of screen for 10 seconds.
4. The Developers Screen will pop up
5. Scroll down to MTP SETTINGS
7. Shut down NUVI and hookup to Computer USB cable
8. Start NUVI and it should recognize it is hooked up to the computer.
9. Explorer will now see all files in ROOT directory and the .System directories.

BTW, have you backed up your Nuvi? If not, then this would be a good time to do it. Could save a lot of grief later if you have a problem.

Apr 17, 2013

wp-admin: You do not have sufficient permissions to access this page

When migrating a Wordpress instalation some things could go wrong.

If you changed the table prefix, you might be getting this error when logging in the wordpress admin:

You do not have sufficient permissions to access this page

Open phpmyadmin or something like that and go through the values in tables:

find values that start with the old prefix, for example wp_ and change it to the new prefix.

wp_usermeta I changed all meta_key values from wp_* to newprefix_*
and in
wp_options I changed wp_user_roles to newprefix_user_roles.

Mar 30, 2013

siwapp :: File does not exists error

We tested siwapp application, which is an opensource invoicing application, but we had some problems, the error log was full of these:

[Sat Mar 30 17:32:55 2013] [error] [client xx.xx.xx.xx] File does not exist: /home/invoice/web/invoices

The site seemed to work fine otherwise.

It seemed that there was a problem with the app's .htaccess.

The main problem was here:
RewriteCond %{REQUEST_URI} \..+$
which matches all files with a dot in the filename, but the rule was ment to match files that start with a dot.

The fix for this is:
RewriteCond %{REQUEST_URI} /\..+$

After that fix, the app created errors because of a request for favicon.ico.
Well, the fix for that is simple enough
RewriteRule .+/favicon.ico$ favicon.ico [L]

So the whole .htaccess looks like this:
Options +FollowSymLinks +ExecCGI -MultiViews

AddDefaultCharset utf-8 

    Order deny,allow
    Deny  from all

    Order deny,allow
    Deny  from all

  RewriteEngine On

  # Rule to test if rewrite module is available during
  # the install process
  RewriteRule test_rewrite1\.txt test_rewrite2.txt
  RewriteRule .+/favicon.ico$ favicon.ico [L]

  # uncomment the following line, if you are having trouble
  # getting no_script_name to work
  #RewriteBase /

  # we skip all files with .something
  RewriteCond %{REQUEST_URI} /\..+$
  RewriteCond %{REQUEST_URI} !\.html$
  RewriteRule .* - [L]

  # we check if the .html version is here (caching)
  RewriteRule ^$ index.html [QSA]
  RewriteRule ^([^.]+)$ $1.html [QSA]

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f

  # no, so we redirect to our front web controller
  RewriteRule (.*) index.php [L,QSA]