aboutsummaryrefslogtreecommitdiffstats
path: root/addon/ldapauth.php
blob: 2ec30caad79592b1567bccd4ec22b4986de18fdc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php

/**
 * Friendika addon
 * 
 * Module: LDAP Authenticate
 *
 * Authenticate a user against an LDAP directory
 * Useful for Windows Active Directory and other LDAP-based organisations
 * to maintain a single password across the organisation.
 *
 * Optionally authenticates only if a member of a given group in the directory.
 *
 * The person must have registered with Friendika using the normal registration 
 * procedures in order to have a Friendika user record, contact, and profile.
 *
 * Note when using with Windows Active Directory: you may need to set TLS_CACERT in your site
 * ldap.conf file to the signing cert for your LDAP server. 
 * 
 * The required configuration options for this module may be set in the .htconfig.php file
 * e.g.:
 *
 * $a->config['ldapauth']['ldap_server'] = 'host.example.com';
 * ...etc.
 *
 */



function ldapauth_install() {
	register_hook('authenticate', 'addon/ldapauth/ldapauth.php', 'ldapauth_hook_authenticate');
}


function ldapauth_uninstall() {
	unregister_hook('authenticate', 'addon/ldapauth/ldapauth.php', 'ldapauth_hook_authenticate');
}


function ldapauth_hook_authenticate($a,&$b) {
	if(ldapauth_authenticate($b['username'],$b['password'])) {
		$results = q("SELECT * FROM `user` WHERE `nickname` = '%s' AND `blocked` = 0 AND `verified` = 1 LIMIT 1",
				dbesc($b['username'])
		);
		if(count($results)) {
				$b['user_record'] = $results[0];
				$b['authenticated'] = 1;
		}
	}
	return;
}


function ldapauth_authenticate($username,$password) {

    $ldap_server   = get_config('ldapauth','ldap_server');
    $ldap_binddn   = get_config('ldapauth','ldap_binddn');
    $ldap_bindpw   = get_config('ldapauth','ldap_bindpw');
    $ldap_searchdn = get_config('ldapauth','ldap_searchdn');
    $ldap_userattr = get_config('ldapauth','ldap_userattr');
    $ldap_group    = get_config('ldapauth','ldap_group');

    if(! ((strlen($password))
            && (function_exists('ldap_connect'))
            && (strlen($ldap_server))))
            return false;

    $connect = @ldap_connect($ldap_server);

    if(! $connect)
        return false;

    @ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION,3);
    @ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
    if((@ldap_bind($connect,$ldap_binddn,$ldap_bindpw)) === false) {
        return false;
    }

    $res = @ldap_search($connect,$ldap_searchdn, $ldap_userattr . '=' . $username);

    if(! $res) {
        return false;
    }

    $id = @ldap_first_entry($connect,$res);

    if(! $id) {
        return false;
    }

    $dn = @ldap_get_dn($connect,$id);

    if(! @ldap_bind($connect,$dn,$password))
        return false;

    if(! strlen($ldap_group))
        return true;

    $r = @ldap_compare($connect,$ldap_group,'member',$dn);
    if ($r === -1) {
        $err = @ldap_error($connect);
        $eno = @ldap_errno($connect);
        @ldap_close($connect);

        if ($eno === 32) {
            logger("ldapauth: access control group Does Not Exist");
            return false;
        }
        elseif ($eno === 16) {
            logger('ldapauth: membership attribute does not exist in access control group');
            return false;
        }
        else {
            logger('ldapauth: error: ' . $err);
            return false;
        }
    }
    elseif ($r === false) {
        @ldap_close($connect);
        return false;
    }

    return true;
}