Joomla 1.5 quirk in [20151206] – Core – Session Hardening patch

The Joomla 1.5 (EOL) patch to the session.php file has a quirk in it that raises a warning notice. The advisory is

[20151206] – Core – Session Hardening

but if you blindly copy that file to your system then you will end up with a web site that raises many error messages,

Notice: Only variable references should be returned by reference in /libraries/joomla/session/session.php on line 343

I thought there would be a fix for this but when I googled for that message I found thousands of hits to broken Joomla web sites. Yes, hundreds of web sites are busted in that they have lots of error messages ! The fix I have done is easy, edit the NEW session.php file you have downloaded and edit this as follows to pass a variable back,

--- /home/admin/Downloads/JOOMLASESSEIONHARDENFIX/sessionNEWSESSIONHARDEN.php
 +++ /home/admin/Downloads/JOOMLASESSEIONHARDENFIX/sessionNEWBORKEDEDITED.php
 @@ -339,8 +339,13 @@
 $error = null;
 return $error;
 }
 -
 - return $this->data->getValue($namespace . '.' . $name, $default);
 +
 +// removed this next line as it generates a Notice: Only variable references should be returned by reference error
 +// return $this->data->getValue($namespace . '.' . $name, $default);
 +// and define a variable with the data to be returned....
 +
 + $getnamespacenamedata = $this->data->getValue($namespace . '.' . $name, $default);
 + return $getnamespacenamedata;
 }

/**

If you don’t know what to do with this change to get rid of that error message then you are going to have to find someone who has some PHP/Joomla experience to edit the files for you.

tentacle server not logging agent data after Pandora FMS upgrade

If you are using the password option for the tentacle protocol then you must also add the password to the TENTACLE_EXT_OPTS in the /etc/init.d/tentacle_serverd  file e.g.

TENTACLE_EXT_OPTS=”-x YOURAGENTPASSWORD  …

If you do not do this then if you are using the agent password option then no agent data will be logged.

This is not a very secure way of data logging.

 

 

Pandora FMS 4.0 to 5.0 upgrade quirks.

This was a painless upgrade but I found two quirks,

1) when you edit your config.php then you must set the chmod permissions to 600. If you try 400 then the Pandora Console still thinks that the file is readable by others. Obviously a bug but nothing to worry about. Note that to edit the ./include/config.php you must copy the new version 5 ./include/config.inc.php to ./include/config.php and then edit that new config.php and copy and paste in your custom settings from your old version 4 config.php file.

2) The ./extras/pandoradb_migrate_4.0.x_to_5.0.mysql.sql  (and actually any of those migration files) is missing a schema change to the tagente_estado table. It has,

ALTER TABLE `tagente_estado` ADD COLUMN `last_known_status` tinyint(4) NOT NULL DEFAULT 0;

but ALSO needs to have,

ALTER TABLE `tagente_estado` ADD COLUMN `last_error` tinyint(4) NOT NULL DEFAULT 0;

else the pandora_server won’t start.

vTiger with PHP 5.4 ( session_unregister function removed)

With PHP 5.4 onwards the session_unregister function is removed. This means that you will get a “Fatal error: Call to undefined function session_unregister()”

vTiger 5.4 (the version number is just happen stance and has no relation to the PHP version number) code needs the following cludge to get around this. In /modules/Users/Authenticate.php around about line 69 then do the following change,

//Security related entries end
// TODO: session_unregister was removed in php 5.4.0 so must remove this backwards compatibility switch.
if (function_exists('session_unregister')) {
    session_unregister('login_password');
    session_unregister('login_error');
    session_unregister('login_user_name');
} else {
    unset($_SESSION['login_password']);
    unset($_SESSION['login_error']);
    unset($_SESSION['login_user_name']);
}

Kohana 2.3 (used by blue.box) and PHP 5.4

If you are using Blue.box to configure your FreeSWITCH softswitch then blue.box uses Kohana 2.3 and this has a quirk with PHP 5.4 which means that you will end up with a blank page (even after a clean git pull) plus a spurious array to string conversion error.

For the BLANK screen issue then the fix is,

See https://gist.github.com/kemo/2881489 for a working fix. Note that that patch isn’t exactly lined up on the line numbers – my git diff is,

diff --git a/system/core/Kohana.php b/system/core/Kohana.php
index 56b44af..ee6c832 100644
--- a/system/core/Kohana.php
+++ b/system/core/Kohana.php
@@ -677,7 +677,7 @@ final class Kohana {
                if (ob_get_level() >= self::$buffer_level)
                {
                        // Set the close function
-                       $close = ($flush === TRUE) ? 'ob_end_flush' : 'ob_end_c
+$close = ($flush === TRUE) ? 'ob_end_flush' : 'Kohana::_ob_end_clean';

                        while (ob_get_level() > self::$buffer_level)
                        {
@@ -686,7 +686,7 @@ final class Kohana {
                        }

                        // This will flush the Kohana buffer, which sets self::
-                       ob_end_clean();
+Kohana::_ob_end_clean();

                        // Reset the buffer level
                        self::$buffer_level = ob_get_level();
@@ -1604,6 +1604,30 @@ final class Kohana {

                return $written;
        }
+ /**
+ * Ends the current output buffer with callback in mind
+ * PHP doesn't pass the output to the callback defined in ob_start() since 5.4
+ *
+ * @param callback $callback
+ * @return boolean
+ */
+ protected static function _ob_end_clean($callback = NULL)
+ {
+ // Pre-5.4 ob_end_clean() will pass the buffer to the callback anyways
+ if (version_compare(PHP_VERSION, '5.4', '<'))
+ return ob_end_clean();
+
+ $output = ob_get_contents();
+
+ if ($callback === NULL)
+ {
+ $callback = arr::get(ob_list_handlers(), ob_get_level() - 1);
+ }
+
+ return is_callable($callback)
+ ? ob_end_clean() AND call_user_func($callback, $output)
+ : ob_end_clean();
+ }

 } // End Kohana

For the array to string conversion error you see the sort of useful orange trace back Kohana error page and this,

An error was detected which prevented the loading of this page. If this problem persists, please contact the website administrator.

bluebox/libraries/doctrine/lib/Doctrine/Query/Abstract.php [1103]:

Array to string conversion

To fix this you need to do changes to Abstract.php and Lib.php which is basically making a new function arrayDiffSimple and then adding that new function to the Lib.php.

diff --git a/bluebox/libraries/doctrine/lib/Doctrine/Lib.php b/bluebox/libraries
index 26c796d..d6b5c94 100644
--- a/bluebox/libraries/doctrine/lib/Doctrine/Lib.php
+++ b/bluebox/libraries/doctrine/lib/Doctrine/Lib.php
@@ -268,6 +268,45 @@ class Doctrine_Lib
         }
     }

+
+    // Code from symfony sfToolkit class. See LICENSE
+    // code from cto at verylastroom dot com
+    /**
+     * arrayDiffSimple
+     *
+     * array arrayDiffSimple ( array array1 , array array2 )
+     *
+     * Like array_diff
+     *
+     * arrayDiffSimple() has exactly the same behavior than array_diff, but can
+     * only 2 arrays. PHP versions > 5.4.0 generate some NOTICE if you use arra
+     * sometimes because of array_diff internal behavior with (string) casts.
+     * This method solves the problem.
+     *
+     * @param array $array1
+     * @param array $array2
+     * @static
+     * @access public
+     * @return array
+     */
+    public static function arrayDiffSimple($array1, $array2)
+    {
+        $diff = array();
+
+        foreach($array1 as $key => $val) {
+            if(!isset($array2[$key])) {
+                $diff[$key] = $val;
+            } else {
+                if(is_array($array2[$key]) && !is_array($val)) {
+                    $diff[$key] = $val;
+                }
+            }
+        }
+
+        return $diff;
+    }
+
+
     /**
      * Makes the directories for a path recursively.
      *
diff --git a/bluebox/libraries/doctrine/lib/Doctrine/Query/Abstract.php b/bluebo
index 981603d..6bc2820 100644
--- a/bluebox/libraries/doctrine/lib/Doctrine/Query/Abstract.php
+++ b/bluebox/libraries/doctrine/lib/Doctrine/Query/Abstract.php
@@ -1098,9 +1098,9 @@ abstract class Doctrine_Query_Abstract
         $componentsAfter = $copy->getQueryComponents();

         $this->_rootAlias = $copy->getRootAlias();
-       
+
         if ($componentsBefore !== $componentsAfter) {
-            return array_diff($componentsAfter, $componentsBefore);
+               return Doctrine_Lib::arrayDiffSimple($componentsAfter, $componen
         } else {
             return $componentsAfter;
         }
@@ -2070,4 +2070,4 @@ abstract class Doctrine_Query_Abstract
     {
         return $this->getDql();
     }
-}
\ No newline at end of file
+}

Mailfilter fails to POP timestamp in message-ID invalid

Mailfilter POP timestamp in message-ID invalid and potentially also causes mailfilter to stall at 100% CPU.

I have a fetchmail daemon that call mailfilter as a postconnect (defined in the .fetchmailrc file). I got the following error message,
mailfilter: Examining 297 message(s).

mailfilter: Error: POP timestamp in message-ID invalid.
mailfilter: Error: Parsing the header of message 292 failed.
mailfilter: Error: Scanning of mail account failed.
mailfilter: Error: Skipping account xxxxxx@example.com@mail.example.com due to earlier errors.

and I noticed that the mailfilter process was running at 100% CPU though that may be unrelated.

I found that mailfilter 0.8.3 has a new option of -i to ignore POP timestamp. This is probably what I want to make this more stable.

As I’m adding this to a Parallels based server it is unlikely to have this version of mailfilter as this package has very little development activity as it is a stable application so I had to build from source.

My server didn’t have svn so I browsed the Sourceforge svn for mailfilter on my local PC and at the bottom there is a linkfor “Download GNU tarball” I copied that link and then pasted into my console and used wget to get this latest tarball from Sourceforge. It has a odd name so moved that to a tar.gz file name e.g. mv index.html\?view\=tar mailfilter.0.8.3.tar.gz and then ran tar xvfz mailfilter.0.8.3.tar.gz

Perquisite packages for building,

  • g++
  • bison
  • flex
  • libssl-dev

There may be more but that is the ones I needed to add to my server.

Making this you cd to the mailfilter directory and then run

./autogen.sh
make
sudo make install

If that works then this’ll probably install the mailfilter to /usr/local/bin/mailfilter so now in the .fetchmailrc change the postconnect line to have,

postconnect ''/usr/local/bin/mailfilter -i ''

use double quotes if you pass the new -i option to ignore timestamps. The -i is a new feature in Mailfilter 0.8.3 (not in 0.8.2).

Killall the mailfilter and fetchmail and then re-launch your fetchmail daemon.

Errors

Missing g++

If you see,

checking whether the C++ compiler works... no
configure: error: in `/root/sources/mailfilter':
configure: error: C++ compiler cannot create executables
See `config.log' for more details.

Then check the log file and look for g++ line e.g.

configure:2879: checking for g++
configure:2909: result: no

Do a g++ and if it comes back with -bash: g++: command not found then install the g++ package and then it will work. Re-run the ./autogen.sh and then make

Missing bison

If you get the make fail and you can see /bin/sh: yacc: command not found then you need a YACC of some kind. I installed bison re-run the ./autogen.sh and then make

Missing flex

If you get an error in the make e.g. it crashes out with g++: rcfile.cc: No such file or directory

g++: no input files
make[2]: *** [rcfile.o] Error 1

then check back and see if you see error: FlexLexer.h: No such file or directory . If so then check flex is installed. Install and then re-run ./autogen.sh and then make

Missing openssl header files
If you see openssl/ssl.h: No such file or directory and similar openssl/rand.h: No such file or directory then you need to install libssl-dev. Install that package and then re-run ./autogen.sh and then make.

After a month and a few weeks of use it has been stable. The erroneous timestamps are also suspected to stall Outlook 2003. I pick up emails in parallel to my customer to provide emergency support when they are on holiday. As Microsoft support for both XP and Office 2003 is finishing in April 2014 I plan to migrate the customer to a newer OS and Office version.

WordPress HTML markup breaks plugin shortcodes

I was extending a WordPress plugin (I don’t think the actual plugin matters but it was the very useful posts-in-page plugin). It has a loop (posts_loop_template.php) that displays the posts on a page. We need this for a web shop.

On the page I had the plugin shortcode, [ic_add_posts thumbnail=’thumbnail’ showposts=’5′ postlink=’1′ layout=’0′ metacats=’0′ metacomments=’0′] as shown and in bold (for no particular reason).

I noticed that my code changes had stopped working.  An hour or so ago they had worked but after adding some of the new options they stopped working. I removed the plugin and added it back (it started working) and then I added back my edits and managed to trigger the problem again. This time I had more data and it was obvious what had gone wrong. When I added in the shortcode options then when you look at the “Text” version I saw that the new option had html markup around it,

<strong><strong>[ic_add_posts thumbnail='thumbnail' showposts='5' postlink='1' 
layout='0' metacats='0' <strong>metacomments='0'</strong>]</strong>
 </strong>

This caused the option arguments to be parsed wrong by WordPress – or perhaps correctly but it wasn’t what I wanted. The options array ended up like this and you can see the “metacomments” option was not parsed but is in the array as [0] => metacomments=’0′ and not [metacomments] => 0

Array ( [post_type] => post [post_status] => publish [orderby] => date 
[order] => DESC [template] => [posts_per_page] => 5 [thumbnail] => thumbnail 
[showposts] => 5 [postlink] => 1 [layout] => 0 
[metacats] => 0 [0] => metacomments='0' [post__not_in] => Array ( ) ) 

When I removed the html formatting from around the plugin shortcode then it worked perfectly. As a guess WordPress should strip tags but that may have backward compatibility issues.

Broken PHP filter_var() hiccups ResourceSpace install on some URL

Was installing the very interesting ResourceSpace package for a client and the client domain names use “-” in the domain part. They also have the non-dashed version too which redirects to the dashed version. There is nothing wrong with having dashes in the host section of a URL as long as it is not the first character.

The install broke because of the dash and the problem is that the PHP filter_var() function is fine with an underscore in the domain name but not a dash thus filter_var(“http://www.bad_example.com”, FILTER_VALIDATE_URL)) will be true even though it’s an invalid domain name but filter_var(“http://www.good-example.com”, FILTER_VALIDATE_URL)) will be false even though it is valid.

There is not really much to do here other than upgrade PHP to the precise version that fixes this and on my development server I am at 5.3.2 but that’s not working and I’m not going to deviate from the Parallels packages for this. Also if you are on shared hosting you are not going to easily demand the hosting company fix this one bug.

So you are going to have to go into the install script and comment out the filter_url() code or alter the user provided URL to swap the “-” to a character that is always valid and swap the “_” to a character that is always invalid no matter if the filter_url() is good or bad.

So I created a “testbaseurl” from the “baseurl” and tested that rather than the original,

$testbaseurl = str_replace(parse_url($baseurl,PHP_URL_HOST), 
               str_replace(array("_", "-"), array("^", "x"), 
               parse_url($baseurl,PHP_URL_HOST) ), $baseurl  );

which you use instead of $baseurl thus in the ResourceSpace example in /pages/setup.php at about line 510 onwards set the file to,

        //Check baseurl (required)
        $baseurl = sslash(get_post('baseurl'));
        //filter_var() is broken in certain PHP versions as it doesn't permit dashes in host but does 
        //permit underscore. Swap these to always legal or illegal characters. Don't use testbaseurl other
        // than with filter_var()
        $testbaseurl = str_replace(parse_url($baseurl,PHP_URL_HOST), 
               str_replace(array("_", "-"), array("^", "x"), 
               parse_url($baseurl,PHP_URL_HOST) ), $baseurl  );
        if ((isset($baseurl)) && ($baseurl!='') && ($baseurl!='http://my.site/resourcespace') && (filter_var($testbaseurl, FILTER_VALIDATE_URL))){
            //Check that the base url seems correct by attempting to fetch the license file
            if (url_exists($baseurl.'/license.txt')){
            $config_output .= "# Base URL of the installation\r\n";
            $config_output .= "\$baseurl = '$baseurl';\r\n\r\n";
            }
            else { //Under certain circumstances this test may fail, but the URL is still correct, so warn the user.
                $warnings['baseurlverify']= true;
            }
        }
        else {
            $errors['baseurl'] = true;
        }

 

 

Ubuntu 10.10 package download of large files can fail with OverflowError: signed integer is less than minimum

I was doing a distribution upgrade on a 10.10 system to 11.04 via do-release-upgrade. The system has games installed, so the total files to download are over 2.5 Gigabytes e.g. games like Nexuiz has a data file that is about 273 Megabytes. The Internet access is low speed broadband (about 70 KBytes per second download maximum) with other machines using this ADSL line so that’s about 10 hours for the whole release.

The  do-release-upgrade downloads can fail on these larger files on congested lines at and if you look at the log file, i.e. tail /var/log/dist-upgrade/main.log ,  it will say something like,

  File "/tmp/update-manager-HXahEI/DistUpgradeViewText.py", line 42, in pulse
    apt.progress.text.AcquireProgress.pulse(self, owner)

  File "/usr/lib/python2.6/dist-packages/apt/progress/text.py", line 164, in pulse
    apt_pkg.time_to_str(eta))

OverflowError: signed integer is less than minimum

If you look at that code in /usr/lib/python2.6/dist-packages/apt/progress/text.py (it’s Python) around line 161 onwards and think about what can happen on …

            eta = int(float(self.total_bytes - self.current_bytes) /
                      self.current_cps)

There are a number of issues here with this. That eta value isn’t checked before it is passed to the apt_pkg.time_to_str() and that’s not good because,

1) I think the self.current_cps can be a float less than 1 and as the size of an int on this system (64bit Athlon with Python 2.6.6 ) is,

>>> import sys
>>> print sys.maxint
9223372036854775807

then the eta could be quite large e.g. if that maximum value was seconds and converted to years would be just under 300 billion years.

2) But the actual error is “signed integer is less than minimum” not an overflow of a maximum so this bug seems to be about some magic number. Now if you enter in the python program,

>>> import apt_pkg
>>> print apt_pkg.time_to_str(-1)
213503982334601d 7h 0min 15s

and if you enter in other odd numbers then you can trigger the “signed integer is less than minimum” e.g. see these examples,

>>> apt_pkg.TimeToStr(-2147483648)
'213503982309746d 3h 46min 8s'
>>> apt_pkg.TimeToStr(-2147483649)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: signed integer is less than minimum

so it clearly can have values over 24855 days i.e. apt_pkg.time_to_str(2147483647) so looks like there are some odd boundaries that cause OverflowError: signed integer is less than minimum as well as a OverflowError: signed integer is greater than maximum. I ran a loop that incremented an integer by 1 and gave up and Control-C it when it went through 836477585 which is 9681d 10h 53min 5s so if there are any boundary conditions it’s not obvious. I suspect that the garbage is with what is fed to the TimeToStr() and not a flaw in TimeToStr(). I suspect that if the download process resets itself then the file size self.total_bytes is temporarily nonsensical e.g. 0 whilst the program resets the download.

So that code section needs sanity limits on the eta because looks like we can’t trust any of self.current_cps to be reasonable or self.total_bytes to be accurate but I think self.current_bytes may always be fine, e.g. I changed line 164 end =… to have some range checking,

            if eta < 0:
                end = " %sB/s ~%s" % (apt_pkg.size_to_str(self.current_cps),apt_pkg.time_to_str(0))
            elif eta > (30 * 24 *60 * 60):
                end = " %sB/s >%s" % (apt_pkg.size_to_str(self.current_cps),apt_pkg.time_to_str(30 * 24 *60 * 60))
            else:
                end = " %sB/s %s" % (apt_pkg.size_to_str(self.current_cps),
                                 apt_pkg.time_to_str(eta))

where the 30*24*60*60 means 30 days but there are other ways of doing this e.g. check  self.total_bytes is greater or equal to self.current_bytes or limit eta to a range and then keep existing calculation.

Once you edit that file you can simply restart the do-release-upgrade console and it will use your new code on the fly.

The bug is in other distributions e.g. see this bug report https://bugs.launchpad.net/ubuntu/+source/update-manager/+bug/884625 but not fixed. The problem is that the apt_pkg.time_to_str(), which is actually apt_pkg.TimeToStr() is probably being passed nonsensical values for self.total_bytes due to file downloads being reset for large and/or poor circuits. The apt_pkg.TimeToStr() should also reasonably handle negative times and not display nonsense but that’s another problem.

Adding WP 3.0 custom menus to older templates

For our LifeSignPress.com web site we have used a nice template by cssmayo.com called Creative by Nature.

Recently we wanted to add a link in the navigation menus so we opened up the Custom Menus for the site and then saw that it did not support the new WordPress 3.0 custom menus.

All is not lost – it is easy to add in the same functionality to this older template without doing many changes and with no CSS style changes.

Here is how I changed the Creative By Nature v0.1 template to use the WordPress 3.0 custom menus,

1) Open your site and select the menu in a browser and then right-mouse and view selection text. Print this out. This is to just get an idea on the div, ul, il, a and spans that are used.

The template we’re using had a div wrapper that was an id of “navigation” and then a ul and then all the a hrefs but the link text was in a span. Now this navigation ID and the span is important as you need to mimic this in the new WordPress 3.0 custom menu unless you plan on changing the CSS style sheet.

2) Firstly find where the navigation menu is located. It will probably be in your template in a file called header.php or a similar name and now find where the menu is generated. It will be a function that is echoed or something similar e.g. we had,

<div id="navigation">
 <ul> 
 <?php echo _generate_navigation(); ?> 
 </ul>
</div>

The “_generate_navigation” is in the theme’s functions.php file. The menu generation will be between these two files i.e. your theme layout code file and your theme functions code file.

3) Now comment or remove the old code that generated the navigation menu and add in your replacement as below, setting the container_id to be the same as the div ID and if needed also wrapping the link text in a <span></span> by setting the link_before and link_after variables e.g.,

<?php wp_nav_menu(array('menu' => 'header_menu',
 'container_id' => 'navigation', 
 'link_before' => '<span>',
 'link_after' => '</span>' )); ?>

In our example that mimics the html that is generated for the same CSS to be used thus no need to change the CSS stylesheet for the theme. For the defaults for this wp_nav_menu() function see here – http://codex.wordpress.org/Function_Reference/wp_nav_menu

4) In the functions.php file for this template you will have to add the following code,

add_action('init', 'register_custom_menu');

function register_custom_menu() {
register_nav_menu('header_menu', __('Header Menu'));
}

You can add as many menus as you like though you would use register_nav_menus() e.g.

...
register_nav_menus( array( 'header_menu' => 'Header Menu', 
 'footer_menu' => 'Footer Menu'));
...

and you can edit out the old _generate_navigation() function if you want. Note that if you want to keep both < 3.0 navigation menus and 3.0 custom menu features at the same time then keep everything and in the header file or in the functions.php you could add a test e.g. if ( function_exists( ‘wp_nav_menu’ ) ) and then use the new 3.0 menus or else use the theme’s old code if that function_exists() returns false.

SLIB 1.8 build problem with GNUCASH

The Ubuntu repository for software lags the new versions for programs. This is a good thing because it would be a nightmare if it was updated for every nightly build for the  tens of thousands of packages !

But sometimes you want the latest version of an application and I wanted the latest version of GNUCash so I wanted to build from source.

I got some odd GUILE issues which are easily fixed as below for an Ubuntu 10.10 platform.

Assuming you have all your other GNUCash make dependencies correct you will probably still get a configure failure with the error,

checking for guile - 1.6.7 <= version < 99.99.99... yes: 1.8.7
checking for guile - 1.8.0 <= version < 99.99.99... yes: 1.8.7
checking for SLIB support... configure: error: 

Cannot find SLIB.  Are you sure you have it installed?
See http://bugzilla.gnome.org/show_bug.cgi?id=347922
and http://bugzilla.gnome.org/show_bug.cgi?id=483631

…because there is no Guile 1.8-slib package (there is a 1.6 package). The package does two things,

1) Adds a soft link in the Guile 1.X to SLIB

cd  /usr/share/guile/1.8/
 sudo ln -s ../../slib slib

2) Builds a slibcat file which can be done with this command,

sudo guile -c "(use-modules (ice-9 slib)) (require 'printf)"

Thus do those two steps and you’ll fix this SLIB issue and can proceed with your make.

Note that after building GNUCash you will probably get the error,

gnucash: error while loading shared libraries: libgnc-qof.so.1: cannot open  shared object file: No such file or directory

…which is because the ldconfig cache is not updated.
You must run,

sudo ldconfig -v

after you have done the make install to fix this issue.

Patching Pandora FMS

Sometimes you need to patch the Pandora FMS. To do this download the patch file (it’ll come from Sourceforge).

Untar it in a suitable location e.g.

cd sources
wget <the patchfile URL>
tar xvfz pandora_console_3.2.1_March_Patch.tar.gz
cp -i -R pandora_console/* /path/to/httpdocs/pandora_console/

and then confirm each change if it makes sense. Repeat for the pandora_server though that is at a different location e.g.,

cp -i -R  pandora_server/* /usr/share/pandora_server/

The console changes will have an effect immediately as that is just PHP scripts but the server needs to have the following,

/etc/init.d/pandora_server restart