Why there are two kinds of programmers

Nowadays Java is taught in most universities. After talking to many young programmers at work and reading this article on how to recognise a good programmer I have realised that you can’t call everyone a "programmer" anymore. You have to differentiate between people that program and people that know how to use libraries. At my work, people who only know Java and call them self computing professionals are laughed at (The story of an A student that didn’t know what a call stack was, is still told). This is due to the fact that if you write Java programs you actually only import the needed library and then use them. So when you learn Java you surely learn how the Object Oriented model works but that is about it. This is not specific to Java. If you look at Python, Perl or Ruby you can always see that all the low level stuff is already done for you. Just take the classic example of a linked list. I was talking to a German Computing student about the performance of a hash map to a linked list. It turned out he knew the concept but he had never programmed one before. He argued that nowadays programmers don’t have to know this because libraries will give this functionality to you. I don’t want to say that this is good or bad, but surly someone who doesn’t understand how pointers work will write different programs than someone who does. Maybe it is just a different approach. I learnt C way before any high level language. And even in Pascal I embedded Assembly to support my mouse. So I learnt programming from the bottom -> up. From low level (Assembly) to high level (Ruby). But library programmers will have to learn top to bottom, if they ever want/have to do something low level. So in short:

Library Programmers
  • Know very well how to use specific libraries for specific programming languages

  • Don’t really care too much about memory / CPU performance

  • “Get the job done” attitude

Low Programmers
  • Understand pointers (had the “pointer moment” as I call it)

  • Care, maybe too much, about performance

  • Care about writing “nice” programs


I still personally think that a bottom -> up approach will give you a more solid understanding of the high level languages.
I am starting to understand that programming is not about people that started with Pascal or Basic when they were nine. Programming has become a career choice. People are now studying computing because they think they can get a well paid laid back job afterwards. Of course this is annoying us passionate programmers that spent their childhood learning how to write slim quick code, because these are our values.
So if someone comes up to you and sais “I am a programmer, but I only know Java” Don’t condemn him right away. He is just a library programmer, if this is good or bad time will show.

id -G funny group

I don't know if this is really a bug. But I would like to request some comments

On a system with afs, if you run

$ id -G
500 1102830893

you will get this very big number at the end.

$ id -G `whoami`
500

will not show this number. This is due to afs creating a group in
memory that is not in /etc/group . This of course becomes more
interesting if you run :

$ id -Gn
me id: cannot find name for group ID 1102830893
1102830893

groups behaves in the same way :
$ groups
me id: cannot find name for group ID 1102830893
1102830893

If you look into the id.c you can see why this is happening:
if (argc - optind == 1)
{
struct passwd *pwd = getpwnam (argv[optind]); /* Will go of to
/etc/nsswitch.conf and appropriate*/
if (pwd == NULL)
error (EXIT_FAILURE, 0, _("%s: No such user"), argv[optind]);
ruid = euid = pwd->pw_uid;
rgid = egid = pwd->pw_gid;
}
else
{
euid = geteuid (); /* glibc will do this */
ruid = getuid ();
egid = getegid ();
rgid = getgid ();
}

This is very easy to fix. I have already done this and it works.

I am aware that this is actually a problem of afs and not coreutils.

Hope this might help someone who is confused about that group :)

Rant about GNU again

I was just looking at OpenCVS and was browsing the OpenBSD cvs repro. Then I found the little program true. A while ago I looked at this in coreutils. And it was a 81 line program. That was basically true and false in one program depending on a #define [link]. Let's say a non self explanetory program at first sight. So now I was interrested how OpenBSD would do such a thing.
#! /bin/sh
# $OpenBSD: true.sh,v 1.2 1996/06/26 05:32:50 deraadt Exp $

exit 0

#! /bin/sh
# $OpenBSD: false.sh,v 1.2 1996/06/26 05:32:50 deraadt Exp $

exit 1
That was it. As easy as that.
A nother WHY do we use coreutils.

Google docs pink?

Guess what day it is today: 14. Feb
And Google has turned my docs into something someone would like who has `brunch` (Added french accent).

Geeks versus Nerds

After trying to explain to my mom what the differnece is here you go http://chickybaberules.blogspot.com/2006/04/chickybabes-guide-to-geeks-and-nerds.html

  1. Geeks are sociable people. Nerds have no social skills and are social outcasts.
  2. Geeks engage in meaningful conversations. They can look you in the eye, give you an unexpected timid smile and may even flirt with you. Nerds can’t maintain eye contact because they look at their gadgets and rattle on specifications. Note: The geek’s flirting methods may be ever so subtle, but it is still considered flirting.
  3. Geeks have a human touch, even during their geekiest moments, such as fixing your PC. Nerds don’t touch; they’re too busy flipping their pencils.
  4. Geeks can be sensitive, romantic and have a witty sense of humour. Nerds get romantic cutting code and playing with circuitboards.
  5. Geeks have style and a good fashion sense, even when they don’t have the physique for it. Nerds think that wearing a pen in your shirt pocket is the latest fashion accessory.
  6. Geeks can look cool in a suit if/when they wear one (ie job interviews). Nerds don’t look cool in anything.
  7. Geeks are sexy and can carry themselves with confidence. The words “nerds” and “sexy” are mutually exclusive.
  8. Geeks can be into sports and outdoor activities. Nerds are identified by pallor on their skin and loss of muscle tone; flipping pencils does not constitute a sport.
  9. Calling someone a geek can be a compliment; calling someone a nerd is derogatory.
  10. Geeks can be well-read and articulate. Nerds read hardware specs and installation guides for leisure.
  11. Geeks know they’re geeks, and they’re proud of it. Nerds don’t label themselves for fear of labels.
  12. Geeks and nerds have an inherent dislike of one another; I wonder why.
  13. Geeks can tell good jokes and laugh. Ever heard a nerd laugh?
  14. A nerd will offer to fix your computer for money. A geek will ask for other favours.
  15. Geeks take their girls to bed, nerds sleep at their desks.
  16. Geeks who talk in their sleep are likely to be dreaming of sex. Nerds who talk during their sleep speak of building computers*.

So now I hope this will never be mixed up again

Why Gentoo is dead :(

I finally removed myself from all the Gentoo mailing lists. I did this with some sad thoughts. I had been using gentoo for almost 4 Years and it tough me quite a lot about Linux. Unfortunately I have been seeing the Gentoo project die over the past Year or so. After going to the Gentoo UK meeting in 2006 I noticed that nothing important / technical was discussed. It was all about the flame wars going on on the mailing lists. "How do we get more girls into gentoo? etc..". My friends that joined me, are still joke about it (Thx Will + Edd). Already then I could see the crumbling of the base. After some time I noticed that more and more packages where without developers and people didn't answer emails anymore. Version didn't get updated. That was the time when I decided I had to move. Then packages.gentoo.org went down without a replacement. This was a big shock, that this had happened, as everyone I knew was using this too look for packages. I moved on but still read the newsletters and the mailing list. Then the weekly newsletter stopped coming and the mailing list became a collection of `packages up for grabs`. Further they dropped the spark architecture due to all the developers leaving. Then a friend told me that they pushed out a broken update for expat. After flaming down Daniel Robbins offer to come back to gentoo and help it to recover 2 times gentoo was doomed. I could go on for ever with what went wrong. But I think the gentoo people should have taken the BSD attitude a little more serious
"SHUT UP AND CODE"
And stay a distro for geeks and not try to get into the ubuntu market. Because of this hacking wasn't fun anymore.
No I only have to administer 2 more gentoo boxes that I don't update anymore and am waiting till I can replace them with something alive.

Update:
It seams like the gentoo people are noticing that have a problem:
http://spyderous.livejournal.com/95715.html

After reading some comments I must say I changed to arch about 6 month ago and I love it.
I know someone is going to post a reply telling me that this is all not true and anyway it is my fault but I am just going to delete it without reading that crap.

How to Simplify Your Life

A disgrace for the human race. Just to qualify I am 23, have a job that pays well and that makes me happy and I have a loving girlfriend. This book is definitely not for me. On the other hand if you are 45, you have a job you suck in and your wife has just left you with the kids and you are standing at the top of a very high house and about to jump you might want to read this book. For me, in my life situation, it was utter crap. Not only does it bore the shit out of you telling you, how arrange your wardrobe, no it spends the whole last chapter making you to a Christan warrior. "How do I pray" etc...
If you are, just a little, successful in life do not think about buying or even reading this book. Because you will know everything already. But as I already mentioned if you want to kill yourself and you want good to help you get on the right path, please PLEASE read it. Or maybe just kill yourself anyway.

Eclipse fu*king sweet feature

For Java programming I use eclipse because of laziness. Now I tripped over a really nice feature. If you press the key and hover over a method it becomes underlined by a little blue line. I normally used this to jump around in my own classes. Just now by accident I clicked on the String.concat method and eclipse showed me the source of java.lang.String. So I could actually read what the String class does. This is really sweet as through this you can actually learn how Java works.
Well done eclipse.
I have been trying eclipse with c{\ and,++} but it really couldn't convince me there. But Java and eclipse just work so nicely.

Buy the way, i tried NetBeans (6.0.1) and it is still utter crap.
bash-3.00$ strace -p 2564
Process 2564 attached - interrupt to quit
[ Process PID=2564 runs in 32 bit mode. ]
futex(0xf7fc9be8, FUTEX_WAIT, 2565, NULL

Cern Week 27

I bought a funky new Keyboard from Dell with a smart card reader. I spent some time writing a script that will start the screen saver when you pull the card and stop it when you put it back in. Further I did some work on putting my kerberos5 token on the card. This turned out to generate quite funky behavior in some programs (ssh for example). Further there was a root exploit for the Linux kernel, through which every user on a SLC5 machine could get root. Unfortunately SLC4 was not affected due to the very old kernel (2.6.9-67) so we got away with a blue eye. NodeCertCheck needed some minor modifications as 2 weeks warning in advance where not perceived to be long enough. So I changed it to 4 weeks. Now the manager will get 6 mails if he doesn't renew the Certificate. Then I added some methods in my rpm build scripts to sign my rpms. Nice for security a pain to add. Further I created a mailing list for my linux ldap user. So now everyone can subscribe to the linuxlda mailing list and get updates about what is going to happen on the Linux ldap side and ask some questions. As the load on my machine is getting more and more I requested a new machine so I can implement a little fail over cluster for production. I did some research into logrotate so my servers can save the log files at an appropriate time. This will be done through quattor in the production system. I tried to get OpenCVS working under Linux but failed miserably. Due to not having Bsd Make and other little things. So I will have to wait till OpenCVS is a little more mature or I get a day off.

Lock my screen with a smartcard

I bought a new Keyboard. A "Dell Smart Card Reader Keyboard" as the Name says it has a smartcard reader integrated in it. Now I wanted that if I pull the smartcard my screen locks and if I push it back in it unlocks. Here is the demon code to do so :

#!/usr/bin/perl

use ExtUtils::testlib;
use Chipcard::PCSC;
use Chipcard::PCSC::Card;

use Data::Dumper;

use warnings;
use strict;

my @mycard = [
59,
105,
0,
0,
36,
148,
1,
2,
1,
0,
1,
1,
169
];

sub compare_arrays {
my ($first, $second) = @_;
no warnings; # silence spurious -w undef complaints
return 0 unless @$first == @$second;
for (my $i = 0; $i < @$first; $i++) {
return 0 if $first->[$i] ne $second->[$i];
}
return 1;
}

sub checkCard(){
#-------------------------------------------------------------------------------
my $hContext = new Chipcard::PCSC();
return 1 unless (defined $hContext);

#-------------------------------------------------------------------------------
my @ReadersList = $hContext->ListReaders ();
return 1 unless (defined($ReadersList[0]));

#-------------------------------------------------------------------------------

my $hCard = new Chipcard::PCSC::Card ($hContext, $ReadersList[0]);
return 1 unless (defined($hCard));

#-------------------------------------------------------------------------------
my @StatusResult = $hCard->Status ();
return 1 unless (defined ($StatusResult[0]));

if (not compare_arrays(\@mycard ,\@{$StatusResult[3]})) {
return 0;
}

#-------------------------------------------------------------------------------

$hCard->Disconnect($Chipcard::PCSC::SCARD_LEAVE_CARD);
undef $hCard;
#-------------------------------------------------------------------------------

$hContext = undef;

}

my $forked =0;
daemonize();
while (1) {


# Device was found and command should be executed
if (checkCard()==0 && $forked == 1) {
system("/bin/sh -c \"killall xscreensaver\"");
system("/bin/sh -c \"xscreensaver -no-splash &\"");
$forked =0;
}

# Device is gone and command should be executed
elsif ( (checkCard()==1) && ($forked != 1) ) {

my $pid =fork();
if ($pid == 0) {
system("/bin/sh -c \"xscreensaver-command -activate\"");
exit(0);
}else{
$forked = 1;
}

}

sleep ( 2 );

}


# Become a daemon
sub daemonize
{
chdir("/");
close(STDIN);
close(STDOUT);
}

Thats why I hate ubuntu


After a system update I was confronted with this. I though Ubuntu was Linux and not Windows. Why would you need to restart Linux.

Limit Groups On Clusters With Ldap and quattor

File overview

  • /etc/ldap.conf
  • /etc/pam.d/system-auth
  • /etc/nsswitch.conf
  • Template

/etc/ldap.conf

As far as I understand there are 2 ways of limiting a box to a specific group. The first is to add every user to the specific group on the ldap server. And then configure the client to read this. The 2 values in ldap.conf are
# Group to enforce membership of
pam_groupdn cn=c3,ou=group,dc=example,dc=edu

# Group member attribute
pam_member_attribute memberUid

So the ldap entry would look something like

# dev, posixGroups, priv, root, com
dn: cn=c3,ou=posixGroups,dc=example,dc=org
cn: c3
objectClass: posixGroup
objectClass: top
gidNumber: 1016
memberUid: cn=didi,ou=People,dc=example,dc=org
memberUid: cn=jan,ou=People,dc=example,dc=org

This of course is a nice way of maneging dynamic groups but if you want to add a member you always have to fiddle with the ldap server and if you have a huge amount of users you can quickly loose the orientation (try doing this with 21717 users) The second way is to add a filter to the ldap search that pam_ldap / nss_ldap does.

As explained in my post http://computingfunnyfacts.blogspot.com/2008/01/pamfilter-not-working.html you have to very careful what you specify as a pam filter.

TIPP: Look at what the ldap server is processing. With $ slapd -d 256 you can get a nice queried overview.

To configure this with quattor you can use the authconfig module:

"/software/components/authconfig/method/ldap/enable" = true;
"/software/components/authconfig/method/ldap/nssonly" = false;
"/software/components/authconfig/method/ldap/conffile" = "/etc/ldap.conf";
"/software/components/authconfig/method/ldap/servers" = list ( "lolol.cern.ch" );
"/software/components/authconfig/method/ldap/basedn" = "dc=example,dc=edu";
"/software/components/authconfig/method/ldap/tls/enable" = false;
"/software/components/authconfig/method/ldap/binddn" = "cn=Manager,dc=example,dc=edu";
"/software/components/authconfig/method/ldap/bindpw" = "NFW";
"/software/components/authconfig/method/ldap/rootbinddn" = "cn=Manager,dc=example,dc=edu";
"/software/components/authconfig/method/ldap/port" = 389;
"/software/components/authconfig/method/ldap/timeouts/idle" = 3600;
"/software/components/authconfig/method/ldap/timeouts/bind" = 300;
"/software/components/authconfig/method/ldap/timeouts/search" = 300;
"/software/components/authconfig/method/ldap/pam_filter" = "gidNumber=1012";

Here the interesting part is the pam_filter which is supported from version 1.1.5

/etc/pam.d/system-auth

The default entry in system-auth is

account [default=bad success=ok user_unknown=ignore] /lib/security/$ISA/pam_ldap.so
which is not enough to fail if the user is not in the specified group.

So you have to change this into


account required /lib/security/$ISA/pam_ldap.so

this is best done through quattor with the authconfig module again. Just add


"/software/components/authconfig/pamadditions/system/conffile"="/etc/pam.d/system-auth";
"/software/components/authconfig/pamadditions/system/section"="account";
"/software/components/authconfig/pamadditions/system/lines"=list( nlist(
"order","last",
"entry","required /lib/security/$ISA/pam_ldap.so"
));
this will overwrite the entry with a more stricter configuration.

/etc/nsswitch.conf

Nswitch should be configured correctly by default but here just be sure the configuration I have been using:

# cat /etc/nsswitch.conf | egrep -v "(^#|^$)"
passwd: files ldap
shadow: files ldap
group: files ldap
hosts: files dns
bootparams: files
ethers: files
netmasks: files
networks: files
protocols: files ldap
rpc: files
services: files ldap
netgroup: files ldap
publickey: files
automount: files ldap
aliases: files

Template

Here an example template with some security important stuff removed:

############################################################
#
# object template profile_lolol
#
# Generated automatically with /distribution/remedy/programs/CDBAddHost script.
#
# Created Thu Jun 2 11:52:22 2005 by remedy
#
# Do NOT edit.
#
############################################################

object template profile_lolol;
include stages/prod;

#
# include profile_base for use of typed properties
#
include pro_declaration_profile_base;
"/software/components/access_control/privileges/acl_root/user/ribalba/0/targets"=list("+node::lolol");
"/software/components/access_control/privileges/acl_interactive/user/me/0/targets"=list("+node::lolol");

#
# used resources
#
include pro_hardware_elonex_2800_64;
include netinfo_lolol;
include pro_type_lxdev_slc4;
#include pro_service_java_sun;
"/hardware/contract" = create("pro_hardware_contract_it_3319");

"/system/cluster/subname" = "zuul";
"/system/function" = "Zuul dev machine / Didi, Jan - FIO/FS";

#
# "deregister" this box
#
"/software/packages" = pkg_del("CERN-CC-regis_client");
"/software/components/regisclient/active" = false;
"/software/components/sindes/all" = "";
delete "/software/components/sindes/items/group-header";
delete "/software/components/sindes/items/passwd-header";
"/software/packages" = pkg_del("ncm-localhomedir");
delete "/software/components/localhomedir";
delete "/system/accounts";

#
# Sendmail options
#
"/software/components/sendmail/localusers" = push("root");
"/software/components/sendmail/localusers" = push("operator");

#
# ncm-accounts
#
"/software/packages" = pkg_repl("ncm-accounts","3.0.5-1","noarch");

#
# So lets do some dev work
#
"/software/components/accounts/ldap" = true;

"/software/components/accounts/active" = true;
"/software/components/accounts/rootpwd" = "$1$HAHAHAHAHAHHAHA";
"/software/components/accounts/shadowpwd" = true;

#
# /etc/group : works fine!
#
"/software/components/accounts/groups" = nlist("ct",nlist("comment","undef","gid",1023),
"ci",nlist("comment","undef","gid",1016),
);

#
# /etc/passwd:
# - does not create /home/operator
# - quotes (") around the gecos field
#
"/software/components/accounts/users" =
nlist("operator",nlist(
"comment" , "Computer Operations",
"homeDir" , "/home/operator",
"createHome" , true,
"groups" , list(1023), # group names or gid's?
#"groups" , list("ct"), # group names or gid's?
"password" , "$1$HAHAHAHAHAHAHAHAHAHAHA",
"shell" , "/bin/tcsh",
"uid" , 616,
),
"oracle",nlist(
"comment" , "Oracle Support",
"homeDir" , "/ORA/dbs01/oracle/home",
"createHome" , true,
"groups" , list(1016), # group names or gid's?
"password" , "$1$HAHAHAHAHAHAHAHAHAHAHAH",
"shell" , "/bin/bash",
"uid" , 1286,
),
);

#
# ncm-authconfig
#
"/software/components/authconfig/active" = true;

"/software/components/authconfig/safemode" = false; # When set to true, no actual configuration will change

"/software/components/authconfig/usemd5" = true; # Enable the use of MD5 hashed password
"/software/components/authconfig/useshadow" = true; # Enable the use of shadow password files
"/software/components/authconfig/usecache" = true; # Enable or disable nscd operation
"/software/components/authconfig/startstop" = true; # ??? Undocumented ???

"/software/components/authconfig/method/files/enable" = true;

#"/software/components/authconfig/method/afs/enable" = false;
#"/software/components/authconfig/method/afs/cell" = "cern.ch";

"/software/components/authconfig/method/ldap/enable" = true;
"/software/components/authconfig/method/ldap/nssonly" = false;
"/software/components/authconfig/method/ldap/conffile" = "/etc/ldap.conf";
"/software/components/authconfig/method/ldap/servers" = list ( "lolol.cern.ch" );
"/software/components/authconfig/method/ldap/basedn" = "dc=example,dc=edu";
"/software/components/authconfig/method/ldap/tls/enable" = false;
"/software/components/authconfig/method/ldap/binddn" = "cn=Manager,dc=example,dc=edu";
"/software/components/authconfig/method/ldap/bindpw" = "NFW";
"/software/components/authconfig/method/ldap/rootbinddn" = "cn=Manager,dc=example,dc=edu";
"/software/components/authconfig/method/ldap/port" = 389;
"/software/components/authconfig/method/ldap/timeouts/idle" = 3600;
"/software/components/authconfig/method/ldap/timeouts/bind" = 30;
"/software/components/authconfig/method/ldap/timeouts/search" = 30;

"/software/components/authconfig/method/ldap/pam_filter" = "gidNumber=1012";

"/software/components/authconfig/method/nis/enable" = false;
"/software/components/authconfig/method/nis/domain" = "nikhef.nl";
"/software/components/authconfig/method/nis/servers" = list ( "ajax.nikhef.nl" );

"/software/components/authconfig/method/krb5/enable" = false;
"/software/components/authconfig/method/krb5/kdcs" = list ( "kdc.nikhef.nl" );
"/software/components/authconfig/method/krb5/adminserver" = list ( "krbadmin.nikhef.nl" );
"/software/components/authconfig/method/krb5/realm" = "NIKHEF.NL";

"/software/components/authconfig/pamadditions/system/conffile"="/etc/pam.d/system-auth";
"/software/components/authconfig/pamadditions/system/section"="account";
"/software/components/authconfig/pamadditions/system/lines"=list( nlist(
"order","last",
"entry","required /lib/security/$ISA/pam_ldap.so"
));



"/hardware/serialnumber" = "ch445-521-77";
# machine moved on 27.02.07 from = "ri17";

include pro_monitoring_hardware_elonex_2800;



"/hardware/cards/nic/0/hwid" = "xxxxxxxxxxxx";
include serial_map_lxc2ri25;
include diskinfo_lxb5477;

# machine moved on 02.03.07 from = "ri17";

"/hardware/rack/name" = "ri17";

-- Main.GeerdDietgerHoffmann - 04 Feb 2008

Cern Week 26

At the beginning of the week I wrote some scripts that on the one hand updated the pam rules in
/etc/pam.d/system.authconfig and updated the ldap.conf to respect these rules. I modified a quattor component to do so (ncm-autconfig). After some test at Nikhef (National institute for subatomic physics in Amsterdam) my patch set was pushed into production. My other posts go into more detail. Further I wrote some documantation about all the canges I had made so that other people could implement Ldap on theire machines. (https://twiki.cern.ch/twiki/bin/view/FIOgroup/LimitGroupsOnClustersWithLdap).
At last I got the OK from my boss to talk to the Windows guys to implement one Ldap server that everyone would use. Through this Windows and Linux can stay in sync without any mayor problems. After some political discussion ("Is Windows capable of processing this", etc...) we decided to just extend a already existing Windows server and Linux would sync with this. I created a public user that only has read writes and that can be used by the clients to query the data. Further I investigated into a database idea I had and still are. Further to come on this. And finally I played around with my new keyboard and tried to get it to authenticate me with a smart card.

Cern Week 25

This week I went to three presentations.
  1. A Dark Universe: Dark Matter and Dark Energy
  2. Which in general was about how the universe was created and how you can calculate the mass and the age.
  3. Germans at Cern
  4. Which was a delegation from German industries that talked about the involvement of Germany in the LHC project.
  5. The brain, an orchestra without conductor(Prof. SINGER, Wolf)
  6. This was basically my Artificial Intelligence course one step further. It was very interesting to find out in more detail how the brain works and how we can save data. Like that the short term memory can only hold about 6 things. That's why all those horrible party games work so nicely.

Further I started adding support for limiting specific groups for specific clusters through quattor templates. This was quite hard as pam_ldap.so has quite a few errors. So I ended up reading 4000 lines of C code and creating a Cern internal package which contains all my patches. Further I extended a quattor module to be able to add the 'pam_filter' to the /etc/ldap.conf file. After looking for an error for half a day I found that I had forgotten to update the PAM file. Which was quite frustrating.

pam_filter not working

So here is the problem you want to limit your cluster to a special user group. You have everything LDAP managed and use pam_ldap for authentication. But when you edit the /etc/ldap.conf and set a pam_filter nothing happens. First of all the the syntax of pam_filter :
(|(gidNumber=1028)(gidNumber=1160))
Will not work
Literally only
pam_filter gidNumber=1028
Will work. This is the way they stupidly implemented it
      else if (!strcasecmp (k, "pam_filter"))
{
CHECKPOINTER (result->filter = strdup (v));
}

where v is everything after the ' '

while (*v != '\0' && *v != ' ' && *v != '\t')
v++;

*(v++) = '\0';

For those that know C
So you can give it one value max. Now you have to modify the /etc/pam.d/system-auth file. The default configuration is:
[root@lxb5477 ~]# cat /etc/pam.d/system-auth.back | grep ldap
auth sufficient /lib/security/$ISA/pam_ldap.so use_first_pass
account [default=bad success=ok user_unknown=ignore] /lib/security/$ISA/pam_ldap.so
password sufficient /lib/security/$ISA/pam_ldap.so use_authtok
session optional /lib/security/$ISA/pam_ldap.so

But of course a optional is not really enough. You, of course, want that if the user doesn't fulfill your filter he should be chucked into nirvana. So change to:
[root@lxb5477 ~]# cat /etc/pam.d/system-auth | grep ldap
auth required /lib/security/$ISA/pam_ldap.so
account required /lib/security/$ISA/pam_ldap.so
password requried /lib/security/$ISA/pam_ldap.so use_authtok
session required /lib/security/$ISA/pam_ldap.so

Through this if ldap fails the login fails.

But be aware that in /etc/nsswitch.conf files is before ldap
passwd:     files ldap
shadow: files ldap
group: files ldap

Otherwise you have locked yourself out :)

Really nice idea

While registering for the BCS I had to supply a Email address, nothing special, but after that they asked me for an alternative Email. What now thinking about it is really clever. If my main server goes offline for some reason. (Gmail starts charging) they can always send messages to my alternative address so I don't lose information. One thing the BCS did well. One out of thousands they did absolutely disgrace full.

strcpy fu**ing easy

While trying to optimize some c code I had a look at the strcpy.c file and was astonished what to see there:

do
{
c = *s++;
s[off] = c;
}
while (c != '\0');

This is pretty much it. Some boundary checks. But THAT is it. And nearly all the files in glibc/string are like that.

update: (thx to Edd) the OpenBSD way of doing it
char *
strcpy(char *to, const char *from)
{
char *save = to;

for (; (*to = *from) != '\0'; ++from, ++to);
return(save);
}

Cern Week 24

I spent most of the week rewriting the
CERN-CC-NodeServiceManagerMsg
As already mentioned this tool scanns all the hosts and if the ssh certificate is about to expire sends an email to the responsible person. Further it creates a webpage so that people can easially check what has to be done.
After some analysis on the current program I decided to rewrite the whole thing. The old version was not maintained the guy who had written it had left and it looked more like a patchwork rung than a properly designed pice of code.
So following a lot of perl code some results
Some optimization I made

$ time CERN-CC-NodeServiceManagerMsg > /dev/null

real 1m12.080s
user 0m23.730s
sys 0m1.930s
$ time ./sendIt > /dev/null

real 0m1.514s
user 0m0.430s
sys 0m0.040s
and more

$ time ./CERN-CC-NodeCertCheck -m > /dev/null

real 0m0.784s
user 0m0.500s
sys 0m0.050s

While reducing the time for the program to run from 72 seconds to 0.78 seconds, I started adding more features, like command line options, showing the ok nodes, checking if the path where the web page should be created exists and if not create the whole path tree, etc... After this was all ok I started writing the spec file for the rpm. Further I wrote a little 'man page' after I had built a source rpm and a 'normal' rpm my package went into testing. After the results had came back and the only thing not Ok was a typo in the email. I started uploading the package onto the official cern repository and rolled it out.
Another thing I did was help a friend with png transparency under windows. Better the not existing one. So now his web page dynamically loads the appropriate image. png for Linux and gif for windows with a Internet Explorer version before 7. I further spent some time on my phone Perl rewrite which is turning out to be quite tricky. Not only because of the backwards compatibility.

Cern Week 23

This was a fairly short week, as I came back from holidays on Thursday. Nothing really has changed since I left. We are all preparing for LHC to start to fire (fingers crossed) so the Castor team is sweating and we are trying to get a untested version to run on SL4. Further I started a little project with Dan to rewrite the phone program, which hasn't been touched since 1999. Further I started writing a Perl script that will find out when a ssh certificate expires and then send an email to the systems admin or the person responsible (Not always the same). Not as easy as you would have thought. You can't run it on every machine. You have to query a huge Oracle database for when the Certificate was created and then find out who is responsible for that machine (root@localhost will NOT work) and then send a very nice email. I further started to set up a Cern chat server. Everything here is done par email. Because no one uses a chat program. This has to change I set up a Jabber server and am now trying to get it to work with the Cern nice login. Which despite the name is not nice because everything is done in SOAP.

Create a /etc/passwd out of ldap

I wanted to create the /etc/passwd and /etc/group file from my ldap server. As LDAP is now replacing these (having a backup is always good :) So here is the perl script that will do such a thing. Of course this is very Cern specific, you will have to modify it for your use. I wrote a script that used the Perl NET::Ldap module. But this was far too slow (3 min +-) . See below right at the end

 1: #!/usr/bin/perl -w
2: #
3: # A program that queries a ldap server and creates /etc/passwd and /etc/groups syntax files
4: #
5: # $Id: cpgfl.pl,v 1.7 2007/12/18 15:01:45 jveldik Exp $
6:
7: #All the includes
8: use strict;
9: use diagnostics;
10: use MIME::Base64;
11: use Data::Dumper;
12: $Data::Dumper::Sortkeys = 1;
13:
14: my $lockfile = "lock_the_file.loc";
15: my $ldappasswdfile = my $ldapgroufile = undef;
16:
17: my $lUsersQuery = '/usr/bin/ldapsearch -h lxb5479 -x -b "ou=People,dc=example,dc=edu" -D "cn=Manager,dc=example,dc=edu" -w youknow "(&(objectClass=posixAccount)(uid=*))" 2> /dev/null |';
18: my $lGroupQuery = '/usr/bin/ldapsearch -h lxb5479 -x -b "ou=Group,dc=example,dc=edu" -D "cn=Manager,dc=example,dc=edu" -w youknow "(&(objectClass=posixGroup)(cn=*))" 2> /dev/null |';
19:
20: sub createLock() {
21: if ( -e $lockfile ) {
22: warn("Program is already running: $lockfile exists\n");
23: exit(1);
24: }
25: open(LOCK, ">$lockfile" ) or die "Cannot open lock file!\n";
26: close(LOCK);
27: }
28:
29: sub releaseLock() {
30: unlink $lockfile;
31: }
32:
33: sub getPasswd () {
34: my %object;
35:
36: open( LDAP, $lUsersQuery ) or die("Cannot run ldapsearch: $!");
37:
38: createLock();
39: open( DAT, ">" . $ldappasswdfile );
40:
41: while (<LDAP>) {
42: chomp;
43: s/\s+$//; # remove trailing whitespace (if any...)
44:
if (/^$/) {
45:
46: #If an emtpy line and uid is defined do some stuff
47: if ( defined( $object{"uid"} ) && ( $object{"uid"} ne "" ) ) {
48:
49: #if ($object{"uid"}) {
50:
51: my $line = join( ":",
52: $object{"uid"}, $object{"userPassword"},
53: $object{"uidNumber"}, $object{"gidNumber"},
54: $object{"gecos"}, $object{"homeDirectory"},
55: $object{"loginShell"} );
56:
57: print DAT $line . "\n";
58: }
59: %object = ();
60: next;
61: }
62:
63: createObjectHash( \%object, $_ );
64:
65: }
66:
67: close DAT;
68: releaseLock();
69:
70: close(LDAP);
71:
72: }
73: ################################################################GROUPS####################
74:
75: sub getGroup () {
76:
77: my %object;
78: open( GROUP,$lGroupQuery ) or die("Cannot run ldapsearch: $!");
79:
80: createLock();
81: open( DAT, ">" . $ldapgroufile );
82:
83: while ( my $buff = <GROUP> ) {
84: chomp $buff;
85: $buff =~ s/\s+$//; # remove trailing whitespace (if any...)
86:
if ( $buff =~ /^$/ ) {
87:
88: #If an emtpy line and uid is defined do some stuff
89: if ( defined( $object{"cn"} ) && ( $object{"cn"} ne "" ) ) {
90:
91: #if ($object{"uid"}) {
92: my $line = join( ":",
93: $object{"cn"}, $object{"userPassword"},
94: $object{"gidNumber"}, "" );
95: print DAT $line . "\n";
96: }
97: %object = ();
98: next;
99: }
100: createObjectHash( \%object, $buff );
101:
102: }
103: close DAT;
104: releaseLock();
105:
106: close(GROUP);
107:
108: }
109:
110: sub createObjectHash($$) {
111: my ( $h_rObj, $comline ) = @_;
112:
113: my ( $lhs, $rhs ) = split( /:\s+/, $comline );
114:
115: #Because of (userPassword:: e2NyeXB0fXg=) the ::
116: if ( $lhs eq "userPassword:" ) {
117:
118: #Have to decode because it comes in base64 encodeing
119: my $a = decode_base64($rhs);
120:
121: #Now we have to get rid of the {crypt}
122: $a =~ s/\{crypt\}//g;
123:

124: $h_rObj->{"userPassword"} = $a;
125: }
126: else {
127: $h_rObj->{$lhs} = $rhs;
128: }
129:
130: }
131:
132: # AND OFF WE GO
133:
134: if ( scalar(@ARGV) == 2 ) {
135: $ldappasswdfile = $ARGV[0];
136: $ldapgroufile = $ARGV[1];
137: print "Getting group\n";
138: getGroup();
139: print "Getting passwd\n";
140: getPasswd();
141: }
142: else {
143: print("A program that gets passwd + group entries out of Ldap\n");
144: print("Usage : ./cpgfl.pl passwdfile groupfile\n");
145: }


And out of interrest here is the version that uses NET::LDAP


#!/usr/bin/perl
# A little program that creates a /etc/passwd from ldap
use strict;
use Net::LDAP;

# Please modify appropriate
my $ldap = Net::LDAP->new("lxb5479.cern.ch") or die "Error in creating new Connection: $@";;

$ldap->bind("cn=Manager,dc=example,dc=edu", password=>"IHATETHIS");

my $mesg = $ldap->search(filter=>"(&(objectClass=posixAccount)(uid=*))", base=>"ou=People,dc=example,dc=edu");

$mesg->code && die $mesg->error;

#########!!!DO NOT TOUCH!!!##########

#foreach my $entry ($mesg->entries) {

while (my $entry=$mesg->pop_entry ( )){

# Get rid of {crypt}
my $a = $entry->get_value("userPassword");
$a =~ s/\{crypt\}//g;

my $line = join (":", $entry->get_value("uid"),
$a ,
$entry->get_value("uidNumber") ,
$entry->get_value("gidNumber") ,
$entry->get_value("gecos") ,
$entry->get_value("homeDirectory") ,
$entry->get_value("loginShell") );
print $line . "\n";
}


$ldap->unbind;

#end