<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://www.theoldmonk.net/blog/"?>
<rss version="2.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:admin="http://webns.net/mvcb/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Filed under: hacks | The Old Monk</title>
<atom:link href="http://www.theoldmonk.net/blog/archives/hacks/index-rss.xml" rel="self" type="application/rss+xml" />
<link>http://www.theoldmonk.net/blog</link>
<description>high wisdom</description>
<dc:language>en-us</dc:language>
<dc:creator>gera</dc:creator>
<dc:date>2010-05-25T17:36:37+05:30</dc:date>
<admin:generatorAgent rdf:resource="http://nanoblogger.sourceforge.net" />
<item>
<link>http://www.theoldmonk.net/blog/archives/2009/08/17/windows_xp_file_ownership/</link>
<guid isPermaLink="true">http://www.theoldmonk.net/blog/archives/2009/08/17/windows_xp_file_ownership/</guid>
<title>Windows XP file ownership</title>
<dc:date>2009-08-17T17:01:16+05:30</dc:date>
<dc:creator>gera</dc:creator>
<dc:subject>tricks, hacks</dc:subject>
<description>
<![CDATA[<p>
As part of a cleanup of someone's notebook, I created a non-admin account and
copied the docs/shortcuts. Thankfully, the data was already in a separate
drive. Trouble is, the non-admin user would see all of it as read-only.
</p>
<p>
I tried changing the perms on the content (via the gui as well as via
attrib.exe), but the non-admin user still wasn't able to write.
</p>
<p>
It turned out that the issue was file ownership. I'm not too sure what the
patchlevel of the XP system was, but a right click -&gt; properties menu
didn't bring up any tab where I could see or change file ownership.
</p>
<p>
The solution: download and install <a href="http://www.cygwin.com">Cygwin</a>,
and then a simple "chown -R &lt;NonAdminUser&gt; /cygdrive/&lt;driveletter&gt;/*".
</p>
<p>
Reinforces my opinion that one really *needs* cygwin to make Windows usable!
</p>]]>
</description>
</item>
<item>
<link>http://www.theoldmonk.net/blog/archives/2009/02/24/ssh_authentication_via_mysql_pam_mysql/</link>
<guid isPermaLink="true">http://www.theoldmonk.net/blog/archives/2009/02/24/ssh_authentication_via_mysql_pam_mysql/</guid>
<title>ssh authentication via mysql (pam_mysql)</title>
<dc:date>2009-02-24T13:39:30+05:30</dc:date>
<dc:creator>gera</dc:creator>
<dc:subject>tricks, technology, hacks</dc:subject>
<description>
<![CDATA[<p>
There's not much info on the interwebs on why ssh authentication via pam_mysql fails, and there are definitely some misleading answers like
<pre>
when logging in via ssh, the ssh daemon checks some files in ~/,
so it can be done if the user already have a valid home directory.
</pre>
from <a href="https://www.linuxquestions.org/questions/linux-security-4/authentication-to-ssh-via-mysql-169733/">this thread</a>.
</p>

<p>
The real reason why it doesn't successfully authenticate is because ssh does a getpwent() call to check if the user exists on the system. If you're using just a PAM solution (which doesn't provide accounts), that call fails if there isn't any such local user. sshd then sets the password to '^H ^M INCORRECT' before passing it to PAM, which obviously thinks it's the wrong password. The simple (and probably unscalable - but then you should be using something like nss_mysql) solution is to add local accounts to the machines for these users. That will make the getpwent() call succeed, and sshd will authenticate successfully via PAM.
</p>

<p>
I've mentioned this <a href="http://www.theoldmonk.net/blog/archives/2008/09/27/trac_mysql_and_authentication/">earlier</a>.
</p>]]>
</description>
</item>
<item>
<link>http://www.theoldmonk.net/blog/archives/2009/02/16/whatthefuck/</link>
<guid isPermaLink="true">http://www.theoldmonk.net/blog/archives/2009/02/16/whatthefuck/</guid>
<title>whatthefuck</title>
<dc:date>2009-02-16T15:08:16+05:30</dc:date>
<dc:creator>gera</dc:creator>
<dc:subject>code, hacks</dc:subject>
<description>
<![CDATA[I'm back from hibernation! Now that I've quit work and have a little free time, I'm back to making my life easier.
<br /><br />
Step one, in that direction is <em>whatthefuck</em>. It's a wrapper around the excellent <em>wtf</em> utility, available via the <em><a href="http://packages.debian.org/search?keywords=bsdgames&searchon=names&suite=stable&section=all">bsdgames</a></em> package in Debian (and <a href="http://packages.ubuntu.com/search?keywords=bsdgames&searchon=names&suite=intrepid&section=all">Ubuntu</a>). <em>wtf</em> is nice, but has some annoyances like :
<pre>
gera@gera-laptop:~$ wtf is 3whs
Gee...  I don't know what 3whs means...
gera@gera-laptop:~$ wtf -t comp is 3whs
3WHS: three-way handshake
</pre>
That's because the term exists in the 'comp' list and not the regular one. Well, chances are that if I don't know wtf it means, I wouldn't know that it's a computing term either. And what about terms which aren't in _any_ list?
<br /><br />
Enter <a href="/whatthefuck">whatthefuck</a>. It's a wrapper around <em>wtf</em>. It does the following, in order:
<ul>
        <li>looks for the term in the default wtf list</li>
        <li>if that doesn't work, looks for it in the comp list</li>
        <li>failing that, gets the wikipedia page for that term</li>
        <li>failing even that, launches a Google search for the term in a browser</li>
</ul>
It detects screen size and then intelligently pages the output via the default pager. For parsing wikipedia HTML, it needs <em>html2text</em>, and for querying the wtf lists, it needs wtf. If it doesn't find wtf, it'll just act as a lookup tool for wikipedia. It launches 'gnome-www-browser' by default, but will use the BROWSER environment variable if that's set. It also ignores the optional 'is', just like <em>wtf</em>:
<pre>
gera@gera-laptop:~$ whatthefuck perl
perl: perl (1) - Practical Extraction and Report Language
gera@gera-laptop:~$ whatthefuck is perl
perl: perl (1) - Practical Extraction and Report Language
</pre>
I alias it to 'wtf' so that I can make this completely transparent.
<pre>
gera@gera-laptop:~$ alias wtf=`which whatthefuck`
gera@gera-laptop:~$ wtf is perl
perl: perl (1) - Practical Extraction and Report Language
</pre>
It's a trivial script and not rocket science. But it's tremendously useful.
<br /><br />
<b>update (21 Feb 2009)</b>: The newer version (available at the same link) checks the uppercased term on wikipedia as well.]]>
</description>
</item>
<item>
<link>http://www.theoldmonk.net/blog/archives/2008/09/27/trac_mysql_and_authentication/</link>
<guid isPermaLink="true">http://www.theoldmonk.net/blog/archives/2008/09/27/trac_mysql_and_authentication/</guid>
<title>Trac, MySQL and authentication</title>
<dc:date>2008-09-27T19:06:10+05:30</dc:date>
<dc:creator>gera</dc:creator>
<dc:subject>tricks, technology, hacks</dc:subject>
<description>
<![CDATA[What we needed at <a href="http://www.chaupaati.in">work</a> :
<ul>
 <li> A wiki</li>
 <li> VPN</li>
 <li> A bug/issue tracker</li>
</ul>
<a href="http://trac.edgewall.org/">Trac</a> gave us the first and the last, and <a href="http://openvpn.net/">OpenVPN</a> gave us the middle. The newer versions of Trac can use MySQL as a database instead of SQLite and have a nice <a href="http://trac-hacks.org/wiki/AccountManagerPlugin">AccountManager</a> plugin.
<br /><br />
And it all comes together with <a href="http://pam-mysql.sourceforge.net/">pam_mysql</a>. The only problem was that Trac likes to store passwords hashed as HTTP-Digest style hashes (not the most secure, I know) with an empty realm, and pam_mysql doesn't work for that. The solution was a simple patch to pam_mysql which adds support for such hashes. I'll publish that soon - I'm making it more general by adding support for realms rather than assuming that realm would be empty.
<br /><br />
OpenVPN (and apache - via mod_auth_pam) etc. can authenticate via <a href="http://www.kernel.org/pub/linux/libs/pam/">PAM</a> and adding authentication to anything is a simple matter of placing the right .htaccess file. And this is a *common* password across all services, which users can change on the wiki, in their browsers, with a nice polished interface. No unix shells for people who can't deal with them.
<br /><br />
This is no <a href="http://en.wikipedia.org/wiki/Kerberos_(protocol)">Kerberos</a>, but is infinitely simpler - which means a lot for a small startup.
<br /><br />
There are a few gotchas though :
<ul>
<li> Apache doesn't like empty realms. This can be worked around by switching to Basic authentication where passwords are passed on to PAM and we ignore realm. Yes, Basic is worse, but there's always SSL. Thus, one can supply _any_ value of realm (the AuthName in .htaccess). The situation might improve if my pam_sql patch accepts realms and we manage to modify the Trac AuthManager plugin to use the same realm.</li>
<li> SSH doesn't like to authenticate users which don't have an account on the machine. It does a getpwent() call, and if it fails, it sets the password to '^H ^M INCORRECT' (the ^H and ^M represent the control chars here, but this is what you see in your logs if you debug PAM). One (ugly, in my opinion) way out is to LD_PRELOAD your own getpwent() method for sshd. The other is to grant ssh access to people on a machine by machine basis. This doesn't scale beyond a point but is good enough for small setups and the most secure. We use this. The cleaner solution of course, is to use something like <a href="http://savannah.nongnu.org/projects/nss-mysql">nss_mysql</a>. This might be our next step, but not in the immediate future.</li>
</ul>
Patch to come Real Soon Now.]]>
</description>
</item>
<item>
<link>http://www.theoldmonk.net/blog/archives/2008/07/05/location_aware_gtd_trick/</link>
<guid isPermaLink="true">http://www.theoldmonk.net/blog/archives/2008/07/05/location_aware_gtd_trick/</guid>
<title>Location aware GTD trick</title>
<dc:date>2008-07-05T12:20:17+05:30</dc:date>
<dc:creator>gera</dc:creator>
<dc:subject>tricks, hacks</dc:subject>
<description>
<![CDATA[I have my <a href="http://www.theoldmonk.net/blog/archives/2008/01/28/commandline_gtd_with_gtdo/">gtdo</a> to manage the TODOs, and it shows me the list every time I open a terminal (via a 't ls' in my .bashrc). But what to do when my '@work' TODO list grows long and is shown to me on every terminal spawn, even at home?
<br /><br />
what I also have is my <a href="http://www.theoldmonk.net/blog/archives/2008/03/04/network_profiles_in_ubuntu/">network profiles setup</a>. Till today, my office profile was called "office" - which I changed to "work". This makes my profile name the same as my context name ('work' and '@work' - we can manage the @ in the context). Do I need to say more? :)
<br /><br />
Every time I do a 'NETSCHEME="work" sudo ifup ath0' and the network comes up, the '/var/run/network/ifstate' contains a line like 'ath0=ath0-home'. Which means, I can get the profile I'm using. Which means, if I name my profiles carefully, I can get the location I'm at. Which then means, if I name my contexts carefully, I can get the relevant context.
<br /><br />
Adding this:
<pre>
LOCATION=`grep -m 1 '-' /var/run/network/ifstate | awk -F '-' '{ print $2 }'`
t ls @$LOCATION
</pre>
to my .bashrc works like magic.
<br /><br />
By the way, I *could* scan for known SSIDs and select a network (and hence a location and a context) automagically, but I don't do that yet - one of the reasons being that I *think* there might be an information leak hidden somewhere. But I haven't thought it through. But I might, and then I might get around to doing it.]]>
</description>
</item>
<item>
<link>http://www.theoldmonk.net/blog/archives/2008/06/25/being_too_smart_is_annoying/</link>
<guid isPermaLink="true">http://www.theoldmonk.net/blog/archives/2008/06/25/being_too_smart_is_annoying/</guid>
<title>Being too smart is annoying</title>
<dc:date>2008-06-25T19:19:20+05:30</dc:date>
<dc:creator>gera</dc:creator>
<dc:subject>tricks, web, hacks</dc:subject>
<description>
<![CDATA[Some people have been saying that Firefox tries to emulate other browsers and be Windows-like in general. Some people have been saying that about Linux/Ubuntu as well. I don't know how correct they are and what they're based on, but there's one thing that comes in the category of being too smart and too user friendly which ends up annoying the regulars.
<br /><br />
I was on my machine and wanted to run a remote instance on Firefox, with the display forwarded back to my machine. I had X forwarding over SSH and my DISPLAY enviroment variable all set up. But when I started 'firefox' on the remote commandline, it opened up an instance of firefox *locally*. WTF!!?
<br /><br />
The <a href="http://linux.derkeiler.com/Mailing-Lists/Fedora/2007-10/msg04000.html">fix</a> to this is a 'MOZ_NO_REMOTE' env variable. Duh.]]>
</description>
</item>
<item>
<link>http://www.theoldmonk.net/blog/archives/2008/03/08/git-bugzilla_integration/</link>
<guid isPermaLink="true">http://www.theoldmonk.net/blog/archives/2008/03/08/git-bugzilla_integration/</guid>
<title>Git-Bugzilla integration</title>
<dc:date>2008-03-08T19:47:35+05:30</dc:date>
<dc:creator>gera</dc:creator>
<dc:subject>tricks, perl, code, hacks</dc:subject>
<description>
<![CDATA[<p>
<em>UPDATE: See my <a
href="http://www.theoldmonk.net/blog/archives/2010/03/08/gitzilla_-_git-bugzilla_integration_done_right/">blog
post</a> about <a href="http://www.theoldmonk.net/gitzilla/">GitZilla</a> - git-bugzilla
integration done right. The stuff below is bitrotten and outdated now.</em>
</p>

<p>There's always <a href="http://www.mkgnu.net/?q=scmbug">SCMBug</a>, but you can cook your own Git-Bugzilla integration very easily. SCMBug's fine, but it's a lot of code if all you want is simple cross-linking between Git, Bugzilla and <a href="http://trac.edgewall.org/">Trac</a> (btw - <a href="http://trac-hacks.org/wiki/GitPlugin">GitPlugin</a> for Trac would throw up an error unless you have at least *two* commits in your repository - talk about undocumented easter bugs!).</p>

<p>Anyhoo - here's what I want : <br />
1. Git should disallow any commit where the commit message does not have a bug number. <br />
2. Git should add a comment to the corresponding bug on a commit, mentioning the author, the Trac changeset link, the commit message and the list of files which changed.</p>

<p>And here's the code to do it. First, the post-receive hook :</p>
<pre>
#!/usr/bin/perl -w
use strict;

# A hook script which integrates with bugzilla. It looks for bug IDs in
# commit messages and adds the commit message as well as a link to the
# changeset as a comment on the bug.

# This program is released under the terms of the GNU General Public License
# version 2. A copy of the license may be obtained by emailing the author,
# or at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#
# The absolute lack of warranty and other disclaimers as per the license
# apply.
#
# Copyright 2008, Devendra Gera. All rights reserved.
#
# Author : Devendra Gera <gera@theoldmonk.net>

### user configurable section

# The bugzilla has contains the server, username and password for the targeted
# bugzilla installation. There's NO 'http://' in the server line.
my $bugzilla = {
        server          => "10.147.251.90/bugzilla",
        user            => "demonuser",
        password        => "daemonuserspassword",
};

# __PATH__ and __REVISION__ are replaced in $browser->{changeset} and
# $browser->{revision} to get the changeset and revision URLs respectively. 
my $browser = {
        changeset       =>
        "http://10.147.251.90/projname/changeset/__REVISION__",
        revision        =>
        "http://10.147.251.90/projname/browser/__PATH__?rev=__REVISION__",
};

# The bug_regex should extract the bug id from the commit message and place
# it in $1
my $bug_regex = 'bug #(\d+)';


##### End user configurable section

use WWW::Bugzilla;

my $input = <>;
chomp $input;

my ($oldrev, $newrev, $refname) = split /\s+/, $input;
my $commit_msg = `git-whatchanged $oldrev..$newrev`;

# prepare the changeset URL
my $changeset_url = $browser->{ changeset };
$changeset_url =~ s/__REVISION__/$newrev/g;

# author
my ($author) = ( $commit_msg =~ /^Author:\s+(.*)$/m );

# files
my @filelist = grep ( /^:/, split( /\n/, $commit_msg ) );

# prepare comment
$commit_msg =~ s/^.*?Date://s;  # eat everything till the Date: heder
$commit_msg =~ s/^.*?\n//m;     # eat the date line completely
$commit_msg =~ s/^:.*?$//mg;    # eat the file list from the msg.
chomp $commit_msg;
my ($bug_number) = ( $commit_msg =~ /$bug_regex/ );

my $comment = &lt;&lt;END_COMMENT;

------------------------------------
changeset $newrev [ $changeset_url ]
    by $author :

$commit_msg
------------------------------------

Files changed :
END_COMMENT

$comment .= join("", @filelist) . "\n";

my $bz = WWW::Bugzilla->new(
        server          => $bugzilla->{ server },
        email           => $bugzilla->{ user },
        password        => $bugzilla->{ password },
        bug_number      => $bug_number
);

die "cannot connect to bugzilla" unless defined $bz;

$bz->additional_comments( $comment );

$bz->commit;
</pre>

<p>And here's the update hook :</p>
<pre>
#!/usr/bin/perl -w
use strict;

my $refname = shift;
my $oldrev = shift;
my $newrev = shift;

my $commit_msg = `git-whatchanged $oldrev..$newrev`;

# check if the commit message contains a bug number
if($commit_msg !~ /bug #\d+/) {
        exit -1;
}

exit 0;
</pre>

<p>The TODO : <br />
1. Push every configurable thing to git's config file and access it via git-config. <br />
2. Code cleanups. One definition of the bug regex (which is hardcoded in the update for now).</p>

<p><em>edit</em> : the here doc in the code was causing a problem with formatting, eating up some of the code. Fixed now.</p>]]>
</description>
</item>
<item>
<link>http://www.theoldmonk.net/blog/archives/2008/03/08/wwwbugzilla_fix/</link>
<guid isPermaLink="true">http://www.theoldmonk.net/blog/archives/2008/03/08/wwwbugzilla_fix/</guid>
<title>WWW::Bugzilla fix</title>
<dc:date>2008-03-08T18:45:35+05:30</dc:date>
<dc:creator>gera</dc:creator>
<dc:subject>perl, hacks</dc:subject>
<description>
<![CDATA[<a href="http://search.cpan.org/~bmc/WWW-Bugzilla-1.3/WWW/Bugzilla.pm">WWW::Bugzilla</a> was a great help in setting up git-bugzilla integration, but there's a small fix which needs to be applied before it would work with my Bugzilla 3 install.
<br /><br />
The problem is that WWW::Mechanize selects the first form on a page by default, and WWW::Bugzilla fails in WWW::Mechanize while setting any field to be updated (with a 'no such field' or 'no field called comment' etc. messages). On my Bugzilla install, there's a small bug search form in the header which makes that happen.
<br /><br />
The fix is a single line and has been emailed to the author. Here it is :
<pre>
@@ -614,6 +614,7 @@
     my $mech = $self->{mech};
 
     if ($self->{bug_number}) {
+        $mech->form_name( "changeform" );
         foreach my $field ( keys %update_field_map ) {
             $mech->field( $update_field_map{$field}, $self->{$field} ) if defined($self->{$field});
             # handle special cases
</pre>]]>
</description>
</item>
<item>
<link>http://www.theoldmonk.net/blog/archives/2008/03/04/network_profiles_in_ubuntu/</link>
<guid isPermaLink="true">http://www.theoldmonk.net/blog/archives/2008/03/04/network_profiles_in_ubuntu/</guid>
<title>Network profiles in Ubuntu</title>
<dc:date>2008-03-04T22:03:31+05:30</dc:date>
<dc:creator>gera</dc:creator>
<dc:subject>tricks, technology, perl, hacks</dc:subject>
<description>
<![CDATA[<p>There are various ways of managing multiple network profiles in Ubuntu, but I've never been a fan of NetworkManager. Commandlines work for me very well, and even there - multiple solutions exist with the help of packages like resolvconf etc. Here's my setup which is very Debian-ish and depends on this nice package called <a href="http://packages.ubuntu.com/gutsy/ifupdown">ifupdown</a>.</p>

<p>First, there's the /etc/network/interfaces file :</p>
<pre>
# we always want the loopback
auto lo
iface lo inet loopback

# mappings
mapping eth0
  script /etc/network/map-scheme
  map dhcp eth0-dhcp
  map emergency eth0-emergency

mapping ath0
  script /etc/network/map-scheme
  map office ath0-office
  map home ath0-home

iface eth0-dhcp inet dhcp
  up iptables -F
  up lokkit -n -q --high --dhcp
  up /etc/init.d/lokkit restart

iface ath0-office inet dhcp
  wpa-driver madwifi
  wpa-conf /etc/wpa_supplicant/office.conf
  up iptables -F
  up lokkit -n -q --high --dhcp
  up /etc/init.d/lokkit restart

iface eth0-emergency inet static
  address 10.9.5.201
  gateway 10.9.4.1
  netmask 255.255.254.0
  up iptables -F
  up lokkit -q --high
  up echo nameserver 172.31.6.5 > /etc/resolv.conf
  up echo nameserver 203.197.12.30 >> /etc/resolv.conf

iface ath0-home inet dhcp
  wpa-driver madwifi
  wpa-conf /etc/wpa_supplicant/home.conf
  up iptables -F
  up lokkit -n -q --high --dhcp
  up /etc/init.d/lokkit restart
</pre>

<p>Notice the mappings section (and see 'man interfaces') - that allows me to say :</p>
<pre>
NETSCHEME="home" sudo ifup ath0
</pre>

<p>or</p>
<pre>
NETSCHEME="office" sudo ifup ath0
</pre>

<p>because the specified script (/etc/network/map-scheme) just looks up the NETSCHEME environment variable and spit out the correct mapping to go to. This thing, by the way, could be rigged to do arbitrarily complex tasks (look in /usr/share/doc/ifupdown/examples/ for sample scripts, including one which tries to ping some known IPs, and decides its location/profile based on successful pings - you could write one which looks for all known wireless SSIDs and then decide which profile to switch to). Here's my trivial script :</p>
<pre>
#!/usr/bin/perl -w
use strict;

my $scheme = $ENV{NETSCHEME} || "home";

while(<>) {
        if ( s/$scheme\s+// ) {
                print;
        }
}
</pre>

<p>The conf files in /etc/wpa_supplicant/* are of course wpa_supplicant configuration files. See 'man wpa_supplicant.conf' for details.</p>]]>
</description>
</item>
<item>
<link>http://www.theoldmonk.net/blog/archives/2008/02/06/eee_pc/</link>
<guid isPermaLink="true">http://www.theoldmonk.net/blog/archives/2008/02/06/eee_pc/</guid>
<title>Eee PC!</title>
<dc:date>2008-02-06T23:29:09+05:30</dc:date>
<dc:creator>gera</dc:creator>
<dc:subject>tricks, hacks</dc:subject>
<description>
<![CDATA[My Eee PC finally arrived. I played with the original Xandros/Asus interface for a day, and then moved to Ubuntu. My <a href="http://www.theoldmonk.net/blog/archives/2007/12/01/encrypted_home_setup/">encrypted $HOME howto</a> worked, but I kept /real_home on a SD card and added "noatime" to every FS mount.
<br /><br />
One fallout is that I can't suspend - the SD card is a USB device and gets reset on suspend/resume. Also, the /var/log, /var/run, /var/tmp and /tmp are tmpfs filesystems. /var/cache/apt/ is a bind mount from the SD card to save the SSD from excessive writes.
<br /><br />
<a href="http://www.flickr.com/photos/gera/2245645565/" title="Eee! by Gera, on Flickr"><img src="http://farm3.static.flickr.com/2305/2245645565_f1174d9d9a_m.jpg" width="240" height="157" alt="Eee!" /></a>
<br /><br />
Processing RAW images from my camera was a problem till I swapped the RAM with one of the modules from my Vostro 1400. GIMP works pretty smoothly now.]]>
</description>
</item>
</channel>
</rss>
