|
21 | 21 | os.environ['LDAPNOINIT'] = '1'
|
22 | 22 |
|
23 | 23 | import ldap
|
24 |
| -from ldap.compat import quote_plus |
| 24 | +from ldap.compat import quote_plus, which |
25 | 25 |
|
26 | 26 | HERE = os.path.abspath(os.path.dirname(__file__))
|
27 | 27 |
|
@@ -109,46 +109,14 @@ def requires_ldapi():
|
109 | 109 | else:
|
110 | 110 | return identity
|
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 |
| - |
120 |
| - def _access_check(fn): |
121 |
| - return (os.path.exists(fn) and os.access(fn, os.F_OK | os.X_OK) |
122 |
| - and not os.path.isdir(fn)) |
123 |
| - |
124 |
| - # Path with directory part skips PATH lookup. |
125 |
| - if os.path.dirname(cmd): |
126 |
| - if _access_check(cmd): |
127 |
| - return cmd |
128 |
| - return None |
129 |
| - |
130 |
| - path = os.environ.get("PATH", os.defpath).split(os.pathsep) |
131 |
| - |
132 |
| - if sys.platform == 'win32': |
133 |
| - if os.curdir not in path: |
134 |
| - path.insert(0, os.curdir) |
135 |
| - # include path extension (.exe) |
136 |
| - pathext = os.environ.get("PATHEXT", "").split(os.pathsep) |
137 |
| - files = [cmd + ext for ext in pathext] |
138 |
| - else: |
139 |
| - # always include sbin for slapd binary |
140 |
| - for sbin in ['/usr/local/sbin', '/sbin', '/usr/sbin']: |
141 |
| - if sbin not in path: |
142 |
| - path.append(sbin) |
143 |
| - files = [cmd] |
144 |
| - |
145 |
| - for directory in path: |
146 |
| - for name in files: |
147 |
| - name = os.path.join(directory, name) |
148 |
| - if _access_check(name): |
149 |
| - return name |
150 |
| - return None |
151 |
| - |
| 112 | +def _add_sbin(path): |
| 113 | + """Add /sbin and related directories to a command search path""" |
| 114 | + directories = path.split(os.pathsep) |
| 115 | + if sys.platform != 'win32': |
| 116 | + for sbin in '/usr/local/sbin', '/sbin', '/usr/sbin': |
| 117 | + if sbin not in directories: |
| 118 | + directories.append(sbin) |
| 119 | + return os.pathsep.join(directories) |
152 | 120 |
|
153 | 121 | def combined_logger(
|
154 | 122 | log_name,
|
@@ -221,14 +189,9 @@ class SlapdObject(object):
|
221 | 189 | SCHEMADIR = "/etc/ldap/schema"
|
222 | 190 | else:
|
223 | 191 | SCHEMADIR = None
|
224 |
| - # _check_requirements turns paths into absolute paths |
225 |
| - PATH_LDAPADD = 'ldapadd' |
226 |
| - PATH_LDAPDELETE = 'ldapdelete' |
227 |
| - PATH_LDAPMODIFY = 'ldapmodify' |
228 |
| - PATH_LDAPWHOAMI = 'ldapwhoami' |
229 |
| - # The following two binaries are usually in /usr/sbin. |
230 |
| - PATH_SLAPD = os.environ.get('SLAPD', 'slapd') |
231 |
| - PATH_SLAPTEST = 'slaptest' |
| 192 | + |
| 193 | + BIN_PATH = os.environ.get('BIN', os.environ.get('PATH', os.defpath)) |
| 194 | + SBIN_PATH = os.environ.get('SBIN', _add_sbin(BIN_PATH)) |
232 | 195 |
|
233 | 196 | # time in secs to wait before trying to access slapd via LDAP (again)
|
234 | 197 | _start_sleep = 1.5
|
@@ -256,29 +219,44 @@ def __init__(self):
|
256 | 219 | self.default_ldap_uri = self.ldap_uri
|
257 | 220 | # Use simple bind via LDAP uri
|
258 | 221 | self.cli_sasl_external = False
|
| 222 | + |
| 223 | + self._find_commands() |
| 224 | + |
| 225 | + if self.SCHEMADIR is None: |
| 226 | + raise ValueError('SCHEMADIR is None, ldap schemas are missing.') |
| 227 | + |
259 | 228 | # TLS certs
|
260 | 229 | self.cafile = os.path.join(HERE, 'certs/ca.pem')
|
261 | 230 | self.servercert = os.path.join(HERE, 'certs/server.pem')
|
262 | 231 | self.serverkey = os.path.join(HERE, 'certs/server.key')
|
263 | 232 | self.clientcert = os.path.join(HERE, 'certs/client.pem')
|
264 | 233 | self.clientkey = os.path.join(HERE, 'certs/client.key')
|
265 | 234 |
|
266 |
| - def _check_requirements(self): |
267 |
| - names = [ |
268 |
| - "PATH_LDAPADD", "PATH_LDAPMODIFY", "PATH_LDAPDELETE", |
269 |
| - "PATH_LDAPWHOAMI", "PATH_SLAPD", "PATH_SLAPTEST", |
270 |
| - ] |
271 |
| - for name in names: |
272 |
| - value = getattr(self, name) |
273 |
| - binary = _which(value) |
274 |
| - if binary is None: |
275 |
| - raise ValueError( |
276 |
| - "Command '{}' not found in PATH".format(value) |
277 |
| - ) |
278 |
| - else: |
279 |
| - setattr(self, name, binary) |
280 |
| - if self.SCHEMADIR is None: |
281 |
| - raise ValueError('SCHEMADIR is None, ldap schemas are missing.') |
| 235 | + def _find_commands(self): |
| 236 | + self.PATH_LDAPADD = self._find_command('ldapadd') |
| 237 | + self.PATH_LDAPDELETE = self._find_command('ldapdelete') |
| 238 | + self.PATH_LDAPMODIFY = self._find_command('ldapmodify') |
| 239 | + self.PATH_LDAPWHOAMI = self._find_command('ldapwhoami') |
| 240 | + |
| 241 | + self.PATH_SLAPD = os.environ.get('SLAPD', None) |
| 242 | + if not self.PATH_SLAPD: |
| 243 | + self.PATH_SLAPD = self._find_command('slapd', in_sbin=True) |
| 244 | + self.PATH_SLAPTEST = self._find_command('slaptest', in_sbin=True) |
| 245 | + |
| 246 | + def _find_command(self, cmd, in_sbin=False): |
| 247 | + if in_sbin: |
| 248 | + path = self.SBIN_PATH |
| 249 | + var_name = 'SBIN' |
| 250 | + else: |
| 251 | + path = self.BIN_PATH |
| 252 | + var_name = 'BIN' |
| 253 | + command = which(cmd, path=path) |
| 254 | + if command is None: |
| 255 | + raise ValueError( |
| 256 | + "Command '{}' not found. Set the {} environment variable to " |
| 257 | + "override slapdtest's search path.".format(value, var_name) |
| 258 | + ) |
| 259 | + return command |
282 | 260 |
|
283 | 261 | def setup_rundir(self):
|
284 | 262 | """
|
@@ -439,7 +417,6 @@ def start(self):
|
439 | 417 | """
|
440 | 418 |
|
441 | 419 | if self._proc is None:
|
442 |
| - self._check_requirements() |
443 | 420 | # prepare directory structure
|
444 | 421 | atexit.register(self.stop)
|
445 | 422 | self._cleanup_rundir()
|
|
0 commit comments