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

No comments: