Project

General

Profile

lighttpd-1.4.31-http_auth.c-ldap_group.diff

sanya, 2013-07-11 10:21

View differences:

src/http_auth.c 2013-07-11 11:36:44.000000000 +0400
304 304
	return ret;
305 305
}
306 306

  
307
static int http_auth_match_rules(server *srv, mod_auth_plugin_data *p, const char *url, const char *username, const char *group, const char *host) {
307
static int http_auth_match_rules(server *srv, mod_auth_plugin_data *p, const char *url, const char *username, const char *group, const char *host, char *dn) {
308 308
	const char *r = NULL, *rules = NULL;
309 309
	size_t i;
310 310
	int username_len;
......
409 409
			}
410 410
		} else if (k_len == 5) {
411 411
			if (0 == strncmp(k, "group", k_len)) {
412
				log_error_write(srv, __FILE__, __LINE__, "s", "group ... (not implemented)");
412
				if(p->conf.auth_backend == AUTH_BACKEND_LDAP && dn != NULL) { 
413
					/* lookup ldap group membership */	
414
#ifdef USE_LDAP
415
					LDAP *ldap = NULL;
416
					LDAPMessage *lm = NULL;
417
					char *attrs[] = { LDAP_NO_ATTRS, NULL };
418
					
419
					/* dn has been passed as char-pointer.. */
420
					if(NULL != (ldap = ldap_init(p->conf.auth_ldap_hostname->ptr, LDAP_PORT))) {
421
						/* init ok, set version */
422
						int ret = LDAP_VERSION3;
423
						if(LDAP_OPT_SUCCESS == (ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
424
							/* set version ok .. contine with stuff */
425
							if(p->conf.auth_ldap_starttls == 1 && LDAP_SUCCESS != (ret = ldap_start_tls_s(ldap, NULL, NULL))) {
426
								log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));
427
								(void)ldap_unbind_s(ldap);
428
								return -1;
429
							} /* we should be ok to bind here, starttls breaks http_auth_basic_check if fails */
430
							if(LDAP_SUCCESS == (ret = ldap_simple_bind_s(ldap, p->conf.auth_ldap_binddn->used ? p->conf.auth_ldap_binddn->ptr : NULL, p->conf.auth_ldap_binddn->used ? p->conf.auth_ldap_bindpw->ptr : NULL))) {
431
								/* build groupfilter */
432
								buffer *groupFilter = buffer_init_string("(&(objectClass=groupOfNames)(member=");
433
								(void)buffer_append_string(groupFilter, dn);
434
								(void)buffer_append_string(groupFilter, "))");
435

  
436
								/* extract groupdn from require */
437
								buffer *groupDN = buffer_init();
438
								(void)buffer_copy_string_len(groupDN, v, (size_t)v_len);
439
					
440
								/* CHECK GROUP MEMBERSHIP - NEED TO EXTRACT groupDN from auth.require.. */
441
								if(LDAP_SUCCESS == ldap_search_s(ldap, groupDN->ptr, LDAP_SCOPE_SUBTREE, groupFilter->ptr, attrs, 0, &lm)) {
442
									if( ldap_count_entries(ldap, lm) > 0 ) {
443
										(void)buffer_free(groupDN);
444
										(void)buffer_free(groupFilter);
445
										(void)ldap_msgfree(lm);
446
										(void)ldap_unbind_s(ldap);
447
										return 0;
448
									} else {
449
										(void)buffer_free(groupDN);
450
										(void)buffer_free(groupFilter);
451
										(void)ldap_msgfree(lm);
452
										(void)ldap_unbind_s(ldap);
453
									}
454
								} else {
455
										(void)buffer_free(groupDN);
456
										(void)buffer_free(groupFilter);
457
										(void)ldap_msgfree(lm);
458
										(void)ldap_unbind_s(ldap);
459
								}
460
							} else {
461
								log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
462
								(void)ldap_unbind_s(ldap);
463
							}
464
						} else {
465
							log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
466
							(void)ldap_unbind_s(ldap);
467
						}
468
					} else {
469
						/* group set, but not auth.backend = "ldap" */
470
						log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", strerror(errno));
471
					}
472
#endif
473
				} else { log_error_write(srv, __FILE__, __LINE__, "s", "group ... (not implemented)"); }
413 474
			} else {
414 475
				log_error_write(srv, __FILE__, __LINE__, "ss", "unknown key", k);
415 476
				return -1;
......
607 668
 * @param pw       password-string from the client
608 669
 */
609 670

  
610
static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p, array *req, buffer *username, buffer *realm, buffer *password, const char *pw) {
671
static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p, array *req, buffer *username, buffer *realm, buffer *password, const char *pw, char **dn) {
611 672
	UNUSED(srv);
612 673
	UNUSED(req);
613 674

  
......
703 764
#ifdef USE_LDAP
704 765
		LDAP *ldap;
705 766
		LDAPMessage *lm, *first;
706
		char *dn;
707 767
		int ret;
708 768
		char *attrs[] = { LDAP_NO_ATTRS, NULL };
709 769
		size_t i;
......
780 840
			return -1;
781 841
		}
782 842

  
783
		if (NULL == (dn = ldap_get_dn(p->anon_conf->ldap, first))) {
843
		if (NULL == (*dn = ldap_get_dn(p->anon_conf->ldap, first))) {
784 844
			log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
785 845

  
786 846
			ldap_msgfree(lm);
......
817 877
 		}
818 878

  
819 879

  
820
		if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, dn, pw))) {
880
		if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, *dn, pw))) {
821 881
			log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
822 882

  
823 883
			ldap_unbind_s(ldap);
......
838 898

  
839 899
int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str) {
840 900
	buffer *username, *password;
841
	char *pw;
901
	char *dn = NULL; //for checking ldap-group membership in http_auth_match_rules (set by http_auth_basic_compare)
902
	char *pw = NULL;
842 903

  
843 904
	data_string *realm;
844 905

  
......
881 942
	}
882 943

  
883 944
	/* password doesn't match */
884
	if (http_auth_basic_password_compare(srv, p, req, username, realm->value, password, pw)) {
945
	if (http_auth_basic_password_compare(srv, p, req, username, realm->value, password, pw, &dn)) {
885 946
		log_error_write(srv, __FILE__, __LINE__, "sbsBss", "password doesn't match for", con->uri.path, "username:", username, ", IP:", inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
886 947

  
887 948
		buffer_free(username);
......
891 952
	}
892 953

  
893 954
	/* value is our allow-rules */
894
	if (http_auth_match_rules(srv, p, url->ptr, username->ptr, NULL, NULL)) {
955
	if (http_auth_match_rules(srv, p, url->ptr, username->ptr, NULL, NULL, dn)) {
895 956
		buffer_free(username);
896 957
		buffer_free(password);
897 958

  
......
1153 1214
	}
1154 1215

  
1155 1216
	/* value is our allow-rules */
1156
	if (http_auth_match_rules(srv, p, url->ptr, username, NULL, NULL)) {
1217
	if (http_auth_match_rules(srv, p, url->ptr, username, NULL, NULL, NULL)) {
1157 1218
		buffer_free(b);
1158 1219

  
1159 1220
		log_error_write(srv, __FILE__, __LINE__, "s",