1/* COPYRIGHT 2 * Copyright (c) 2002-2003 Igor Brezac 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY IGOR BREZAC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IGOR BREZAC OR 18 * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 21 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 23 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25 * DAMAGE. 26 * END COPYRIGHT */ 27 28#ifndef AUTH_LDAP 29 #include "mechanisms.h" 30 #include "utils.h" 31#endif 32 33#ifdef AUTH_LDAP 34 35#include <sys/time.h> 36#include <stdio.h> 37#include <stdlib.h> 38#include <string.h> 39#include <syslog.h> 40#include <ctype.h> 41 42#ifdef HAVE_UNISTD_H 43#include <unistd.h> 44#endif 45 46#ifdef HAVE_CRYPT_H 47#include <crypt.h> 48#endif 49 50#ifdef HAVE_OPENSSL 51#ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT 52#define OPENSSL_DISABLE_OLD_DES_SUPPORT 53#endif 54#include <openssl/evp.h> 55#include <openssl/des.h> 56#endif 57 58#include <ldap.h> 59#include <lber.h> 60#include <sasl.h> 61#include "lak.h" 62 63typedef struct lak_auth_method { 64 int method; 65 int (*check) (LAK *lak, const char *user, const char *service, const char *realm, const char *password) ; 66} LAK_AUTH_METHOD; 67 68typedef struct lak_hash_rock { 69 const char *mda; 70 int salted; 71} LAK_HASH_ROCK; 72 73typedef struct lak_password_scheme { 74 char *hash; 75 int (*check) (const char *cred, const char *passwd, void *rock); 76 void *rock; 77} LAK_PASSWORD_SCHEME; 78 79static int lak_config_read(LAK_CONF *, const char *); 80static int lak_config_int(const char *); 81static int lak_config_switch(const char *); 82static void lak_config_free(LAK_CONF *); 83static int lak_config(const char *, LAK_CONF **); 84static int lak_escape(const char *, const unsigned int, char **); 85static int lak_tokenize_domains(const char *, int, char **); 86static int lak_expand_tokens(const char *, const char *, const char *, const char *, const char *, char **); 87static int lak_connect(LAK *); 88static int lak_bind(LAK *, LAK_USER *); 89static void lak_unbind(LAK *); 90static int lak_auth_custom(LAK *, const char *, const char *, const char *, const char *); 91static int lak_auth_bind(LAK *, const char *, const char *, const char *, const char *); 92static int lak_auth_fastbind(LAK *, const char *, const char *, const char *, const char *); 93static int lak_group_member(LAK *, const char *, const char *, const char *, const char *); 94static char *lak_result_get(const LAK_RESULT *, const char *); 95static int lak_result_add(const char *, const char *, LAK_RESULT **); 96static int lak_check_password(const char *, const char *, void *); 97static int lak_check_crypt(const char *, const char *, void *); 98#ifdef HAVE_OPENSSL 99static int lak_base64_decode(const char *, char **, int *); 100static int lak_check_hashed(const char *, const char *, void *); 101#endif 102static int lak_sasl_interact(LDAP *, unsigned, void *, void *); 103static int lak_user(const char *, const char *, const char *, const char *, const char *, const char *, LAK_USER **); 104static int lak_user_copy(LAK_USER **, const LAK_USER *); 105static int lak_user_cmp(const LAK_USER *, const LAK_USER *); 106static void lak_user_free(LAK_USER *); 107 108static LAK_AUTH_METHOD authenticator[] = { 109 { LAK_AUTH_METHOD_BIND, lak_auth_bind }, 110 { LAK_AUTH_METHOD_CUSTOM, lak_auth_custom }, 111 { LAK_AUTH_METHOD_FASTBIND, lak_auth_fastbind }, 112 { -1, NULL } 113}; 114 115static LAK_HASH_ROCK hash_rock[] = { 116 { "md5", 0 }, 117 { "md5", 1 }, 118 { "sha1", 0 }, 119 { "sha1", 1 } 120}; 121 122static LAK_PASSWORD_SCHEME password_scheme[] = { 123 { "{CRYPT}", lak_check_crypt, NULL }, 124 { "{UNIX}", lak_check_crypt, NULL }, 125#ifdef HAVE_OPENSSL 126 { "{MD5}", lak_check_hashed, &hash_rock[0] }, 127 { "{SMD5}", lak_check_hashed, &hash_rock[1] }, 128 { "{SHA}", lak_check_hashed, &hash_rock[2] }, 129 { "{SSHA}", lak_check_hashed, &hash_rock[3] }, 130#endif 131 { NULL, NULL, NULL } 132}; 133 134static const char *dn_attr = "dn"; 135 136#define ISSET(x) ((x != NULL) && (*(x) != '\0')) 137#define EMPTY(x) ((x == NULL) || (*(x) == '\0')) 138 139static int lak_config_read( 140 LAK_CONF *conf, 141 const char *configfile) 142{ 143 FILE *infile; 144 int lineno = 0; 145 char buf[4096]; 146 char *p, *key; 147 148 infile = fopen(configfile, "r"); 149 if (!infile) { 150 syslog(LOG_ERR|LOG_AUTH, 151 "Could not open saslauthd config file: %s (%m)", 152 configfile); 153 return LAK_FAIL; 154 } 155 156 while (fgets(buf, sizeof(buf), infile)) { 157 lineno++; 158 159 if (buf[strlen(buf)-1] == '\n') 160 buf[strlen(buf)-1] = '\0'; 161 for (p = buf; *p && isspace((int) *p); p++); 162 if (!*p || *p == '#') 163 continue; 164 165 key = p; 166 while (*p && (isalnum((int) *p) || *p == '-' || *p == '_')) { 167 if (isupper((int) *p)) 168 *p = tolower(*p); 169 p++; 170 } 171 if (*p != ':') 172 return LAK_FAIL; 173 174 *p++ = '\0'; 175 176 while (*p && isspace((int) *p)) 177 p++; 178 179 if (!*p) 180 return LAK_FAIL; 181 182 if (!strcasecmp(key, "ldap_servers")) 183 strlcpy(conf->servers, p, LAK_URL_LEN); 184 185 else if (!strcasecmp(key, "ldap_bind_dn")) 186 strlcpy(conf->bind_dn, p, LAK_DN_LEN); 187 188 else if (!strcasecmp(key, "ldap_bind_pw") || 189 !strcasecmp(key, "ldap_password")) 190 strlcpy(conf->password, p, LAK_BUF_LEN); 191 192 else if (!strcasecmp(key, "ldap_version")) 193 conf->version = lak_config_int(p); 194 195 else if (!strcasecmp(key, "ldap_search_base")) 196 strlcpy(conf->search_base, p, LAK_DN_LEN); 197 198 else if (!strcasecmp(key, "ldap_filter")) 199 strlcpy(conf->filter, p, LAK_DN_LEN); 200 201 else if (!strcasecmp(key, "ldap_password_attr")) 202 strlcpy(conf->password_attr, p, LAK_BUF_LEN); 203 204 else if (!strcasecmp(key, "ldap_group_dn")) 205 strlcpy(conf->group_dn, p, LAK_DN_LEN); 206 207 else if (!strcasecmp(key, "ldap_group_attr")) 208 strlcpy(conf->group_attr, p, LAK_BUF_LEN); 209 210 else if (!strcasecmp(key, "ldap_group_filter")) 211 strlcpy(conf->group_filter, p, LAK_BUF_LEN); 212 213 else if (!strcasecmp(key, "ldap_group_search_base")) 214 strlcpy(conf->group_search_base, p, LAK_BUF_LEN); 215 216 else if (!strcasecmp(key, "ldap_group_scope")) { 217 if (!strcasecmp(p, "one")) { 218 conf->group_scope = LDAP_SCOPE_ONELEVEL; 219 } else if (!strcasecmp(p, "base")) { 220 conf->group_scope = LDAP_SCOPE_BASE; 221 } 222 } else if (!strcasecmp(key, "ldap_group_match_method")) { 223 if (!strcasecmp(p, "filter")) { 224 conf->group_match_method = LAK_GROUP_MATCH_METHOD_FILTER; 225 } else if (!strcasecmp(p, "attr")) { 226 conf->group_match_method = LAK_GROUP_MATCH_METHOD_ATTR; 227 } 228 } else if (!strcasecmp(key, "ldap_default_realm") || 229 !strcasecmp(key, "ldap_default_domain")) 230 strlcpy(conf->default_realm, p, LAK_BUF_LEN); 231 232 else if (!strcasecmp(key, "ldap_auth_method")) { 233 if (!strcasecmp(p, "custom")) { 234 conf->auth_method = LAK_AUTH_METHOD_CUSTOM; 235 } else if (!strcasecmp(p, "fastbind")) { 236 conf->auth_method = LAK_AUTH_METHOD_FASTBIND; 237 } 238 } else if (!strcasecmp(key, "ldap_timeout")) { 239 conf->timeout.tv_sec = lak_config_int(p); 240 conf->timeout.tv_usec = 0; 241 } else if (!strcasecmp(key, "ldap_size_limit")) 242 conf->size_limit = lak_config_int(p); 243 244 else if (!strcasecmp(key, "ldap_time_limit")) 245 conf->time_limit = lak_config_int(p); 246 247 else if (!strcasecmp(key, "ldap_deref")) { 248 if (!strcasecmp(p, "search")) { 249 conf->deref = LDAP_DEREF_SEARCHING; 250 } else if (!strcasecmp(p, "find")) { 251 conf->deref = LDAP_DEREF_FINDING; 252 } else if (!strcasecmp(p, "always")) { 253 conf->deref = LDAP_DEREF_ALWAYS; 254 } else if (!strcasecmp(p, "never")) { 255 conf->deref = LDAP_DEREF_NEVER; 256 } 257 } else if (!strcasecmp(key, "ldap_referrals")) { 258 conf->referrals = lak_config_switch(p); 259 260 } else if (!strcasecmp(key, "ldap_restart")) { 261 conf->restart = lak_config_switch(p); 262 263 } else if (!strcasecmp(key, "ldap_scope")) { 264 if (!strcasecmp(p, "one")) { 265 conf->scope = LDAP_SCOPE_ONELEVEL; 266 } else if (!strcasecmp(p, "base")) { 267 conf->scope = LDAP_SCOPE_BASE; 268 } 269 } else if (!strcasecmp(key, "ldap_use_sasl")) { 270 conf->use_sasl = lak_config_switch(p); 271 272 } else if (!strcasecmp(key, "ldap_id") || 273 !strcasecmp(key, "ldap_sasl_authc_id")) 274 strlcpy(conf->id, p, LAK_BUF_LEN); 275 276 else if (!strcasecmp(key, "ldap_authz_id") || 277 !strcasecmp(key, "ldap_sasl_authz_id")) 278 strlcpy(conf->authz_id, p, LAK_BUF_LEN); 279 280 else if (!strcasecmp(key, "ldap_realm") || 281 !strcasecmp(key, "ldap_sasl_realm")) 282 strlcpy(conf->realm, p, LAK_BUF_LEN); 283 284 else if (!strcasecmp(key, "ldap_mech") || 285 !strcasecmp(key, "ldap_sasl_mech")) 286 strlcpy(conf->mech, p, LAK_BUF_LEN); 287 288 else if (!strcasecmp(key, "ldap_sasl_secprops")) 289 strlcpy(conf->sasl_secprops, p, LAK_BUF_LEN); 290 291 else if (!strcasecmp(key, "ldap_start_tls")) 292 conf->start_tls = lak_config_switch(p); 293 294 else if (!strcasecmp(key, "ldap_tls_check_peer")) 295 conf->tls_check_peer = lak_config_switch(p); 296 297 else if (!strcasecmp(key, "ldap_tls_cacert_file")) 298 strlcpy(conf->tls_cacert_file, p, LAK_PATH_LEN); 299 300 else if (!strcasecmp(key, "ldap_tls_cacert_dir")) 301 strlcpy(conf->tls_cacert_dir, p, LAK_PATH_LEN); 302 303 else if (!strcasecmp(key, "ldap_tls_ciphers")) 304 strlcpy(conf->tls_ciphers, p, LAK_BUF_LEN); 305 306 else if (!strcasecmp(key, "ldap_tls_cert")) 307 strlcpy(conf->tls_cert, p, LAK_PATH_LEN); 308 309 else if (!strcasecmp(key, "ldap_tls_key")) 310 strlcpy(conf->tls_key, p, LAK_PATH_LEN); 311 312 else if (!strcasecmp(key, "ldap_debug")) 313 conf->debug = lak_config_int(p); 314 } 315 316 if (conf->version != LDAP_VERSION3 && 317 (conf->use_sasl || 318 conf->start_tls)) 319 conf->version = LDAP_VERSION3; 320 321 if (conf->use_sasl && 322 conf->auth_method == LAK_AUTH_METHOD_BIND) 323 conf->auth_method = LAK_AUTH_METHOD_FASTBIND; 324 325 if ( ISSET(conf->group_filter) && 326 ISSET(conf->search_base) && 327 EMPTY(conf->group_search_base) ) 328 strlcpy(conf->group_search_base, conf->search_base, LAK_DN_LEN); 329 330 fclose(infile); 331 332 return LAK_OK; 333} 334 335static int lak_config_int( 336 const char *val) 337{ 338 if (!val) return 0; 339 340 if (!isdigit((int) *val) && (*val != '-' || !isdigit((int) val[1]))) return 0; 341 342 return atoi(val); 343} 344 345static int lak_config_switch( 346 const char *val) 347{ 348 if (!val) return 0; 349 350 if (*val == '0' || *val == 'n' || 351 (*val == 'o' && val[1] == 'f') || *val == 'f') { 352 return 0; 353 } else if (*val == '1' || *val == 'y' || 354 (*val == 'o' && val[1] == 'n') || *val == 't') { 355 return 1; 356 } 357 return 0; 358} 359 360static int lak_config( 361 const char *configfile, 362 LAK_CONF **ret) 363{ 364 LAK_CONF *conf; 365 int rc = 0; 366 367 conf = malloc( sizeof(LAK_CONF) ); 368 if (conf == NULL) { 369 return LAK_NOMEM; 370 } 371 372 memset(conf, 0, sizeof(LAK_CONF)); 373 374 strlcpy(conf->servers, "ldap://localhost/", LAK_BUF_LEN); 375 conf->version = LDAP_VERSION3; 376 strlcpy(conf->filter, "(uid=%u)", LAK_DN_LEN); 377 strlcpy(conf->password_attr, "userPassword", LAK_BUF_LEN); 378 conf->scope = LDAP_SCOPE_SUBTREE; 379 strlcpy(conf->group_attr, "uniqueMember", LAK_BUF_LEN); 380 conf->group_scope = LDAP_SCOPE_SUBTREE; 381 conf->group_match_method = LAK_GROUP_MATCH_METHOD_ATTR; 382 conf->auth_method = LAK_AUTH_METHOD_BIND; 383 conf->timeout.tv_sec = 5; 384 conf->timeout.tv_usec = 0; 385 conf->size_limit = 1; 386 conf->time_limit = 5; 387 conf->deref = LDAP_DEREF_NEVER; 388 conf->restart = 1; 389 conf->start_tls = 0; 390 conf->use_sasl = 0; 391 392 strlcpy(conf->path, configfile, LAK_PATH_LEN); 393 394 rc = lak_config_read(conf, conf->path); 395 if (rc != LAK_OK) { 396 lak_config_free(conf); 397 return rc; 398 } 399 400 *ret = conf; 401 return LAK_OK; 402} 403 404static void lak_config_free( 405 LAK_CONF *conf) 406{ 407 if (conf == NULL) { 408 return; 409 } 410 411 memset(conf, 0, sizeof(LAK_CONF)); 412 413 free (conf); 414 415 return; 416} 417 418/* 419 * Note: calling function must free memory. 420 */ 421static int lak_escape( 422 const char *s, 423 const unsigned int n, 424 char **result) 425{ 426 char *buf; 427 char *end, *ptr, *temp; 428 429 if (n > strlen(s)) // Sanity check, just in case 430 return LAK_FAIL; 431 432 buf = malloc(n * 5 + 1); 433 if (buf == NULL) { 434 return LAK_NOMEM; 435 } 436 437 buf[0] = '\0'; 438 ptr = (char *)s; 439 end = ptr + n; 440 441 while (((temp = strpbrk(ptr, "*()\\\0"))!=NULL) && (temp<end)) { 442 443 if (temp>ptr) 444 strncat(buf, ptr, temp-ptr); 445 446 switch (*temp) { 447 case '*': 448 strcat(buf, "\\2a"); 449 break; 450 case '(': 451 strcat(buf, "\\28"); 452 break; 453 case ')': 454 strcat(buf, "\\29"); 455 break; 456 case '\\': 457 strcat(buf, "\\5c"); 458 break; 459 case '\0': 460 strcat(buf, "\\00"); 461 break; 462 } 463 ptr=temp+1; 464 } 465 if (ptr<end) 466 strncat(buf, ptr, end-ptr); 467 468 *result = buf; 469 470 return LAK_OK; 471} 472 473static int lak_tokenize_domains( 474 const char *d, 475 int n, 476 char **result) 477{ 478 char *s, *s1; 479 char *lasts; 480 int nt, i, rc; 481 482 *result = NULL; 483 484 if (d == NULL || n < 1 || n > 9) 485 return LAK_FAIL; 486 487 s = strdup(d); 488 if (s == NULL) 489 return LAK_NOMEM; 490 491 for( nt=0, s1=s; *s1; s1++ ) 492 if( *s1 == '.' ) nt++; 493 nt++; 494 495 if (n > nt) { 496 free(s); 497 return LAK_FAIL; 498 } 499 500 i = nt - n; 501 s1 = (char *)strtok_r(s, ".", &lasts); 502 while(s1) { 503 if (i == 0) { 504 rc = lak_escape(s1, strlen(s1), result); 505 free(s); 506 return rc; 507 } 508 s1 = (char *)strtok_r(NULL, ".", &lasts); 509 i--; 510 } 511 512 free(s); 513 return LAK_FAIL; 514} 515 516#define LAK_MAX(a,b) (a>b?a:b) 517 518/* 519 * lak_expand_tokens 520 * Parts with the strings provided. 521 * %% = % 522 * %u = user 523 * %U = user part of %u 524 * %d = domain part of %u if available, othwise same as %r 525 * %1-9 = domain if not available realm, token 526 * (%1 = tld, %2 = domain when %r = domain.tld) 527 * %s = service 528 * %r = realm 529 * %R = prepend '@' to realm 530 * %D = user DN 531 * Note: calling function must free memory. 532 */ 533static int lak_expand_tokens( 534 const char *pattern, 535 const char *username, 536 const char *service, 537 const char *realm, 538 const char *dn, 539 char **result) 540{ 541 char *buf; 542 char *end, *ptr, *temp; 543 char *ebuf, *user; 544 char *domain; 545 int rc; 546 547 /* to permit multiple occurences of username and/or realm in filter */ 548 /* and avoid memory overflow in filter build [eg: (|(uid=%u)(userid=%u)) ] */ 549 int percents, service_len, realm_len, dn_len, user_len, maxparamlength; 550 551 if (pattern == NULL) { 552 syslog(LOG_ERR|LOG_AUTH, "filter pattern not setup"); 553 return LAK_FAIL; 554 } 555 556 /* find the longest param of username and realm, 557 do not worry about domain because it is always shorter 558 then username */ 559 user_len=ISSET(username) ? strlen(username) : 0; 560 service_len=ISSET(service) ? strlen(service) : 0; 561 realm_len=ISSET(realm) ? strlen(realm) : 0; 562 dn_len=ISSET(dn) ? strlen(dn) : 0; 563 564 maxparamlength = LAK_MAX(user_len, service_len); 565 maxparamlength = LAK_MAX(maxparamlength, realm_len + 1); /* +1 for %R when '@' is prepended */ 566 maxparamlength = LAK_MAX(maxparamlength, dn_len); 567 568 /* find the number of occurences of percent sign in filter */ 569 for( percents=0, buf=(char *)pattern; *buf; buf++ ) { 570 if( *buf == '%' ) percents++; 571 } 572 573 /* percents * 3 * maxparamlength because we need to account for 574 * an entirely-escaped worst-case-length parameter */ 575 buf=malloc(strlen(pattern) + (percents * 3 * maxparamlength) + 1); 576 if(buf == NULL) 577 return LAK_NOMEM; 578 buf[0] = '\0'; 579 580 ptr = (char *)pattern; 581 end = ptr + strlen(ptr); 582 583 while ((temp=strchr(ptr,'%'))!=NULL ) { 584 585 if ((temp-ptr) > 0) 586 strncat(buf, ptr, temp-ptr); 587 588 if ((temp+1) >= end) { 589 syslog(LOG_DEBUG|LOG_AUTH, "Incomplete lookup substitution format"); 590 break; 591 } 592 593 switch (*(temp+1)) { 594 case '%': 595 strncat(buf,temp+1,1); 596 break; 597 case 'u': 598 if (ISSET(username)) { 599 rc=lak_escape(username, strlen(username), &ebuf); 600 if (rc == LAK_OK) { 601 strcat(buf,ebuf); 602 free(ebuf); 603 } 604 } else 605 syslog(LOG_DEBUG|LOG_AUTH, "Username not available."); 606 break; 607 case 'U': 608 if (ISSET(username)) { 609 user = strchr(username, '@'); 610 rc=lak_escape(username, (user ? user - username : strlen(username)), &ebuf); 611 if (rc == LAK_OK) { 612 strcat(buf,ebuf); 613 free(ebuf); 614 } 615 } else 616 syslog(LOG_DEBUG|LOG_AUTH, "Username not available."); 617 break; 618 case '1': 619 case '2': 620 case '3': 621 case '4': 622 case '5': 623 case '6': 624 case '7': 625 case '8': 626 case '9': 627 if (ISSET(username) && 628 ((domain = strchr(username, '@')) && domain[1]!='\0')) { 629 rc=lak_tokenize_domains(domain+1, (int) *(temp+1)-48, &ebuf); 630 if (rc == LAK_OK) { 631 strcat(buf,ebuf); 632 free(ebuf); 633 } 634 } else if (ISSET(realm)) { 635 rc=lak_tokenize_domains(realm, (int) *(temp+1)-48, &ebuf); 636 if (rc == LAK_OK) { 637 strcat(buf,ebuf); 638 free(ebuf); 639 } 640 } else 641 syslog(LOG_DEBUG|LOG_AUTH, "Domain/Realm not available."); 642 break; 643 case 'd': 644 if (ISSET(username) && 645 ((domain = strchr(username, '@')) && domain[1]!='\0')) { 646 rc=lak_escape(domain+1, strlen(domain+1), &ebuf); 647 if (rc == LAK_OK) { 648 strcat(buf,ebuf); 649 free(ebuf); 650 } 651 break; 652 } 653 case 'R': 654 case 'r': 655 if (ISSET(realm)) { 656 rc = lak_escape(realm, strlen(realm), &ebuf); 657 if (rc == LAK_OK) { 658 if (*(temp+1) == 'R') 659 strcat(buf,"@"); 660 strcat(buf,ebuf); 661 free(ebuf); 662 } 663 } else 664 syslog(LOG_DEBUG|LOG_AUTH, "Domain/Realm not available."); 665 break; 666 case 's': 667 if (ISSET(service)) { 668 rc = lak_escape(service, strlen(service), &ebuf); 669 if (rc == LAK_OK) { 670 strcat(buf,ebuf); 671 free(ebuf); 672 } 673 } else 674 syslog(LOG_DEBUG|LOG_AUTH, "Service not available."); 675 break; 676 case 'D': 677 if (ISSET(dn)) { 678 rc = lak_escape(dn, strlen(dn), &ebuf); 679 if (rc == LAK_OK) { 680 strcat(buf,ebuf); 681 free(ebuf); 682 } 683 } else 684 syslog(LOG_DEBUG|LOG_AUTH, "User DN not available."); 685 break; 686 default: 687 break; 688 } 689 ptr=temp+2; 690 } 691 if (temp<end) 692 strcat(buf, ptr); 693 694 *result = buf; 695 696 return LAK_OK; 697} 698 699int lak_init( 700 const char *configfile, 701 LAK **ret) 702{ 703 LAK *lak; 704 int rc; 705 706 lak = *ret; 707 708 if (lak != NULL) { 709 return LAK_OK; 710 } 711 712 lak = (LAK *)malloc(sizeof(LAK)); 713 if (lak == NULL) 714 return LAK_NOMEM; 715 716 lak->status=LAK_NOT_BOUND; 717 lak->ld=NULL; 718 lak->conf=NULL; 719 lak->user=NULL; 720 721 rc = lak_config(configfile, &lak->conf); 722 if (rc != LAK_OK) { 723 free(lak); 724 return rc; 725 } 726 727#ifdef HAVE_OPENSSL 728 OpenSSL_add_all_digests(); 729#endif 730 731 *ret=lak; 732 return LAK_OK; 733} 734 735void lak_close( 736 LAK *lak) 737{ 738 739 if (lak == NULL) 740 return; 741 742 lak_config_free(lak->conf); 743 744 lak_unbind(lak); 745 746 free(lak); 747 748#ifdef HAVE_OPENSSL 749 EVP_cleanup(); 750#endif 751 752 return; 753} 754 755static int lak_connect( 756 LAK *lak) 757{ 758 int rc = 0; 759 char *p = NULL; 760 761 if (ISSET(lak->conf->tls_cacert_file)) { 762 rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE, lak->conf->tls_cacert_file); 763 if (rc != LDAP_SUCCESS) { 764 syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_CACERTFILE (%s).", ldap_err2string (rc)); 765 } 766 } 767 768 if (ISSET(lak->conf->tls_cacert_dir)) { 769 rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR, lak->conf->tls_cacert_dir); 770 if (rc != LDAP_SUCCESS) { 771 syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_CACERTDIR (%s).", ldap_err2string (rc)); 772 } 773 } 774 775 if (lak->conf->tls_check_peer != 0) { 776 rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &lak->conf->tls_check_peer); 777 if (rc != LDAP_SUCCESS) { 778 syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_REQUIRE_CERT (%s).", ldap_err2string (rc)); 779 } 780 } 781 782 if (ISSET(lak->conf->tls_ciphers)) { 783 /* set cipher suite, certificate and private key: */ 784 rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, lak->conf->tls_ciphers); 785 if (rc != LDAP_SUCCESS) { 786 syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_CIPHER_SUITE (%s).", ldap_err2string (rc)); 787 } 788 } 789 790 if (ISSET(lak->conf->tls_cert)) { 791 rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, lak->conf->tls_cert); 792 if (rc != LDAP_SUCCESS) { 793 syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_CERTFILE (%s).", ldap_err2string (rc)); 794 } 795 } 796 797 if (ISSET(lak->conf->tls_key)) { 798 rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, lak->conf->tls_key); 799 if (rc != LDAP_SUCCESS) { 800 syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_KEYFILE (%s).", ldap_err2string (rc)); 801 } 802 } 803 804 rc = ldap_initialize(&lak->ld, lak->conf->servers); 805 if (rc != LDAP_SUCCESS) { 806 syslog(LOG_ERR|LOG_AUTH, "ldap_initialize failed (%s)", lak->conf->servers); 807 return LAK_CONNECT_FAIL; 808 } 809 810 if (lak->conf->debug) { 811 rc = ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &(lak->conf->debug)); 812 if (rc != LDAP_OPT_SUCCESS) 813 syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_DEBUG_LEVEL %x.", lak->conf->debug); 814 } 815 816 rc = ldap_set_option(lak->ld, LDAP_OPT_PROTOCOL_VERSION, &(lak->conf->version)); 817 if (rc != LDAP_OPT_SUCCESS) { 818 819 if (lak->conf->use_sasl || 820 lak->conf->start_tls) { 821 syslog(LOG_ERR|LOG_AUTH, "Failed to set LDAP_OPT_PROTOCOL_VERSION %d, required for ldap_start_tls and ldap_use_sasl.", lak->conf->version); 822 lak_unbind(lak); 823 return LAK_CONNECT_FAIL; 824 } else 825 syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_PROTOCOL_VERSION %d.", lak->conf->version); 826 827 lak->conf->version = LDAP_VERSION2; 828 829 } 830 831 rc = ldap_set_option(lak->ld, LDAP_OPT_NETWORK_TIMEOUT, &(lak->conf->timeout)); 832 if (rc != LDAP_OPT_SUCCESS) { 833 syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_NETWORK_TIMEOUT %d.%d.", lak->conf->timeout.tv_sec, lak->conf->timeout.tv_usec); 834 } 835 836 rc = ldap_set_option(lak->ld, LDAP_OPT_TIMELIMIT, &(lak->conf->time_limit)); 837 if (rc != LDAP_OPT_SUCCESS) { 838 syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_TIMELIMIT %d.", lak->conf->time_limit); 839 } 840 841 rc = ldap_set_option(lak->ld, LDAP_OPT_DEREF, &(lak->conf->deref)); 842 if (rc != LDAP_OPT_SUCCESS) { 843 syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_DEREF %d.", lak->conf->deref); 844 } 845 846 rc = ldap_set_option(lak->ld, LDAP_OPT_REFERRALS, lak->conf->referrals ? LDAP_OPT_ON : LDAP_OPT_OFF); 847 if (rc != LDAP_OPT_SUCCESS) { 848 syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_REFERRALS."); 849 } 850 851 rc = ldap_set_option(lak->ld, LDAP_OPT_SIZELIMIT, &(lak->conf->size_limit)); 852 if (rc != LDAP_OPT_SUCCESS) 853 syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_SIZELIMIT %d.", lak->conf->size_limit); 854 855 rc = ldap_set_option(lak->ld, LDAP_OPT_RESTART, lak->conf->restart ? LDAP_OPT_ON : LDAP_OPT_OFF); 856 if (rc != LDAP_OPT_SUCCESS) { 857 syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_RESTART."); 858 } 859 860 if (lak->conf->start_tls) { 861 862 rc = ldap_start_tls_s(lak->ld, NULL, NULL); 863 if (rc != LDAP_SUCCESS) { 864 syslog(LOG_ERR|LOG_AUTH, "start tls failed (%s).", ldap_err2string(rc)); 865 lak_unbind(lak); 866 return LAK_CONNECT_FAIL; 867 } 868 } 869 870 if (lak->conf->use_sasl) { 871 872 if (EMPTY(lak->conf->mech)) { 873 ldap_get_option(lak->ld, LDAP_OPT_X_SASL_MECH, &p); 874 if (p) 875 strlcpy(lak->conf->mech, p, LAK_BUF_LEN); 876 } 877 878 if (EMPTY(lak->conf->realm)) { 879 ldap_get_option(lak->ld, LDAP_OPT_X_SASL_REALM, &p); 880 if (p) 881 strlcpy(lak->conf->realm, p, LAK_BUF_LEN); 882 } 883 884 if (ISSET(lak->conf->sasl_secprops)) { 885 rc = ldap_set_option(lak->ld, LDAP_OPT_X_SASL_SECPROPS, (void *) lak->conf->sasl_secprops); 886 if( rc != LDAP_OPT_SUCCESS ) { 887 syslog(LOG_ERR|LOG_AUTH, "Unable to set LDAP_OPT_X_SASL_SECPROPS."); 888 lak_unbind(lak); 889 return LAK_CONNECT_FAIL; 890 } 891 } 892 } 893 894 895 return LAK_OK; 896} 897 898static int lak_user( 899 const char *bind_dn, 900 const char *id, 901 const char *authz_id, 902 const char *mech, 903 const char *realm, 904 const char *password, 905 LAK_USER **ret) 906{ 907 LAK_USER *lu = NULL; 908 909 *ret = NULL; 910 911 lu = (LAK_USER *)malloc(sizeof(LAK_USER)); 912 if (lu == NULL) 913 return LAK_NOMEM; 914 915 memset(lu, 0, sizeof(LAK_USER)); 916 917 if (ISSET(bind_dn)) 918 strlcpy(lu->bind_dn, bind_dn, LAK_DN_LEN); 919 920 if (ISSET(id)) 921 strlcpy(lu->id, id, LAK_BUF_LEN); 922 923 if (ISSET(authz_id)) 924 strlcpy(lu->authz_id, authz_id, LAK_BUF_LEN); 925 926 if (ISSET(mech)) 927 strlcpy(lu->mech, mech, LAK_BUF_LEN); 928 929 if (ISSET(realm)) 930 strlcpy(lu->realm, realm, LAK_BUF_LEN); 931 932 if (ISSET(password)) 933 strlcpy(lu->password, password, LAK_BUF_LEN); 934 935 *ret = lu; 936 return LAK_OK; 937} 938 939static int lak_user_cmp( 940 const LAK_USER *lu1, 941 const LAK_USER *lu2) 942{ 943 944 if (lu1 == NULL || 945 lu2 == NULL) 946 return LAK_FAIL; 947 948 if (memcmp(lu1, lu2, sizeof(LAK_USER)) == 0) 949 return LAK_OK; 950 951 return LAK_FAIL; 952} 953 954static int lak_user_copy( 955 LAK_USER **lu1, 956 const LAK_USER *lu2) 957{ 958 LAK_USER *lu; 959 960 lu = *lu1; 961 962 if (lu2 == NULL) 963 return LAK_FAIL; 964 965 if (lu == NULL) { 966 lu = (LAK_USER *)malloc(sizeof(LAK_USER)); 967 if (lu == NULL) 968 return LAK_NOMEM; 969 970 *lu1 = lu; 971 } 972 973 memcpy((void *)lu, (void *)lu2, sizeof(LAK_USER)); 974 975 return LAK_OK; 976} 977 978static void lak_user_free( 979 LAK_USER *user) 980{ 981 if (user == NULL) { 982 return; 983 } 984 985 memset(user, 0, sizeof(LAK_USER)); 986 987 free(user); 988 989 return; 990} 991 992static int lak_sasl_interact( 993 LDAP *ld, 994 unsigned flags __attribute__((unused)), 995 void *def, 996 void *inter) 997{ 998 sasl_interact_t *in = inter; 999 const char *p; 1000 LAK_USER *lu = def; 1001 1002 for (;in->id != SASL_CB_LIST_END;in++) { 1003 p = NULL; 1004 switch(in->id) { 1005 case SASL_CB_AUTHNAME: 1006 if (ISSET(lu->id)) 1007 p = lu->id; 1008 if (!p) 1009 ldap_get_option( ld, LDAP_OPT_X_SASL_AUTHCID, &p); 1010 break; 1011 case SASL_CB_USER: 1012 if (ISSET(lu->authz_id)) 1013 p = lu->authz_id; 1014 if (!p) 1015 ldap_get_option( ld, LDAP_OPT_X_SASL_AUTHZID, &p); 1016 break; 1017 case SASL_CB_GETREALM: 1018 if (ISSET(lu->realm)) 1019 p = lu->realm; 1020 break; 1021 case SASL_CB_PASS: 1022 if (ISSET(lu->password)) 1023 p = lu->password; 1024 break; 1025 } 1026 1027 in->result = ISSET(p) ? p : ""; 1028 in->len = strlen(in->result); 1029 } 1030 1031 return LDAP_SUCCESS; 1032} 1033 1034static int lak_bind( 1035 LAK *lak, 1036 LAK_USER *user) 1037{ 1038 int rc; 1039 1040 if (user == NULL) // Sanity Check 1041 return LAK_FAIL; 1042 1043 if ((lak->status == LAK_BOUND) && 1044 (lak_user_cmp(lak->user, user) == LAK_OK)) 1045 return LAK_OK; 1046 1047 lak_user_free(lak->user); 1048 lak->user = NULL; 1049 1050 if ( 1051#if LDAP_VENDOR_VERSION < 20204 1052 lak->conf->use_sasl || 1053#endif 1054 lak->conf->version == LDAP_VERSION2) 1055 lak->status = LAK_NOT_BOUND; 1056 1057 if (lak->status == LAK_NOT_BOUND) { 1058 lak_unbind(lak); 1059 rc = lak_connect(lak); 1060 if (rc != LAK_OK) 1061 return rc; 1062 } 1063 1064 if (lak->conf->use_sasl) 1065 rc = ldap_sasl_interactive_bind_s( 1066 lak->ld, 1067 user->bind_dn, 1068 user->mech, 1069 NULL, 1070 NULL, 1071 LDAP_SASL_QUIET, 1072 lak_sasl_interact, 1073 user); 1074 else 1075 rc = ldap_simple_bind_s(lak->ld, user->bind_dn, user->password); 1076 1077 switch (rc) { 1078 case LDAP_SUCCESS: 1079 break; 1080 case LDAP_INVALID_CREDENTIALS: 1081 case LDAP_INSUFFICIENT_ACCESS: 1082 case LDAP_INVALID_DN_SYNTAX: 1083 case LDAP_OTHER: 1084 lak->status = LAK_NOT_BOUND; 1085 return LAK_BIND_FAIL; 1086 case LDAP_TIMEOUT: 1087 case LDAP_SERVER_DOWN: 1088 default: 1089 syslog(LOG_DEBUG|LOG_AUTH, 1090 (lak->conf->use_sasl ? "ldap_sasl_interactive_bind() failed %d (%s)." : "ldap_simple_bind() failed %d (%s)."), rc, ldap_err2string(rc)); 1091 lak->status = LAK_NOT_BOUND; 1092 return LAK_RETRY; 1093 } 1094 1095 rc = lak_user_copy(&(lak->user), user); 1096 if (rc != LAK_OK) 1097 return rc; 1098 1099 lak->status = LAK_BOUND; 1100 1101 return LAK_OK; 1102} 1103 1104static void lak_unbind( 1105 LAK *lak) 1106{ 1107 if (!lak) 1108 return; 1109 1110 lak_user_free(lak->user); 1111 1112 if (lak->ld) 1113 ldap_unbind(lak->ld); 1114 1115 lak->ld = NULL; 1116 lak->user = NULL; 1117 lak->status = LAK_NOT_BOUND; 1118 1119 return; 1120} 1121 1122/* 1123 * lak_retrieve - retrieve user@realm values specified by 'attrs' 1124 */ 1125int lak_retrieve( 1126 LAK *lak, 1127 const char *user, 1128 const char *service, 1129 const char *realm, 1130 const char **attrs, 1131 LAK_RESULT **ret) 1132{ 1133 int rc = 0, i; 1134 char *filter = NULL; 1135 char *search_base = NULL; 1136 LDAPMessage *res = NULL; 1137 LDAPMessage *entry = NULL; 1138 BerElement *ber = NULL; 1139 char *attr = NULL, **vals = NULL, *dn = NULL; 1140 LAK_USER *lu = NULL; 1141 1142 *ret = NULL; 1143 1144 if (lak == NULL) { 1145 syslog(LOG_ERR|LOG_AUTH, "lak_init did not run."); 1146 return LAK_FAIL; 1147 } 1148 1149 if (EMPTY(user)) 1150 return LAK_FAIL; 1151 1152 if (EMPTY(realm)) 1153 realm = lak->conf->default_realm; 1154 1155 rc = lak_user( 1156 lak->conf->bind_dn, 1157 lak->conf->id, 1158 lak->conf->authz_id, 1159 lak->conf->mech, 1160 lak->conf->realm, 1161 lak->conf->password, 1162 &lu); 1163 if (rc != LAK_OK) 1164 return rc; 1165 1166 rc = lak_bind(lak, lu); 1167 if (rc != LAK_OK) 1168 goto done; 1169 1170 rc = lak_expand_tokens(lak->conf->filter, user, service, realm, NULL, &filter); 1171 if (rc != LAK_OK) 1172 goto done; 1173 1174 rc = lak_expand_tokens(lak->conf->search_base, user, service, realm, NULL, &search_base); 1175 if (rc != LAK_OK) 1176 goto done; 1177 1178 rc = ldap_search_st(lak->ld, search_base, lak->conf->scope, filter, (char **) attrs, 0, &(lak->conf->timeout), &res); 1179 switch (rc) { 1180 case LDAP_SUCCESS: 1181 case LDAP_NO_SUCH_OBJECT: 1182 break; 1183 case LDAP_TIMELIMIT_EXCEEDED: 1184 case LDAP_BUSY: 1185 case LDAP_UNAVAILABLE: 1186 case LDAP_INSUFFICIENT_ACCESS: 1187 /* We do not need to re-connect to the LDAP server 1188 under these conditions */ 1189 syslog(LOG_ERR|LOG_AUTH, "user ldap_search_st() failed: %s", ldap_err2string(rc)); 1190 rc = LAK_USER_NOT_FOUND; 1191 goto done; 1192 case LDAP_TIMEOUT: 1193 case LDAP_SERVER_DOWN: 1194 default: 1195 syslog(LOG_ERR|LOG_AUTH, "user ldap_search_st() failed: %s", ldap_err2string(rc)); 1196 rc = LAK_RETRY; 1197 lak->status = LAK_NOT_BOUND; 1198 goto done; 1199 } 1200 1201 i = ldap_count_entries(lak->ld, res); 1202 if (i != 1) { 1203 if (i == 0) 1204 syslog(LOG_DEBUG|LOG_AUTH, "Entry not found (%s).", filter); 1205 else 1206 syslog(LOG_DEBUG|LOG_AUTH, "Duplicate entries found (%s).", filter); 1207 rc = LAK_USER_NOT_FOUND; 1208 goto done; 1209 } 1210 1211 rc = LAK_FAIL; 1212 1213 if ((entry = ldap_first_entry(lak->ld, res)) != NULL) { 1214 for (i=0; attrs[i] != NULL; i++) { 1215 1216 if (!strcmp(attrs[i], dn_attr)) { 1217 dn = ldap_get_dn(lak->ld, entry); 1218 if (dn == NULL) 1219 goto done; 1220 1221 rc = lak_result_add(dn_attr, dn, ret); 1222 if (rc != LAK_OK) { 1223 lak_result_free(*ret); 1224 *ret = NULL; 1225 goto done; 1226 } 1227 } 1228 } 1229 1230 for (attr = ldap_first_attribute(lak->ld, entry, &ber); attr != NULL; 1231 attr = ldap_next_attribute(lak->ld, entry, ber)) { 1232 1233 vals = ldap_get_values(lak->ld, entry, attr); 1234 if (vals == NULL) 1235 continue; 1236 1237 for (i = 0; vals[i] != NULL; i++) { 1238 rc = lak_result_add(attr, vals[i], ret); 1239 if (rc != LAK_OK) { 1240 lak_result_free(*ret); 1241 *ret = NULL; 1242 goto done; 1243 } 1244 } 1245 1246 ldap_value_free(vals); 1247 vals = NULL; 1248 ldap_memfree(attr); 1249 attr = NULL; 1250 } 1251 } 1252 1253done:; 1254 if (res) 1255 ldap_msgfree(res); 1256 if (dn) 1257 ldap_memfree(dn); 1258 if (vals) 1259 ldap_value_free(vals); 1260 if (attr) 1261 ldap_memfree(attr); 1262 if (ber != NULL) 1263 ber_free(ber, 0); 1264 if (filter) 1265 free(filter); 1266 if (search_base) 1267 free(search_base); 1268 if (lu) 1269 lak_user_free(lu); 1270 1271 return rc; 1272} 1273 1274static int lak_group_member( 1275 LAK *lak, 1276 const char *user, 1277 const char *service, 1278 const char *realm, 1279 const char *dn) 1280{ 1281 char *group_dn = NULL, *user_dn = NULL; 1282 char *group_filter = NULL; 1283 char *group_search_base = NULL; 1284 struct berval *dn_bv = NULL; 1285 int rc; 1286 LAK_RESULT *lres = NULL; 1287 const char *attrs[] = { dn_attr, NULL }; 1288 const char *group_attrs[] = {"1.1", NULL}; 1289 1290 LDAPMessage *res = NULL; 1291 1292 user_dn = (char *)dn; 1293 1294 if (EMPTY(user_dn)) { 1295 if (lak->conf->use_sasl) { 1296 1297#if LDAP_VENDOR_VERSION >= 20122 1298 if (ldap_whoami_s(lak->ld, &dn_bv, NULL, NULL) != LDAP_SUCCESS || !dn_bv) { 1299 syslog(LOG_ERR|LOG_AUTH, "ldap_whoami_s() failed."); 1300 rc = LAK_NOT_GROUP_MEMBER; 1301 goto done; 1302 } 1303 1304 user_dn = dn_bv->bv_val; 1305#else 1306 syslog(LOG_ERR|LOG_AUTH, "Your OpenLDAP API does not supported ldap_whoami()."); 1307 rc = LAK_NOT_GROUP_MEMBER; 1308 goto done; 1309#endif 1310 1311 } else { 1312 1313 rc = lak_retrieve(lak, user, service, realm, attrs, &lres); 1314 if (rc != LAK_OK) 1315 goto done; 1316 1317 user_dn = lres->value; 1318 } 1319 } 1320 1321 if (lak->conf->group_match_method == LAK_GROUP_MATCH_METHOD_ATTR) { 1322 1323 rc = lak_expand_tokens(lak->conf->group_dn, user, service, realm, NULL, &group_dn); 1324 if (rc != LAK_OK) 1325 goto done; 1326 1327 rc = ((ldap_compare_s(lak->ld, group_dn, lak->conf->group_attr, user_dn)) == LDAP_COMPARE_TRUE ? 1328 LAK_OK : LAK_NOT_GROUP_MEMBER); 1329 1330 } else if (lak->conf->group_match_method == LAK_GROUP_MATCH_METHOD_FILTER) { 1331 1332 rc = lak_expand_tokens(lak->conf->group_filter, user, service, realm, user_dn, &group_filter); 1333 if (rc != LAK_OK) 1334 goto done; 1335 1336 rc = lak_expand_tokens(lak->conf->group_search_base, user, service, realm, user_dn, &group_search_base); 1337 if (rc != LAK_OK) 1338 goto done; 1339 1340 rc = ldap_search_st(lak->ld, group_search_base, lak->conf->group_scope, group_filter, (char **) group_attrs, 0, &(lak->conf->timeout), &res); 1341 switch (rc) { 1342 case LDAP_SUCCESS: 1343 case LDAP_NO_SUCH_OBJECT: 1344 break; 1345 case LDAP_TIMELIMIT_EXCEEDED: 1346 case LDAP_BUSY: 1347 case LDAP_UNAVAILABLE: 1348 case LDAP_INSUFFICIENT_ACCESS: 1349 syslog(LOG_ERR|LOG_AUTH, "group ldap_search_st() failed: %s", ldap_err2string(rc)); 1350 rc = LAK_NOT_GROUP_MEMBER; 1351 goto done; 1352 case LDAP_TIMEOUT: 1353 case LDAP_SERVER_DOWN: 1354 default: 1355 syslog(LOG_ERR|LOG_AUTH, "group ldap_search_st() failed: %s", ldap_err2string(rc)); 1356 rc = LAK_RETRY; 1357 lak->status = LAK_NOT_BOUND; 1358 goto done; 1359 } 1360 1361 rc = ( (ldap_count_entries(lak->ld, res) >= 1) ? LAK_OK : LAK_NOT_GROUP_MEMBER ); 1362 1363 } else { 1364 1365 syslog(LOG_WARNING|LOG_AUTH, "Unknown ldap_group_match_method value."); 1366 rc = LAK_FAIL; 1367 1368 } 1369 1370done:; 1371 if (res) 1372 ldap_msgfree(res); 1373 if (group_dn) 1374 free(group_dn); 1375 if (group_filter) 1376 free(group_filter); 1377 if (group_search_base) 1378 free(group_search_base); 1379 if (lres) 1380 lak_result_free(lres); 1381 if (dn_bv) 1382 ber_bvfree(dn_bv); 1383 1384 return rc; 1385} 1386 1387static int lak_auth_custom( 1388 LAK *lak, 1389 const char *user, 1390 const char *service, 1391 const char *realm, 1392 const char *password) 1393{ 1394 LAK_RESULT *lres; 1395 int rc; 1396 const char *attrs[] = { lak->conf->password_attr, NULL}; 1397 1398 rc = lak_retrieve(lak, user, service, realm, attrs, &lres); 1399 if (rc != LAK_OK) 1400 return rc; 1401 1402 rc = lak_check_password(lres->value, password, NULL); 1403 1404 if ( rc == LAK_OK && 1405 (ISSET(lak->conf->group_dn) || 1406 ISSET(lak->conf->group_filter)) ) 1407 rc = lak_group_member(lak, user, service, realm, NULL); 1408 1409 lak_result_free(lres); 1410 1411 return(rc); 1412} 1413 1414static int lak_auth_bind( 1415 LAK *lak, 1416 const char *user, 1417 const char *service, 1418 const char *realm, 1419 const char *password) 1420{ 1421 LAK_USER *lu = NULL; 1422 LAK_RESULT *dn = NULL; 1423 int rc; 1424 const char *attrs[] = {dn_attr, NULL}; 1425 1426 rc = lak_retrieve(lak, user, service, realm, attrs, &dn); 1427 if (rc != LAK_OK) 1428 goto done; 1429 1430 rc = lak_user( 1431 dn->value, 1432 NULL, 1433 NULL, 1434 NULL, 1435 NULL, 1436 password, 1437 &lu); 1438 if (rc != LAK_OK) 1439 goto done; 1440 1441 rc = lak_bind(lak, lu); 1442 1443 if ( rc == LAK_OK && 1444 (ISSET(lak->conf->group_dn) || 1445 ISSET(lak->conf->group_filter)) ) 1446 rc = lak_group_member(lak, user, service, realm, dn->value); 1447 1448done:; 1449 if (lu) 1450 lak_user_free(lu); 1451 if (dn) 1452 lak_result_free(dn); 1453 1454 return rc; 1455} 1456 1457static int lak_auth_fastbind( 1458 LAK *lak, 1459 const char *user, 1460 const char *service, 1461 const char *realm, 1462 const char *password) 1463{ 1464 int rc; 1465 LAK_USER *lu = NULL; 1466 char *dn = NULL; 1467 char id[LAK_BUF_LEN]; 1468 1469 *id = '\0'; 1470 1471 if (lak->conf->use_sasl) { 1472 strlcpy(id, user, LAK_BUF_LEN); 1473 if (!strchr(id, '@') && 1474 (ISSET(realm))) { 1475 strlcat(id, "@", LAK_BUF_LEN); 1476 strlcat(id, realm, LAK_BUF_LEN); 1477 } 1478 } else { 1479 rc = lak_expand_tokens(lak->conf->filter, user, service, realm, NULL, &dn); 1480 if (rc != LAK_OK || 1481 EMPTY(dn)) 1482 goto done; 1483 } 1484 1485 rc = lak_user( 1486 dn, 1487 id, 1488 NULL, 1489 lak->conf->mech, 1490 lak->conf->realm, 1491 password, 1492 &lu); 1493 if (rc != LAK_OK) 1494 goto done; 1495 1496 rc = lak_bind(lak, lu); 1497 1498 if ( rc == LAK_OK && 1499 (ISSET(lak->conf->group_dn) || 1500 ISSET(lak->conf->group_filter)) ) 1501 rc = lak_group_member(lak, user, service, realm, dn); 1502 1503done:; 1504 if (lu) 1505 lak_user_free(lu); 1506 if (dn != NULL) 1507 free(dn); 1508 1509 return rc; 1510} 1511 1512int lak_authenticate( 1513 LAK *lak, 1514 const char *user, 1515 const char *service, 1516 const char *realm, 1517 const char *password) 1518{ 1519 int i; 1520 int rc; 1521 int retry = 2; 1522 1523 if (lak == NULL) { 1524 syslog(LOG_ERR|LOG_AUTH, "lak_init did not run."); 1525 return LAK_FAIL; 1526 } 1527 1528 if (EMPTY(user)) 1529 return LAK_FAIL; 1530 1531 if (EMPTY(realm)) 1532 realm = lak->conf->default_realm; 1533 1534 for (i = 0; authenticator[i].method != -1; i++) { 1535 if (authenticator[i].method == lak->conf->auth_method) { 1536 if (authenticator[i].check) { 1537 for (;retry > 0; retry--) { 1538 rc = (authenticator[i].check)(lak, user, service, realm, password); 1539 switch(rc) { 1540 case LAK_OK: 1541 return LAK_OK; 1542 case LAK_RETRY: 1543 if (retry > 1) { 1544 syslog(LOG_INFO|LOG_AUTH, "Retrying authentication"); 1545 break; 1546 } 1547 default: 1548 syslog( 1549 LOG_DEBUG|LOG_AUTH, 1550 "Authentication failed for %s%s%s: %s (%d)", 1551 user, 1552 (ISSET(realm) ? "/" : ""), 1553 (ISSET(realm) ? realm : ""), 1554 lak_error(rc), 1555 rc); 1556 return LAK_FAIL; 1557 } 1558 } 1559 } 1560 break; 1561 } 1562 } 1563 1564 /* Should not get here */ 1565 syslog(LOG_DEBUG|LOG_AUTH, "Authentication method not setup properly (%d)", lak->conf->auth_method); 1566 1567 return LAK_FAIL; 1568} 1569 1570char *lak_error( 1571 const int errno) 1572{ 1573 1574 switch (errno) { 1575 case LAK_OK: 1576 return "Success"; 1577 case LAK_FAIL: 1578 return "Generic error"; 1579 case LAK_NOMEM: 1580 return "Out of memory"; 1581 case LAK_RETRY: 1582 return "Retry condition (ldap server connection reset or broken)"; 1583 case LAK_NOT_GROUP_MEMBER: 1584 return "Group member check failed"; 1585 case LAK_INVALID_PASSWORD: 1586 return "Invalid password"; 1587 case LAK_USER_NOT_FOUND: 1588 return "User not found"; 1589 case LAK_BIND_FAIL: 1590 return "Bind to ldap server failed (invalid user/password or insufficient access)"; 1591 case LAK_CONNECT_FAIL: 1592 return "Cannot connect to ldap server (configuration error)"; 1593 default: 1594 return "Unknow error"; 1595 } 1596} 1597 1598static char *lak_result_get( 1599 const LAK_RESULT *lres, 1600 const char *attr) 1601{ 1602 LAK_RESULT *ptr; 1603 1604 1605 for (ptr = (LAK_RESULT *)lres; ptr != NULL; ptr = ptr->next) 1606 if (!strcasecmp(ptr->attribute, attr)) 1607 return ptr->value; 1608 1609 return NULL; 1610} 1611 1612static int lak_result_add( 1613 const char *attr, 1614 const char *val, 1615 LAK_RESULT **ret) 1616{ 1617 LAK_RESULT *lres; 1618 1619 lres = (LAK_RESULT *) malloc(sizeof(LAK_RESULT)); 1620 if (lres == NULL) { 1621 return LAK_NOMEM; 1622 } 1623 1624 lres->next = NULL; 1625 1626 lres->attribute = strdup(attr); 1627 if (lres->attribute == NULL) { 1628 lak_result_free(lres); 1629 return LAK_NOMEM; 1630 } 1631 1632 lres->value = strdup(val); 1633 if (lres->value == NULL) { 1634 lak_result_free(lres); 1635 return LAK_NOMEM; 1636 } 1637 lres->len = strlen(lres->value); 1638 1639 lres->next = *ret; 1640 1641 *ret = lres; 1642 return LAK_OK; 1643} 1644 1645void lak_result_free( 1646 LAK_RESULT *res) 1647{ 1648 LAK_RESULT *lres, *ptr = res; 1649 1650 if (ptr == NULL) 1651 return; 1652 1653 for (lres = ptr; lres != NULL; lres = ptr) { 1654 1655 ptr = lres->next; 1656 1657 if (lres->attribute != NULL) { 1658 memset(lres->attribute, 0, strlen(lres->attribute)); 1659 free(lres->attribute); 1660 } 1661 1662 if (lres->value != NULL) { 1663 memset(lres->value, 0, strlen(lres->value)); 1664 free(lres->value); 1665 } 1666 1667 lres->next = NULL; 1668 1669 free(lres); 1670 } 1671 1672 return; 1673} 1674 1675static int lak_check_password( 1676 const char *hash, 1677 const char *passwd, 1678 void *rock __attribute__((unused))) 1679{ 1680 int i, hlen; 1681 1682 if (EMPTY(hash)) 1683 return LAK_INVALID_PASSWORD; 1684 1685 if (EMPTY(passwd)) 1686 return LAK_INVALID_PASSWORD; 1687 1688 for (i = 0; password_scheme[i].hash != NULL; i++) { 1689 1690 hlen = strlen(password_scheme[i].hash); 1691 if (!strncasecmp(password_scheme[i].hash, hash, hlen)) { 1692 if (password_scheme[i].check) { 1693 return (password_scheme[i].check)(hash+hlen, passwd, 1694 password_scheme[i].rock); 1695 } 1696 return LAK_FAIL; 1697 } 1698 } 1699 1700 return strcmp(hash, passwd) ? LAK_INVALID_PASSWORD : LAK_OK; 1701} 1702 1703#ifdef HAVE_OPENSSL 1704 1705static int lak_base64_decode( 1706 const char *src, 1707 char **ret, 1708 int *rlen) 1709{ 1710 1711 int rc, i, tlen = 0; 1712 char *text; 1713 EVP_ENCODE_CTX EVP_ctx; 1714 1715 text = (char *)malloc(((strlen(src)+3)/4 * 3) + 1); 1716 if (text == NULL) 1717 return LAK_NOMEM; 1718 1719 EVP_DecodeInit(&EVP_ctx); 1720 rc = EVP_DecodeUpdate(&EVP_ctx, text, &i, (char *)src, strlen(src)); 1721 if (rc < 0) { 1722 free(text); 1723 return LAK_FAIL; 1724 } 1725 tlen += i; 1726 EVP_DecodeFinal(&EVP_ctx, text, &i); 1727 1728 *ret = text; 1729 if (rlen != NULL) 1730 *rlen = tlen; 1731 1732 return LAK_OK; 1733} 1734 1735static int lak_check_hashed( 1736 const char *hash, 1737 const char *passwd, 1738 void *rock) 1739{ 1740 int rc, clen; 1741 LAK_HASH_ROCK *hrock = (LAK_HASH_ROCK *) rock; 1742 EVP_MD_CTX mdctx; 1743 const EVP_MD *md; 1744 unsigned char digest[EVP_MAX_MD_SIZE]; 1745 char *cred; 1746 1747 md = EVP_get_digestbyname(hrock->mda); 1748 if (!md) 1749 return LAK_FAIL; 1750 1751 rc = lak_base64_decode(hash, &cred, &clen); 1752 if (rc != LAK_OK) 1753 return rc; 1754 1755 EVP_DigestInit(&mdctx, md); 1756 EVP_DigestUpdate(&mdctx, passwd, strlen(passwd)); 1757 if (hrock->salted) { 1758 EVP_DigestUpdate(&mdctx, &cred[EVP_MD_size(md)], 1759 clen - EVP_MD_size(md)); 1760 } 1761 EVP_DigestFinal(&mdctx, digest, NULL); 1762 1763 rc = memcmp((char *)cred, (char *)digest, EVP_MD_size(md)); 1764 free(cred); 1765 return rc ? LAK_INVALID_PASSWORD : LAK_OK; 1766} 1767 1768#endif /* HAVE_OPENSSL */ 1769 1770static int lak_check_crypt( 1771 const char *hash, 1772 const char *passwd, 1773 void *rock __attribute__((unused))) 1774{ 1775 char *cred; 1776 1777 if (strlen(hash) < 2 ) 1778 return LAK_INVALID_PASSWORD; 1779 1780 cred = crypt(passwd, hash); 1781 if (EMPTY(cred)) 1782 return LAK_INVALID_PASSWORD; 1783 1784 return strcmp(hash, cred) ? LAK_INVALID_PASSWORD : LAK_OK; 1785} 1786 1787#endif /* AUTH_LDAP */ 1788