src/server/daemon/ldap_auth.c

changeset 471
9aa5ae3258f5
parent 470
467ed0f559af
child 472
d6bc67906c8c
equal deleted inserted replaced
470:467ed0f559af 471:9aa5ae3258f5
325 } 325 }
326 ldap_value_free_len(values); 326 ldap_value_free_len(values);
327 } 327 }
328 } 328 }
329 } 329 }
330
330 if(uid_values[0].ptr) { 331 if(uid_values[0].ptr) {
331 // if we found a value for the first attribute, we can use that 332 // if we found a value for the first attribute, we can use that
332 break; 333 break;
333 } 334 }
334 335
335 ldap_memfree(attribute); 336 ldap_memfree(attribute);
336 attribute = ldap_next_attribute(ldap, msg, ber); 337 attribute = ldap_next_attribute(ldap, msg, ber);
337 } 338 }
339 if(ber) {
340 ber_free(ber, 0);
341 }
342
338 343
339 344
340 // use first value as uid 345 // use first value as uid
341 for(int i=0;i<numUidAttributes;i++) { 346 for(int i=0;i<numUidAttributes;i++) {
342 if(uid_values[i].ptr) { 347 if(uid_values[i].ptr) {
441 ldap_msgfree(result); 446 ldap_msgfree(result);
442 447
443 return (User*)user; 448 return (User*)user;
444 } 449 }
445 450
451
452 static int is_member_attribute(LDAPAuthDB *auth, const char *attribute) {
453 LDAPConfig *config = &auth->config;
454 cxstring attr = cx_str(attribute);
455 for(int i=0;i<config->numMemberAttributes;i++) {
456 if(!cx_strcmp(config->memberAttributes[i], attr)) {
457 return 1;
458 }
459 }
460 return 0;
461 }
462
463 static int group_add_member(LDAPGroup *group, LDAP *ldap, LDAPMessage *msg, char *attribute) {
464 struct berval **values = ldap_get_values_len(ldap, msg, attribute);
465 int ret = 0;
466 if(values) {
467 int count = ldap_count_values_len(values);
468 for(int i=0;i<count;i++) {
469 cxstring memberValue = cx_strn(values[i]->bv_val, values[i]->bv_len);
470 CxHashKey key = cx_hash_key(memberValue.ptr, memberValue.length);
471 char *g_member = cxMapGet(group->members, key);
472 if(!g_member) {
473 cxmutstr member = cx_strdup_a(group->members->allocator, memberValue);
474 if(!member.ptr) {
475 ret = 1;
476 break;
477 }
478 if(cxMapPut(group->members, key, member.ptr)) {
479 ret = 1;
480 break;
481 }
482 }
483 }
484 ldap_value_free_len(values);
485 }
486 return ret;
487 }
488
489 static LDAPGroup* ldap_msg_to_group(
490 Session *sn,
491 Request *rq,
492 LDAPAuthDB *authdb,
493 LDAP *ldap,
494 LDAPMessage *msg,
495 const char *group_name)
496 {
497 CxAllocator *a = pool_allocator(sn->pool);
498
499 LDAPGroup *group = pool_malloc(sn->pool, sizeof(LDAPGroup));
500 if(!group) {
501 return NULL;
502 }
503 group->members = cxHashMapCreate(a, 32);
504 if(!group->members) {
505 pool_free(sn->pool, group);
506 return NULL;
507 }
508 group->name = pool_strdup(sn->pool, group_name);
509
510 BerElement *ber = NULL;
511 char *attribute = ldap_first_attribute(ldap, msg, &ber);
512 while(attribute) {
513 if(is_member_attribute(authdb, attribute)) {
514 if(group_add_member(group, ldap, msg, attribute)) {
515 // OOM
516 ldap_memfree(attribute);
517 // free at least some memory
518 cxMapDestroy(group->members);
519 pool_free(sn->pool, group);
520 group = NULL;
521 break;
522 }
523 }
524
525 ldap_memfree(attribute);
526 attribute = ldap_next_attribute(ldap, msg, ber);
527 }
528 if(ber) {
529 ber_free(ber, 0);
530 }
531
532 return group;
533 }
534
446 LDAPGroup* ldap_get_group(Session *sn, Request *rq, LDAPAuthDB *authdb, const char *group) { 535 LDAPGroup* ldap_get_group(Session *sn, Request *rq, LDAPAuthDB *authdb, const char *group) {
447 printf("ldap_get_group: %s\n", group);
448
449 LDAPConfig *config = &authdb->config; 536 LDAPConfig *config = &authdb->config;
537 CxAllocator *a = pool_allocator(sn->pool);
450 538
451 LDAP *ld = get_ldap_session(sn, rq, authdb); 539 LDAP *ld = get_ldap_session(sn, rq, authdb);
452 if (ld == NULL) { 540 if (ld == NULL) {
453 fprintf(stderr, "ldap_init failed\n"); 541 return NULL;
454 return NULL; 542 }
455 } 543
456 544 cxstring groupSearch = cx_str(config->groupSearchFilter);
457 // get the user dn 545 cxmutstr filter = cx_strreplace_a(a, groupSearch, cx_str("%s"), cx_str(group));
458 // TODO: use config for filter 546 if(!filter.ptr) {
459 // TODO: use asprintf 547 return NULL;
460 char filter[128]; 548 }
461 int s = snprintf(filter, 127, "cn=%s", group);
462 filter[s] = 0;
463 549
464 LDAPMessage *result; 550 LDAPMessage *result;
465 struct timeval timeout; 551 struct timeval timeout;
466 timeout.tv_sec = 8; 552 timeout.tv_sec = 8;
467 timeout.tv_usec = 0; 553 timeout.tv_usec = 0;
468 int r = ldap_search_ext_s( 554 int r = ldap_search_ext_s(
469 ld, 555 ld,
470 config->basedn, 556 config->basedn,
471 LDAP_SCOPE_SUBTREE, 557 LDAP_SCOPE_SUBTREE,
472 filter, 558 filter.ptr,
473 NULL, 559 NULL,
474 0, 560 0,
475 NULL, // server controls 561 NULL, // server controls
476 NULL, // client controls 562 NULL, // client controls
477 &timeout, 563 &timeout,
478 1, // size limit 564 2, // size limit
479 &result); 565 &result);
480 if (r != LDAP_SUCCESS) { 566 if (r != LDAP_SUCCESS) {
481 //ws_ldap_close(ld); 567 if(result) {
482 568 ldap_msgfree(result);
483 fprintf(stderr, "ldap_search_ext_s failed\n"); 569 }
484 return NULL; 570 log_ereport(LOG_FAILURE, "ldap_get_group: search failed: %s", ldap_err2string(r));
485 } 571 return NULL;
486 572 }
573
574 LDAPMessage *msg = ldap_first_entry(ld, result);
487 LDAPGroup *wsgroup = NULL; 575 LDAPGroup *wsgroup = NULL;
576 if(msg) {
577 if(ldap_count_entries(ld, msg) > 1) {
578 log_ereport(LOG_FAILURE, "ldap_get_user: more than one search result");
579 } else {
580 wsgroup = ldap_msg_to_group(sn, rq, authdb, ld, msg, group);
581 }
582 }
583 ldap_msgfree(result);
584
585 /*
488 LDAPMessage *msg = ldap_first_entry(ld, result); 586 LDAPMessage *msg = ldap_first_entry(ld, result);
489 if (msg) { 587 if (msg) {
490 // create group object 588 // create group object
491 wsgroup = malloc(sizeof(LDAPGroup)); 589 wsgroup = malloc(sizeof(LDAPGroup));
492 wsgroup->name = strdup(group); 590 wsgroup->name = strdup(group);
527 } 625 }
528 if(attribute) { 626 if(attribute) {
529 ldap_memfree(attribute); 627 ldap_memfree(attribute);
530 } 628 }
531 } 629 }
532 630 */
533 //ws_ldap_close(ld); 631
534 return wsgroup; 632 return wsgroup;
535 } 633 }
536 634
537 int ldap_user_verify_password(User *u, const char *password) { 635 int ldap_user_verify_password(User *u, const char *password) {
538 LDAPUser *user = (LDAPUser*)u; 636 LDAPUser *user = (LDAPUser*)u;
539 637
540 //int r = ldap_simple_bind_s(user->ldap, user->userdn, password);
541 struct berval cred; 638 struct berval cred;
542 cred.bv_val = (char*)password; 639 cred.bv_val = (char*)password;
543 cred.bv_len = strlen(password); 640 cred.bv_len = strlen(password);
544 struct berval *server_cred; 641 struct berval *server_cred;
545 int r = ldap_sasl_bind_s( 642 int r = ldap_sasl_bind_s(
563 LDAPUser *user = (LDAPUser*)u; 660 LDAPUser *user = (LDAPUser*)u;
564 661
565 int ret = 0; 662 int ret = 0;
566 663
567 LDAPGroup *group = ldap_get_group(user->sn, user->rq, user->authdb, group_str); 664 LDAPGroup *group = ldap_get_group(user->sn, user->rq, user->authdb, group_str);
568 for(int i=0;i<group->nmembers;i++) { 665 if(group) {
569 char *member = group->members[i].name; 666 char *member = cxMapGet(group->members, cx_hash_key_str(u->name));
570 if(!strcmp(member, u->name)) { 667 if(member) {
571 printf("is member\n");
572 ret = 1; 668 ret = 1;
573 } 669 }
574 } 670 }
575 671
576 // TODO: free or cache group
577 672
578 return ret; 673 return ret;
579 } 674 }
580 675
581 void ldap_user_free(User *u) { 676 void ldap_user_free(User *u) {

mercurial