1 | /******************************************************************* |
---|
2 | * main.c |
---|
3 | * |
---|
4 | * LDAP plugin for pppd. Performs PAP authentication and sets |
---|
5 | * pppd parameters using LDAP as a backend. |
---|
6 | * |
---|
7 | * Copyright (c) Nordcomp LTD, Syktyvkar, Russian Federation |
---|
8 | * Initial version written by Grigoriy Sitkarev <sitkarew@nordcomp.ru> |
---|
9 | * |
---|
10 | * This plugin may be distributed according to the terms of the GNU |
---|
11 | * General Public License, version 2 or any later version. |
---|
12 | * |
---|
13 | ********************************************************************/ |
---|
14 | /* |
---|
15 | * 2004/05/17: first release!!! :) v 0.10 |
---|
16 | * |
---|
17 | * 2004/05/19: Small bugfix. If peer's address was specified by pppd options |
---|
18 | * at startup use it if can't get if from LDAP. Usefull feature for those |
---|
19 | * who needn't have per-user fixed IP for one part and define fixed IP for |
---|
20 | * another through LDAP. |
---|
21 | * |
---|
22 | * 2004/05/20: Cleanups. IP address handling improved. |
---|
23 | * |
---|
24 | * 2004/05/21: Plugin can talk TLS/SSL now. Added a hack to run with servers |
---|
25 | * which can use only LDAPS. Code seems beeing more clean. Created TODO file. |
---|
26 | * v 0.11 --> v 0.11b |
---|
27 | * |
---|
28 | * 2004/05/30: Plugin can log ppp session data (login, line, IP, time etc) to |
---|
29 | * ppp_utmp file. A simple tool "ppp_list" can list active entries. New option |
---|
30 | * "lutmp" introduced. This functionality NEEDS COMPEHENSIVE TESTING. |
---|
31 | * v 0.11b --> v 0.12 |
---|
32 | * |
---|
33 | * 2004/04/03: VERY DIRTY bugs fixed in new code. Shame of you, Grisha!!! :)) |
---|
34 | * Didn't I told that code needs testing? |
---|
35 | * v 0.12a --> v 0.12b |
---|
36 | */ |
---|
37 | |
---|
38 | #include <stdio.h> |
---|
39 | #include <string.h> |
---|
40 | #include <errno.h> |
---|
41 | #include <sys/types.h> |
---|
42 | #include <sys/socket.h> |
---|
43 | #include <arpa/inet.h> |
---|
44 | #include <sys/fcntl.h> |
---|
45 | |
---|
46 | #include <netinet/in.h> |
---|
47 | #include <ldap.h> |
---|
48 | |
---|
49 | #include "pppd.h" |
---|
50 | #include "fsm.h" |
---|
51 | #include "ipcp.h" |
---|
52 | #include "lcp.h" |
---|
53 | #include "main.h" |
---|
54 | |
---|
55 | #include "ppp_utmp.h" |
---|
56 | |
---|
57 | char pppd_version[] = VERSION; |
---|
58 | static char rcsid[] = "$Id: main.c, v 0.12b-DatuX 2006/11/16 13:37:00 Erwin Drent Exp$"; |
---|
59 | |
---|
60 | #ifndef LDAP_FILT_MAXSIZ |
---|
61 | #define LDAP_FILT_MAXSIZ 1024 |
---|
62 | #endif |
---|
63 | |
---|
64 | static char ldap_host[MAX_BUF] = "localhost"; |
---|
65 | static char ldap_dn[MAX_BUF]; |
---|
66 | static char ldap_pw[MAX_BUF]; |
---|
67 | static char userbasedn[MAX_BUF]; |
---|
68 | static int ldap_port = LDAP_PORT; |
---|
69 | static int ldap_timeout = 15; |
---|
70 | static int ldap_nettimeout = 10; |
---|
71 | static bool ldap_usetls = 0; |
---|
72 | static bool lutmp = 0; |
---|
73 | |
---|
74 | static struct ldap_data ldap_data; |
---|
75 | |
---|
76 | static option_t ldap_options[] = { |
---|
77 | |
---|
78 | { "ldaphost", o_string, ldap_host, |
---|
79 | "LDAP server host name", |
---|
80 | OPT_PRIV | OPT_STATIC, NULL, (MAX_BUF - 1)}, |
---|
81 | |
---|
82 | { "ldapdn", o_string, ldap_dn, |
---|
83 | "DN to bind with to LDAP server", |
---|
84 | OPT_PRIV | OPT_STATIC, NULL, (MAX_BUF - 1)}, |
---|
85 | |
---|
86 | { "ldappw", o_string, ldap_pw, |
---|
87 | "DN password", |
---|
88 | OPT_PRIV | OPT_STATIC, NULL, (MAX_BUF - 1)}, |
---|
89 | |
---|
90 | { "ldapport", o_int, &ldap_port, |
---|
91 | "LDAP server port", |
---|
92 | OPT_PRIV | OPT_STATIC}, |
---|
93 | |
---|
94 | { "userbasedn", o_string, userbasedn, |
---|
95 | "LDAP user base DN", |
---|
96 | OPT_PRIV | OPT_STATIC, NULL, (MAX_BUF - 1)}, |
---|
97 | |
---|
98 | { "ldaptimeout", o_int, &ldap_timeout, |
---|
99 | "LDAP search timeout", |
---|
100 | OPT_PRIV | OPT_STATIC}, |
---|
101 | |
---|
102 | { "ldapnettimeout", o_int, &ldap_nettimeout, |
---|
103 | "LDAP network activity timeout", |
---|
104 | OPT_PRIV | OPT_STATIC }, |
---|
105 | #ifdef OPT_WITH_TLS |
---|
106 | { "ldapusetls", o_bool, &ldap_usetls, |
---|
107 | "Connect to LDAP server using TLS", 1}, |
---|
108 | #endif |
---|
109 | |
---|
110 | { "lutmp", o_bool, &lutmp, |
---|
111 | "Write session data to ppp_utmp", 1}, |
---|
112 | |
---|
113 | { NULL } |
---|
114 | }; |
---|
115 | |
---|
116 | int plugin_init() |
---|
117 | { |
---|
118 | add_options(ldap_options); |
---|
119 | pap_check_hook = ldap_pap_check; |
---|
120 | pap_auth_hook = ldap_pap_auth; |
---|
121 | ip_choose_hook = ldap_ip_choose; |
---|
122 | allowed_address_hook = ldap_address_allowed; |
---|
123 | |
---|
124 | add_notifier(&ip_down_notifier, ldap_ip_down, NULL); |
---|
125 | add_notifier(&ip_up_notifier, ldap_ip_up, NULL); |
---|
126 | |
---|
127 | info("LDAP: plugin initialized."); |
---|
128 | } |
---|
129 | |
---|
130 | /* |
---|
131 | * FUNCTION: ldap_pap_auth() |
---|
132 | * PURPOSE: Authenticates PAP user against LDAP server. |
---|
133 | * |
---|
134 | * ARGUMENTS: |
---|
135 | * user - user name |
---|
136 | * password - user password |
---|
137 | * msgp - PAP message to send |
---|
138 | * |
---|
139 | * RETURN: 0 - Supplied username/password values incorrect |
---|
140 | * 1 - Success |
---|
141 | * -1 - Error, proceed to normal pap-options file |
---|
142 | */ |
---|
143 | |
---|
144 | static int ldap_pap_auth(char *user, char *password, char **msgp, |
---|
145 | struct wordlist **paddrs, struct wordlist **popts) |
---|
146 | { |
---|
147 | int rc,ldap_errno; |
---|
148 | int version = LDAP_VERSION3; |
---|
149 | char filter[LDAP_FILT_MAXSIZ]; |
---|
150 | char userdn[MAX_BUF]; |
---|
151 | char **ldap_values; |
---|
152 | LDAP *ldap; |
---|
153 | LDAPMessage *ldap_mesg; |
---|
154 | LDAPMessage *ldap_entry; |
---|
155 | |
---|
156 | /* Initiate session and bind to LDAP server */ |
---|
157 | |
---|
158 | |
---|
159 | if ((ldap = ldap_init(ldap_host, ldap_port)) == NULL) { |
---|
160 | error("LDAP: failed to initialize session\n"); |
---|
161 | return -1; |
---|
162 | } |
---|
163 | |
---|
164 | /* Set LDAP specific options such as timeout, version and tls */ |
---|
165 | |
---|
166 | if ((rc = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, |
---|
167 | &version) != LDAP_OPT_SUCCESS)) { |
---|
168 | error("LDAP: failed to set protocol version\n"); |
---|
169 | return -1; |
---|
170 | } |
---|
171 | |
---|
172 | if ((rc = ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, |
---|
173 | &ldap_nettimeout) != LDAP_OPT_SUCCESS)) { |
---|
174 | error("LDAP: failed to set network timeout version\n"); |
---|
175 | return -1; |
---|
176 | } |
---|
177 | |
---|
178 | if ((rc = ldap_set_option(ldap, LDAP_OPT_TIMELIMIT, |
---|
179 | &ldap_timeout) != LDAP_OPT_SUCCESS)) { |
---|
180 | error("LDAP: failed to set timeout option\n"); |
---|
181 | return -1; |
---|
182 | } |
---|
183 | |
---|
184 | #ifdef OPT_WITH_TLS |
---|
185 | |
---|
186 | /* Some servers support only LDAPS but not TLS */ |
---|
187 | if ((ldap_port == LDAPS_PORT) && ldap_usetls) { |
---|
188 | int tls_opt = LDAP_OPT_X_TLS_HARD; |
---|
189 | if ((rc = ldap_set_option(ldap, LDAP_OPT_X_TLS, |
---|
190 | (void *)&tls_opt)) != LDAP_SUCCESS) { |
---|
191 | ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno); |
---|
192 | error("LDAP: failed to set TLS option: %s\n", ldap_err2string(rc)); |
---|
193 | return -1; |
---|
194 | } |
---|
195 | } |
---|
196 | |
---|
197 | if (ldap_usetls) { |
---|
198 | #ifdef DEBUG |
---|
199 | info("LDAP: Setting TLS option -> ON\n"); |
---|
200 | #endif |
---|
201 | if((rc = ldap_start_tls_s(ldap, NULL, NULL) != LDAP_SUCCESS)) { |
---|
202 | ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno); |
---|
203 | error("LDAP: failed to initiate TLS: %s\n", ldap_err2string(ldap_errno)); |
---|
204 | return -1; |
---|
205 | } |
---|
206 | }; |
---|
207 | |
---|
208 | #endif |
---|
209 | |
---|
210 | /* Perform binding at last */ |
---|
211 | |
---|
212 | if ((rc = ldap_bind_s(ldap, ldap_dn, ldap_pw, LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS) { |
---|
213 | ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno); |
---|
214 | error("LDAP: failed to bind: %s\n",ldap_err2string(rc)); |
---|
215 | ldap_unbind(ldap); |
---|
216 | return -1; |
---|
217 | } |
---|
218 | |
---|
219 | /* Form a search filter from supplied peer's credentials */ |
---|
220 | |
---|
221 | if ((rc = snprintf(filter, LDAP_FILT_MAXSIZ,"(&(uid=%s)(objectClass=%s))", |
---|
222 | user, RADIUS_OBJECTCLASS)) == -1) { |
---|
223 | error("LDAP: LDAP filter too big\n"); |
---|
224 | ldap_unbind(ldap); |
---|
225 | return -1; |
---|
226 | }; |
---|
227 | |
---|
228 | #ifdef DEBUG |
---|
229 | info("LDAP: search filter: %s\n",filter); |
---|
230 | #endif |
---|
231 | |
---|
232 | /* Perform search*/ |
---|
233 | |
---|
234 | if ((rc = ldap_search_s(ldap, userbasedn, LDAP_SCOPE_SUBTREE, filter, |
---|
235 | NULL, 0, &ldap_mesg)) != LDAP_SUCCESS) { |
---|
236 | ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno); |
---|
237 | error("LDAP: Can't perform search: %s\n", |
---|
238 | ldap_err2string(rc)); |
---|
239 | ldap_unbind(ldap); |
---|
240 | return -1; |
---|
241 | }; |
---|
242 | |
---|
243 | /* If search returned more than 2 results or 0 - something is wrong! */ |
---|
244 | |
---|
245 | if ( ldap_mesg == NULL ){ |
---|
246 | info("LDAP: No such user \"%s\"\n",user); |
---|
247 | ldap_unbind(ldap); |
---|
248 | return -1; |
---|
249 | } |
---|
250 | |
---|
251 | if ((ldap_count_entries(ldap, ldap_mesg)) > 1){ |
---|
252 | warn("LDAP: more than one user \"%s\" exists!\n",user); |
---|
253 | ldap_unbind(ldap); |
---|
254 | return -1; |
---|
255 | } |
---|
256 | |
---|
257 | /* Check existance of dialupAccess attribute and it's value */ |
---|
258 | #ifdef DEBUG |
---|
259 | info("LDAP: found %u entries\n",ldap_count_entries(ldap, ldap_mesg)); |
---|
260 | #endif |
---|
261 | |
---|
262 | /* radiusAuthType = LDAP -> check it! */ |
---|
263 | |
---|
264 | ldap_entry = ldap_first_entry(ldap, ldap_mesg); |
---|
265 | |
---|
266 | ldap_values = ldap_get_values(ldap, ldap_entry, RADIUS_AUTHTYPE); |
---|
267 | |
---|
268 | if (ldap_count_values(ldap_values) != 0) { |
---|
269 | |
---|
270 | if ((strncasecmp(ldap_values[0],"LDAP",4) != 0)) { |
---|
271 | #ifdef DEBUG |
---|
272 | info("LDAP: Sorry, only authtype=LDAP is supported\n"); |
---|
273 | #endif |
---|
274 | ldap_unbind(ldap); |
---|
275 | ldap_msgfree(ldap_mesg); |
---|
276 | return -1; |
---|
277 | } |
---|
278 | } else { |
---|
279 | #ifdef DEBUG |
---|
280 | info("LDAP: Can not get authentication type\n"); |
---|
281 | #endif |
---|
282 | ldap_unbind(ldap); |
---|
283 | ldap_msgfree(ldap_mesg); |
---|
284 | return -1; |
---|
285 | } |
---|
286 | |
---|
287 | ldap_values = ldap_get_values(ldap, ldap_entry, RADIUS_DIALUPACCESS); |
---|
288 | if (((strncasecmp(ldap_values[0],"YES",3) == 0)) || |
---|
289 | ((strncasecmp(ldap_values[0],"FALSE",5)) != 0)) { |
---|
290 | |
---|
291 | /* Rebind with peers supplied credentials */ |
---|
292 | |
---|
293 | if ((rc = snprintf(userdn,MAX_BUF,"%s",ldap_get_dn(ldap,ldap_entry))) == -1) |
---|
294 | warn("LDAP: user DN stripped\n"); |
---|
295 | |
---|
296 | #ifdef DEBUG |
---|
297 | info("LDAP: rebind DN: %s\n",userdn); |
---|
298 | #endif |
---|
299 | |
---|
300 | if ((rc = ldap_simple_bind_s(ldap,userdn,password)) != LDAP_SUCCESS) { |
---|
301 | error("LDAP: username or password incorrect\n"); |
---|
302 | *msgp = "Username or password incorrect!"; |
---|
303 | ldap_unbind(ldap); |
---|
304 | ldap_msgfree(ldap_mesg); |
---|
305 | return 0; |
---|
306 | } |
---|
307 | } else { |
---|
308 | |
---|
309 | error("LDAP: dialup access disabled for user %s\n",user); |
---|
310 | *msgp = "Dial-in access not allowed!"; |
---|
311 | ldap_unbind(ldap); |
---|
312 | ldap_msgfree(ldap_mesg); |
---|
313 | return 0; |
---|
314 | } |
---|
315 | |
---|
316 | /* Set pppd options */ |
---|
317 | |
---|
318 | ldap_setoptions(ldap, ldap_mesg, &ldap_data); |
---|
319 | |
---|
320 | #ifdef DEBUG |
---|
321 | info("LDAP: Auth success\n"); |
---|
322 | #endif |
---|
323 | *msgp = "Access OK!"; |
---|
324 | ldap_data.access_ok = 1; |
---|
325 | |
---|
326 | /* Write ppp_utmp data in place */ |
---|
327 | |
---|
328 | return 1; |
---|
329 | } |
---|
330 | |
---|
331 | static void ldap_ip_choose(u_int32_t *addrp) |
---|
332 | { |
---|
333 | if (ldap_data.address_set) |
---|
334 | *addrp = ldap_data.addr; |
---|
335 | } |
---|
336 | |
---|
337 | static void ldap_ip_down(void *opaque, int arg) |
---|
338 | { |
---|
339 | if(lutmp) |
---|
340 | ldap_deactivate_utmp(devnam); |
---|
341 | } |
---|
342 | |
---|
343 | static void ldap_ip_up(void *opaque, int arg) |
---|
344 | { |
---|
345 | if(lutmp) |
---|
346 | ldap_activate_utmp(&ldap_data, devnam, ifname, peer_authname); |
---|
347 | } |
---|
348 | |
---|
349 | static int ldap_address_allowed(u_int32_t addr) |
---|
350 | { |
---|
351 | /* if (ldap_data.address_set) return 1;*/ |
---|
352 | if (ntohl(addr) == ldap_data.addr) return 1; |
---|
353 | |
---|
354 | /* if peer's address was specified in options |
---|
355 | allow it */ |
---|
356 | if ((ipcp_wantoptions[0].hisaddr != 0) && |
---|
357 | (ipcp_wantoptions[0].hisaddr == addr)) return 1; |
---|
358 | |
---|
359 | return 0; |
---|
360 | } |
---|
361 | |
---|
362 | static int ldap_pap_check(void) |
---|
363 | { |
---|
364 | return 1; |
---|
365 | } |
---|
366 | |
---|
367 | |
---|
368 | /* |
---|
369 | * FUNCTION: ldap_activate_utmp(struct ldap_data *ldap_data, |
---|
370 | char *devnam, char *ppp_devname, char *user); |
---|
371 | * PURPOSE: Writes ppp session data to ppp_utmp file |
---|
372 | * ARGUMENTS: |
---|
373 | * ldap_data - pointer to ldap_data structure |
---|
374 | * devnam - tty device name ("/dev/" will be stripped) |
---|
375 | * ppp_devname - interface name (ppp1, ppp0, etc) associated with |
---|
376 | * ppp session |
---|
377 | * user - user login name |
---|
378 | * |
---|
379 | * RETURNS: -1 in case of error |
---|
380 | 1 if success |
---|
381 | */ |
---|
382 | |
---|
383 | static int ldap_activate_utmp(struct ldap_data *ldap_data, |
---|
384 | char *devnam, char *ppp_devname, char* user) |
---|
385 | { |
---|
386 | int rc; |
---|
387 | int fd; |
---|
388 | off_t offset; |
---|
389 | struct ppp_utmp entry; |
---|
390 | char *device; |
---|
391 | char *p; |
---|
392 | |
---|
393 | memset(&entry, 0, sizeof(struct ppp_utmp)); |
---|
394 | |
---|
395 | if ((device = malloc(MAXPATHLEN)) == NULL) { |
---|
396 | error("Not enough memory\n"); |
---|
397 | return -1; |
---|
398 | } |
---|
399 | |
---|
400 | memset(device, '\0', MAXPATHLEN); |
---|
401 | |
---|
402 | if ((fd = open(UTMP , O_RDWR | O_CREAT, 0644)) == -1) |
---|
403 | { |
---|
404 | error("LDAP: can't open utmp file\n"); |
---|
405 | return -1; |
---|
406 | } |
---|
407 | |
---|
408 | strncpy(device, devnam, MAXLINELEN-1); |
---|
409 | |
---|
410 | p = device; |
---|
411 | if(strncmp(device,"/dev/",5) == 0) p += 5; |
---|
412 | |
---|
413 | if ((rc = lockf(fd, F_LOCK, 0)) == -1) |
---|
414 | { |
---|
415 | error("LDAP: can't lock utmp file: %s\n", |
---|
416 | strerror(errno)); |
---|
417 | return -1; |
---|
418 | } |
---|
419 | |
---|
420 | switch ((offset = utmp_seek(fd, devnam))) { |
---|
421 | |
---|
422 | case -1: |
---|
423 | |
---|
424 | strncpy(entry.line, p, MAXLINELEN-1); |
---|
425 | strncpy(entry.login, user, MAXNAMELEN-1); |
---|
426 | strncpy(entry.ifname, ppp_devname, MAXIFLEN-1); |
---|
427 | |
---|
428 | if (!ldap_data->address_set) |
---|
429 | entry.ip_address = ipcp_wantoptions[0].hisaddr; |
---|
430 | else entry.ip_address = ldap_data->addr; |
---|
431 | |
---|
432 | entry.time = time(NULL); |
---|
433 | entry.state = ACTIVE; |
---|
434 | |
---|
435 | lseek(fd, 0, SEEK_END); |
---|
436 | if ((write_n(fd, &entry, sizeof(struct ppp_utmp))) == -1){ |
---|
437 | error("LDAP: failed to write utmp entry\n"); |
---|
438 | return -1; |
---|
439 | } |
---|
440 | |
---|
441 | break; |
---|
442 | |
---|
443 | default: |
---|
444 | |
---|
445 | lseek(fd, offset, SEEK_SET); |
---|
446 | read_n(fd,&entry,sizeof(struct ppp_utmp)); |
---|
447 | |
---|
448 | strncpy(entry.line, p, MAXLINELEN-1); |
---|
449 | strncpy(entry.login, user, MAXNAMELEN-1); |
---|
450 | strncpy(entry.ifname, ppp_devname, MAXIFLEN-1); |
---|
451 | |
---|
452 | if (!ldap_data->address_set) |
---|
453 | entry.ip_address = ipcp_wantoptions[0].hisaddr; |
---|
454 | else entry.ip_address = ldap_data->addr; |
---|
455 | |
---|
456 | entry.time = time(NULL); |
---|
457 | entry.state = ACTIVE; |
---|
458 | |
---|
459 | lseek(fd, offset, SEEK_SET); |
---|
460 | if ((write_n(fd, &entry, sizeof(struct ppp_utmp))) == -1){ |
---|
461 | error("LDAP: failed to write utmp entry\n"); |
---|
462 | return -1; |
---|
463 | } |
---|
464 | |
---|
465 | break; |
---|
466 | } |
---|
467 | |
---|
468 | free(device); |
---|
469 | |
---|
470 | lseek(fd, 0, SEEK_SET); |
---|
471 | if ((rc = lockf(fd, F_ULOCK, 0)) == -1) |
---|
472 | { |
---|
473 | error("LDAP: can't unlock utmp file: %s\n", |
---|
474 | strerror(errno)); |
---|
475 | return -1; |
---|
476 | } |
---|
477 | |
---|
478 | if ((rc = close(fd)) == -1) |
---|
479 | { |
---|
480 | error("LDAP: can't close utmp file: %s\n", |
---|
481 | strerror(errno)); |
---|
482 | return -1; |
---|
483 | } |
---|
484 | |
---|
485 | return 1; |
---|
486 | |
---|
487 | } |
---|
488 | |
---|
489 | /* |
---|
490 | * FUNCTION: ldap_deactivate_utmp(char *devnam); |
---|
491 | * PURPOSE: sets ppp session data to IDLE in ppp_utmp associated with tty |
---|
492 | * ARGUMENTS: |
---|
493 | * devnam - tty device name ("/dev/" will be stripped) |
---|
494 | * |
---|
495 | * RETURNS: -1 in case of error |
---|
496 | 1 if success |
---|
497 | */ |
---|
498 | |
---|
499 | |
---|
500 | static int ldap_deactivate_utmp(char *devnam) |
---|
501 | { |
---|
502 | |
---|
503 | int rc; |
---|
504 | int fd; |
---|
505 | off_t offset; |
---|
506 | struct ppp_utmp entry; |
---|
507 | char *device; |
---|
508 | char *p; |
---|
509 | |
---|
510 | if ((device = malloc(MAXPATHLEN)) == NULL) { |
---|
511 | error("Not enough memory\n"); |
---|
512 | return -1; |
---|
513 | } |
---|
514 | |
---|
515 | memset(device, 0, MAXPATHLEN); |
---|
516 | memset(&entry, 0, sizeof(struct ppp_utmp)); |
---|
517 | |
---|
518 | p = device; |
---|
519 | |
---|
520 | strncpy(device, devnam, MAXLINELEN-1); |
---|
521 | if(strncmp(device,"/dev/",5) == 0) p += 5; |
---|
522 | |
---|
523 | #ifdef DEBUG |
---|
524 | info("LDAP: deactivating %s\n",devnam); |
---|
525 | #endif |
---|
526 | |
---|
527 | if ((fd = open(UTMP, O_RDWR, 0600)) == -1){ |
---|
528 | error("LDAP: can't open utmp file: %s\n", |
---|
529 | strerror(errno)); |
---|
530 | return -1; |
---|
531 | } |
---|
532 | |
---|
533 | if ((rc = lockf(fd, F_LOCK, 0)) == -1){ |
---|
534 | error("LDAP: can't lock utmp file: %s\n", |
---|
535 | strerror(errno)); |
---|
536 | return -1; |
---|
537 | } |
---|
538 | |
---|
539 | while(read_n(fd, &entry, sizeof(struct ppp_utmp))) { |
---|
540 | if (strncmp(entry.line, p, MAXLINELEN-1) == 0) { |
---|
541 | entry.state = IDLE; |
---|
542 | lseek(fd, -sizeof(struct ppp_utmp), SEEK_CUR); |
---|
543 | if ((rc = write_n(fd, &entry, sizeof(struct ppp_utmp))) == -1) { |
---|
544 | error("LDAP: can't change utmp record status: %s\n", |
---|
545 | strerror(errno)); |
---|
546 | return -1; |
---|
547 | } |
---|
548 | } |
---|
549 | } |
---|
550 | |
---|
551 | free(device); |
---|
552 | |
---|
553 | lseek(fd, 0, SEEK_SET); |
---|
554 | if ((rc = lockf(fd, F_ULOCK, 0)) == -1){ |
---|
555 | error("LDAP: can't unlock utmp file: %s\n", |
---|
556 | strerror(errno)); |
---|
557 | return -1; |
---|
558 | } |
---|
559 | |
---|
560 | close(fd); |
---|
561 | return 1; |
---|
562 | } |
---|
563 | |
---|
564 | /* |
---|
565 | * FUNCTION: ldapset_options() |
---|
566 | * PURPOSE: sets different pppd options retrieved from user's LDAP entry |
---|
567 | * Currently ldap_set_options() processes radiusFramedIPAddress, radiusSessionTimeout, |
---|
568 | * radiusIdleTimeout. Additional options should be easy. |
---|
569 | * |
---|
570 | * ARGUMENTS: |
---|
571 | * ld - pointer to current LDAP structure |
---|
572 | * ldap_entry - points to current LDAP entry we want to process |
---|
573 | * ldap_data - points to ldap_data structure which holds necessary values |
---|
574 | * |
---|
575 | * RETURNS: Nothing |
---|
576 | * |
---|
577 | */ |
---|
578 | |
---|
579 | static int ldap_setoptions(LDAP *ld, LDAPMessage *ldap_entry, struct ldap_data *ldap_data) |
---|
580 | { |
---|
581 | int rc; |
---|
582 | char **ldap_values; |
---|
583 | |
---|
584 | if (((ldap_values = ldap_get_values(ld, ldap_entry, |
---|
585 | RADIUS_FRAMEDIPADDRESS)) != NULL) && |
---|
586 | ((ldap_count_values(ldap_values)) != 0)) { |
---|
587 | if ((rc = inet_pton(AF_INET, ldap_values[0],&ldap_data->addr)) > 0){ |
---|
588 | ldap_data->address_set = 1; |
---|
589 | #ifdef DEBUG |
---|
590 | info("LDAP: peer address is %p\n",ldap_data->addr); |
---|
591 | #endif |
---|
592 | } else |
---|
593 | { |
---|
594 | switch(rc) { |
---|
595 | case 0: |
---|
596 | error("LDAP: LDAP server supplied incorrect IP address\n"); |
---|
597 | break; |
---|
598 | |
---|
599 | default: |
---|
600 | error("LDAP: Can not convert supplied IP address: %s\n", |
---|
601 | strerror(rc)); |
---|
602 | break; |
---|
603 | } |
---|
604 | } |
---|
605 | } |
---|
606 | |
---|
607 | if (((ldap_values = ldap_get_values(ld, ldap_entry, |
---|
608 | RADIUS_IDLETIMEOUT)) != NULL ) && |
---|
609 | ((ldap_count_values(ldap_values)) != 0)) { |
---|
610 | ldap_data->idle_time_limit = atoi(ldap_values[0]); |
---|
611 | #ifdef DEBUG |
---|
612 | info("LDAP: peer idle timeout is %u seconds\n", |
---|
613 | ldap_data->idle_time_limit); |
---|
614 | #endif |
---|
615 | idle_time_limit = ldap_data->idle_time_limit; |
---|
616 | } |
---|
617 | |
---|
618 | if (((ldap_values = ldap_get_values(ld, ldap_entry, |
---|
619 | RADIUS_SESSIONTIMEOUT)) != NULL ) && |
---|
620 | ((ldap_count_values(ldap_values)) != 0)) { |
---|
621 | ldap_data->maxconnect = atoi(ldap_values[0]); |
---|
622 | #ifdef DEBUG |
---|
623 | info("LDAP: peer session timeout is %u seconds\n", |
---|
624 | ldap_data->maxconnect); |
---|
625 | #endif |
---|
626 | maxconnect = ldap_data->maxconnect; |
---|
627 | } |
---|
628 | |
---|
629 | } |
---|