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
125
126
127
128
129
130
131
132
133
134
135
136
137
|
"""
Authentication module that uses ldap
Settings in /etc/cobbler/authn_ldap.conf
Choice of authentication module is in /etc/cobbler/modules.conf
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
"""
import distutils.sysconfig
import sys
import os
from utils import _
import md5
import traceback
# we'll import this just a bit later
# to keep it from being a requirement
# import ldap
plib = distutils.sysconfig.get_python_lib()
mod_path="%s/cobbler" % plib
sys.path.insert(0, mod_path)
import cexceptions
import utils
import api as cobbler_api
def register():
"""
The mandatory cobbler module registration hook.
"""
return "authn"
def authenticate(api_handle,username,password):
"""
Validate an ldap bind, returning True/False
"""
import ldap
server = api_handle.settings().ldap_server
basedn = api_handle.settings().ldap_base_dn
port = api_handle.settings().ldap_port
tls = api_handle.settings().ldap_tls
anon_bind = api_handle.settings().ldap_anonymous_bind
prefix = api_handle.settings().ldap_search_prefix
# allow multiple servers split by a space
if server.find(" "):
servers = server.split()
else:
servers = [server]
uri = ""
for server in servers:
# form our ldap uri based on connection port
if port == '389':
uri += 'ldap://' + server
elif port == '636':
uri += 'ldaps://' + server
else:
uri += 'ldap://' + "%s:%s" % (server,port)
uri += ' '
uri = uri.strip()
# connect to LDAP host
dir = ldap.initialize(uri)
# start_tls if tls is 'on', 'true' or 'yes'
# and we're not already using old-SSL
tls = str(tls).lower()
if port != '636':
if tls in [ "on", "true", "yes", "1" ]:
try:
dir.start_tls_s()
except:
traceback.print_exc()
return False
# if we're not allowed to search anonymously,
# grok the search bind settings and attempt to bind
anon_bind = str(anon_bind).lower()
if anon_bind not in [ "on", "true", "yes", "1" ]:
searchdn = api_handle.settings().ldap_search_bind_dn
searchpw = api_handle.settings().ldap_search_passwd
if searchdn == '' or searchpw == '':
raise "Missing search bind settings"
try:
dir.simple_bind_s(searchdn, searchpw)
except:
traceback.print_exc()
return False
# perform a subtree search in basedn to find the full dn of the user
# TODO: what if username is a CN? maybe it goes into the config file as well?
filter = prefix + username
result = dir.search_s(basedn, ldap.SCOPE_SUBTREE, filter, [])
if result:
for dn,entry in result:
# username _should_ be unique so we should only have one result
# ignore entry; we don't need it
pass
else:
return False
try:
# attempt to bind as the user
dir.simple_bind_s(dn,password)
dir.unbind()
return True
except:
# traceback.print_exc()
return False
# catch-all
return False
if __name__ == "__main__":
api_handle = cobbler_api.BootAPI()
print authenticate(api_handle, "guest", "guest")
|