I compared the two ldap modules here:
http://www.mail-archive.com/[email protected]/msg01381.html
(Was it really three years ago??)
Is there any reason to maintain both? What does "full" mean in
ldapfull?
Justin
On Wed, Dec 12, 2012 at 05:07:34PM +0100, Guido Winkelmann wrote:
> This patch appears to work. Note, I have only done superficial testing
> (checked that I can log in as a user who is in the specified group and that I
> can not log in as one that is not in this group). I have not tested this
> against AD, only OpenLDAP.
>
> This patch applies to 2.2.17, but not to git-master.
>
> Guido
> diff -rup jabberd-2.2.17-orig/etc/c2s.xml.dist.in
> jabberd-2.2.17/etc/c2s.xml.dist.in
> --- jabberd-2.2.17-orig/etc/c2s.xml.dist.in 2012-05-22 22:27:51.000000000
> +0200
> +++ jabberd-2.2.17/etc/c2s.xml.dist.in 2012-12-12 16:39:54.490003311
> +0100
> @@ -546,6 +546,15 @@
> <!--
> <validattr>valid</validattr>
> -->
> +
> + <!-- Group that users must be members of
> + If this is set, only user that are members of the specified LDAP
> + group can log in. The group must be specified with its full
> + distinguished name -->
> + <!--
> + <group_dn>cn=jabberdusers,ou=servicegroups,dc=example,dc=com</group_dn>
> + -->
> +
> <fulluid/>
> <!-- If pwscheme is not defined, then passwords are stored in clear
> text and digest authentication may be done.
> diff -rup jabberd-2.2.17-orig/storage/authreg_ldapfull.c
> jabberd-2.2.17/storage/authreg_ldapfull.c
> --- jabberd-2.2.17-orig/storage/authreg_ldapfull.c 2012-02-19
> 14:23:09.000000000 +0100
> +++ jabberd-2.2.17/storage/authreg_ldapfull.c 2012-12-12 16:52:30.400003587
> +0100
> @@ -68,6 +68,7 @@ typedef struct moddata_st
> char *objectclass;
> char *uidattr;
> char *validattr;
> + char *group_dn;
> char *pwattr;
> char *pwscheme;
>
> @@ -583,6 +584,50 @@ retry:
> return dn;
> }
>
> +/** Is this user part of the given LDAP group? */
> +static int _ldapfull_user_in_group(moddata_t data, char *user_dn, char
> *group_dn)
> +{
> + LDAPMessage *result, *entry;
> + int tried = 0;
> + char filter[1024];
> +
> + log_debug(ZONE, "checking whether user with dn %s is in group %s",
> user_dn, group_dn);
> +
> + memset(filter, 0, 1024);
> + snprintf(filter, 1024, "(member=%s)", user_dn); // TODO Check if
> snprintf result was truncated
> +
> + retry:
> + if(ldap_search_s(data->ld, group_dn, LDAP_SCOPE_BASE, filter, NULL, 0,
> &result))
> + {
> + if( tried++ < LDAPFULL_SEARCH_MAX_RETRIES ) {
> + log_debug(ZONE, "ldap: group search fail, will retry; %s: %s",
> filter, ldap_err2string(_ldapfull_get_lderrno(data->ld)));
> + _ldapfull_unbind(data);
> + if( _ldapfull_connect_bind(data) == 0 ) {
> + goto retry;
> + } else {
> + return 0;
> + }
> + }
> + log_write(data->ar->c2s->log, LOG_ERR, "ldap: group search %s
> failed: %s", filter, ldap_err2string(_ldapfull_get_lderrno(data->ld)));
> + _ldapfull_unbind(data);
> + return 0;
> + }
> +
> + entry = ldap_first_entry(data->ld, result);
> + if(entry == NULL)
> + {
> + ldap_msgfree(result);
> +
> + return 0;
> + }
> + else
> + {
> + ldap_msgfree(result);
> +
> + return 1;
> + }
> +}
> +
> /** do we have this user? */
> static int _ldapfull_find_user_dn(moddata_t data, char *username, char
> *realm, char **dn)
> {
> @@ -601,6 +646,11 @@ static int _ldapfull_user_exists(authreg
> {
> char *dn;
> if (_ldapfull_find_user_dn((moddata_t) ar->private, username, realm,
> &dn)) {
> + if(((moddata_t) ar->private)->group_dn != NULL
> + && !_ldapfull_user_in_group((moddata_t) ar->private, dn,
> ((moddata_t) ar->private)->group_dn)) {
> + ldap_memfree(dn);
> + return 0;
> + }
> ldap_memfree(dn);
> return 1;
> }
> @@ -748,22 +798,40 @@ static int _ldapfull_check_password(auth
> {
> moddata_t data = (moddata_t) ar->private;
> char buf[LDAPFULL_PASSBUF_MAX];
> + char *dn;
>
> log_debug(ZONE, "checking password for %s", username);
>
> if(password[0] == '\0')
> return 1;
>
> + if(data->group_dn != NULL) {
> + if (!_ldapfull_find_user_dn(data, username, realm, &dn))
> + return 1;
> + }
> /* The bind scheme doesn't need the password read first, so short circuit
> the whole passhash scheme */
> - if (!strcmp(data->pwscheme, "bind"))
> - return _ldapfull_check_password_bind(ar, username, realm, password);
> + if (!strcmp(data->pwscheme, "bind")) {
> + if(_ldapfull_check_password_bind(ar, username, realm, password) ==
> 0) {
> + if(data->group_dn != NULL && !_ldapfull_user_in_group(data, dn,
> data->group_dn))
> + return 1;
> + else
> + return 0;
> + }
> + }
>
> if( _ldapfull_get_password(ar,username,realm,buf) != 0 ) {
> return 1;
> }
>
> - return ! _ldapfull_check_passhash(data,buf,password);
> + if(_ldapfull_check_passhash(data,buf,password)){
> + if(data->group_dn != NULL && !_ldapfull_user_in_group(data, dn,
> data->group_dn))
> + return 1;
> + else
> + return 0;
> + }
> + else
> + return 1;
> }
>
> static int _ldapfull_create_user(authreg_t ar, char *username, char *realm) {
> @@ -856,6 +924,8 @@ DLLEXPORT int ar_init(authreg_t ar)
>
> data->validattr = config_get_one(ar->c2s->config,
> "authreg.ldapfull.validattr", 0);
>
> + data->group_dn = config_get_one(ar->c2s->config,
> "authreg.ldapfull.group_dn", 0);
> +
> data->pwattr = config_get_one(ar->c2s->config,
> "authreg.ldapfull.pwattr", 0);
> if(data->pwattr == NULL)
> data->pwattr = "jabberPassword";