@@ -259,7 +259,6 @@ def _find_commands(self):
259259 self .PATH_LDAPDELETE = self ._find_command ('ldapdelete' )
260260 self .PATH_LDAPMODIFY = self ._find_command ('ldapmodify' )
261261 self .PATH_LDAPWHOAMI = self ._find_command ('ldapwhoami' )
262- self .PATH_SLAPADD = self ._find_command ('slapadd' , in_sbin = True )
263262
264263 self .PATH_SLAPD = os .environ .get ('SLAPD' , None )
265264 if not self .PATH_SLAPD :
@@ -483,34 +482,57 @@ def _stopped(self):
483482 self ._log .info ('slapd[%d] terminated' , self ._proc .pid )
484483 self ._proc = None
485484
486- def _cli_auth_args (self ):
487- if self .cli_sasl_external :
488- authc_args = [
489- '-Y' , 'EXTERNAL' ,
490- ]
491- if not self ._log .isEnabledFor (logging .DEBUG ):
492- authc_args .append ('-Q' )
493- else :
494- authc_args = [
495- '-x' ,
496- '-D' , self .root_dn ,
497- '-w' , self .root_pw ,
498- ]
499- return authc_args
485+ def _cli_slap (self , cmd = None , extra_args = None , stdin_data = None ): # pragma: no cover
486+ """Entry point for slap* commands directly modifying DB files."""
487+ if self ._proc is not None :
488+ self ._log .warning ('Directly modifying DB files while slapd is running' )
489+
490+ args = [self .PATH_SLAPD ]
491+
492+ if cmd :
493+ args .append ('-T' + cmd )
494+
495+ args += ['-F' , self ._slapd_conf ] + (extra_args or [])
496+
497+ return self ._cli_exec (args , stdin_data = stdin_data )
498+
499+ def _cli_ldap (self , ldapcommand , extra_args = None , ldap_uri = None ,
500+ bind_dn = None , bind_pw = None ,
501+ stdin_data = None ): # pragma: no cover
502+ """
503+ Entry point for ldap* commands, interacting with running slapd
504+ """
505+ if self ._proc is None :
506+ raise RuntimeError ('Must start daemon before LDAP access is possible' )
500507
501- # no cover to avoid spurious coverage changes
502- def _cli_popen (self , ldapcommand , extra_args = None , ldap_uri = None ,
503- stdin_data = None ): # pragma: no cover
504508 if ldap_uri is None :
505509 ldap_uri = self .default_ldap_uri
506510
507- if ldapcommand .split ("/" )[- 1 ].startswith ("ldap" ):
508- args = [ldapcommand , '-H' , ldap_uri ] + self ._cli_auth_args ()
511+ args = [ldapcommand , '-H' , ldap_uri or self .default_ldap_uri ]
512+
513+ if ldap_uri .startswith ('ldapi://' ):
514+ args += ['-Y' , 'EXTERNAL' ]
515+
516+ if not self ._log .isEnabledFor (logging .DEBUG ):
517+ args .append ('-Q' )
518+
519+ if bind_dn or bind_pw :
520+ raise RuntimeError ('-Y EXTERNAL ignores -D and -w' )
521+
509522 else :
510- args = [ldapcommand , '-F' , self ._slapd_conf ]
523+ args += [
524+ '-x' ,
525+ '-D' , bind_dn or self .root_dn ,
526+ '-w' , bind_pw or self .root_pw ,
527+ ]
511528
512- args += (extra_args or [])
529+ if extra_args :
530+ args += extra_args
513531
532+ return self ._cli_exec (args , stdin_data = stdin_data )
533+
534+ # no cover to avoid spurious coverage changes
535+ def _cli_exec (self , args , stdin_data = None ): # pragma: no cover
514536 self ._log .debug ('Run command: %r' , ' ' .join (args ))
515537 proc = subprocess .Popen (
516538 args , stdin = subprocess .PIPE , stdout = subprocess .PIPE ,
@@ -530,27 +552,28 @@ def _cli_popen(self, ldapcommand, extra_args=None, ldap_uri=None,
530552 )
531553 return stdout_data , stderr_data
532554
533- def ldapwhoami (self , extra_args = None ):
555+ def ldapwhoami (self , extra_args = None , ** kws ):
534556 """
535557 Runs ldapwhoami on this slapd instance
536558 """
537- self ._cli_popen (self .PATH_LDAPWHOAMI , extra_args = extra_args )
559+ return self ._cli_ldap (self .PATH_LDAPWHOAMI , extra_args = extra_args ,
560+ ** kws )
538561
539- def ldapadd (self , ldif , extra_args = None ):
562+ def ldapadd (self , ldif , extra_args = None , ** kws ):
540563 """
541564 Runs ldapadd on this slapd instance, passing it the ldif content
542565 """
543- self ._cli_popen (self .PATH_LDAPADD , extra_args = extra_args ,
544- stdin_data = ldif .encode ('utf-8' ))
566+ return self ._cli_ldap (self .PATH_LDAPADD , extra_args = extra_args ,
567+ stdin_data = ldif .encode ('utf-8' ), ** kws )
545568
546- def ldapmodify (self , ldif , extra_args = None ):
569+ def ldapmodify (self , ldif , extra_args = None , ** kws ):
547570 """
548- Runs ldapadd on this slapd instance, passing it the ldif content
571+ Runs ldapmodify on this slapd instance, passing it the ldif content
549572 """
550- self ._cli_popen (self .PATH_LDAPMODIFY , extra_args = extra_args ,
551- stdin_data = ldif .encode ('utf-8' ))
573+ return self ._cli_ldap (self .PATH_LDAPMODIFY , extra_args = extra_args ,
574+ stdin_data = ldif .encode ('utf-8' ), ** kws )
552575
553- def ldapdelete (self , dn , recursive = False , extra_args = None ):
576+ def ldapdelete (self , dn , recursive = False , extra_args = None , ** kws ):
554577 """
555578 Runs ldapdelete on this slapd instance, deleting 'dn'
556579 """
@@ -559,14 +582,15 @@ def ldapdelete(self, dn, recursive=False, extra_args=None):
559582 if recursive :
560583 extra_args .append ('-r' )
561584 extra_args .append (dn )
562- self ._cli_popen (self .PATH_LDAPDELETE , extra_args = extra_args )
585+ return self ._cli_ldap (self .PATH_LDAPDELETE , extra_args = extra_args ,
586+ ** kws )
563587
564588 def slapadd (self , ldif , extra_args = None ):
565589 """
566590 Runs slapadd on this slapd instance, passing it the ldif content
567591 """
568- self ._cli_popen (
569- self . PATH_SLAPADD ,
592+ return self ._cli_slap (
593+ 'add' ,
570594 stdin_data = ldif .encode ("utf-8" ) if ldif else None ,
571595 extra_args = extra_args ,
572596 )
0 commit comments