Friday, January 29, 2010

Barking Dogs and Irresponsible Neighbors

For the past several years, I have had to listen to two dogs barking next door. I've asked their owner several times to take responsibility for the dogs and prevent the barking. Until today, I haven't been pushed to the point where I was motivated to file a report with animal control. I have tried shushing the dogs, but of course that doesn't work. I have tried making them uncomfortable with one of those ultrasonic things, but those are a big joke because they only work sometimes, with really small dogs, that have ultra-sensitive ears, and are no more than two feet away from the device. (So if you were thinking those things might help you in a similar scenario, forget it. They're junk.)

This week I decided a water sprinkler spraying a mist of water might train the dogs not to bark on my side of the irresponsible neighbor's house. Instead, the dogs just played in the water and kept on barking. However, the presence of the sprinkler caught the attention of the owner. This is someone who cares so little for her pets that she leaves them outside all day, every day, to bark and beg for attention from anyone who walks by. She has never, to my knowledge, bothered to walk the dogs, and there is a growing, stinking collection of dog poop in the corner of the yard that she has not bothered to clean up for months. But when she noticed that her dogs were being discouraged from barking by water mist from a sprinkler, which isn't even a fraction of the discomfort imposed by the rain, snow, and even hail storms that have pummeled her dogs, because she leaves them outside all day, every day, then she suddenly has cause to care about how her dogs are being treated. I reminded her that if she had obeyed the law and responded to the complaint to keep the dogs from barking all day, I would have no reason to even try to discourage the barking. Water mist from a sprinkler was the only thing I thought might encourage the dogs to choose the other side of the house for their barking. Again, they just played in the water, so it didn't help anyway.

But when the irresponsible dog owner saw the sprinkler, she decided to march over into my yard and start threatening to report me for all kinds of things that aren't actually a violation of any kind of law, except in her imagination. I told her she could take responsibility for the dogs, prevent them from barking all day long every day, and clean up after them or I would file a report to compel her to control her dogs' barking. Allowing your dogs to bark actually is a violation of the local disturbing-the-peace laws. And I suggested that if she chose not to clean up after the dogs, I'd have cause to ask animal control to come and decide whether they thought her mistreatment of the dogs was criminally abusive. I actually don't know what the criteria are for that, but if it were up to my opinion on the matter, the dogs would be given a new home with someone who wouldn't just leave them outside in rain and snow.

The argument went on with some more screaming about whether she needed to take responsibility for the dogs, or I just needed to put up with it. Then she screamed a threat at me that I just will not tolerate. She threatened to file a report with children's services claiming that she had reason to believe I was abusing my children. Obviously this was her infantile response to being confronted about her responsibility to care for and control her pets, but with all the stories about children's services agencies acting first and investigating later, I can't allow this to dispute to go unrecorded. If only she'd threatened to do bodily harm. That would solve the problem of the dogs and the irresponsible owner since they'd both be taken away. However, the consequence of what she did threaten could be much harder to deal with, so that was the shove I needed to get motivated about filing the report to complain about the dogs.

So, I called a neighbor, who is a detective in a nearby jurisdiction and he suggested that, if it were possible, I should file some kind of "calm civil dispute" report so that there is a record of the incident, if the irresponsible dog owner were to follow through on the threat, for which she has no basis, by the way, because there _is_ no basis. Unfortunately, I was told by the sheriff's deputy, there is no such report to be filed in our jurisdiction, so I couldn't provide any context to the authorities to put her threats in the proper perspective. Our kids are well fed, loved, well clothed, receive individualized education, are immunized against every known microbe on a government prescribed schedule, and have a much larger percentage of the toys they've asked for than I did when I was a kid. None of that even gets within long range radar of what anyone could call abuse. Yet I have to consider the real threat that someone who does not know me would file a report and it's very likely I'd be considered guilty until proven innocent.

The irresponsible dog owner neighbor still refused to take any responsibility for the dogs barking. Her words were "So what? They're dogs. They bark." I have the complaint form filled out and ready to submit to county animal control. She could have chosen to take care of the dogs and obey the law that prohibits their incessant barking, but instead she chose to threaten me. This blog post may not be read by anyone, but it will be published and public today so that if I have to produce a record of how this dispute started, I can just point to this.

If you have had similar problems with your neighbor (regarding dogs or threats), and have found clever ways to handle it, please post a reply. Or, if you have dogs and your attitude is that they should be allowed to do whatever they want, no matter if it disturbs your neighbor, please post a very long reply, that takes you a few hours to write, so I can then delete what you write, because you're wrong. A dog owner is always primarily responsible for the actions of their pet.

Friday, January 22, 2010

VMWare Server Console 2.0

I just upgraded VMWare server to version 2.0.2 on a Linux machine. THEN I realized that the friendly folks at VMWare had taken most of what I knew about connecting to a virtual machine via the VMWare console and tossed it out in the waste bin.

The first clue was when the old VMWare console application, the one you used to be able to install in the normal way you install other windows apps, wouldn't let me connect any more. What exactly is "501 Global command GLOBAL server to non-host agent targets not supported" supposed to mean to me anyway? Well? VMWare? Are you trying to be as obtuse with your error messages as your buddies in Redmond? If so, then mission accomplished!!

So I relented, and read enough of the manual to realize that the whole remote console in VMWare server is now rewritten as some kind of web-browser based monster. I knew that I had set values for the http and https ports, 8222 and 8333 respectively, when I ran the vmware-configure script. I also knew that I would need to allow inbound access to those ports in the Linux firewall (iptables) configuration, so I had already added:
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8222 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8333 -j ACCEPT
What I didn't know is that using the web-browser based VMWare console is the only way in v2.0, at least initially, to access the virtual machine guests.

Getting the web-browser based VMWare console application to show me the console was a little frustrating. VMWare still has something to fix on this part of it, but until they do, if you get a blank page on the https:/myvmwareserverbox:8333/ui page:
1. Accept the SSL certificate
2. Reload/refresh the page (ctrl + F5) over and over until the login prompt finally shows up.

But wait, there's more!!!
Not only do you have to throw the Ginsu knives up in the air several times before they stick in your meatloaf, you have to pull out the nonstick pan instead of cooking on a diamond ring. Ok, it has nothing to do with mid-80s "as seen on TV" cookware, but it's about that goofy.

You need to install a browser add-on to see the desktop of any virtual machine guests. Before you're given the opportunity to install the browser add-on, you have to start one of the virtual machine guests by selecting it from the inventory list and clicking the "play" button, and then switch to its console tab. THEN you're offered the chance to install the browser add-on. At this point I was getting worried that all access to my virtual machine guests would be trapped inside a web browser window/tab. However, as it turns out, the browser add-on is actually the core client binary executable application portion of the old vmware console app.

The documentation detailing how to use this client binary outside of a browser has a few holes in it. This blog post is my feeble attempt to fill a few of those holes.

1. Finding the path to the executable.
Since the VMWare console client is installed as a browser add-on, it will most likely be buried somewhere deep in the OS user's browser profile directory. This varies depending on which browser and which OS, but with a VM guest (named MyVmGuest for instance) selected in the Inventory panel of the web-browser based VMWare console app, in the "Command" panel of the "Summary" tab, there should be a link labeled "Generate Virtual Machine Shortcut." Clicking that link pops up a box that has a link labeled "Install Desktop Shortcut to MyVmGuest" Click that, answer the prompts, and then examine the target of the shortcut it creates. On a windows machine using Firefox, it's probably something ugly like:
That vmware-vmrc.exe IS the new console client binary!!!

2. Understanding the parameters.
I didn't look all that thoroughly in the documentation but most of what I found on VMWare's site, or elsewhere, about the parameters to vmware-vmrc.exe was in discussion thread form and required a bit of noise filtering to isolate the speculative conclusions that actually worked.

-X - Start in the client console for the VM guest in full screen mode.

-h {hostname} - this is just what it sounds like, the host name or ip address where VMWare server is running. However, unlike the old vmware console, which had a -P switch for the port, this one just takes a hostname:port combined, like myvmwareserverbox:8333

-u {username} - the username on the vmware server host that is permitted to access the vm guest. This is only useful in combination with the password switch. Note: Does not work as of v2.0.2 in combination with the -M switch.

-p {password} - supplies the password to be used with the username In the old version of vmware console, this was the -w switch. -p makes more sense I guess. Note: Does not work as of v2.0.2 in combination with the -M switch.

-M ## - this identifies the VM guest from the inventory in a simplified way (example -M 33). Unfortunately, this does not work when combined with the -u username -p password parameters.

{vm guest datastore path} - This is the last parameter and replaces the -M ## to specify a VM guest. The format of this may be documented somewhere, but I didn't end up finding that either. The forum posts I found on the topic were difficult to decipher because the brackets were translated into markup characters by the forum app. The format is:
"[standard] vmguest subdir/vmguest name.vmx"
Note: [standard] is a verbatim part of the pattern and is followed by a space. It tells VMWare Server to find the subdir and vmx file in the configured location for vmware guests.
Note: The -u and -p switches only work with this form of specifying the VM guest.

So, here's a full example of the target to a "click it and connect" shortcut (ignoring security precautions related to embedding a password):

"C:\Users\whirly\AppData\Roaming\Mozilla\Firefox\Profiles\jkbr2e9f.default\extensions\\plugins\vmware-vmrc.exe" -h myvmwareserverbox:8333 -u "vmwareadmin" -p "myvmwarepw" "[standard] Old Windows 2000 Pro VM/Old Windows 2000 Pro VM.vmx"

  • Note: C:\Users is the standard home directory path for Windows Vista. On XP, this part of the path would probably be C:\Documents and Settings
  • Note: whirly, in the example, is just the username on the client machine
  • Note: The quotes around the executable path, username, password, and vm guest datastore path are necessary if there are spaces in the corresponding parameter values. Quotes may not be necessary when there are no spaces in a parameter value, but using quotes anyway removes some guessing if something still doesn't work.
  • Note: Old Windows 2000 Pro VM, in the example, is the subdirectory that appears within /var/lib/vmware/virtual_machines on the Linux machine. /var/lib/vmware/virtual_machines is the location that is set in the VMWare Server configuration as the default place to store virtual machine guests.
  • Note: Old Windows 2000 Pro VM.vmx is the VM guest configuration file that appears within the Old Windows 2000 Pro VM subdirectory.
  • Note: In the datastore path, [standard] is interpreted on the VMWare Server end as equivalent to the configured default path of /var/lib/vmware/virtual_machines

I'm sure the reasons for these changes are related to VMWare's consolidation of components between the legacy GSX product and the ESX / infrastructure product line, which ultimately allows the development team to focus on features instead of dividing attention and support between products that have bigger differences in their behavior. But, I just can't resist being a little sarcastic, so I'd like to say thanks again VMWare for changing everything. I'm looking forward to learning it all from scratch again when 3.0 is released ;)

There are other posts, similar to this one, that refer to the ESXi product line. I found a few (links below) that may help if this didn't answer your questions. Searching for the executable name vmware-vmrc might find other information on the topic too.

Thursday, January 14, 2010

Another Fight between SELinux and PHP

After I installed the web portion of ZoneMinder, and navigated to the main console page, the system message log started filling up with a message saying:

SELinux is preventing /usr/bin/uptime from using potentially mislabeled files utmp (initrc_var_run_t)

Great, I thought... another annoying SELinux nag message to eliminate and another convoluted SELinux policy setting to figure out. Well, this time it was just PHP code, so then I thought, maybe there's an easier way to fix this one. There was.

ZoneMinder's PHP code was parsing the output of the uptime command just to get the system load information, and as long as the browser was sitting on the ZM console page, it would call the function again every few minutes. However, in addition to the system load info, the uptime command also collects the OS level user-session info by reading the /var/run/utmp file. SELinux prevents that file from being read by anything running in the web server (Apache) process. After a little searching around, I found that the load information is also available by just examining /proc/loadavg, so I changed the PHP code from
shell_exec('cat /proc/loadavg')
which SELinux doesn't seem to care anything about.

When the uptime command is used in a PHP script, the output could be parsed in various ways, but in the ZoneMinder PHP code, the output from shell_exec( 'uptime' ), which looks like this:
16:22:09 up 284 days, 1:04, 1 user, load average: 0.06, 0.06, 0.00
was being parsed by the preg_match PHP function like this:
preg_match( '/load average: ([\d.]+)/', $uptime, $matches )
so that $matches[1] got the value of the first system load number.

Instead, since /proc/loadavg only has the system load numbers in it like this:
0.06 0.06 0.00 1/239 5581
the preg_match PHP function needed to be a little different, like this:
preg_match( '/([\d.]+)/', $loadRaw, $matches )
and the rest of the code worked just like it did when it used the output from the uptime command.

Now the logs are quiet again, SELinux is still standing guard and preventing access to utmp from anything running in Apache, and I can get back to whatever I was doing before this annoyance from SELinux popped up... well, if I can remember what that was. I think SELinux must be preventing access to my own short term memory now. Grrr.

Apparently, this will not be changed in SELinux's default policies per:

I reported this to the author(s) of ZoneMinder in case they care to fix it permanently in their product's PHP code. But, I'm sure this is a larger problem since there are many references floating around that describe executing the uptime command from PHP. ZoneMinder also has other SELinux conflicts, but they'll have to wait for another day... probably after I find a decent webcam for Linux that has a stable v4l compatible driver.

Wednesday, January 6, 2010

Joomla! Installation Gotchas

After installing a number of Unix/Linux applications (at least the ones for which there is no convenient RPM in a repository somewhere) you get accustomed to the routine of "tar-xzf some_software-1.2.3.tar.gz", then "cd some_software-1.2.3", followed by "./configure", then "make", sometimes "make test", and finally "make install". It's just a little inconvenient when something isn't packaged that way and you actually have to find and read the install-readme file. Likewise, most LAMP (Linux Apache MySQL PHP) applications follow an install sequence of "cd my_webserver_root", "tar -xzf /my_downloads/some_lamp_app.tar.gz", "cd some_lamp_app", maybe "cp config.php-dist config.php", then "chgrp apache config.php" (or similar), and "chmod 775 config.php", followed by pointing the browser to "http://mywebsite/some_lamp_app/installer" (or similar). It's just a little inconvenient when something doesn't quite follow that pattern, and more so if it chews up time trying to figure out why something is subtly different. Joomla! has a few of those little time munchers so until they fix it, here are a few things that I stumbled over and how I got them fixed.

Unpacking Joomla!
It is just irritating to unpack any distribution and find that it has created more than a single directory within which the rest of the contents are unpacked. Unfortunately, Joomla! is distributed in an archive with no internal top level directory to contain the rest. Unless you want a few dozen files unpacked directly into your working directory, Create a directory first, change into that directory, and THEN
'tar -xzf Joomla_1.5.15-Stable-Full_Package.tar.gz'

FTP Layer Setup
Issue 1: If you get an message like: Error: the XML response that was returned from the server is invalid, you may have made the same mistake I made by copying /var/www/http/joomla_1_5_15/configuration.php-dist to configuration.php. Apparently, the installer script depends on code somewhere in the product that uses the ftp settings in the existing configuration.php file instead of what you filled in on the form. So, instead of copying configuration.php-dist, just create an empty configuration.php, adjust its permissions so that the installer can write to it at the end, and start the install process over. Also, since you would have already gone past the database table creation step, the advanced options on the database connection information page allow you to drop the previous tables before creating new ones.
Note: Even if you got through the install process, this same issue can show up the first time the actual Joomla site is accessed but the message may be something like: JError Unable to load Database Driver Starting with an empty configuration.php seems to avoid this too.

Issue 2:
If the "Verify FTP Settings" button reports that the ftp server may be incompatible, or it says that it the STOR ftp command failed, the Joomla! install directory is probably not writable and executable by the ftp user account (Note: Directories in a Unix/Linux file system must be 'executable' in order for their contents to be listed). Most likely this comes up because the ftp user account provided for Joomla's to use is a non-shell access account that is different from the owner of the files in the install directory. For example, if the ftp user account were 'joomlaftp' and the owner of the joomla files is set to a shell account called 'webmaster'). The group on the Joomla directory and files within it may be set to the group under which the webserver runs so that if the webserver process needs to write anything (e.g. an uploads directory) the write access can be granted using something like chmod g+w uploads. It probably wouldn't be a good idea to add the 'webmaster' group to the ftp user account's group list, because that could extend it's reach past the Joomla files, and defeat the purpose of even having the FTP Layer. It may not be practical to change the group on the Joomla files either. So, on most recent Unix/Linux distributions, ACL rules can provide more specific access on specific files, to a specific user or group. Add read/write/execute to the Joomla install directory for the special Joomla FTP account (-R is 'recursive' and -m is 'modify'):

setfacl -R -m u:joomlaftp:rwx /var/www/http/joomla_1_5_15

Then verify that the permissions now consist of the normal file system permissions plus the ACL.

getfacl /var/www/http/joomla_1_5_15
getfacl: Removing leading '/' from absolute path names
# file: var/www/http/joomla_1_5_15

# owner: webmaster
# group: apache

64 bit Linux Zip Library Bug
This has been reported to the Joomla! developers (see tracker 15044) but either they think it is a closed issue because they tested on a 32 bit system, or maybe it just isn't very high on the priority list because 64 bit Linux systems are a secondary concern. This issue may not affect more "bleeding edge" distributions but does affect CentOS 5 (i.e. RedHat Enterprise Linux 5) x86_64 distributions. If uploading a plugin or a template that is in pkzip (*.zip) format just silently fails on your 64bit system, you can try (at your own risk of course) applying this patch to the Joomla zip.php library code by saving the following patch file text into a file and running these commands...

cd /var/www/http/joomla_1_5_15/libraries/joomla/filesystem/archive
mv zip.php zip.php.orig
patch --ignore-whitespace < zip_php_fix.patch

------------- snip file: zip_php_fix.patch ----------------
--- zip.php.orig
+++ zip.php
@@ -223,8 +223,8 @@
function _extractNative($archive, $destination, $options)
- if ($zip = zip_open($archive)) {
- if (is_resource($zip)) {
+ $zip = zip_open($archive);
+ if (is_resource($zip)) {
// Make sure the destination folder exists
if (!JFolder::create($destination)) {
$this->set('error.message', 'Unable to create destination');
@@ -248,9 +248,8 @@
- }
} else {
- $this->set('error.message', 'Unable to open archive');
+ $this->set('error.message', 'Unable to open archive. Error code '.$zip);
return false;
return true;
------------- snip file: zip_php_fix.patch ----------------

It is a struggle to resist the urge to just shut off Security Enhanced Linux. SELinux is always locking up something to send you on a quest to figure out how to unlock it. Even if SELinux does some useful things in terms of protecting against intrusions or unauthorized modifications, it may just be a notch more difficult than sendmail to configure it correctly. That said, these rules for Joomla's files may not be exactly right, but they seem to give Joomla the access it needs while keeping SELinux set to enforcing. (Note: This assumes that everything in /var/www is already labeled by a default SELinux rule as httpd_sys_content_t but you may need to add a corresponding rule explictly if Joomla's install directory is elsewhere in the file system).

semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/components(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/configuration\.php'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/images(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/media(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/modules(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/plugins(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/templates(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/tmp(/.*)?'
restorecon -R -F -v /www/joomlainstalldir