Project

General

Profile

lighttpd-1.4.44-mod_authn_ldap-group.patch

*UNTESTED* - gstrauss, 2016-12-23 01:50

View differences:

src/mod_authn_ldap.c
21 21
    buffer *auth_ldap_bindpw;
22 22
    buffer *auth_ldap_filter;
23 23
    buffer *auth_ldap_cafile;
24
    buffer *auth_ldap_groupmember;
24 25
    unsigned short auth_ldap_starttls;
25 26
    unsigned short auth_ldap_allow_empty_pw;
26 27
} plugin_config;
......
70 71
            buffer_free(s->auth_ldap_bindpw);
71 72
            buffer_free(s->auth_ldap_filter);
72 73
            buffer_free(s->auth_ldap_cafile);
74
            buffer_free(s->auth_ldap_groupmember);
73 75

  
74 76
            if (NULL != s->ldap) ldap_unbind_ext_s(s->ldap, NULL, NULL);
75 77
            free(s);
......
94 96
        { "auth.backend.ldap.bind-dn",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 5 */
95 97
        { "auth.backend.ldap.bind-pw",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 6 */
96 98
        { "auth.backend.ldap.allow-empty-pw",     NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
99
        { "auth.backend.ldap.groupmember",  NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
97 100
        { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
98 101
    };
99 102

  
......
111 114
        s->auth_ldap_bindpw = buffer_init();
112 115
        s->auth_ldap_filter = buffer_init();
113 116
        s->auth_ldap_cafile = buffer_init();
117
        s->auth_ldap_groupmember = buffer_init_string("memberUid");
114 118
        s->auth_ldap_starttls = 0;
115 119
        s->ldap = NULL;
116 120

  
......
122 126
        cv[5].destination = s->auth_ldap_binddn;
123 127
        cv[6].destination = s->auth_ldap_bindpw;
124 128
        cv[7].destination = &(s->auth_ldap_allow_empty_pw);
129
        cv[8].destination = s->auth_ldap_groupmember;
125 130

  
126 131
        p->config_storage[i] = s;
127 132

  
......
156 161
    PATCH(auth_ldap_cafile);
157 162
    PATCH(auth_ldap_starttls);
158 163
    PATCH(auth_ldap_allow_empty_pw);
164
    PATCH(auth_ldap_groupmember);
159 165
    p->anon_conf = s;
160 166

  
161 167
    /* skip the first, the global context */
......
187 193
                PATCH(auth_ldap_bindpw);
188 194
            } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.allow-empty-pw"))) {
189 195
                PATCH(auth_ldap_allow_empty_pw);
196
            } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.groupmember"))) {
197
                PATCH(auth_ldap_groupmember);
190 198
            }
191 199
        }
192 200
    }
......
380 388
    return dn;
381 389
}
382 390

  
391
static handler_t mod_authn_ldap_memberOf(server *srv, plugin_config *s, const http_auth_require_t *require, const buffer *username, const char *userdn) {
392
    array *groups = require->group;
393
    buffer *filter = buffer_init();
394
    handler_t rc = HANDLER_ERROR;
395

  
396
    buffer_copy_string_len(filter, CONST_STR_LEN("("));
397
    buffer_append_string_buffer(filter, s->auth_ldap_groupmember);
398
    buffer_append_string_len(filter, CONST_STR_LEN("="));
399
    if (buffer_is_equal_string(s->auth_ldap_groupmember,
400
                               CONST_STR_LEN("member"))) {
401
        buffer_append_string(filter, userdn);
402
    } else { /*(assume "memberUid"; consider validating in SETDEFAULTS_FUNC)*/
403
        buffer_append_string_buffer(filter, username);
404
    }
405
    buffer_append_string_len(filter, CONST_STR_LEN(")"));
406

  
407
    for (size_t i = 0; i < groups->used; ++i) {
408
        char *base = groups->data[i]->key->ptr;
409
        LDAPMessage *lm = mod_authn_ldap_search(srv, s, base, filter->ptr);
410
        if (NULL != lm) {
411
            int count = ldap_count_entries(s->ldap, lm);
412
            ldap_msgfree(lm);
413
            if (count > 0) {
414
                rc = HANDLER_GO_ON;
415
                break;
416
            }
417
        }
418
    }
419

  
420
    buffer_free(filter);
421
    return rc;
422
}
423

  
383 424
static handler_t mod_authn_ldap_basic(server *srv, connection *con, void *p_d, const http_auth_require_t *require, const buffer *username, const char *pw) {
384 425
    plugin_data *p = (plugin_data *)p_d;
385 426
    LDAP *ld;
386 427
    char *dn;
387 428
    buffer *template;
429
    handler_t rc;
388 430

  
389 431
    mod_authn_ldap_patch_connection(srv, con, p);
390 432

  
......
467 509
    }
468 510

  
469 511
    ldap_unbind_ext_s(ld, NULL, NULL); /* disconnect */
512

  
513
    if (http_auth_match_rules(require, username->ptr, NULL, NULL)) {
514
        rc = HANDLER_GO_ON; /* access granted */
515
    } else {
516
        rc = HANDLER_ERROR;
517
        if (require->group->used) {
518
            /*(must not re-use p->ldap_filter, since it might be used for dn)*/
519
            rc = mod_authn_ldap_memberOf(srv, &p->conf, require, username, dn);
520
        }
521
    }
522

  
470 523
    if (dn != p->ldap_filter->ptr) ldap_memfree(dn);
471
    return http_auth_match_rules(require, username->ptr, NULL, NULL)
472
      ? HANDLER_GO_ON  /* access granted */
473
      : HANDLER_ERROR;
524
    return rc;
474 525
}
475 526

  
476 527
int mod_authn_ldap_plugin_init(plugin *p);