#332 Command line perl scripts should attempt most secure connection type first
Closed: wontfix None Opened 11 years ago by brett.

OS RHEL 6.2 (x86_64)

Packages Installed:

389-admin-1.1.29-1.el6.x86_64
389-admin-console-1.1.8-1.el6.noarch
389-admin-console-doc-1.1.8-1.el6.noarch
389-adminutil-1.1.15-1.el6.x86_64
389-console-1.1.7-1.el6.noarch
389-ds-1.2.2-1.el6.noarch
389-ds-base-1.2.9.14-1.el6_2.2.x86_64
389-ds-base-libs-1.2.9.14-1.el6_2.2.x86_64
389-ds-console-1.2.6-1.el6.noarch
389-ds-console-doc-1.2.6-1.el6.noarch
389-dsgw-1.1.9-1.el6.x86_64
openldap-clients-2.4.23-20.el6.x86_64



/usr/lib64/dirsrv/slapd-<instance>/db2bak.pl -v -D "cn=Directory Manager" -w -
Bind Password:
Back up directory: /var/lib/dirsrv/slapd-<instance>/bak/<instance>-2012_3_30_10_13_21
ldap_initialize( ldap://<FQDN>:389 )
ldap_bind: Confidentiality required (13)
        additional info: Operation requires a secure connection

For me the following simple fix proved to be a working solution (having said that I haven’t tried a restore yet):
With ldapmodify, ldap://<host> apparently kicks off a TLS connection whereas <host> on it’s own doesn’t. All very odd, anyhoo:

db2bak.pl : Line 125 add “ldap://” before the host name.

open(FOO, "| ldapmodify -x $vstr -h ldap://<host> -p 389 -D \"$rootdn\" -w \"$passwd\" -a" );

Rerunning with ldap:// added:

/usr/lib64/dirsrv/slapd-<instance>/db2bak.pl -v -D "cn=Directory Manager" -w -
Bind Password:
Back up directory: /var/lib/dirsrv/slapd-<instance>/bak/<instance>-2012_3_30_10_14_14
ldap_initialize( <DEFAULT> )
add objectclass:
        top
        extensibleObject
add cn:
        backup_2012_3_30_10_14_14
add nsArchiveDir:
        /var/lib/dirsrv/slapd-<instance>/bak/<instance>-2012_3_30_10_14_14
add nsDatabaseType:
        ldbm database
adding new entry "cn=backup_2012_3_30_10_14_14, cn=backup, cn=tasks, cn=config"
modify complete

Straight forward enough change to the template…


It would be nice to provide a way for the perl-based CLI utilities to have the connection method specified. For example, one might want to use LDAP vs LDAPS, vs LDAPI. Being able to configure this in a central place for use by all of the perl-based CLI would be very useful. Having this centralized is also a nicer solution than adding more arguments to the CLI utilities to specify the connection parameters.

What about an environment variable which specifies the connection protocol for CLI utilities? If the environment variable is not defined, "ldap://" would be assumed. Any suggestion for the name of the environment variable?

This method allows someone to easily change the connection method on a per-use basis while not requiring the addition of argument-handling code to various utilities.

Replying to [comment:3 dukeleto]:

What about an environment variable which specifies the connection protocol for CLI utilities? If the environment variable is not defined, "ldap://" would be assumed. Any suggestion for the name of the environment variable?

An environment variable would work. I would like to have a default defined in a central location somehow, which can be overridden by locally setting the environment variable. It could make sense to leverage the /etc/sysconfig/dirsrv-<instance> files that we create, which have instance specific environment variables already. This would work with the current layout since each instance has it's own copy of the perl CLI utilities. I don't think that this is optimal though, for the reasons mentioned below.

This method allows someone to easily change the connection method on a per-use basis while not requiring the addition of argument-handling code to various utilities.

The other thing that we have discussed in the past was to centralize the perl-script CLI utilities. Currently, we create these scripts from a template when an individual 389 DS instance is created. Each instance has it's own set of scripts in it's instance directory (for instance, /usr/lib64/dirsrv/slapd-example). There are a few problems with this approach. One is that we're not really following FHS (Filesystem Hierarchy Standards). We should have CLI utilities in /usr/bin. We also should only have one copy of each CLI utility per system, not per-instance.

The 389 DS instance name can be passed as an option, which could then be used to look up the connection info (from the /etc/sysconfig/dirsrv-<instance> file associated with the instance name). We can put default environment variables for the connection details in this file at instance creation time, but one could change them afterwards if they want to use a different connection method.

Replying to [comment:4 nkinder]:

Replying to [comment:3 dukeleto]:

What about an environment variable which specifies the connection protocol for CLI utilities? If the environment variable is not defined, "ldap://" would be assumed. Any suggestion for the name of the environment variable?

An environment variable would work. I would like to have a default defined in a central location somehow, which can be overridden by locally setting the environment variable. It could make sense to leverage the /etc/sysconfig/dirsrv-<instance> files that we create, which have instance specific environment variables already. This would work with the current layout since each instance has it's own copy of the perl CLI utilities. I don't think that this is optimal though, for the reasons mentioned below.

The script should first read /etc/sysconfig/dirsrv-<instance> then /etc/dirsrv/slapd-<instance>/dse.ldif to get all of the instance information. The script can use the key/cert db in /etc/dirsrv/slapd-<instance> for secure connections too.

This method allows someone to easily change the connection method on a per-use basis while not requiring the addition of argument-handling code to various utilities.

The other thing that we have discussed in the past was to centralize the perl-script CLI utilities. Currently, we create these scripts from a template when an individual 389 DS instance is created. Each instance has it's own set of scripts in it's instance directory (for instance, /usr/lib64/dirsrv/slapd-example). There are a few problems with this approach. One is that we're not really following FHS (Filesystem Hierarchy Standards). We should have CLI utilities in /usr/bin.

and/or /usr/sbin

We also should only have one copy of each CLI utility per system, not per-instance.

The 389 DS instance name can be passed as an option, which could then be used to look up the connection info (from the /etc/sysconfig/dirsrv-<instance> file associated with the instance name). We can put default environment variables for the connection details in this file at instance creation time, but one could change them afterwards if they want to use a different connection method.

OK, so what I hear is:

1) We see if a default connection method is defined in etc/sysconfig/dirsrv-<instance>
2) If not, we defer to /etc/dirsrv/slapd-<instance>/dse.ldif
3) If neither, then we inspect an environment variable. LDAP_CONNECTION_METHOD ?

I like the ideas about centralizing (and modernizing) the perl utilities, but that sounds like a different ticket.

Replying to [comment:6 dukeleto]:

OK, so what I hear is:

1) We see if a default connection method is defined in etc/sysconfig/dirsrv-<instance>

Yes, although we don't have a field for that yet. I would suggest we use the following order by default:
a) try to use the ldapi socket
b) try to use StartTLS
c) use plain old unencrypted LDAP

That should work in 99% of cases.

2) If not, we defer to /etc/dirsrv/slapd-<instance>/dse.ldif

That doesn't have the preferred connection method either, but it does contain information about where to find the ldapi socket and whether ldapi or tls/ssl is enabled.

3) If neither, then we inspect an environment variable. LDAP_CONNECTION_METHOD ?

Yes.

I like the ideas about centralizing (and modernizing) the perl utilities, but that sounds like a different ticket.

Yes.

The above patch makes db2bak.pl default to ldapi:// and also allows an environment variable, LDAP_CONNECTION_METHOD, to override that.

I can also implement the suggestion of rmeggins, which is a default search order, but at that point I believe the entire script should be improved by adding "use strict; use warnings" and the necessary refactoring. I can do that if that is wanted.

Replying to [comment:8 dukeleto]:

The above patch makes db2bak.pl default to ldapi:// and also allows an environment variable, LDAP_CONNECTION_METHOD, to override that.

I don't think this will work:
{{{
my $ldap_connection_method = $ENV{LDAP_CONNECTION_METHOD} || 'ldapi://';
my $ldapmodify = sprintf '| ldapmodify @ldaptool_opts@ %s -h %s{{SERVER-NAME}} -p {{SERVER-PORT}} -D "%s" -w "%s" -a',
129 $vstr, $ldap_connection_method, $rootdn, $passwd;
}}}
$ldapmodify will expand to something like this:
{{{
ldapmodify -x -h ldapi://ldap.example.com -p 389 -D "cn=directory manager" -w password -a
}}}

This won't work.

I apologize for not being clearer earlier, but you cannot use ldapi with mozldap, only with openldap. To use it with openldap, you do
{{{
ldapmodify -x -H ldapi://pathtosocket.socket -D "cn=directory manager" -w password -a
}}}
Where '''pathtosocket.socket''' is the full absolute path of the socket file, with the '/' replaced with '%2F' - you can get this value by getting the nsslapd-ldapifilepath from cn=config in dse.ldif

mozldap does not even support passing the URL with -H - in mozldap, -H just prints the usage.

And it's even more problematic than that. Since ldapi is turned off by default, most people will want to use SSL. To further complicate matters, telling openldap cmd line tools how to use SSL is completely different than in the mozldap tools. With openldap you would do something like this:
{{{
LDAPTLS_CACERTDIR=/etc/dirsrv/slapd-INSTANCE ldapmodify -x -ZZ -h ldap.example.com -p 389 -D "cn=directory manager" -w password -a
}}}
while with mozldap you would do this:
{{{
ldapmodify -ZZZ -P /etc/dirsrv/slapd-INSTANCE/cert8.db -h ldap.example.com -p 389 -D "cn=directory manager" -w password -a
}}}
We would need to add a couple of replaceable parameters to m4/openldap.m4, configure.ac, Makefile.am, and all of the db.pl and db.pl scripts.

I can also implement the suggestion of rmeggins, which is a default search order, but at that point I believe the entire script should be improved by adding "use strict; use warnings" and the necessary refactoring. I can do that if that is wanted.

I think the entire script would be improved by rewriting it as a plain old shell script - there is really no reason to use perl, since we're not using the perl LDAP API.

However, in the interest of simplicity and of solving the original problem, we should just figure out a way to allow the use of SSL first, then fall back to plain old ldap.

set default ticket origin to Community

Added initial screened field value.

The idea is that we should check if we can use the most secure connection available (ldapi, SSL, TLS, etc). If one is not available try the next type, and so on, until you get all the way down to simple unsecured connection.

DSSharedLib should not go in @sbindir@ - if it is intended that a user may want to edit it, then maybe /etc/sysconfig @initconfigdir@ or /etc/dirsrv @instconfigdir@ - if it is read-only, then /usr/share/dirsrv/data @datadir@

When parsing dse.ldif, be aware that the line may wrap, especially for the ldapi filename. You could also use Mozilla::LDAP::LDIF to read the dse.ldif into a Mozilla::LDAP::Entry.

mozldap ldapsearch/ldapmodify do not support -H ldaps:// nor do they support ldapi at all. So if we compile with mozldap support, we should either omit the LDAPI option entirely, or just print an error message.

For the TLS/SSL commands - how are you specifying the location of the cert db? For mozldap, you have to use -P /path/to/slapd-INST/cert8.db. For openldap, you have to set the LDAPTLS_CACERTDIR=/path/to/slapd-INST environment variable.

mozldap ldaps:
ldapsearch -Z -P /path/to/slapd-INST/cert8.db -h fqdn ...
openldap ldaps:
LDAPTLS_CACERTDIR=/path/to/slapd-INST ldapsearch -H ldaps://fqdn ...

mozldap starttls:
ldapsearch -ZZZ -P /path/to/slapd-INST/cert8.db -h fqdn ...
openldap starttls:
LDAPTLS_CACERTDIR=/path/to/slapd-INST ldapsearch -ZZ -h fqdn ...

Replying to [comment:17 rmeggins]:

DSSharedLib should not go in @sbindir@ - if it is intended that a user may want to edit it, then maybe /etc/sysconfig @initconfigdir@ or /etc/dirsrv @instconfigdir@ - if it is read-only, then /usr/share/dirsrv/data @datadir@

Ok, it should be read only.

When parsing dse.ldif, be aware that the line may wrap, especially for the ldapi filename. You could also use Mozilla::LDAP::LDIF to read the dse.ldif into a Mozilla::LDAP::Entry.

Ok I'll look into it.

mozldap ldapsearch/ldapmodify do not support -H ldaps:// nor do they support ldapi at all. So if we compile with mozldap support, we should either omit the LDAPI option entirely, or just print an error message.

I actually thought moving forward we were done using mozldap.

For the TLS/SSL commands - how are you specifying the location of the cert db? For mozldap, you have to use -P /path/to/slapd-INST/cert8.db. For openldap, you have to set the LDAPTLS_CACERTDIR=/path/to/slapd-INST environment variable.

mozldap ldaps:
ldapsearch -Z -P /path/to/slapd-INST/cert8.db -h fqdn ...
openldap ldaps:
LDAPTLS_CACERTDIR=/path/to/slapd-INST ldapsearch -H ldaps://fqdn ...

mozldap starttls:
ldapsearch -ZZZ -P /path/to/slapd-INST/cert8.db -h fqdn ...
openldap starttls:
LDAPTLS_CACERTDIR=/path/to/slapd-INST ldapsearch -ZZ -h fqdn ...

I'll work on this.

Thanks,
Mark

Replying to [comment:18 mreynolds]:

Replying to [comment:17 rmeggins]:

DSSharedLib should not go in @sbindir@ - if it is intended that a user may want to edit it, then maybe /etc/sysconfig @initconfigdir@ or /etc/dirsrv @instconfigdir@ - if it is read-only, then /usr/share/dirsrv/data @datadir@

Ok, it should be read only.

When parsing dse.ldif, be aware that the line may wrap, especially for the ldapi filename. You could also use Mozilla::LDAP::LDIF to read the dse.ldif into a Mozilla::LDAP::Entry.

Ok I'll look into it.

mozldap ldapsearch/ldapmodify do not support -H ldaps:// nor do they support ldapi at all. So if we compile with mozldap support, we should either omit the LDAPI option entirely, or just print an error message.

I actually thought moving forward we were done using mozldap.

Red Hat/Fedora distributions of 389 only use openldap. But other distributions of 389 still use mozldap. So I suppose it's ok as long as it still works the same way as it did before, if using mozldap. And then if someone from the community who uses mozldap wants to contribute patches to add the extra functionality, that's fine. But we must make sure that we don't break or take a way functionality for those distributions that still use mozldap.

For the TLS/SSL commands - how are you specifying the location of the cert db? For mozldap, you have to use -P /path/to/slapd-INST/cert8.db. For openldap, you have to set the LDAPTLS_CACERTDIR=/path/to/slapd-INST environment variable.

mozldap ldaps:
ldapsearch -Z -P /path/to/slapd-INST/cert8.db -h fqdn ...
openldap ldaps:
LDAPTLS_CACERTDIR=/path/to/slapd-INST ldapsearch -H ldaps://fqdn ...

mozldap starttls:
ldapsearch -ZZZ -P /path/to/slapd-INST/cert8.db -h fqdn ...
openldap starttls:
LDAPTLS_CACERTDIR=/path/to/slapd-INST ldapsearch -ZZ -h fqdn ...

I'll work on this.

Thanks,
Mark

Added support for both mozldap/openldap clients, improved dse.ldif file parsing (wrapped lines), moved the location of DSSharedLib, improved protocol checking/failover to valid protocol, and other minor improvements.

Most of this was done in DSUtil.pm and DSSharedLib. monitor/ldif2ldap also had significant changes made.

Unfortunately this isn't good enough to tell between openldap and mozldap:
{{{
+ #
+ # Are we using openLDAP or Mozilla?
+ #
+ my $path = which ldapsearch;
+ if ($path =~ m/\/usr\/bin/){
+ $info{openldap} = "yes";
} else {
- $prefix =~ s/\/sbin//;
+ # mozldap
+ $info{openldap} = "no";
}
}}}

I wanted to avoid this if possible, but the tls/ssl/ldapi stuff is just too difficult to do otherwise. I had already defined @ldaptool_bindir@ @ldaptool_opts@ and @plainldif_opts@. Looks like you will have to add @use_openldap@ instead.

Alternately, you could attempt to parse the output of ldapsearch -V e.g.
{{{
my $lsout = @ldaptool_bindir@/ldapsearch -V 2>&1;
if ($lsout =~ /OpenLDAP/) { $info{openldap} = "yes"; } else { $info{openldap} = "no"; }
}}}
or something like that.

{{{
+ exec ldapmodify @ldaptool_opts@ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w \"$info{rootdnpw}\" $info{args} -f \"$file\";
}}}

should prefix the ldap commands here and elsewhere with @ldaptool_bindir@ - mozldap will usually be in /usr/lib[64]/mozldap and not in $PATH.

Also, using the backtick in perl does an exec, so this does a double exec - I think you just need to do something like this: {{{ + system "ldapmodify @ldaptool_opts@ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w \"$info{rootdnpw}\" $info{args} -f \"$file\""; }}} I guess it works since is also a quoting operator in perl, but it is unnecessary. I'm surprised it works at all with exec - http://perldoc.perl.org/functions/exec.html

Replying to [comment:21 rmeggins]:

Unfortunately this isn't good enough to tell between openldap and mozldap:
{{{
+ #
+ # Are we using openLDAP or Mozilla?
+ #
+ my $path = which ldapsearch;
+ if ($path =~ m/\/usr\/bin/){
+ $info{openldap} = "yes";
} else {
- $prefix =~ s/\/sbin//;
+ # mozldap
+ $info{openldap} = "no";
}
}}}

Why not? Openldap is installed in /usr/bin, and mozldap is in /usr/lib64/mozldap. Am I missing something?

I wanted to avoid this if possible, but the tls/ssl/ldapi stuff is just too difficult to do otherwise. I had already defined @ldaptool_bindir@ @ldaptool_opts@ and @plainldif_opts@. Looks like you will have to add @use_openldap@ instead.

Hmm, not sure that will work. I can build DS anyway I want, with or without openldap, but I can still only have mozldap-tools installed, and not openldap-clients, etc. So I guess I'll just parse the ldapsearch -V output.

Alternately, you could attempt to parse the output of ldapsearch -V e.g.
{{{
my $lsout = @ldaptool_bindir@/ldapsearch -V 2>&1;
if ($lsout =~ /OpenLDAP/) { $info{openldap} = "yes"; } else { $info{openldap} = "no"; }
}}}
or something like that.

{{{
+ exec ldapmodify @ldaptool_opts@ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w \"$info{rootdnpw}\" $info{args} -f \"$file\";
}}}

should prefix the ldap commands here and elsewhere with @ldaptool_bindir@ - mozldap will usually be in /usr/lib[64]/mozldap and not in $PATH.

Again, I'm not sure if this will work in all cases. I had updated the path for mozldap in all the perl scripts, thought that would of been enough. The scripts look in /usr/bin first, and then /usr/lib64/mozldap.

Also, using the backtick in perl does an exec, so this does a double exec - I think you just need to do something like this: {{{ + system "ldapmodify @ldaptool_opts@ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w \"$info{rootdnpw}\" $info{args} -f \"$file\""; }}} I guess it works since is also a quoting operator in perl, but it is unnecessary. I'm surprised it works at all with exec - http://perldoc.perl.org/functions/exec.html

Actually using system causes issues, it messes with the return code of ldapmodify. I had to use exec over system to get it work properly.

Replying to [comment:22 mreynolds]:

Replying to [comment:21 rmeggins]:

Unfortunately this isn't good enough to tell between openldap and mozldap:
{{{
+ #
+ # Are we using openLDAP or Mozilla?
+ #
+ my $path = which ldapsearch;
+ if ($path =~ m/\/usr\/bin/){
+ $info{openldap} = "yes";
} else {
- $prefix =~ s/\/sbin//;
+ # mozldap
+ $info{openldap} = "no";
}
}}}

Why not? Openldap is installed in /usr/bin, and mozldap is in /usr/lib64/mozldap. Am I missing something?

Those are the paths used on RHEL/Fedora but not on other platforms.

I wanted to avoid this if possible, but the tls/ssl/ldapi stuff is just too difficult to do otherwise. I had already defined @ldaptool_bindir@ @ldaptool_opts@ and @plainldif_opts@. Looks like you will have to add @use_openldap@ instead.

Hmm, not sure that will work. I can build DS anyway I want, with or without openldap, but I can still only have mozldap-tools installed, and not openldap-clients, etc. So I guess I'll just parse the ldapsearch -V output.

Either you have to tell the scripts which cmd line tools you are using, or the scripts will have to figure that out for themselves. That's what the @ldaptool_bindir@ @ldaptool_opts@ and @plainldif_opts@ are for - so you can specify that stuff at build time. The way the scripts work now is that you have to specify at build time if you are going to be using openldap or mozldap command line tools. Otherwise, there will have to be logic in the scripts that know that you have to add -x to the openldap tools to do a simple bind, but omit with mozldap. Or use -LLL for minimal ldapsearch output with openldap, but use -1 with mozldap ldapsearch. If you want to make it so that you can build with one ldap sdk and use a different one at runtime, you'll have to build that logic into the command line script "libraries". Which is fine. But you'll need to come up with a robust way to determine at runtime if openldap or mozldap is being used.

Alternately, you could attempt to parse the output of ldapsearch -V e.g.
{{{
my $lsout = @ldaptool_bindir@/ldapsearch -V 2>&1;
if ($lsout =~ /OpenLDAP/) { $info{openldap} = "yes"; } else { $info{openldap} = "no"; }
}}}
or something like that.

{{{
+ exec ldapmodify @ldaptool_opts@ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w \"$info{rootdnpw}\" $info{args} -f \"$file\";
}}}

should prefix the ldap commands here and elsewhere with @ldaptool_bindir@ - mozldap will usually be in /usr/lib[64]/mozldap and not in $PATH.

Again, I'm not sure if this will work in all cases. I had updated the path for mozldap in all the perl scripts, thought that would of been enough. The scripts look in /usr/bin first, and then /usr/lib64/mozldap.

Ok. If you're going to change the scripts to figure out at runtime if they are using openldap or mozldap, then this doesn't matter.

Also, using the backtick in perl does an exec, so this does a double exec - I think you just need to do something like this: {{{ + system "ldapmodify @ldaptool_opts@ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w \"$info{rootdnpw}\" $info{args} -f \"$file\""; }}} I guess it works since is also a quoting operator in perl, but it is unnecessary. I'm surprised it works at all with exec - http://perldoc.perl.org/functions/exec.html

Actually using system causes issues, it messes with the return code of ldapmodify. I had to use exec over system to get it work properly.

Ok. I'm just surprised it works with exec - exec is supposed to terminate the current process, so you should never execute any code after the call to exec.

There is another authentication option for OpenLDAP using ldapi - EXTERNAL as root. The autobind code in the directory server can be configured so that if you use
-H ldapi://....socket -Y EXTERNAL
as root, the server will map the unix user id 0 of root to cn=Directory Manager. This allows you to manage your server as directory manager without having to pass in any dn or password. This would be a good secure authentication option to have.

Replying to [comment:23 rmeggins]:

Replying to [comment:22 mreynolds]:

Replying to [comment:21 rmeggins]:

Unfortunately this isn't good enough to tell between openldap and mozldap:
{{{
+ #
+ # Are we using openLDAP or Mozilla?
+ #
+ my $path = which ldapsearch;
+ if ($path =~ m/\/usr\/bin/){
+ $info{openldap} = "yes";
} else {
- $prefix =~ s/\/sbin//;
+ # mozldap
+ $info{openldap} = "no";
}
}}}

Why not? Openldap is installed in /usr/bin, and mozldap is in /usr/lib64/mozldap. Am I missing something?

Those are the paths used on RHEL/Fedora but not on other platforms.

Ahh, excellent point.

I wanted to avoid this if possible, but the tls/ssl/ldapi stuff is just too difficult to do otherwise. I had already defined @ldaptool_bindir@ @ldaptool_opts@ and @plainldif_opts@. Looks like you will have to add @use_openldap@ instead.

Hmm, not sure that will work. I can build DS anyway I want, with or without openldap, but I can still only have mozldap-tools installed, and not openldap-clients, etc. So I guess I'll just parse the ldapsearch -V output.

Either you have to tell the scripts which cmd line tools you are using, or the scripts will have to figure that out for themselves. That's what the @ldaptool_bindir@ @ldaptool_opts@ and @plainldif_opts@ are for - so you can specify that stuff at build time. The way the scripts work now is that you have to specify at build time if you are going to be using openldap or mozldap command line tools. Otherwise, there will have to be logic in the scripts that know that you have to add -x to the openldap tools to do a simple bind, but omit with mozldap. Or use -LLL for minimal ldapsearch output with openldap, but use -1 with mozldap ldapsearch. If you want to make it so that you can build with one ldap sdk and use a different one at runtime, you'll have to build that logic into the command line script "libraries". Which is fine. But you'll need to come up with a robust way to determine at runtime if openldap or mozldap is being used.

Currently the scripts automatically check what the existing client is, and then it uses the correct args. I will parse the -V output to determine what library is being used. Also, I don't think this should be confined to what we use to build the server, but instead what is available on the system.

Alternately, you could attempt to parse the output of ldapsearch -V e.g.
{{{
my $lsout = @ldaptool_bindir@/ldapsearch -V 2>&1;
if ($lsout =~ /OpenLDAP/) { $info{openldap} = "yes"; } else { $info{openldap} = "no"; }
}}}
or something like that.

{{{
+ exec ldapmodify @ldaptool_opts@ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w \"$info{rootdnpw}\" $info{args} -f \"$file\";
}}}

should prefix the ldap commands here and elsewhere with @ldaptool_bindir@ - mozldap will usually be in /usr/lib[64]/mozldap and not in $PATH.

Again, I'm not sure if this will work in all cases. I had updated the path for mozldap in all the perl scripts, thought that would of been enough. The scripts look in /usr/bin first, and then /usr/lib64/mozldap.

Ok. If you're going to change the scripts to figure out at runtime if they are using openldap or mozldap, then this doesn't matter.

Yes this is what it currently does.

Also, using the backtick in perl does an exec, so this does a double exec - I think you just need to do something like this: {{{ + system "ldapmodify @ldaptool_opts@ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w \"$info{rootdnpw}\" $info{args} -f \"$file\""; }}} I guess it works since is also a quoting operator in perl, but it is unnecessary. I'm surprised it works at all with exec - http://perldoc.perl.org/functions/exec.html

Actually using system causes issues, it messes with the return code of ldapmodify. I had to use exec over system to get it work properly.

Ok. I'm just surprised it works with exec - exec is supposed to terminate the current process, so you should never execute any code after the call to exec.

It definitely works for me, but the docs are conflicting. My perl book gives a very different description of exec than that link you provided. Strange, but the existing code works very well - catches errors, doesn't "exit", etc.

There is another authentication option for OpenLDAP using ldapi - EXTERNAL as root. The autobind code in the directory server can be configured so that if you use
-H ldapi://....socket -Y EXTERNAL
as root, the server will map the unix user id 0 of root to cn=Directory Manager. This allows you to manage your server as directory manager without having to pass in any dn or password. This would be a good secure authentication option to have.

Hmmm, interesting. One issue I have is that we require a bind DN and password in all the scripts. So I'll have to work on this.

Thanks,
Mark

Replying to [comment:24 mreynolds]:

Replying to [comment:23 rmeggins]:

Replying to [comment:22 mreynolds]:

Replying to [comment:21 rmeggins]:
<snip>

I wanted to avoid this if possible, but the tls/ssl/ldapi stuff is just too difficult to do otherwise. I had already defined @ldaptool_bindir@ @ldaptool_opts@ and @plainldif_opts@. Looks like you will have to add @use_openldap@ instead.

Hmm, not sure that will work. I can build DS anyway I want, with or without openldap, but I can still only have mozldap-tools installed, and not openldap-clients, etc. So I guess I'll just parse the ldapsearch -V output.

Either you have to tell the scripts which cmd line tools you are using, or the scripts will have to figure that out for themselves. That's what the @ldaptool_bindir@ @ldaptool_opts@ and @plainldif_opts@ are for - so you can specify that stuff at build time. The way the scripts work now is that you have to specify at build time if you are going to be using openldap or mozldap command line tools. Otherwise, there will have to be logic in the scripts that know that you have to add -x to the openldap tools to do a simple bind, but omit with mozldap. Or use -LLL for minimal ldapsearch output with openldap, but use -1 with mozldap ldapsearch. If you want to make it so that you can build with one ldap sdk and use a different one at runtime, you'll have to build that logic into the command line script "libraries". Which is fine. But you'll need to come up with a robust way to determine at runtime if openldap or mozldap is being used.

Currently the scripts automatically check what the existing client is, and then it uses the correct args. I will parse the -V output to determine what library is being used. Also, I don't think this should be confined to what we use to build the server, but instead what is available on the system.

That would be better and more flexible.

<snip>

Also, using the backtick in perl does an exec, so this does a double exec - I think you just need to do something like this: {{{ + system "ldapmodify @ldaptool_opts@ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w \"$info{rootdnpw}\" $info{args} -f \"$file\""; }}} I guess it works since is also a quoting operator in perl, but it is unnecessary. I'm surprised it works at all with exec - http://perldoc.perl.org/functions/exec.html

Actually using system causes issues, it messes with the return code of ldapmodify. I had to use exec over system to get it work properly.

Ok. I'm just surprised it works with exec - exec is supposed to terminate the current process, so you should never execute any code after the call to exec.

It definitely works for me, but the docs are conflicting. My perl book gives a very different description of exec than that link you provided. Strange, but the existing code works very well - catches errors, doesn't "exit", etc.

What book are you using? I have an old "camel" book and it gives pretty much the same description of "exec" as that link.

If the problem is that $? is not set correctly, we had the same problem in the setup scripts. For example:
{{{
my $cmd = "$inf->{slapd}->{inst_dir}/ldif2db -n $inf->{slapd}->{ds_bename} -i \'$ldiffile\'";
$? = 0; # clear error condition
my $output = $cmd 2>&1;
my $result = $?;
}}}
We had to reset $? to clear any existing error condition, otherwise, if $cmd was successful, it would not set $? to 0, so we would be checking some older error code. Note that backtick ` is essentially the same as system() except that it captures the output.

If in the perl script you don't need to parse the output of ldapmodify/ldapsearch, or check the error code in the script itself, you could simply exec "ldapsearch .. args" and replace the perl process with ldapsearch. That way the output will go to the console and the shell will handle the error code from ldapsearch.

There is another authentication option for OpenLDAP using ldapi - EXTERNAL as root. The autobind code in the directory server can be configured so that if you use
-H ldapi://....socket -Y EXTERNAL
as root, the server will map the unix user id 0 of root to cn=Directory Manager. This allows you to manage your server as directory manager without having to pass in any dn or password. This would be a good secure authentication option to have.

Hmmm, interesting. One issue I have is that we require a bind DN and password in all the scripts. So I'll have to work on this.

For example, this would mean you could run db2bak.pl in exactly the same way as you run db2bak - login as root, run the command.

Thanks,
Mark

git merge ticket332
Updating 6602685..d2e68d7
Fast-forward
Makefile.am | 4 +-
Makefile.in | 425 +-
aclocal.m4 | 114 +-
compile | 228 +-
config.guess | 259 +-
config.h.in | 6 -
config.sub | 204 +-
configure |14849 +++++++++++++-------
depcomp | 190 +-
install-sh | 29 +-
ldap/admin/src/scripts/DSSharedLib.in | 109 +-
ldap/admin/src/scripts/DSUtil.pm.in | 380 +-
ldap/admin/src/scripts/bak2db.in | 12 +-
ldap/admin/src/scripts/bak2db.pl.in | 133 +-
ldap/admin/src/scripts/cleanallruv.pl.in | 131 +-
ldap/admin/src/scripts/db2bak.in | 28 +-
ldap/admin/src/scripts/db2bak.pl.in | 126 +-
ldap/admin/src/scripts/db2index.in | 27 +-
ldap/admin/src/scripts/db2index.pl.in | 214 +-
ldap/admin/src/scripts/db2ldif.in | 23 +-
ldap/admin/src/scripts/db2ldif.pl.in | 320 +-
ldap/admin/src/scripts/dbverify.in | 15 +-
ldap/admin/src/scripts/dn2rdn.in | 22 +-
ldap/admin/src/scripts/fixup-linkedattrs.pl.in | 123 +-
ldap/admin/src/scripts/fixup-memberof.pl.in | 132 +-
ldap/admin/src/scripts/ldif2db.in | 20 +-
ldap/admin/src/scripts/ldif2db.pl.in | 281 +-
ldap/admin/src/scripts/ldif2ldap.in | 142 +-
ldap/admin/src/scripts/monitor.in | 135 +-
ldap/admin/src/scripts/ns-accountstatus.pl.in | 1046 +-
ldap/admin/src/scripts/ns-activate.pl.in | 1066 +-
ldap/admin/src/scripts/ns-inactivate.pl.in | 1069 +-
ldap/admin/src/scripts/ns-newpwpolicy.pl.in | 345 +-
ldap/admin/src/scripts/restart-slapd.in | 6 +-
ldap/admin/src/scripts/restoreconfig.in | 8 +-
ldap/admin/src/scripts/saveconfig.in | 8 +-
ldap/admin/src/scripts/schema-reload.pl.in | 124 +-
ldap/admin/src/scripts/start-slapd.in | 6 +-
ldap/admin/src/scripts/stop-slapd.in | 6 +-
ldap/admin/src/scripts/suffix2instance.in | 12 +-
ldap/admin/src/scripts/syntax-validate.pl.in | 138 +-
ldap/admin/src/scripts/template-bak2db.pl.in | 2 +
ldap/admin/src/scripts/template-cleanallruv.pl.in | 2 +
ldap/admin/src/scripts/template-db2bak.pl.in | 3 +
ldap/admin/src/scripts/template-db2index.pl.in | 2 +
ldap/admin/src/scripts/template-db2ldif.pl.in | 2 +
.../src/scripts/template-fixup-linkedattrs.pl.in | 2 +
.../src/scripts/template-fixup-memberof.pl.in | 2 +
ldap/admin/src/scripts/template-ldif2db.pl.in | 2 +
.../src/scripts/template-ns-accountstatus.pl.in | 2 +
ldap/admin/src/scripts/template-ns-activate.pl.in | 2 +
.../admin/src/scripts/template-ns-inactivate.pl.in | 2 +
.../src/scripts/template-ns-newpwpolicy.pl.in | 2 +
.../admin/src/scripts/template-schema-reload.pl.in | 2 +
.../src/scripts/template-syntax-validate.pl.in | 2 +
.../scripts/template-usn-tombstone-cleanup.pl.in | 2 +
ldap/admin/src/scripts/template-verify-db.pl.in | 2 +
ldap/admin/src/scripts/upgradedb.in | 29 +-
ldap/admin/src/scripts/upgradednformat.in | 12 +-
ldap/admin/src/scripts/usn-tombstone-cleanup.pl.in | 158 +-
ldap/admin/src/scripts/verify-db.pl.in | 21 +-
ldap/admin/src/scripts/vlvindex.in | 20 +-
ltmain.sh | 3958 ++----
missing | 53 +-
64 files changed, 14772 insertions(+), 12027 deletions(-)

git push origin master
Counting objects: 128, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (64/64), done.
Writing objects: 100% (70/70), 94.52 KiB, done.
Total 70 (delta 64), reused 6 (delta 5)
To ssh://git.fedorahosted.org/git/389/ds.git
6602685..d2e68d7 master -> master

A little, tiny one... :) '[' before -g is not closed?
ldap/admin/src/scripts/ldif2db.pl.in
64 print(STDERR " [-E] [-g [string] [-G namespace_id] {-i filename}*\n");

git merge ticket588
Updating d2e68d7..129b3aa
Fast-forward
ldap/admin/src/scripts/bak2db.pl.in | 4 ++--
ldap/admin/src/scripts/db2index.pl.in | 2 +-
ldap/admin/src/scripts/db2ldif.pl.in | 6 +++---
ldap/admin/src/scripts/dbverify.in | 8 ++++++--
ldap/admin/src/scripts/dn2rdn.in | 2 +-
ldap/admin/src/scripts/ldif2db.in | 9 ++++++++-
ldap/admin/src/scripts/ldif2db.pl.in | 6 +++---
ldap/admin/src/scripts/ns-accountstatus.pl.in | 4 ++--
ldap/admin/src/scripts/ns-activate.pl.in | 4 ++--
ldap/admin/src/scripts/upgradednformat.in | 2 +-
ldap/admin/src/scripts/verify-db.pl.in | 2 +-
11 files changed, 30 insertions(+), 19 deletions(-)

git push origin master
Counting objects: 33, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (16/16), done.
Writing objects: 100% (17/17), 1.96 KiB, done.
Total 17 (delta 15), reused 0 (delta 0)
To ssh://git.fedorahosted.org/git/389/ds.git
d2e68d7..129b3aa master -> master

Fixed a minor quoting issue:

git merge ticket332
Updating 129b3aa..07af826
Fast-forward
ldap/admin/src/scripts/ldif2ldap.in | 10 +++++-----
ldap/admin/src/scripts/monitor.in | 11 +++++++----
2 files changed, 12 insertions(+), 9 deletions(-)

git push origin master
Counting objects: 15, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (8/8), 803 bytes, done.
Total 8 (delta 6), reused 0 (delta 0)
To ssh://git.fedorahosted.org/git/389/ds.git
129b3aa..07af826 master -> master

In monitor,ldif2ldap, and DSUTIL: "LDAPTLS_CACERRTDIR" was used instead of "TLS_CACERTDIR"

Reopening...

I thought the environment variable was supposed to be LDAPTLS_CACERTDIR?
{{{
$ man ldap.conf
...
Environmental variables may also be used to augment the file based
defaults. The name of the variable is the option name with an added
prefix of LDAP. For example, to define BASE via the environment, set
the variable LDAPBASE to the desired value.
...
TLS_CACERTDIR <path>
Specifies the path of a directory that contains Certifi‐
cate Authority certificates in separate individual files.
The TLS_CACERT is always used before TLS_CACERTDIR. The
specified directory must be managed with the OpenSSL
c_rehash utility. This parameter is ignored with GnuTLS.

          When using Mozilla NSS, <path> may contain a Mozilla  NSS
          cert/key  database.   If  <path>  contains  a Mozilla NSS
          cert/key database and CA cert files,  OpenLDAP  will  use
          the cert/key database and will ignore the CA cert files.

}}}

Okay nevermind. I just saw it while working on a different issue, and thought it was a typo. I did some research on it (DS docs, and google), but could not find LDAPTLS_CACERTDIR anywhere.

Metadata Update from @mreynolds:
- Issue assigned to mreynolds
- Issue set to the milestone: 1.3.1

7 years ago

389-ds-base is moving from Pagure to Github. This means that new issues and pull requests
will be accepted only in 389-ds-base's github repository.

This issue has been cloned to Github and is available here:
- https://github.com/389ds/389-ds-base/issues/332

If you want to receive further updates on the issue, please navigate to the github issue
and click on subscribe button.

Thank you for understanding. We apologize for all inconvenience.

Metadata Update from @spichugi:
- Issue close_status updated to: wontfix (was: Fixed)

3 years ago

Login to comment on this ticket.

Metadata