Project

General

Profile

Feature #1817 » lighttpd-http_auth.c-ldap_group.diff

patch -p0 < patch, in root of tarball - mr_bond, 2008-11-07 15:32

View differences:

src/http_auth.c 2008-11-07 14:05:26.000000000 +0000
295 295
	return ret;
296 296
}
297 297

  
298
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) {
298
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) {
299 299
	const char *r = NULL, *rules = NULL;
300 300
	size_t i;
301 301
	int username_len;
......
400 400
			}
401 401
		} else if (k_len == 5) {
402 402
			if (0 == strncmp(k, "group", k_len)) {
403
				log_error_write(srv, __FILE__, __LINE__, "s", "group ... (not implemented)");
403
				if(p->conf.auth_backend == AUTH_BACKEND_LDAP && dn != NULL) { 
404
					/* lookup ldap group membership */	
405
#ifdef USE_LDAP
406
					LDAP *ldap = NULL;
407
					LDAPMessage *lm = NULL;
408
					char *attrs[] = { LDAP_NO_ATTRS, NULL };
409
					
410
					/* dn has been passed as char-pointer.. */
411
					if(NULL != (ldap = ldap_init(p->conf.auth_ldap_hostname->ptr, LDAP_PORT))) {
412
						/* init ok, set version */
413
						int ret = LDAP_VERSION3;
414
						if(LDAP_OPT_SUCCESS == (ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
415
							/* set version ok .. contine with stuff */
416
							if(p->conf.auth_ldap_starttls == 1 && LDAP_SUCCESS != (ret = ldap_start_tls_s(ldap, NULL, NULL))) {
417
								log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));
418
								(void)ldap_unbind_s(ldap);
419
								return -1;
420
							} /* we should be ok to bind here, starttls breaks http_auth_basic_check if fails */
421
							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))) {
422
								/* build groupfilter */
423
								buffer *groupFilter = buffer_init_string("(&(objectClass=groupOfNames)(member=");
424
								(void)buffer_append_string(groupFilter, dn);
425
								(void)buffer_append_string(groupFilter, "))");
426

  
427
								/* extract groupdn from require */
428
								buffer *groupDN = buffer_init();
429
								(void)buffer_copy_string_len(groupDN, v, (size_t)v_len);
430
					
431
								/* CHECK GROUP MEMBERSHIP - NEED TO EXTRACT groupDN from auth.require.. */
432
								if(LDAP_SUCCESS == ldap_search_s(ldap, groupDN->ptr, LDAP_SCOPE_SUBTREE, groupFilter->ptr, attrs, 0, &lm)) {
433
									if( ldap_count_entries(ldap, lm) > 0 ) {
434
										(void)buffer_free(groupDN);
435
										(void)buffer_free(groupFilter);
436
										(void)ldap_msgfree(lm);
437
										(void)ldap_unbind_s(ldap);
438
										return 0;
439
									} else {
440
										(void)buffer_free(groupDN);
441
										(void)buffer_free(groupFilter);
442
										(void)ldap_msgfree(lm);
443
										(void)ldap_unbind_s(ldap);
444
									}
445
								} else {
446
										(void)buffer_free(groupDN);
447
										(void)buffer_free(groupFilter);
448
										(void)ldap_msgfree(lm);
449
										(void)ldap_unbind_s(ldap);
450
								}
451
							} else {
452
								log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
453
								(void)ldap_unbind_s(ldap);
454
							}
455
						} else {
456
							log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
457
							(void)ldap_unbind_s(ldap);
458
						}
459
					} else {
460
						/* group set, but not auth.backend = "ldap" */
461
						log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", strerror(errno));
462
					}
463
#endif
464
				} else { log_error_write(srv, __FILE__, __LINE__, "s", "group ... (not implemented)"); }
404 465
			} else {
405 466
				log_error_write(srv, __FILE__, __LINE__, "ss", "unknown key", k);
406 467
				return -1;
......
598 659
 * @param pw       password-string from the client
599 660
 */
600 661

  
601
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) {
662
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) {
602 663
	UNUSED(srv);
603 664
	UNUSED(req);
604 665

  
......
699 760
#ifdef USE_LDAP
700 761
		LDAP *ldap = NULL;
701 762
		LDAPMessage *lm, *first;
702
		char *dn;
703 763
		int ret;
704 764
		char *attrs[] = { LDAP_NO_ATTRS, NULL };
705 765
		size_t i;
......
774 834
			return -1;
775 835
		}
776 836

  
777
		if (NULL == (dn = ldap_get_dn(p->conf.ldap, first))) {
837
		if (NULL == (*dn = ldap_get_dn(p->conf.ldap, first))) {
778 838
			log_error_write(srv, __FILE__, __LINE__, "s", "ldap: ldap_get_dn failed");
779 839

  
780 840
			ldap_msgfree(lm);
......
819 879
 		}
820 880

  
821 881

  
822
		if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, dn, pw))) {
882
		if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, *dn, pw))) {
823 883
			log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
824 884

  
825 885
			ldap_unbind_s(ldap);
......
840 900

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

  
845 906
	data_string *realm;
846 907

  
......
879 940
	}
880 941

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

  
885 946
		buffer_free(username);
......
889 950
	}
890 951

  
891 952
	/* value is our allow-rules */
892
	if (http_auth_match_rules(srv, p, url->ptr, username->ptr, NULL, NULL)) {
953
	if (http_auth_match_rules(srv, p, url->ptr, username->ptr, NULL, NULL, dn)) {
893 954
		buffer_free(username);
894 955
		buffer_free(password);
895 956

  
......
1155 1216
	}
1156 1217

  
1157 1218
	/* value is our allow-rules */
1158
	if (http_auth_match_rules(srv, p, url->ptr, username, NULL, NULL)) {
1219
	if (http_auth_match_rules(srv, p, url->ptr, username, NULL, NULL, NULL)) {
1159 1220
		buffer_free(b);
1160 1221

  
1161 1222
		log_error_write(srv, __FILE__, __LINE__, "s",
(1-1/5)