1 |
<?php |
2 |
// |
3 |
// @(#)$Id$ |
4 |
// |
5 |
// nikEmployeeNumbers (nikENlib) retrieval and manipulation of employee numbers |
6 |
// from the Nikhef LDAP directory |
7 |
// for proper functioning it MUST connect to LDAP, and the password MUST |
8 |
// be configured in an external file (see config section below) |
9 |
// |
10 |
// this module exports the following functions |
11 |
// |
12 |
// function nikENfindEmployeeNumberByUid($uid) |
13 |
// retrieve the employee number of user <uid> |
14 |
// function nikENfindUidByEmployeeNumber($employeeNumber) |
15 |
// retrieve the uid for employee <number> |
16 |
// function nikENfindCNByEmployeeNumber($employeeNumber) |
17 |
// retrieve the friendly common name for employee <number> |
18 |
// function nikENfindCNByUid($uid) |
19 |
// retrieve the friendly common name for user <uid> |
20 |
// function nikENlistAllElegibleUids() |
21 |
// get a list of all <uids> that match the LDAP filter |
22 |
// function nikENlistAllElegibleEmployeeNumbers() |
23 |
// get a list of all <employee numbers> that match the LDAP filter |
24 |
// |
25 |
// If you want to do bulk-operations (such as reporting) it is faster |
26 |
// to first cache *all* of the possible entries. This is done implicitly |
27 |
// by the "nikENlistAllElegible*" functions, but it may be called |
28 |
// explicitly via |
29 |
// function nikENcacheLdap() |
30 |
// retrieve all relevant entries from LDAP and cache in memory |
31 |
// |
32 |
// NOTES |
33 |
// This library is designed to work with the NikIdM system, and may |
34 |
// not be suitable for any other purpose (or even for any purpose) |
35 |
// |
36 |
// FILES /usr/local/etc/nikENconfig.conf |
37 |
// a <attribute> <value> file with the following permitted directives |
38 |
// "(binddn|bindpw|ldapurl|ldapdit|ldapfilter)"A |
39 |
// The default LDAP filter for finding elegible employees is |
40 |
// (&(employeeNumber=*)(eduPersonAffiliation=employee)) |
41 |
// and any filter MUSt be enclosed in brackets |
42 |
// |
43 |
// BUGS |
44 |
// may be present, exterminate them with DDT |
45 |
// |
46 |
// --------------------------------------------------------------------------- |
47 |
// static configuration, override via config file |
48 |
$nikENconfigFile="/usr/local/etc/nikENconfig.conf"; |
49 |
$nikENbindDN="cn=agent-mortal-urenreg,ou=Managers,dc=farmnet,dc=nikhef,dc=nl"; |
50 |
$nikENbindPassword="USE_CONFIG_FILE_FOR_THIS_PLEASE"; |
51 |
$nikENldapUrl="ldaps://ldap.nikhef.nl/"; |
52 |
$nikENldapDIT="ou=LocalUsers,dc=farmnet,dc=nikhef,dc=nl"; |
53 |
$nikENldapFilter="(&(employeeNumber=*)(eduPersonAffiliation=employee))"; |
54 |
$nikENtesting=0; |
55 |
|
56 |
// --------------------------------------------------------------------------- |
57 |
// base code |
58 |
if ( !file_exists($nikENconfigFile) ) { |
59 |
error_log("nikEmployeeNumber: invoked, but no config file found"); |
60 |
exit(1); |
61 |
} |
62 |
if ( !$fh = fopen($nikENconfigFile,"r") ) { |
63 |
error_log("nikEmployeeNumber: cannot open config file $nikENconfigFile"); |
64 |
exit(1); |
65 |
} |
66 |
while (!feof($fh)) { |
67 |
$nikENcLine = fgets($fh,8192); |
68 |
if ( $nikENcLine === false ) break; |
69 |
rtrim($nikENcLine); |
70 |
if (!preg_match("/^(binddn|bindpw|ldapurl|ldapdit|ldapfilter)\s+(.*)$/", |
71 |
$nikENcLine,$nikENcm)) { |
72 |
error_log("nikEmployeeNumber: syntax error in config file"); |
73 |
exit(1); |
74 |
} |
75 |
if ( $nikENcm[1] == "binddn" ) $nikENbindDN=$nikENcm[2]; |
76 |
if ( $nikENcm[1] == "bindpw" ) $nikENbindPassword=$nikENcm[2]; |
77 |
if ( $nikENcm[1] == "ldapurl" ) $nikENldapUrl=$nikENcm[2]; |
78 |
if ( $nikENcm[1] == "ldapdit" ) $nikENldapDIT=$nikENcm[2]; |
79 |
if ( $nikENcm[1] == "ldapfilter" ) $nikENldapFilter=$nikENcm[2]; |
80 |
} |
81 |
fclose($fh); |
82 |
|
83 |
if ( !preg_match("/^\(.*=.*\)$/",$nikENldapFilter) ) { |
84 |
error_log("nikENlib: LDAP filter expression invalid"); exit(1); |
85 |
} |
86 |
if ( !preg_match("/^ldaps?:\/\/\w+\.\w+.*\/.*$/",$nikENldapUrl) ) { |
87 |
error_log("nikENlib: LDAP server URL invalid syntax"); exit(1); |
88 |
} |
89 |
if ( !preg_match("/^\w+=.*,\w+=.*$/",$nikENldapDIT) ) { |
90 |
error_log("nikENlib: LDAP DIT invalid syntax"); exit(1); |
91 |
} |
92 |
if ( !preg_match("/^\w+=.*,\w+=.*$/",$nikENbindDN) ) { |
93 |
error_log("nikENlib: LDAP bind DN invalid syntax"); exit(1); |
94 |
} |
95 |
|
96 |
// --------------------------------------------------------------------------- |
97 |
// public API function |
98 |
// |
99 |
function nikENfindEmployeeNumberByUid($uid) { |
100 |
global $nikENemplNoByUid,$nikENUidByEmplNo,$nikENCNByUid; |
101 |
if (!preg_match("/[a-z0-9]{1,16}/",$uid)) { |
102 |
error_log("nikENfindEmployeeNumberByUid invoked with non-alpha ". |
103 |
"or too long argument"); |
104 |
exit(1); |
105 |
} |
106 |
if ( isset($nikENemplNoByUid[$uid]) ) return $nikENemplNoByUid[$uid]; |
107 |
if ( ! nikENldapRetrieve("uid",$uid) ) return false; |
108 |
return $nikENemplNoByUid[$uid]; |
109 |
} |
110 |
|
111 |
function nikENfindUidByEmployeeNumber($employeeNumber) { |
112 |
global $nikENemplNoByUid,$nikENUidByEmplNo,$nikENCNByUid; |
113 |
if (!preg_match("/\d+/",$employeeNumber)) { |
114 |
error_log("nikENfindUidByEmployeeNumber invoked with non-numeric argument"); |
115 |
exit(1); |
116 |
} |
117 |
if ( isset( $nikENUidByEmplNo[$employeeNumber]) ) |
118 |
return $nikENUidByEmplNo[$employeeNumber]; |
119 |
if ( ! nikENldapRetrieve("employeenumber",$employeeNumber) ) return false; |
120 |
return $nikENUidByEmplNo[$employeeNumber]; |
121 |
} |
122 |
|
123 |
function nikENfindCNByEmployeeNumber($employeeNumber) { |
124 |
global $nikENemplNoByUid,$nikENUidByEmplNo,$nikENCNByUid; |
125 |
if (!preg_match("/\d+/",$employeeNumber)) { |
126 |
error_log("nikENfindUidByEmployeeNumber invoked with non-numeric argument"); |
127 |
exit(1); |
128 |
} |
129 |
if ( isset( $nikENUidByEmplNo[$employeeNumber]) ) |
130 |
return $nikENUidByEmplNo[$employeeNumber]; |
131 |
if ( ! nikENldapRetrieve("employeenumber",$employeeNumber) ) return false; |
132 |
return $nikENCNByUid[$nikENUidByEmplNo[$employeeNumber]]; |
133 |
} |
134 |
|
135 |
function nikENfindCNByUid($uid) { |
136 |
global $nikENemplNoByUid,$nikENUidByEmplNo,$nikENCNByUid; |
137 |
if (!preg_match("/[a-z0-9]{1,16}/",$uid)) { |
138 |
error_log("nikENfindEmployeeNumberByUid invoked with non-alpha ". |
139 |
"or too long argument"); |
140 |
exit(1); |
141 |
} |
142 |
if ( isset( $nikENCNByUid[$uid]) ) |
143 |
return $nikENCNByUid[$uid]; |
144 |
if ( ! nikENldapRetrieve("uid",$uid) ) return false; |
145 |
return $nikENCNByUid[$uid]; |
146 |
} |
147 |
|
148 |
function nikENlistAllElegibleUids() { |
149 |
global $nikENemplNoByUid,$nikENUidByEmplNo,$nikENCNByUid; |
150 |
nikENcacheLdap(); |
151 |
return array_keys($nikENemplNoByUid); |
152 |
} |
153 |
|
154 |
function nikENlistAllElegibleEmployeeNumbers() { |
155 |
global $nikENemplNoByUid,$nikENUidByEmplNo,$nikENCNByUid; |
156 |
nikENcacheLdap(); |
157 |
return array_keys($nikENUidByEmplNo); |
158 |
} |
159 |
|
160 |
// --------------------------------------------------------------------------- |
161 |
// Internal support functions |
162 |
// |
163 |
function nikENldapInit() { |
164 |
global $nikENbindDN,$nikENbindPassword,$nikENldapUrl; |
165 |
global $nikENds; |
166 |
|
167 |
if ( ! ($nikENds = ldap_connect($nikENldapUrl) ) ) { |
168 |
error_log("nikEmployeeNumber: cannot connect to LDAP server"); |
169 |
return false; |
170 |
} |
171 |
if ( ! ($bindresult = ldap_bind($nikENds,$nikENbindDN,$nikENbindPassword) )) { |
172 |
error_log("nikEmployeeNumber: cannot bind to LDAP as agent"); |
173 |
return false; |
174 |
} |
175 |
return true; |
176 |
} |
177 |
|
178 |
function nikENcacheLdap() { |
179 |
global $nikENds; |
180 |
global $nikENldapDIT,$nikENldapFilter; |
181 |
global $nikENemplNoByUid; |
182 |
global $nikENUidByEmplNo; |
183 |
global $nikENCNByUid; |
184 |
|
185 |
if ( isset($nikENCNbyUid) ) return true; |
186 |
|
187 |
if ( !isset($nikENds) ) { |
188 |
if (!nikENldapInit()) return false; |
189 |
} |
190 |
|
191 |
$searchresult = ldap_search($nikENds,$nikENldapDIT,$nikENldapFilter, |
192 |
array("uid","cn","employeeNumber")); |
193 |
if ( !$searchresult ) { |
194 |
error_log("nikEmployeeNumber: nikENcacheLdap cannot search directory"); |
195 |
return false; |
196 |
} |
197 |
|
198 |
$gentries = ldap_get_entries($nikENds, $searchresult); |
199 |
for ( $i=0 ; $i < $gentries["count"] ; $i++) { |
200 |
// skip this entry unless we have some actual useful data |
201 |
if ( !isset($gentries[$i]["cn"][0]) || !$gentries[$i]["cn"][0] ) continue; |
202 |
if ( !isset($gentries[$i]["uid"][0]) || !$gentries[$i]["uid"][0] ) continue; |
203 |
if ( !isset($gentries[$i]["employeenumber"][0]) || !$gentries[$i]["employeenumber"][0] ) continue; |
204 |
|
205 |
$nikENUidByEmplNo[$gentries[$i]["employeenumber"][0]] = |
206 |
$gentries[$i]["uid"][0]; |
207 |
$nikENemplNoByUid[$gentries[$i]["uid"][0]] = |
208 |
$gentries[$i]["employeenumber"][0]; |
209 |
$nikENCNByUid[$gentries[$i]["uid"][0]] = $gentries[$i]["cn"][0]; |
210 |
} |
211 |
|
212 |
ldap_close($nikENds); |
213 |
unset($nikENds); |
214 |
|
215 |
return true; |
216 |
} |
217 |
|
218 |
function nikENldapRetrieve($attr,$value) { |
219 |
global $nikENds,$nikENldapDIT,$nikENldapFilter; |
220 |
global $nikENemplNoByUid,$nikENUidByEmplNo,$nikENCNByUid; |
221 |
|
222 |
if ( !preg_match("/^(cn|uid|employeenumber)$/",$attr) ) { |
223 |
error_log("nikENldapRetrieve invoked with invalid attribute name"); |
224 |
return false; |
225 |
} |
226 |
|
227 |
if ( !isset($nikENds) ) nikENldapInit(); |
228 |
if ( !isset($nikENds) ) return false; |
229 |
|
230 |
$searchresult = ldap_search($nikENds,$nikENldapDIT, |
231 |
"(&($attr=$value)$nikENldapFilter)",array("uid","cn","employeeNumber")); |
232 |
if ( !$searchresult ) { |
233 |
error_log("nikEmployeeNumber: nikENldapRetrieve cannot search directory for $attr"); |
234 |
return false; |
235 |
} |
236 |
|
237 |
$gentries = ldap_get_entries($nikENds, $searchresult); |
238 |
// skip this entry unless we have some actual useful data |
239 |
if ( !isset($gentries) || $gentries["count"] != 1 ) return false; |
240 |
if ( !isset($gentries[0]["cn"][0]) || !$gentries[0]["cn"][0] ) return false; |
241 |
if ( !isset($gentries[0]["uid"][0]) || |
242 |
!$gentries[0]["uid"][0] ) return false; |
243 |
if ( !isset($gentries[0]["employeenumber"][0]) || |
244 |
!$gentries[0]["employeenumber"][0] ) return false; |
245 |
|
246 |
$nikENUidByEmplNo[$gentries[0]["employeenumber"][0]] = |
247 |
$gentries[0]["uid"][0]; |
248 |
$nikENemplNoByUid[$gentries[0]["uid"][0]] = |
249 |
$gentries[0]["employeenumber"][0]; |
250 |
$nikENCNByUid[$gentries[0]["uid"][0]] = $gentries[0]["cn"][0]; |
251 |
|
252 |
return true; |
253 |
} |
254 |
|
255 |
|
256 |
|
257 |
// --------------------------------------------------------------------------- |
258 |
// --------------------------------------------------------------------------- |
259 |
// Examples and unit tests |
260 |
// |
261 |
|
262 |
if ( $nikENtesting ) { |
263 |
print "<html><head><title>Testing nikEN</title></head>\n<body>\n<pre>\n"; |
264 |
print "employeeNumber of davidg is ".nikENfindEmployeeNumberByUid("davidg")."\n"; |
265 |
print "Name of davidg is ".nikENfindCNByUid("davidg")."\n"; |
266 |
print "Name of employee 35470 is ".nikENfindCNByEmployeeNumber(35470)."\n"; |
267 |
|
268 |
print "The following people are elegible to urenreg:\n"; |
269 |
foreach ( nikENlistAllElegibleUids() as $k ) { |
270 |
print " $k\n"; |
271 |
} |
272 |
|
273 |
print "\n</pre>\n</body></html>\n"; |
274 |
} |