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