Project

General

Profile

lighttpd-1.4.39-mod_auth-group-ldap.patch

rajven, 2016-01-22 13:00

View differences:

lighttpd-1.4.39.ldap/src/http_auth.c 2016-01-22 15:07:33.832266220 +0300
222 222
	return ret;
223 223
}
224 224

  
225
int http_auth_match_rules(server *srv, array *req, const char *username, const char *group, const char *host) {
225
int http_auth_match_rules(server *srv, array *req, const char *username, const char *group, const char *host, char *dn, mod_auth_plugin_data *p) {
226 226
	const char *r = NULL, *rules = NULL;
227 227
	int username_len;
228 228
	data_string *require;
......
309 309
			}
310 310
		} else if (k_len == 5) {
311 311
			if (0 == strncmp(k, "group", k_len)) {
312
				log_error_write(srv, __FILE__, __LINE__, "s", "group ... (not implemented)");
312
/***   START PATCH   ***********************************************/
313
				if(p->conf.auth_backend == AUTH_BACKEND_LDAP && dn != NULL) { 
314
					/* lookup ldap group membership */	
315
#ifdef USE_LDAP
316
					LDAP *ldap = NULL;
317
					LDAPMessage *lm = NULL;
318
					char *attrs[] = { LDAP_NO_ATTRS, NULL };
319
					
320
					/* dn has been passed as char-pointer.. */
321
					if(NULL != (ldap = ldap_init(p->conf.auth_ldap_hostname->ptr, LDAP_PORT))) {
322
						/* init ok, set version */
323
						int ret = LDAP_VERSION3;
324
						if(LDAP_OPT_SUCCESS == (ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
325
							/* set version ok .. contine with stuff */
326
							if(p->conf.auth_ldap_starttls == 1 && LDAP_SUCCESS != (ret = ldap_start_tls_s(ldap, NULL, NULL))) {
327
								log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));
328
								(void)ldap_unbind_s(ldap);
329
								return -1;
330
							} /* we should be ok to bind here, starttls breaks http_auth_basic_check if fails */
331
							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))) {
332

  
333
								/* build groupfilter */
334
								buffer *groupFilter = buffer_init_string("(");
335
								(void)buffer_append_string(groupFilter, p->conf.auth_ldap_groupmember->ptr);
336
								(void)buffer_append_string(groupFilter, "=");
337
								(void)buffer_append_string(groupFilter, username);
338
								(void)buffer_append_string(groupFilter, ")");
339

  
340
								/* extract groupdn from require */
341
								buffer *groupDN = buffer_init();
342
								(void)buffer_copy_string_len(groupDN, v, (size_t)v_len);
343
								/* CHECK GROUP MEMBERSHIP - NEED TO EXTRACT groupDN from auth.require.. */
344
								if(LDAP_SUCCESS == ldap_search_s(ldap, groupDN->ptr, LDAP_SCOPE_SUBTREE, groupFilter->ptr, attrs, 0, &lm)) {
345
									if( ldap_count_entries(ldap, lm) > 0 ) {
346
										(void)buffer_free(groupDN);
347
										(void)buffer_free(groupFilter);
348
										(void)ldap_msgfree(lm);
349
										(void)ldap_unbind_s(ldap);
350
										return 0;
351
									} else {
352
										(void)buffer_free(groupDN);
353
										(void)buffer_free(groupFilter);
354
										(void)ldap_msgfree(lm);
355
										(void)ldap_unbind_s(ldap);
356
									}
357
								} else {
358
										(void)buffer_free(groupDN);
359
										(void)buffer_free(groupFilter);
360
										(void)ldap_msgfree(lm);
361
										(void)ldap_unbind_s(ldap);
362
								}
363
							} else {
364
								log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
365
								(void)ldap_unbind_s(ldap);
366
							}
367
						} else {
368
							log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
369
							(void)ldap_unbind_s(ldap);
370
						}
371
					} else {
372
						/* group set, but not auth.backend = "ldap" */
373
						log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", strerror(errno));
374
					}
375
#endif
376
				} else { log_error_write(srv, __FILE__, __LINE__, "s", "group ... (not implemented)"); }
377
/***   END PATCH   ***********************************************/
313 378
			} else {
314 379
				log_error_write(srv, __FILE__, __LINE__, "ss", "unknown key", k);
315 380
				return -1;
......
526 591
 * @param pw       password-string from the client
527 592
 */
528 593

  
529
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) {
594
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) {
530 595
	UNUSED(srv);
531 596
	UNUSED(req);
532 597

  
......
602 667
#ifdef USE_LDAP
603 668
		LDAP *ldap;
604 669
		LDAPMessage *lm, *first;
605
		char *dn;
606 670
		int ret;
607 671
		char *attrs[] = { LDAP_NO_ATTRS, NULL };
608 672
		size_t i, len;
......
681 745
			return -1;
682 746
		}
683 747

  
684
		if (NULL == (dn = ldap_get_dn(p->anon_conf->ldap, first))) {
748
		if (NULL == (*dn = ldap_get_dn(p->anon_conf->ldap, first))) {
685 749
			log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
686 750

  
687 751
			ldap_msgfree(lm);
......
718 782
 		}
719 783

  
720 784

  
721
		if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, dn, pw))) {
785
		if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, *dn, pw))) {
722 786
			log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
723 787

  
724 788
			ldap_unbind_s(ldap);
......
740 804
int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, const char *realm_str) {
741 805
	buffer *username, *password;
742 806
	char *pw;
807
	char *dn;  // remember ldap DN to pass it into http_auth_match_rules()
743 808

  
744 809
	data_string *realm;
745 810

  
......
781 846
	}
782 847

  
783 848
	/* password doesn't match */
784
	if (http_auth_basic_password_compare(srv, p, req, username, realm->value, password, pw)) {
849
	if (http_auth_basic_password_compare(srv, p, req, username, realm->value, password, pw, &dn)) {
785 850
		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)));
786 851

  
787 852
		buffer_free(username);
......
791 856
	}
792 857

  
793 858
	/* value is our allow-rules */
794
	if (http_auth_match_rules(srv, req, username->ptr, NULL, NULL)) {
859
	if (http_auth_match_rules(srv, req, username->ptr, NULL, NULL, dn, p)) {
795 860
		buffer_free(username);
796 861
		buffer_free(password);
797 862

  
......
1065 1130
	}
1066 1131

  
1067 1132
	/* value is our allow-rules */
1068
	if (http_auth_match_rules(srv, req, username, NULL, NULL)) {
1133
	if (http_auth_match_rules(srv, req, username, NULL, NULL, NULL, NULL)) {
1069 1134
		buffer_free(b);
1070 1135

  
1071 1136
		log_error_write(srv, __FILE__, __LINE__, "s",
lighttpd-1.4.39.ldap/src/http_auth.h 2016-01-22 13:54:41.329258606 +0300
34 34
	buffer *auth_ldap_binddn;
35 35
	buffer *auth_ldap_bindpw;
36 36
	buffer *auth_ldap_filter;
37
	buffer *auth_ldap_groupmember;
37 38
	buffer *auth_ldap_cafile;
38 39
	unsigned short auth_ldap_starttls;
39 40
	unsigned short auth_ldap_allow_empty_pw;
......
59 60

  
60 61
#ifdef USE_LDAP
61 62
	buffer *ldap_filter;
63
	buffer *ldap_groupmember;
62 64
#endif
63 65

  
64 66
	mod_auth_plugin_config **config_storage;
......
69 71
int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, const char *realm_str);
70 72
int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, const char *realm_str);
71 73
int http_auth_digest_generate_nonce(server *srv, mod_auth_plugin_data *p, buffer *fn, char hh[33]);
72
int http_auth_match_rules(server *srv, array *req, const char *username, const char *group, const char *host);
74
int http_auth_match_rules(server *srv, array *req, const char *username, const char *group, const char *host, char *dn, mod_auth_plugin_data *p);
73 75

  
74 76
#endif
lighttpd-1.4.39.ldap/src/mod_auth.c 2016-01-22 15:09:17.776264180 +0300
74 74
			buffer_free(s->auth_ldap_binddn);
75 75
			buffer_free(s->auth_ldap_bindpw);
76 76
			buffer_free(s->auth_ldap_filter);
77
			buffer_free(s->auth_ldap_groupmember);
77 78
			buffer_free(s->auth_ldap_cafile);
78 79

  
79 80
#ifdef USE_LDAP
......
111 112
	PATCH(auth_ldap_binddn);
112 113
	PATCH(auth_ldap_bindpw);
113 114
	PATCH(auth_ldap_filter);
115
	PATCH(auth_ldap_groupmember);
114 116
	PATCH(auth_ldap_cafile);
115 117
	PATCH(auth_ldap_starttls);
116 118
	PATCH(auth_ldap_allow_empty_pw);
......
153 155
#endif
154 156
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.base-dn"))) {
155 157
				PATCH(auth_ldap_basedn);
158
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.groupmember"))) {
159
				PATCH(auth_ldap_groupmember);
156 160
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.filter"))) {
157 161
				PATCH(auth_ldap_filter);
158 162
#ifdef USE_LDAP
......
236 240
			con->http_status = 401;
237 241
			con->mode = DIRECT;
238 242
			return HANDLER_FINISHED;
239
		} else if (http_auth_match_rules(srv, req, ds->value->ptr, NULL, NULL)) {
243
		} else if (http_auth_match_rules(srv, req, ds->value->ptr, NULL, NULL, NULL, NULL)) {
240 244
			log_error_write(srv, __FILE__, __LINE__, "s", "rules didn't match");
241 245
			con->http_status = 401;
242 246
			con->mode = DIRECT;
......
361 365
		{ "auth.backend.htdigest.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 12 */
362 366
		{ "auth.backend.htpasswd.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 13 */
363 367
		{ "auth.debug",                     NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },  /* 14 */
368
		{ "auth.backend.ldap.groupmember",  NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 15 */
364 369
		{ NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
365 370
	};
366 371

  
......
384 389
		s->auth_ldap_binddn = buffer_init();
385 390
		s->auth_ldap_bindpw = buffer_init();
386 391
		s->auth_ldap_filter = buffer_init();
392
		s->auth_ldap_groupmember = buffer_init_string("memberUid");;
387 393
		s->auth_ldap_cafile = buffer_init();
388 394
		s->auth_ldap_starttls = 0;
389 395
		s->auth_debug = 0;
......
411 417
		cv[12].destination = s->auth_htdigest_userfile;
412 418
		cv[13].destination = s->auth_htpasswd_userfile;
413 419
		cv[14].destination = &(s->auth_debug);
420
		cv[15].destination = s->auth_ldap_groupmember;
414 421

  
415 422
		p->config_storage[i] = s;
416 423