|
Line 0
Link Here
|
|
|
1 |
/* |
| 2 |
* $Id: openssh-lpk-4.3p1-0.3.7.patch,v 1.3 2006/04/18 15:29:09 eau Exp $ |
| 3 |
*/ |
| 4 |
|
| 5 |
/* |
| 6 |
* |
| 7 |
* Copyright (c) 2005, Eric AUGE <eau@phear.org> |
| 8 |
* All rights reserved. |
| 9 |
* |
| 10 |
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
| 11 |
* |
| 12 |
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
| 13 |
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
| 14 |
* Neither the name of the phear.org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. |
| 15 |
* |
| 16 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, |
| 17 |
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 18 |
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, |
| 19 |
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 20 |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| 21 |
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 22 |
* |
| 23 |
* |
| 24 |
*/ |
| 25 |
|
| 26 |
#include "includes.h" |
| 27 |
|
| 28 |
#ifdef WITH_LDAP_PUBKEY |
| 29 |
|
| 30 |
#include <stdio.h> |
| 31 |
#include <stdlib.h> |
| 32 |
#include <unistd.h> |
| 33 |
#include <string.h> |
| 34 |
|
| 35 |
#include "ldapauth.h" |
| 36 |
#include "log.h" |
| 37 |
|
| 38 |
static char *attrs[] = { |
| 39 |
PUBKEYATTR, |
| 40 |
NULL |
| 41 |
}; |
| 42 |
|
| 43 |
/* filter building infos */ |
| 44 |
#define FILTER_GROUP_PREFIX "(&(objectclass=posixGroup)" |
| 45 |
#define FILTER_OR_PREFIX "(|" |
| 46 |
#define FILTER_OR_SUFFIX ")" |
| 47 |
#define FILTER_CN_PREFIX "(cn=" |
| 48 |
#define FILTER_CN_SUFFIX ")" |
| 49 |
#define FILTER_UID_FORMAT "(memberUid=%s)" |
| 50 |
#define FILTER_GROUP_SUFFIX ")" |
| 51 |
#define FILTER_GROUP_SIZE(group) (size_t) (strlen(group)+(ldap_count_group(group)*5)+52) |
| 52 |
|
| 53 |
/* just filter building stuff */ |
| 54 |
#define REQUEST_GROUP_SIZE(filter, uid) (size_t) (strlen(filter)+strlen(uid)+1) |
| 55 |
#define REQUEST_GROUP(buffer, prefilter, pwname) \ |
| 56 |
buffer = (char *) calloc(REQUEST_GROUP_SIZE(prefilter, pwname), sizeof(char)); \ |
| 57 |
if (!buffer) { \ |
| 58 |
perror("calloc()"); \ |
| 59 |
return FAILURE; \ |
| 60 |
} \ |
| 61 |
snprintf(buffer, REQUEST_GROUP_SIZE(prefilter,pwname), prefilter, pwname) |
| 62 |
/* |
| 63 |
XXX OLD group building macros |
| 64 |
#define REQUEST_GROUP_SIZE(grp, uid) (size_t) (strlen(grp)+strlen(uid)+46) |
| 65 |
#define REQUEST_GROUP(buffer,pwname,grp) \ |
| 66 |
buffer = (char *) calloc(REQUEST_GROUP_SIZE(grp, pwname), sizeof(char)); \ |
| 67 |
if (!buffer) { \ |
| 68 |
perror("calloc()"); \ |
| 69 |
return FAILURE; \ |
| 70 |
} \ |
| 71 |
snprintf(buffer,REQUEST_GROUP_SIZE(grp,pwname),"(&(objectclass=posixGroup)(cn=%s)(memberUid=%s))",grp,pwname) |
| 72 |
*/ |
| 73 |
|
| 74 |
/* |
| 75 |
XXX stock upstream version without extra filter support |
| 76 |
#define REQUEST_USER_SIZE(uid) (size_t) (strlen(uid)+64) |
| 77 |
#define REQUEST_USER(buffer, pwname) \ |
| 78 |
buffer = (char *) calloc(REQUEST_USER_SIZE(pwname), sizeof(char)); \ |
| 79 |
if (!buffer) { \ |
| 80 |
perror("calloc()"); \ |
| 81 |
return NULL; \ |
| 82 |
} \ |
| 83 |
snprintf(buffer,REQUEST_USER_SIZE(pwname),"(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s))",pwname) |
| 84 |
*/ |
| 85 |
|
| 86 |
#define REQUEST_USER_SIZE(uid, filter) (size_t) (strlen(uid)+64+(filter != NULL ? strlen(filter) : 0)) |
| 87 |
#define REQUEST_USER(buffer, pwname, customfilter) \ |
| 88 |
buffer = (char *) calloc(REQUEST_USER_SIZE(pwname, customfilter), sizeof(char)); \ |
| 89 |
if (!buffer) { \ |
| 90 |
perror("calloc()"); \ |
| 91 |
return NULL; \ |
| 92 |
} \ |
| 93 |
snprintf(buffer, REQUEST_USER_SIZE(pwname, customfilter), \ |
| 94 |
"(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s)%s)", \ |
| 95 |
pwname, (customfilter != NULL ? customfilter : "")) |
| 96 |
|
| 97 |
/* some portable and working tokenizer, lame though */ |
| 98 |
static int tokenize(char ** o, size_t size, char * input) { |
| 99 |
unsigned int i = 0, num; |
| 100 |
const char * charset = " \t"; |
| 101 |
char * ptr = input; |
| 102 |
|
| 103 |
/* leading white spaces are ignored */ |
| 104 |
num = strspn(ptr, charset); |
| 105 |
ptr += num; |
| 106 |
|
| 107 |
while ((num = strcspn(ptr, charset))) { |
| 108 |
if (i < size-1) { |
| 109 |
o[i++] = ptr; |
| 110 |
ptr += num; |
| 111 |
if (*ptr) |
| 112 |
*ptr++ = '\0'; |
| 113 |
} |
| 114 |
} |
| 115 |
o[i] = NULL; |
| 116 |
return SUCCESS; |
| 117 |
} |
| 118 |
|
| 119 |
void ldap_close(ldap_opt_t * ldap) { |
| 120 |
|
| 121 |
if (!ldap) |
| 122 |
return; |
| 123 |
|
| 124 |
if ( ldap_unbind_ext(ldap->ld, NULL, NULL) < 0) |
| 125 |
ldap_perror(ldap->ld, "ldap_unbind()"); |
| 126 |
|
| 127 |
ldap->ld = NULL; |
| 128 |
FLAG_SET_DISCONNECTED(ldap->flags); |
| 129 |
|
| 130 |
return; |
| 131 |
} |
| 132 |
|
| 133 |
/* init && bind */ |
| 134 |
int ldap_connect(ldap_opt_t * ldap) { |
| 135 |
int version = LDAP_VERSION3; |
| 136 |
|
| 137 |
if (!ldap->servers) |
| 138 |
return FAILURE; |
| 139 |
|
| 140 |
/* Connection Init and setup */ |
| 141 |
ldap->ld = ldap_init(ldap->servers, LDAP_PORT); |
| 142 |
if (!ldap->ld) { |
| 143 |
ldap_perror(ldap->ld, "ldap_init()"); |
| 144 |
return FAILURE; |
| 145 |
} |
| 146 |
|
| 147 |
if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) { |
| 148 |
ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_PROTOCOL_VERSION)"); |
| 149 |
return FAILURE; |
| 150 |
} |
| 151 |
|
| 152 |
/* Timeouts setup */ |
| 153 |
if (ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, &ldap->b_timeout) != LDAP_SUCCESS) { |
| 154 |
ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT)"); |
| 155 |
} |
| 156 |
if (ldap_set_option(ldap->ld, LDAP_OPT_TIMEOUT, &ldap->s_timeout) != LDAP_SUCCESS) { |
| 157 |
ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_TIMEOUT)"); |
| 158 |
} |
| 159 |
|
| 160 |
/* TLS support */ |
| 161 |
if ( (ldap->tls == -1) || (ldap->tls == 1) ) { |
| 162 |
if (ldap_start_tls_s(ldap->ld, NULL, NULL ) != LDAP_SUCCESS) { |
| 163 |
/* failed then reinit the initial connect */ |
| 164 |
ldap_perror(ldap->ld, "ldap_connect: (TLS) ldap_start_tls()"); |
| 165 |
if (ldap->tls == 1) |
| 166 |
return FAILURE; |
| 167 |
|
| 168 |
ldap->ld = ldap_init(ldap->servers, LDAP_PORT); |
| 169 |
if (!ldap->ld) { |
| 170 |
ldap_perror(ldap->ld, "ldap_init()"); |
| 171 |
return FAILURE; |
| 172 |
} |
| 173 |
|
| 174 |
if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) { |
| 175 |
ldap_perror(ldap->ld, "ldap_set_option()"); |
| 176 |
return FAILURE; |
| 177 |
} |
| 178 |
} |
| 179 |
} |
| 180 |
|
| 181 |
|
| 182 |
if ( ldap_simple_bind_s(ldap->ld, ldap->binddn, ldap->bindpw) != LDAP_SUCCESS) { |
| 183 |
ldap_perror(ldap->ld, "ldap_simple_bind_s()"); |
| 184 |
return FAILURE; |
| 185 |
} |
| 186 |
|
| 187 |
/* says it is connected */ |
| 188 |
FLAG_SET_CONNECTED(ldap->flags); |
| 189 |
|
| 190 |
return SUCCESS; |
| 191 |
} |
| 192 |
|
| 193 |
/* must free allocated ressource */ |
| 194 |
static char * ldap_build_host(char *host, int port) { |
| 195 |
unsigned int size = strlen(host)+11; |
| 196 |
char * h = (char *) calloc (size, sizeof(char)); |
| 197 |
int rc; |
| 198 |
if (!h) |
| 199 |
return NULL; |
| 200 |
|
| 201 |
rc = snprintf(h, size, "%s:%d ", host, port); |
| 202 |
if (rc == -1) |
| 203 |
return NULL; |
| 204 |
return h; |
| 205 |
} |
| 206 |
|
| 207 |
static int ldap_count_group(const char * input) { |
| 208 |
const char * charset = " \t"; |
| 209 |
const char * ptr = input; |
| 210 |
unsigned int count = 0; |
| 211 |
unsigned int num; |
| 212 |
|
| 213 |
num = strspn(ptr, charset); |
| 214 |
ptr += num; |
| 215 |
|
| 216 |
while ((num = strcspn(ptr, charset))) { |
| 217 |
count++; |
| 218 |
ptr += num; |
| 219 |
ptr++; |
| 220 |
} |
| 221 |
|
| 222 |
return count; |
| 223 |
} |
| 224 |
|
| 225 |
/* format filter */ |
| 226 |
char * ldap_parse_groups(const char * groups) { |
| 227 |
unsigned int buffer_size = FILTER_GROUP_SIZE(groups); |
| 228 |
char * buffer = (char *) calloc(buffer_size, sizeof(char)); |
| 229 |
char * g = NULL; |
| 230 |
char * garray[32]; |
| 231 |
unsigned int i = 0; |
| 232 |
|
| 233 |
if ((!groups)||(!buffer)) |
| 234 |
return NULL; |
| 235 |
|
| 236 |
g = strdup(groups); |
| 237 |
if (!g) { |
| 238 |
free(buffer); |
| 239 |
return NULL; |
| 240 |
} |
| 241 |
|
| 242 |
/* first separate into n tokens */ |
| 243 |
if ( tokenize(garray, sizeof(garray)/sizeof(*garray), g) < 0) { |
| 244 |
free(g); |
| 245 |
free(buffer); |
| 246 |
return NULL; |
| 247 |
} |
| 248 |
|
| 249 |
/* build the final filter format */ |
| 250 |
strlcat(buffer, FILTER_GROUP_PREFIX, buffer_size); |
| 251 |
strlcat(buffer, FILTER_OR_PREFIX, buffer_size); |
| 252 |
i = 0; |
| 253 |
while (garray[i]) { |
| 254 |
strlcat(buffer, FILTER_CN_PREFIX, buffer_size); |
| 255 |
strlcat(buffer, garray[i], buffer_size); |
| 256 |
strlcat(buffer, FILTER_CN_SUFFIX, buffer_size); |
| 257 |
i++; |
| 258 |
} |
| 259 |
strlcat(buffer, FILTER_OR_SUFFIX, buffer_size); |
| 260 |
strlcat(buffer, FILTER_UID_FORMAT, buffer_size); |
| 261 |
strlcat(buffer, FILTER_GROUP_SUFFIX, buffer_size); |
| 262 |
|
| 263 |
free(g); |
| 264 |
return buffer; |
| 265 |
} |
| 266 |
|
| 267 |
/* a bit dirty but leak free */ |
| 268 |
char * ldap_parse_servers(const char * servers) { |
| 269 |
char * s = NULL; |
| 270 |
char * tmp = NULL, *urls[32]; |
| 271 |
unsigned int num = 0 , i = 0 , asize = 0; |
| 272 |
LDAPURLDesc *urld[32]; |
| 273 |
|
| 274 |
if (!servers) |
| 275 |
return NULL; |
| 276 |
|
| 277 |
/* local copy of the arg */ |
| 278 |
s = strdup(servers); |
| 279 |
if (!s) |
| 280 |
return NULL; |
| 281 |
|
| 282 |
/* first separate into URL tokens */ |
| 283 |
if ( tokenize(urls, sizeof(urls)/sizeof(*urls), s) < 0) |
| 284 |
return NULL; |
| 285 |
|
| 286 |
i = 0; |
| 287 |
while (urls[i]) { |
| 288 |
if (! ldap_is_ldap_url(urls[i]) || |
| 289 |
(ldap_url_parse(urls[i], &urld[i]) != 0)) { |
| 290 |
return NULL; |
| 291 |
} |
| 292 |
i++; |
| 293 |
} |
| 294 |
|
| 295 |
/* now free(s) */ |
| 296 |
free (s); |
| 297 |
|
| 298 |
/* how much memory do we need */ |
| 299 |
num = i; |
| 300 |
for (i = 0 ; i < num ; i++) |
| 301 |
asize += strlen(urld[i]->lud_host)+11; |
| 302 |
|
| 303 |
/* alloc */ |
| 304 |
s = (char *) calloc( asize+1 , sizeof(char)); |
| 305 |
if (!s) { |
| 306 |
for (i = 0 ; i < num ; i++) |
| 307 |
ldap_free_urldesc(urld[i]); |
| 308 |
return NULL; |
| 309 |
} |
| 310 |
|
| 311 |
/* then build the final host string */ |
| 312 |
for (i = 0 ; i < num ; i++) { |
| 313 |
/* built host part */ |
| 314 |
tmp = ldap_build_host(urld[i]->lud_host, urld[i]->lud_port); |
| 315 |
strncat(s, tmp, strlen(tmp)); |
| 316 |
ldap_free_urldesc(urld[i]); |
| 317 |
free(tmp); |
| 318 |
} |
| 319 |
|
| 320 |
return s; |
| 321 |
} |
| 322 |
|
| 323 |
void ldap_options_print(ldap_opt_t * ldap) { |
| 324 |
debug("ldap options:"); |
| 325 |
debug("servers: %s", ldap->servers); |
| 326 |
if (ldap->u_basedn) |
| 327 |
debug("user basedn: %s", ldap->u_basedn); |
| 328 |
if (ldap->g_basedn) |
| 329 |
debug("group basedn: %s", ldap->g_basedn); |
| 330 |
if (ldap->binddn) |
| 331 |
debug("binddn: %s", ldap->binddn); |
| 332 |
if (ldap->bindpw) |
| 333 |
debug("bindpw: %s", ldap->bindpw); |
| 334 |
if (ldap->sgroup) |
| 335 |
debug("group: %s", ldap->sgroup); |
| 336 |
if (ldap->filter) |
| 337 |
debug("filter: %s", ldap->filter); |
| 338 |
} |
| 339 |
|
| 340 |
void ldap_options_free(ldap_opt_t * l) { |
| 341 |
if (!l) |
| 342 |
return; |
| 343 |
if (l->servers) |
| 344 |
free(l->servers); |
| 345 |
if (l->u_basedn) |
| 346 |
free(l->u_basedn); |
| 347 |
if (l->g_basedn) |
| 348 |
free(l->g_basedn); |
| 349 |
if (l->binddn) |
| 350 |
free(l->binddn); |
| 351 |
if (l->bindpw) |
| 352 |
free(l->bindpw); |
| 353 |
if (l->sgroup) |
| 354 |
free(l->sgroup); |
| 355 |
if (l->fgroup) |
| 356 |
free(l->fgroup); |
| 357 |
if (l->filter) |
| 358 |
free(l->filter); |
| 359 |
if (l->l_conf) |
| 360 |
free(l->l_conf); |
| 361 |
free(l); |
| 362 |
} |
| 363 |
|
| 364 |
/* free keys */ |
| 365 |
void ldap_keys_free(ldap_key_t * k) { |
| 366 |
ldap_value_free_len(k->keys); |
| 367 |
free(k); |
| 368 |
return; |
| 369 |
} |
| 370 |
|
| 371 |
ldap_key_t * ldap_getuserkey(ldap_opt_t *l, const char * user) { |
| 372 |
ldap_key_t * k = (ldap_key_t *) calloc (1, sizeof(ldap_key_t)); |
| 373 |
LDAPMessage *res, *e; |
| 374 |
char * filter; |
| 375 |
int i; |
| 376 |
|
| 377 |
if ((!k) || (!l)) |
| 378 |
return NULL; |
| 379 |
|
| 380 |
/* Am i still connected ? RETRY n times */ |
| 381 |
/* XXX TODO: setup some conf value for retrying */ |
| 382 |
if (!(l->flags & FLAG_CONNECTED)) |
| 383 |
for (i = 0 ; i < 2 ; i++) |
| 384 |
if (ldap_connect(l) == 0) |
| 385 |
break; |
| 386 |
|
| 387 |
/* quick check for attempts to be evil */ |
| 388 |
if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) || |
| 389 |
(strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL)) |
| 390 |
return NULL; |
| 391 |
|
| 392 |
/* build filter for LDAP request */ |
| 393 |
REQUEST_USER(filter, user, l->filter); |
| 394 |
|
| 395 |
if ( ldap_search_st( l->ld, |
| 396 |
l->u_basedn, |
| 397 |
LDAP_SCOPE_SUBTREE, |
| 398 |
filter, |
| 399 |
attrs, 0, &l->s_timeout, &res ) != LDAP_SUCCESS) { |
| 400 |
|
| 401 |
ldap_perror(l->ld, "ldap_search_st()"); |
| 402 |
|
| 403 |
free(filter); |
| 404 |
free(k); |
| 405 |
|
| 406 |
/* XXX error on search, timeout etc.. close ask for reconnect */ |
| 407 |
ldap_close(l); |
| 408 |
|
| 409 |
return NULL; |
| 410 |
} |
| 411 |
|
| 412 |
/* free */ |
| 413 |
free(filter); |
| 414 |
|
| 415 |
/* check if any results */ |
| 416 |
i = ldap_count_entries(l->ld,res); |
| 417 |
if (i <= 0) { |
| 418 |
ldap_msgfree(res); |
| 419 |
free(k); |
| 420 |
return NULL; |
| 421 |
} |
| 422 |
|
| 423 |
if (i > 1) |
| 424 |
debug("[LDAP] duplicate entries, using the FIRST entry returned"); |
| 425 |
|
| 426 |
e = ldap_first_entry(l->ld, res); |
| 427 |
k->keys = ldap_get_values_len(l->ld, e, PUBKEYATTR); |
| 428 |
k->num = ldap_count_values_len(k->keys); |
| 429 |
|
| 430 |
ldap_msgfree(res); |
| 431 |
return k; |
| 432 |
} |
| 433 |
|
| 434 |
|
| 435 |
/* -1 if trouble |
| 436 |
0 if user is NOT member of current server group |
| 437 |
1 if user IS MEMBER of current server group |
| 438 |
*/ |
| 439 |
int ldap_ismember(ldap_opt_t * l, const char * user) { |
| 440 |
LDAPMessage *res; |
| 441 |
char * filter; |
| 442 |
int i; |
| 443 |
|
| 444 |
if ((!l->sgroup) || !(l->g_basedn)) |
| 445 |
return 1; |
| 446 |
|
| 447 |
/* Am i still connected ? RETRY n times */ |
| 448 |
/* XXX TODO: setup some conf value for retrying */ |
| 449 |
if (!(l->flags & FLAG_CONNECTED)) |
| 450 |
for (i = 0 ; i < 2 ; i++) |
| 451 |
if (ldap_connect(l) == 0) |
| 452 |
break; |
| 453 |
|
| 454 |
/* quick check for attempts to be evil */ |
| 455 |
if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) || |
| 456 |
(strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL)) |
| 457 |
return FAILURE; |
| 458 |
|
| 459 |
/* build filter for LDAP request */ |
| 460 |
REQUEST_GROUP(filter, l->fgroup, user); |
| 461 |
|
| 462 |
if (ldap_search_st( l->ld, |
| 463 |
l->g_basedn, |
| 464 |
LDAP_SCOPE_SUBTREE, |
| 465 |
filter, |
| 466 |
NULL, 0, &l->s_timeout, &res) != LDAP_SUCCESS) { |
| 467 |
|
| 468 |
ldap_perror(l->ld, "ldap_search_st()"); |
| 469 |
|
| 470 |
free(filter); |
| 471 |
|
| 472 |
/* XXX error on search, timeout etc.. close ask for reconnect */ |
| 473 |
ldap_close(l); |
| 474 |
|
| 475 |
return FAILURE; |
| 476 |
} |
| 477 |
|
| 478 |
free(filter); |
| 479 |
|
| 480 |
/* check if any results */ |
| 481 |
if (ldap_count_entries(l->ld, res) > 0) { |
| 482 |
ldap_msgfree(res); |
| 483 |
return 1; |
| 484 |
} |
| 485 |
|
| 486 |
ldap_msgfree(res); |
| 487 |
return 0; |
| 488 |
} |
| 489 |
|
| 490 |
/* |
| 491 |
* ldap.conf simple parser |
| 492 |
* XXX TODO: sanity checks |
| 493 |
* must either |
| 494 |
* - free the previous ldap_opt_before replacing entries |
| 495 |
* - free each necessary previously parsed elements |
| 496 |
* ret: |
| 497 |
* -1 on FAILURE, 0 on SUCCESS |
| 498 |
*/ |
| 499 |
int ldap_parse_lconf(ldap_opt_t * l) { |
| 500 |
FILE * lcd; /* ldap.conf descriptor */ |
| 501 |
char buf[BUFSIZ]; |
| 502 |
char * s = NULL, * k = NULL, * v = NULL; |
| 503 |
int li, len; |
| 504 |
|
| 505 |
lcd = fopen (l->l_conf, "r"); |
| 506 |
if (lcd == NULL) { |
| 507 |
/* debug("Cannot open %s", l->l_conf); */ |
| 508 |
perror("ldap_parse_lconf()"); |
| 509 |
return FAILURE; |
| 510 |
} |
| 511 |
|
| 512 |
while (fgets (buf, sizeof (buf), lcd) != NULL) { |
| 513 |
|
| 514 |
if (*buf == '\n' || *buf == '#') |
| 515 |
continue; |
| 516 |
|
| 517 |
k = buf; |
| 518 |
v = k; |
| 519 |
while (*v != '\0' && *v != ' ' && *v != '\t') |
| 520 |
v++; |
| 521 |
|
| 522 |
if (*v == '\0') |
| 523 |
continue; |
| 524 |
|
| 525 |
*(v++) = '\0'; |
| 526 |
|
| 527 |
while (*v == ' ' || *v == '\t') |
| 528 |
v++; |
| 529 |
|
| 530 |
li = strlen (v) - 1; |
| 531 |
while (v[li] == ' ' || v[li] == '\t' || v[li] == '\n') |
| 532 |
--li; |
| 533 |
v[li + 1] = '\0'; |
| 534 |
|
| 535 |
if (!strcasecmp (k, "uri")) { |
| 536 |
if ((l->servers = ldap_parse_servers(v)) == NULL) { |
| 537 |
fatal("error in ldap servers"); |
| 538 |
return FAILURE; |
| 539 |
} |
| 540 |
|
| 541 |
} |
| 542 |
else if (!strcasecmp (k, "base")) { |
| 543 |
s = strchr (v, '?'); |
| 544 |
if (s != NULL) { |
| 545 |
len = s - v; |
| 546 |
l->u_basedn = malloc (len + 1); |
| 547 |
strncpy (l->u_basedn, v, len); |
| 548 |
l->u_basedn[len] = '\0'; |
| 549 |
} else { |
| 550 |
l->u_basedn = strdup (v); |
| 551 |
} |
| 552 |
} |
| 553 |
else if (!strcasecmp (k, "binddn")) { |
| 554 |
l->binddn = strdup (v); |
| 555 |
} |
| 556 |
else if (!strcasecmp (k, "bindpw")) { |
| 557 |
l->bindpw = strdup (v); |
| 558 |
} |
| 559 |
else if (!strcasecmp (k, "timelimit")) { |
| 560 |
l->s_timeout.tv_sec = atoi (v); |
| 561 |
} |
| 562 |
else if (!strcasecmp (k, "bind_timelimit")) { |
| 563 |
l->b_timeout.tv_sec = atoi (v); |
| 564 |
} |
| 565 |
else if (!strcasecmp (k, "ssl")) { |
| 566 |
if (!strcasecmp (v, "start_tls")) |
| 567 |
l->tls = 1; |
| 568 |
} |
| 569 |
} |
| 570 |
|
| 571 |
fclose (lcd); |
| 572 |
return SUCCESS; |
| 573 |
} |
| 574 |
|
| 575 |
#endif /* WITH_LDAP_PUBKEY */ |