9
9
10
10
import os
11
11
import socket
12
+ import sys
12
13
import time
13
14
import subprocess
14
15
import logging
@@ -109,6 +110,35 @@ def requires_ldapi():
109
110
return identity
110
111
111
112
113
+ def _which (cmd ):
114
+ """Specialized which command based on shutil.which() from Python 3.6.
115
+
116
+ * simplified
117
+ * always adds /sbin directories to path
118
+ """
119
+ path = os .environ .get ("PATH" , os .defpath ).split (os .pathsep )
120
+
121
+ if sys .platform == 'win32' :
122
+ if os .curdir not in path :
123
+ path .insert (0 , os .curdir )
124
+ # include path extension (.exe)
125
+ pathext = os .environ .get ("PATHEXT" , "" ).split (os .pathsep )
126
+ files = [cmd + ext for ext in pathext ]
127
+ else :
128
+ # always include sbin for slapd binary
129
+ for sbin in ['/sbin' , '/usr/sbin' , '/usr/local/sbin' ]:
130
+ if sbin not in path :
131
+ path .append (sbin )
132
+ files = [cmd ]
133
+
134
+ for directory in path :
135
+ for name in files :
136
+ name = os .path .join (directory , name )
137
+ if os .path .exists (name ) and os .access (name , os .F_OK | os .X_OK ):
138
+ return name
139
+ return None
140
+
141
+
112
142
def combined_logger (
113
143
log_name ,
114
144
log_level = logging .WARN ,
@@ -172,8 +202,6 @@ class SlapdObject(object):
172
202
)
173
203
174
204
TMPDIR = os .environ .get ('TMP' , os .getcwd ())
175
- SBINDIR = os .environ .get ('SBIN' , '/usr/sbin' )
176
- BINDIR = os .environ .get ('BIN' , '/usr/bin' )
177
205
if 'SCHEMA' in os .environ :
178
206
SCHEMADIR = os .environ ['SCHEMA' ]
179
207
elif os .path .isdir ("/etc/openldap/schema" ):
@@ -182,12 +210,12 @@ class SlapdObject(object):
182
210
SCHEMADIR = "/etc/ldap/schema"
183
211
else :
184
212
SCHEMADIR = None
185
- PATH_LDAPADD = os . path . join ( BINDIR , 'ldapadd' )
186
- PATH_LDAPDELETE = os . path . join ( BINDIR , 'ldapdelete' )
187
- PATH_LDAPMODIFY = os . path . join ( BINDIR , 'ldapmodify' )
188
- PATH_LDAPWHOAMI = os . path . join ( BINDIR , 'ldapwhoami' )
189
- PATH_SLAPD = os .environ .get ('SLAPD' , os . path . join ( SBINDIR , 'slapd' ))
190
- PATH_SLAPTEST = os . path . join ( SBINDIR , 'slaptest' )
213
+ PATH_LDAPADD = _which ( 'ldapadd' )
214
+ PATH_LDAPDELETE = _which ( 'ldapdelete' )
215
+ PATH_LDAPMODIFY = _which ( 'ldapmodify' )
216
+ PATH_LDAPWHOAMI = _which ( 'ldapwhoami' )
217
+ PATH_SLAPD = os .environ .get ('SLAPD' , _which ( 'slapd' ))
218
+ PATH_SLAPTEST = _which ( 'slaptest' )
191
219
192
220
# time in secs to wait before trying to access slapd via LDAP (again)
193
221
_start_sleep = 1.5
@@ -223,13 +251,15 @@ def __init__(self):
223
251
self .clientkey = os .path .join (HERE , 'certs/client.key' )
224
252
225
253
def _check_requirements (self ):
226
- binaries = [
227
- self .PATH_LDAPADD , self .PATH_LDAPMODIFY , self .PATH_LDAPWHOAMI ,
228
- self .PATH_SLAPD , self .PATH_SLAPTEST
229
- ]
230
- for binary in binaries :
231
- if not os .path .isfile (binary ):
232
- raise ValueError ('Binary {} is missing.' .format (binary ))
254
+ for name in dir (self ):
255
+ if not name .startswith ('PATH_' ):
256
+ continue
257
+ value = getattr (self , name )
258
+ if value is None or not os .path .isfile (value ):
259
+ cmd = name [5 :].lower ()
260
+ raise ValueError (
261
+ "Command '{}' not found in PATH" .format (cmd )
262
+ )
233
263
if self .SCHEMADIR is None :
234
264
raise ValueError ('SCHEMADIR is None, ldap schemas are missing.' )
235
265
0 commit comments