Posts tagged plugin

racktables password management

posted on 2016-06-02 23:48

Starting with racktables 0.20.11 a new plugin management was introduced. This post depicts how to use external plugins, especially how to get password management into this DCIM solution.

My regular layout looks like this:

root@racktables:/var/www/racktables# tree -L 2
|-- RackTables-0.20.11
|   |-- COPYING
|   |-- ChangeLog
|   |-- LICENSE
|   |-- Makefile
|   |-- README ->
|   |-- README.Fedora
|   |--
|   |-- gateways
|   |-- plugins
|   |-- scripts
|   `-- wwwroot
|-- RackTables-0.20.11.tar.gz
|-- htdocs -> RackTables-0.20.11/wwwroot/
|-- logs
`-- tmp

By convention, webroots are always set up under /var/www/<domainname>, and docroots at /var/www/<domainname>/htdocs. To easier switch between versions and not having to reconfigure vhosts or add new ones, the versions are just thrown into the webroot. htdocs is a symlink created and points to wwwroot, as racktables wants it. Newer versions are simply dropped into the webroot, and htdocs is symlinked to the new installation.

The plugins folder is where you put plugin files into.

For password management, I found the following script on the mailinglist here.

The full script will be copy-pasted below without any modifications, it worked out-of-the-box with racktables 0.20.11:


 * Object passwords tab by Gjermund Jensvoll
 * Version 0.7
 *      1. create ObjectPWs Table in your RackTables database

  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `object_id` int(10) unsigned NOT NULL,
  `user_name` char(64) DEFAULT NULL,
  `password_hash` char(64) DEFAULT NULL,
  `comment` text,
  PRIMARY KEY (`id`),
  KEY `object_id` (`object_id`)

 *      2. copy passwords.php to plugins directory
 *  3. change $key variable to something random (important!)
 *  4. make sure passwords.php is only readable by webserver and root (also important!)

$tab['object']['passwords'] = 'Passwords';
$tabhandler['object']['passwords'] = 'passwordsTabHandler';

//$ophandler['object']['passwords']['addPW'] = 'addPW';
//registerOpHandler (object, passwords, addPW, addPW, after);

$key = "hj9kai2uru1Hoo6eezooyeeghohy9Ielah5aek9wa3quaek3tohjerie3iuPo6chu6ahj";

// Function for adding new passwords
function commitNewPassword($object_id, $user_name, $password, $comment) {
        global $key;
    /* TODO check permissions */

    $encrypted = openssl_encrypt($password, "AES-256-CBC", $key);
    return usePreparedExecuteBlade
        "INSERT INTO ObjectPWs (object_id, user_name, password_hash, comment) VALUES (?, ?, ?, ?)",
        array ($object_id, $user_name, $encrypted, $comment)

} /* commitNewPassword */

// Function for updating existing passwords
function commitUpdatePassword($pw_id, $user_name, $password, $comment) {
        global $key;

    /* TODO check permissions */

    $encrypted = openssl_encrypt($password, "AES-256-CBC", $key);
    return usePreparedExecuteBlade
        "UPDATE ObjectPWs SET user_name=?, password_hash = ?, comment = ? WHERE id = ?",
        array ($user_name, $encrypted, $comment, $pw_id)

} /* commitUpdatePassword */

// Function for deleting passwords
function commitDeletePassword($pw_id) {

    /* TODO check permissions */

    return usePreparedExecuteBlade
        "DELETE FROM ObjectPWs WHERE id = ?",
        array ($pw_id)

} /* commitDeletePassword */

// Main function
function passwordsTabHandler () {
        global $key;

// Show warning for IE users
echo "<SCRIPT language=\"JavaScript\">
var browserName = navigator.appName;
var bN = navigator.appCodeName;
if (browserName == \"Microsoft Internet Explorer\") {
document.write(\"<center><br><br><font color=red>This page requires a html5 capable browser. Turn off compatability mode in Internet Explorer.</font></center>\");
</SCRIPT>"; /* IE warning */

// JS toogle show/hide password
echo "<SCRIPT language='JavaScript'>
function ShowHide(pwfieldId,buttonId)
        if(document.getElementById(pwfieldId).type != 'password')
                document.getElementById(pwfieldId).type = 'password';
                document.getElementById(buttonId).value = 'show';
                document.getElementById(pwfieldId).type = 'text';
                document.getElementById(buttonId).value = 'hide';
"; /* toogle show/hide password */

        $display ="<center><br><br><br>\n";

// Debug _POST array
//if (isset($_POST['object_id']))
//print_r ($_POST);

        if (isset($_POST['op'])) {
                if ($_POST['op'] == "addPW") {
                        commitNewPassword($_POST['object_id'], $_POST['user_name'], $_POST['password'], $_POST['comment']);
        if ($_POST['op'] == "editPW") {
            commitUpdatePassword($_POST['pw_id'], $_POST['user_name'], $_POST['password'], $_POST['comment']);

        if (isset($_GET['op'])) {
            if ($_GET['op'] == "delPW") {

        // Table header -> display
        $display .= "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>";
        $display .= "<tr><th>&nbsp;</th>";
        $display .= "<th class=tdleft>Username</th>";
        $display .= "<th class=tdleft>Password</th>";
        $display .= "<th class=tdleft>Comment</th>";
        $display .= "<th>&nbsp;</th></tr>";

        assertUIntArg ('object_id', __FUNCTION__);
        $object = spotEntity ('object', $_REQUEST['object_id']);

        // Existing passwords -> display
        $query = "SELECT * FROM ObjectPWs WHERE object_id = '$object[id]'";
        $result = NULL;
        $result = usePreparedSelectBlade ($query);
        while ($row = $result->fetch (PDO::FETCH_ASSOC)) {
                $pw_id = $row['id'];
                $object_id = $row['object_id'];
                $user_name = $row['user_name'];
                $password = openssl_decrypt($row['password_hash'], "AES-256-CBC", $key);
                $comment = $row['comment'];

                $display .= "<form method=post id=editPW name=editPW autocomplete=off action=\"\">";
                $display .= "<input type=hidden name=\"pw_id\" value=\"".$pw_id."\">";
        $display .= "<input type=hidden name=\"op\" value=\"editPW\">";
        $display .= "<input type=hidden name=\"object_id\" value=\"".$object_id."\">";
                $display .= "<tr><td><a href='?page=object&tab=passwords&object_id=".$object_id."&op=delPW&pw_id=".$pw_id."' onclick=\"javascript:return confirm('Are you sure you want to delete this password?')\">";
                $display .= "<img src='?module=chrome&uri=pix/tango-list-remove.png' width=16 height=16 border=0 title='Delete this password'></a></td>";
                $display .= "<td class='tdleft' NOWRAP><input type=text name=user_name value='".$user_name."' size=20></td>";

                $display .= "<td class='tdleft' NOWRAP><input type='password' id='password".$pw_id."' name='password' value='".$password."' size=30 required>";
                $display .= "<input type='button' id='button".$pw_id."' value='show' onclick=\"javascript:ShowHide('password".$pw_id."','button".$pw_id."')\"></td>\n";

                $display .= "<td class='tdleft' NOWRAP><input type=text name=comment value='".$comment."' size=30></td>";
                $display .= "<td><input type=image name=submit class=icon src='?module=chrome&uri=pix/tango-document-save-16x16.png' border=0 title='Save changes' onclick=\"javascript:return confirm('Are you sure you want to edit this password?')\"></td></form></tr>";


        // Form to add new password -> display
        $display .= "<form action=\"\" method=post autocomplete=off id=\"addPW\" name=\"addPW\">";
        $display .= "<input type=hidden name=\"object_id\" value=\"".$object['id']."\">";
        $display .= "<input type=hidden name=\"op\" value=\"addPW\">";
    $display .= "<tr><td><input type=image name=submit class=icon src='?module=chrome&uri=pix/tango-list-add.png' border=0  title='add a new password'></td>";
    $display .= "<td class='tdleft'><input type=text size=20 name=user_name tabindex=100></td>";

        $display .= "<td class='tdleft'><input type=text name='password' id=newpassword tabindex=101 size=30 required>";
        $display .= "<input type='button' id='newbutton' value='hide' onclick=\"javascript:ShowHide('newpassword','newbutton')\"></td>\n";

    $display .= "<td class='tdleft'><input type=text size=30 name=comment tabindex=102></td>";
    $display .= "<td><input type=image name=submit class=icon src='?module=chrome&uri=pix/tango-list-add.png' border=0 tabindex=103 title='add a new password'></td></tr>";
    $display .= "</form>";
    $display .= "</table><br></center>";

    // Output all display
    echo $display;

} /* passwordsTabHandler */


Read the instructions on top carefully, create the database table, and save it to plugins/passwords.php. After a page reload you should have the Passwords tab when opening an object in racktables.

This blog covers .csv, .htaccess, .pfx, .vmx, /etc/crypttab, /etc/network/interfaces, /etc/sudoers, /proc, 10.04, 14.04, AS, ASA, ControlPanel, DS1054Z, GPT, HWR, Hyper-V, IPSEC, KVM, LSI, LVM, LXC, MBR, MTU, MegaCli, PHP, PKI, R, RAID, S.M.A.R.T., SNMP, SSD, SSL, TLS, TRIM, VEEAM, VMware, VServer, VirtualBox, Virtuozzo, XenServer, acpi, adaptec, algorithm, ansible, apache, apache2.4, apachebench, apple, applet, arcconf, arch, architecture, areca, arping, asa, asdm, autoconf, awk, backup, bandit, bar, bash, benchmarking, binding, bitrate, blackarmor, blockdev, blowfish, bochs, bond, bonding, booknotes, bootable, bsd, btrfs, buffer, c-states, cache, caching, ccl, centos, certificate, certtool, cgdisk, cheatsheet, chrome, chroot, cisco, clamav, cli, clp, clush, cluster, coleslaw, colorscheme, common lisp, configuration management, console, container, containers, controller, cron, cryptsetup, csync2, cu, cups, cygwin, d-states, database, date, db2, dcfldd, dcim, dd, debian, debug, debugger, debugging, decimal, desktop, df, dhclient, dhcp, diff, dig, display manager, dm-crypt, dmesg, dmidecode, dns, docker, dos, drivers, dtrace, dtrace4linux, du, dynamictracing, e2fsck, eBPF, ebook, efi, egrep, emacs, encoding, env, error, ess, esx, esxcli, esxi, ethtool, evil, expect, exportfs, factory reset, factory_reset, factoryreset, fail2ban, fbsd, fdisk, fedora, file, filesystem, find, fio, firewall, firmware, fish, flashrom, forensics, free, freebsd, freedos, fritzbox, fsck, fstrim, ftp, ftps, g-states, gentoo, ghostscript, git, git-filter-branch, github, gitolite, global, gnutls, gradle, grep, grml, grub, grub2, guacamole, hardware, haskell, hdd, hdparm, hellowor, hex, hexdump, history, howto, htop, htpasswd, http, httpd, https, i3, icmp, ifenslave, iftop, iis, imagemagick, imap, imaps, init, innoDB, innodb, inodes, intel, ioncube, ios, iostat, ip, iperf, iphone, ipmi, ipmitool, iproute2, ipsec, iptables, ipv6, irc, irssi, iw, iwconfig, iwlist, iwlwifi, jailbreak, jails, java, javascript, javaws, js, juniper, junit, kali, kde, kemp, kernel, keyremap, kill, kpartx, krypton, lacp, lamp, languages, ldap, ldapsearch, less, leviathan, liero, lightning, links, linux, linuxin3months, lisp, list, livedisk, lmctfy, loadbalancing, locale, log, logrotate, looback, loopback, losetup, lsblk, lsi, lsof, lsusb, lsyncd, luks, lvextend, lvm, lvm2, lvreduce, lxc, lxde, macbook, macro, magento, mailclient, mailing, mailq, manpages, markdown, mbr, mdadm, megacli, micro sd, microsoft, minicom, mkfs, mktemp, mod_pagespeed, mod_proxy, modbus, modprobe, mount, mouse, movement, mpstat, multitasking, myISAM, mysql, mysql 5.7, mysql workbench, mysqlcheck, mysqldump, nagios, nas, nat, nc, netfilter, networking, nfs, nginx, nmap, nocaps, nodejs, numberingsystem, numbers, od, onyx, opcode-cache, openVZ, openlierox, openssl, openvpn, openvswitch, openwrt, oracle linux, org-mode, os, oscilloscope, overview, parallel, parameter expansion, parted, partitioning, passwd, patch, pct, pdf, performance, pfsense, php, php7, phpmyadmin, pi, pidgin, pidstat, pins, pkill, plasma, plesk, plugin, posix, postfix, postfixadmin, postgres, postgresql, poudriere, powershell, preview, profiling, prompt, proxmox, ps, puppet, pv, pveam, pvecm, pvesm, pvresize, python, qemu, qemu-img, qm, qmrestore, quicklisp, quickshare, r, racktables, raid, raspberry pi, raspberrypi, raspbian, rbpi, rdp, redhat, redirect, registry, requirements, resize2fs, rewrite, rewrites, rhel, rigol, roccat, routing, rs0485, rs232, rsync, s-states, s_client, samba, sar, sata, sbcl, scite, scp, screen, scripting, seafile, seagate, security, sed, serial, serial port, setup, sftp, sg300, shell, shopware, shortcuts, showmount, signals, slattach, slip, slow-query-log, smbclient, snmpget, snmpwalk, software RAID, software raid, softwareraid, sophos, spacemacs, spam, specification, speedport, spi, sqlite, squid, ssd, ssh, ssh-add, sshd, ssl, stats, storage, strace, stronswan, su, submodules, subzone, sudo, sudoers, sup, swaks, swap, switch, switching, synaptics, synergy, sysfs, systemd, systemtap, tar, tcpdump, tcsh, tee, telnet, terminal, terminator, testdisk, testing, throughput, tmux, todo, tomcat, top, tput, trafficshaping, ttl, tuning, tunnel, tunneling, typo3, uboot, ubuntu, ubuntu 16.04, udev, uefi, ulimit, uname, unetbootin, unit testing, upstart, uptime, usb, usbstick, utf8, utm, utm 220, ux305, vcs, vgchange, vim, vimdiff, virtualbox, virtualization, visual studio code, vlan, vmstat, vmware, vnc, vncviewer, voltage, vpn, vsphere, vzdump, w, w701, wakeonlan, wargames, web, webdav, weechat, wget, whois, wicd, wifi, windowmanager, windows, wine, wireshark, wpa, wpa_passphrase, wpa_supplicant, x11vnc, x2x, xfce, xfreerdp, xmodem, xterm, xxd, yum, zones, zsh

Unless otherwise credited all material Creative Commons License by sjas