1 #!/usr/bin/perl
2 #
3 # Igor Muratov <migor@altlinux.org>
4 #
5 # Find changes at LDAP and put this to filesystem
6 #
7 #
8 # Igor Muratov <migor@altlinux.org>
9 # 20041004
10 # - Added rebuildVirtual function
11 #
12 # Igor Muratov <migor@altlinux.org>
13 # 20040617:
14 # - Changed search fiter to exclude gosaUserTemplate entries
15 #
16 # Simon Liebold <s.liebold@gmx.de>:
17 # 20040617:
18 # - Changed $TS_FILE-location
19 #
20 # $Id: goAgent.pl,v 1.4 2004/11/19 21:46:56 migor-guest Exp $
21 #
23 use strict;
24 use Net::LDAP;
26 my $LDAP_HOST='localhost';
27 my $LDAP_PORT='389';
28 my $LDAP_BASE='dc=example,dc=com';
29 #my $LDAP_USER='cn=admin,dc=example,dc=com';
30 #my $LDAP_PASS='secret';
32 my $HOME_DIR='/home';
33 my $TS_FILE='/tmp/gosa_timestamp';
34 my $KEYS_DIR='/etc/openssh/authorized_keys2';
35 my $MAIL_DIR='/var/spool/mail';
36 my $VLOCAL='/etc/postfix/virtual_local';
37 my $VFORWARD='/etc/postfix/virtual_forward';
38 my ($ldap, $mesg, $entry);
39 my $virtuals = 0;
41 # Anonymous bind to LDAP
42 sub anonBind
43 {
44 my $ldap = Net::LDAP->new( $LDAP_HOST, port => $LDAP_PORT );
45 my $mesg = $ldap->bind();
46 $mesg->code && die $mesg->error;
47 return $ldap;
48 }
50 # Bind as LDAP user
51 #sub userBind
52 #{
53 # my $ldap = Net::LDAP->new( $LDAP_HOST, port => $LDAP_PORT );
54 # my $mesg = $ldap->bind($LDAP_USER, password=>$LDAP_PASS);
55 # $mesg->code && die $mesg->error;
56 # return $ldap;
57 #}
59 # Read timestamp
60 sub getTS
61 {
62 open(F, "< $TS_FILE");
63 my $ts = <F>;
64 chop $ts;
65 $ts ||= "19700101000000Z";
66 return $ts;
67 }
69 # save timestamp
70 sub putTS
71 {
72 my $ts = `date -u '+%Y%m%d%H%M%SZ'`;
73 open(F, "> $TS_FILE");
74 print F $ts;
75 }
77 sub rebuildVirtuals
78 {
79 print "Rebuild virtuals table for postfix\n";
80 $mesg = $ldap->search(
81 base => $LDAP_BASE,
82 filter => "(&(objectClass=gosaMailAccount)(gosaMailDeliveryMode=[*L*])(|(mail=*)(gosaMailAlternateAddress=*)))",
83 attrs => [
84 'mail',
85 'uid',
86 'gosaMailForwardingAddress',
87 'memberUid'
88 ],
89 );
91 # Work if changes is present
92 open(VIRT, "> $VLOCAL");
93 foreach my $entry ($mesg->all_entries)
94 {
95 foreach my $addr ($entry->get_value('mail'))
96 {
97 print VIRT "$addr\t";
98 print VIRT join(",", (
99 $entry->get_value("uid"),
100 $entry->get_value("gosaMailForwardingAddress"),
101 $entry->get_value("memberUid"),
102 ));
103 print VIRT "\n";
104 }
105 }
106 close(VIRT);
107 `postmap $VLOCAL`;
109 $mesg = $ldap->search(
110 base => $LDAP_BASE,
111 filter => "(&(objectClass=gosaMailAccount)(!(gosaMailDeliveryMode=[*L*]))(|(mail=*)(gosaMailAlternateAddress=*)))",
112 attrs => [
113 'gosaMailForwardingAddress',
114 ],
115 );
117 # Work if changes is present
118 open(VIRT, "> $VFORWARD");
119 foreach my $entry ($mesg->all_entries)
120 {
121 foreach my $addr ($entry->get_value('mail'))
122 {
123 print VIRT "$addr\t";
124 print VIRT join(",", (
125 $entry->get_value("gosaMailForwardingAddress"),
126 ));
127 print VIRT "\n";
128 }
129 }
130 close(VIRT);
131 `postmap $VFORWARD`;
132 }
134 sub posixAccount
135 {
136 my $entry = shift;
137 my $uid = ($entry->get_value('uid'))[0];
138 my $home = ($entry->get_value('homeDirectory'))[0];
139 my $uidNumber = ($entry->get_value('uidNumber'))[0];
140 my $gidNumber = ($entry->get_value('gidNumber'))[0];
142 print "Update posixAccount: $uid\n";
143 `install -dD -m0701 -o$uidNumber:$gidNumber $home`;
144 #`install -d -m0700 -o$uidNumber:$gidNumber $home/.ssh`;
145 #`install -d -m0751 -o$uidNumber:$gidNumber $home/.public_html`;
146 print "\tEntry ".$entry->dn()." updated\n";
147 }
149 # Get ssh keys and place to system directory
150 sub strongAuthenticationUser
151 {
152 my $entry = shift;
153 my $uid = ($entry->get_value('uid'))[0];
154 open(KEYS, "> $KEYS_DIR/$uid");
155 print KEYS $_ foreach ($entry->get_value('userCertificate;binary'));
156 }
158 # Create mailbox if need
159 sub inetLocalMailRecipient
160 {
161 my $entry = shift;
162 my $uid = ($entry->get_value('uid'))[0];
163 my $mail = ($entry->get_value('mailLocalAddress'))[0];
164 my $addr = ($entry->get_value('mailRoutingAddress'))[0];
165 my $uidNumber = ($entry->get_value('uidNumber'))[0];
166 my $mailbox = "$MAIL_DIR/$uid";
168 print "Update inetLocalMailRecipient: $mail\n";
169 if( $uid eq $addr )
170 {
171 if( -f "$mailbox" )
172 {
173 print "Warning: mailbox $mailbox alredy exists. No changes.\n";
174 } else {
175 `install -m660 -o$uidNumber -gmail /dev/null $mailbox`;
176 }
177 }
178 print "\tEntry ".$entry->dn()." updated\n";
179 }
181 sub disassemble
182 {
183 my $entry = shift;
185 foreach my $attr ($entry->get_value('objectClass'))
186 {
187 if( $attr eq "posixAccount" ) {
188 posixAccount($entry);
189 } elsif( $attr eq "inetLocalMailRecipient" ) {
190 inetLocalMailRecipient($entry);
191 } elsif( $attr eq "strongAuthenticationUser" ) {
192 strongAuthenticationUser($entry);
193 } elsif( $attr eq "gosaMailAccount" ) {
194 $virtuals++;
195 }
196 }
197 }
199 #
200 # Start main process
201 #
203 # Read timestamp from file
204 my $ts = getTS;
206 $ldap = anonBind;
207 $mesg = $ldap->search(
208 base => $LDAP_BASE,
209 filter => "(&(modifyTimestamp>=$ts)(!(objectClass=gosaUserTemplate)))"
210 );
212 # Put timestamp to file
213 putTS;
215 # Work if changes is present
216 if($mesg->count > 0)
217 {
218 print "Processing records modified after $ts\n\n";
220 foreach my $entry ($mesg->all_entries)
221 {
222 disassemble($entry);
223 }
224 rebuildVirtuals if $virtuals;
225 }