XML is way too hard for the rocket scientists at EMC

Navicli is the command line tool to configure/query a Clariion SAN. Apparently you need some special license to use it, which is weird but I guess a command line tool is unusual for an appliance that's built on a point-click OS such as the Windows 3.11 underlying this storage system.

I won't go into too many details as to how this C.L.I. sucks; let's just instead pick one obvious way it does.
It conveniently provides an -xml switch. Sweet! you might mistakenly think, I shall be able to reliably parse query results! Alas, no.

In the previous version (6.29.something), it didn't even output well-formed XML. It is evidently way too hard for  a multi-billion dollar company to publish code that respects decade old standards. And after all, you've just spend $200k on that piece of hardware, you wouldn't want code that works, too?

Well they appear to have fixed that (or maybe I just got lucky and didn't trigger the bug recently), and the XML now passes basic checks. But it's still unusable. To wit, here's an excerpt of the output of the getdisk subcommand, which is supposed to list all the disks with all their parameters:

<?xml version="1.0" encoding="utf-8"?>
      <METHODRESPONSE NAME="ExecuteClientRequest">
          <VALUE>Bus 0 Enclosure 0  Disk 0
<PARAMVALUE NAME="Vendor Id" TYPE="string">
              <VALUE>SEAGATE </VALUE>
            <PARAMVALUE NAME="Product Id" TYPE="string">
              <VALUE>STT30065 CLAR300</VALUE>

At first it looks like a straightforward list of key/value pairs, with added (mostly useless) loose type information. But notice the "Bus 0..." information. Now look at the next instance of it:

            <PARAMVALUE NAME="Prct Busy" TYPE="uint64">

Bus 0 Enclosure 0  Disk 2
<PARAMVALUE NAME="Vendor Id" TYPE="string">
              <VALUE>SEAGATE </VALUE>

That's right, it's a stray printf in the middle of XML output. It's completely unparsable. On top of that, everything is indeed linear, the hierarchy of data is not preserved. For instance, they could have grouped all  Bus 0 items under one element, and then Enclosure 0, and so on; instead it's all listed at the same level. 

Edit: and I forgot to add, the RPM for version asks a question in the %postinst section, which appears to break installation through yum. Is there anything those MS-DOS types can't get wrong?


Firmly stupid Linux firmware updating with IBM

IBM boasts of plenty of admin-friendly tools for updating drivers and firmwares. Unfortunately, as usual with administration tools, it looks like they've been packaged by complete retards.

 Apparently they don't like tar.gz, zip, tar.bz2, 7z or even rar, arc or what have you. Nope, the geniuses at IBM are so nostalgic of the good ole DOS days that they decided to resuscitate the very bad scheme of self-unpacking executables.

If that malware-spreading nonsense wasn't bad enough in itself, they made sure that:
 - it required an executable /tmp
 - that unpacking required root privileges most of the time
 - you couldn't specify the temp dir with TMPDIR or anything, really
 - it writes random log files in random places, such as the current directory, without telling anyone, and happily overwriting any file with that name. What if that file happens to be a symlink towards /etc/passwd? Don't worry, IBM's got you covered, it will fuck your system up free of charge.


SELinux policy module for pipslited

Pipslited is the daemon part of the official Linux driver for Epson inkjets. It used to suck quite frankly, but as far as I can tell the latest versions have been improving visibly. Problem is that it hasn't got an SELinux policy module. Oddly I thought there was one but I just realized today that I couldn't print. So I got to work with Slide, the Eclipse-based SELinux policy editor.

This is on Fedora 13, selinux-policy 3.7.19

The code


## <summary>epson cups module</summary>
Yes it's empty, as usual.



require {
 type fs_t;
 type setroubleshootd_t;
 type cupsd_t;
 type printer_device_t;

type pipslite_t;
type pipslite_exec_t;
type pipslite_config_t;
type pipslite_pid_t;
type pipslite_fifo_t;
type pipslite_tmp_t;


# Access to shared libraries



# Type for the daemon
domain_entry_file(pipslite_t, pipslite_exec_t)

# Type for configuration files

allow pipslite_t pipslite_config_t:file { getattr read create_file_perms };
allow pipslite_t pipslite_config_t:dir { create_dir_perms };

# Type for PID file

allow pipslite_t pipslite_pid_t:file manage_file_perms;
allow pipslite_t pipslite_pid_t:dir rw_dir_perms;

# Type for temporary files
# Probably not necessary, but in case pipslite wants to create
# temp files, it's there and it's secure

allow pipslite_t pipslite_tmp_t:file create_file_perms;
allow pipslite_t pipslite_tmp_t:dir create_dir_perms;
files_tmp_filetrans(pipslite_t,pipslite_tmp_t,{file dir})

# We define a new type for the fifo used by cups to connect to pipslite
allow pipslite_t pipslite_fifo_t:fifo_file { read create open };
filetrans_pattern(pipslite_t, var_run_t, pipslite_fifo_t, fifo_file)
allow pipslite_fifo_t fs_t:filesystem associate;
allow pipslite_t pipslite_fifo_t:fifo_file unlink;

# Network connections, incoming
allow pipslite_t self:tcp_socket { bind create setopt listen };

# Makes the init.d script execute in the desired domain
# Without this, it just takes the context of the caller, unconfined typically.
init_daemon_domain(pipslite_t, pipslite_exec_t)

# --- Getting to the point ---
# Pipslite needs to talk to the printer
allow pipslite_t printer_device_t:chr_file { read write open };

# .. and cupsd needs to talk to pipslited
allow cupsd_t pipslite_fifo_t:fifo_file { write open };

# No idea why this is needed, new thing?
allow setroubleshootd_t pipslite_fifo_t:fifo_file getattr;


/usr/lib64/pipslite/pipslited -- gen_context(system_u:object_r:pipslite_exec_t,s0)
/etc/pipslite(/.*)? gen_context(system_u:object_r:pipslite_config_t,s0)
/var/run/pipslited.pid -- gen_context(system_u:object_r:pipslite_pid_t,s0)
# This is needed because pipslited doesn't seem to always delete
# the fifo on exit, and it doesn't recreate it if it's already there
/var/run/pipslite[^/.]* gen_context(system_u:object_r:pipslite_fifo_t,s0)

Compiling and installing the module

# service pipslited stop
# ln -s /usr/share/selinux/devel/Makefile .
# make
Compiling targeted pipslite module
/usr/bin/checkmodule:  loading policy configuration from tmp/pipslite.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 10) to tmp/pipslite.mod
Creating targeted pipslite.pp policy package
rm tmp/pipslite.mod tmp/pipslite.mod.fc
# semodule -i pipslite.pp
# restorecon -Rv /etc/pipslite/ /usr/lib64/pipslite/pipslited /var/run/pips* 
# service pipslited start