rpm/389-ds-base.spec.in
by William Brown
rpm/389-ds-base.spec.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 75b545af1105b1f86344bc0c4a0e8a0087301663
Author: William Brown <firstyear(a)redhat.com>
Date: Tue Feb 9 15:08:32 2016 +1000
No ticket: One line rpm fix
Bug Description: Nunc stans won't build in the same env if lib already exists
Fix Description: Change mkdir to mkdir -p so that make rpms will work correctly
Author: wibrown
diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in
index 163bc33..8cc2818 100644
--- a/rpm/389-ds-base.spec.in
+++ b/rpm/389-ds-base.spec.in
@@ -221,7 +221,7 @@ cp %{SOURCE2} README.devel
pushd ../nunc-stans-%{nunc_stans_ver}
%configure --with-fhs --libdir=%{_libdir}/%{pkgname}
make %{?_smp_mflags}
-mkdir lib
+mkdir -p lib
cp .libs/libnunc-stans.so.0.0.0 lib/libnunc-stans.so
mkdir -p include/nunc-stans
cp nunc-stans.h include/nunc-stans/nunc-stans.h
8 years, 2 months
ldap/servers rpm/389-ds-base.spec.in wrappers/systemd.template.service.in
by William Brown
ldap/servers/slapd/daemon.c | 12 ++++++++++++
ldap/servers/slapd/main.c | 21 +++++++++++++++++++++
rpm/389-ds-base.spec.in | 3 ++-
wrappers/systemd.template.service.in | 2 +-
4 files changed, 36 insertions(+), 2 deletions(-)
New commits:
commit ab81e175cedbc4db52ac8a8c3089bdd5165ddb27
Author: William Brown <firstyear(a)redhat.com>
Date: Tue Jan 19 12:57:09 2016 +1000
Ticket 47944 - Implement sd_notify for systemd
Bug Description: Systemd assumes processes are ready as soon as the PID file
is ready.
Fix Description: By calling sd_notify, we are able to tell systemd when we are
actually ready to process requests (or as close to it as possible), and when
we are shutting down.
https://fedorahosted.org/389/ticket/47977
Author: wibrown
Review by: mreynolds (Thanks!)
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
index ba7a39a..4fb85d5 100644
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -1247,6 +1247,14 @@ void slapd_daemon( daemon_ports_t *ports )
/* The server is ready and listening for connections. Logging "slapd started" message. */
unfurl_banners(the_connection_table,ports,n_tcps,s_tcps,i_unix);
+#ifdef WITH_SYSTEMD
+ sd_notifyf(0, "READY=1\n"
+ "STATUS=slapd started: Ready to process requests\n"
+ "MAINPID=%lu",
+ (unsigned long) getpid()
+ );
+#endif
+
#ifdef ENABLE_NUNC_STANS
if (enable_nunc_stans && ns_thrpool_wait(tp)) {
LDAPDebug( LDAP_DEBUG_ANY,
@@ -1284,6 +1292,10 @@ void slapd_daemon( daemon_ports_t *ports )
/* We get here when the server is shutting down */
/* Do what we have to do before death */
+#ifdef WITH_SYSTEMD
+ sd_notify(0, "STOPPING=1");
+#endif
+
connection_table_abandon_all_operations(the_connection_table); /* abandon all operations in progress */
if ( ! in_referral_mode ) {
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index 1181628..c04408c 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -619,6 +619,27 @@ main( int argc, char **argv)
}
}
+#ifdef WITH_SYSTEMD
+ /*
+ * HUGE WARNING: Systemd has some undocumented magic. with Type=notify, this
+ * acts as type=simple, but waits for ns-slapd to tell systemd it's good to go.
+ * If ns-slapd daemonises, systemd will KILL IT because simple==no forking.
+ *
+ * So instead, we need to work out if we have the NOTIFY_SOCKET env variable
+ * and if we do, we need to prevent forking so systemd doesn't nail us to
+ * the wall.
+ *
+ * Of course, systemd makes NO GUARANTEE that it will be called notify_socket
+ * in the next version, nor that it won't give the variable to a service type
+ * which isn't of the type notify ..... This could all go very wrong :)
+ */
+ char *notify = getenv( "NOTIFY_SOCKET");
+ if (notify) {
+ should_detach = 0;
+ }
+#endif
+
+
/* used to set configfile to the default config file name here */
if ( (myname = strrchr( argv[0], '/' )) == NULL ) {
myname = slapi_ch_strdup( argv[0] );
diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in
index 7dfa0b5..163bc33 100644
--- a/rpm/389-ds-base.spec.in
+++ b/rpm/389-ds-base.spec.in
@@ -247,7 +247,8 @@ NUNC_STANS_FLAGS="--enable-nunc-stans --with-nunc-stans=../nunc-stans-%{nunc_sta
%configure --enable-autobind --with-selinux $OPENLDAP_FLAG $TMPFILES_FLAG \
--with-systemdsystemunitdir=%{_unitdir} \
--with-systemdsystemconfdir=%{_sysconfdir}/systemd/system \
- --with-systemdgroupname=%{groupname} $NSSARGS $NUNC_STANS_FLAGS
+ --with-systemdgroupname=%{groupname} $NSSARGS $NUNC_STANS_FLAGS \
+ --with-systemd
# Generate symbolic info for debuggers
export XCFLAGS=$RPM_OPT_FLAGS
diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in
index f0aa287..4e4cf76 100644
--- a/wrappers/systemd.template.service.in
+++ b/wrappers/systemd.template.service.in
@@ -18,7 +18,7 @@ PartOf=@systemdgroupname@
After=chronyd.service
[Service]
-Type=forking
+Type=notify
EnvironmentFile=@initconfigdir@/@package_name@
EnvironmentFile=@initconfigdir@/@package_name@-%i
ExecStart=@sbindir@/ns-slapd -D @instconfigdir@/slapd-%i -i @localstatedir@/run/@package_name(a)/slapd-%i.pid -w @localstatedir@/run/@package_name(a)/slapd-%i.startpid
8 years, 2 months
ldap/admin man/man8
by Mark Reynolds
ldap/admin/src/scripts/ns-accountstatus.pl.in | 923 ++++++++++++++++++--------
ldap/admin/src/scripts/ns-activate.pl.in | 361 +++++-----
ldap/admin/src/scripts/ns-inactivate.pl.in | 220 ++----
man/man8/ns-accountstatus.pl.8 | 35
4 files changed, 964 insertions(+), 575 deletions(-)
New commits:
commit 9795ec82a08026264e956e095400b8cdbb7dcd1e
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Feb 8 10:52:48 2016 -0500
Ticket 48269 - RFE: need an easy way to detect locked
accounts locked by inactivity.
Description: The previous version of ns-accountstatus and ns-activate do not work
with the Account Policy Plugin. This patch allows these scripts to
properly detect when an account is "inactivated" due to inactivity.
Also, added some new features:
[1] Verbose output - prints createtime, modifytime, lastlogintime,
time until inactive, time since inactive, and
the account state.
[2] Check the status of many entries by uising a search base, scope,
and filter.
[3] Option to display only "inactivated" users
[4] Option to display users that will become inactive within a
certain timeframe
Also the three scripts all used the same source code, and they would
check the script name to know what actions to perform. Each script
has been stripped on duplicate/unnecessary code.
https://fedorahosted.org/389/ticket/48269
Design Doc: http://www.port389.org/docs/389ds/design/enhanced-account-tools.html
Reviewed by: wibrown(Thanks!)
diff --git a/ldap/admin/src/scripts/ns-accountstatus.pl.in b/ldap/admin/src/scripts/ns-accountstatus.pl.in
index f16048d..db3224c 100644
--- a/ldap/admin/src/scripts/ns-accountstatus.pl.in
+++ b/ldap/admin/src/scripts/ns-accountstatus.pl.in
@@ -2,7 +2,7 @@
#
# BEGIN COPYRIGHT BLOCK
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
-# Copyright (C) 2013 Red Hat, Inc.
+# Copyright (C) 2016 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
@@ -12,14 +12,16 @@
use lib qw(@perlpath@);
use DSUtil;
+use Time::Local;
DSUtil::libpath_add("@nss_libdir@");
DSUtil::libpath_add("/usr/lib");
$ENV{'PATH'} = "@ldaptool_bindir@:/usr/bin:/usr/lib64/mozldap/";
$ENV{'SHLIB_PATH'} = "$ENV{'LD_LIBRARY_PATH'}";
-$single = 0;
-$role = 0;
+my $single = 0;
+my $role = 0;
+my $verbose = 0;
###############################
# SUB-ROUTINES
@@ -27,9 +29,10 @@ $role = 0;
sub usage
{
- print (STDERR "ns-accountstatus.pl [-Z serverID] [-D rootdn] { -w password | -w - | -j filename } \n");
- print (STDERR " [-p port] [-h host] [-P protocol] -I DN-to-$operation\n\n");
- print (STDERR "May be used to $operation a user or a domain of users\n\n");
+ print (STDERR "ns-accountstatus.pl [-Z serverID] [-D rootdn] { -w password | -w - | -j filename }\n");
+ print (STDERR " [-p port] [-h host] [-P protocol] {-I DN | -b basedn -f filter [-s scope]}"
+ print (STDERR " [-i] [-g seconds]\n\n");
+ print (STDERR "May be used to get the status a user or a domain of users\n\n");
print (STDERR "Arguments:\n");
print (STDERR " -? - Display usage\n");
print (STDERR " -D rootdn - Provide a Directory Manager DN\n");
@@ -40,7 +43,13 @@ sub usage
print (STDERR " -p port - Provide a port\n");
print (STDERR " -h host - Provide a host name\n");
print (STDERR " -P protocol - STARTTLS, LDAPS, LDAPI, LDAP (default: uses most secure protocol available)\n");
- print (STDERR " -I DN-to-$operation - Single entry DN or role DN to $operation\n");
+ print (STDERR " -I DN - Single entry DN or role DN to get status\n");
+ print (STDERR " -b basedn - Search base for finding entries**\n");
+ print (STDERR " -f filter - Search filter for finding entries**\n");
+ print (STDERR " -s scope - Search scope (base, one, sub - default is sub)**\n");
+ print (STDERR " -i - Only display inactivated entries\n");
+ print (STDERR " -g seconds - Only display entries that will become inactive within the timeframe\n");
+ print (STDERR " -V - Display verbose information\n");
}
sub debug
@@ -319,39 +328,397 @@ sub checkScope
}
}
+#
+# Check if an account is locked by inactivity
+# Take the lastlogintime (which is in Generalized Time), and convert it to its
+# EPOCH time. Then compare this to the current time and the inactivity limit
+#
+sub checkForInactivity
+{
+ my $gentime_lastlogin = shift;
+ my $limit = shift;
-###############################
-# MAIN ROUTINE
-###############################
+ if ($limit == 0){
+ return 0;
+ }
+ my ($year, $mon, $day, $hour, $min, $sec) =
+ ($gentime_lastlogin =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
+ my $lastlogin = timegm($sec, $min, $hour, $day, ($mon-1), $year); # EPOCH time
+ my $now = time(); # EPOCH time
-# Determine which command we are running
-if ( $0 =~ /ns-inactivate(.pl)?$/ ){
- $cmd="ns-inactivate.pl";
- $operation="inactivate";
- $state="inactivated";
- $modrole="add";
- $already="already";
+ if (($now - $lastlogin) > $limit){
+ # Account has be inactive for too long
+ return 1;
+ }
+ # Account is fine and active
+ return 0;
+}
+
+sub checkForUpcomingInactivity
+{
+ my $gentime_lastlogin = shift;
+ my $limit = shift;
+ my $timeframe = shift;
+
+ if ($limit == 0){
+ return 0;
+ }
+ my ($year, $mon, $day, $hour, $min, $sec) =
+ ($gentime_lastlogin =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
+ my $lastlogin = timegm($sec, $min, $hour, $day, ($mon-1), $year); # EPOCH time
+ my $now = time(); # EPOCH time
+ my $time_to_inactive = ($limit - ($now - $lastlogin));
+ if ($time_to_inactive <= $timeframe){
+ return 1;
+ } else {
+ return 0;
+ }
}
-elsif ( $0 =~ /ns-activate(.pl)?$/ ){
- $cmd="ns-activate.pl";
- $operation="activate";
- $state="activated";
- $modrole="delete";
- $already="already";
+
+#
+# Return the time in seconds until the account reaches the limit
+#
+sub getTimeToInactivity
+{
+ my $gentime_lastlogin = shift;
+ my $limit = shift;
+
+ my ($year, $mon, $day, $hour, $min, $sec) =
+ ($gentime_lastlogin =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
+ my $lastlogin = timegm($sec, $min, $hour, $day, ($mon-1), $year); # EPOCH time
+ my $now = time(); # EPOCH time
+
+ return ($limit - ($now - $lastlogin));
}
-elsif ( $0 =~ /ns-accountstatus(.pl)?$/ ){
- $cmd="ns-accountstatus.pl";
- $operation="get status of";
- $state="activated";
- # no need for $modrole as no operation is performed
- $already="";
-} else {
- out("$0: unknown command\n");
- exit 100;
+#
+# Return the time in seconds until the account reaches the limit
+#
+sub getTimeSinceInactive
+{
+ my $gentime_lastlogin = shift;
+ my $limit = shift;
+
+ my ($year, $mon, $day, $hour, $min, $sec) =
+ ($gentime_lastlogin =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
+ my $lastlogin = timegm($sec, $min, $hour, $day, ($mon-1), $year); # EPOCH time
+ my $now = time(); # EPOCH time
+
+ return ($now - ($lastlogin + $limit));
+ #return (($now - $lastlogin) - limit);
+}
+
+#
+# Return various components of the acct policy
+#
+sub getAcctPolicy
+{
+ my %srch = %{$_[0]};
+ my $entry = $_[1];
+
+ my $enabled = 0;
+ my $stateattr = 0;
+ my $altstateattr = 0;
+ my $cosspecattr = 0;
+ my $limitattr = 0;
+ my $limit = 0;
+ my $configentry = 0;
+ my $templateDN = "";
+
+ $srch{base} = "cn=Account Policy Plugin,cn=plugins,cn=config";
+ $srch{filter} = "(&(objectclass=top)(nsslapd-pluginarg0=*))";
+ $srch{scope} = "base";
+ $srch{attrs} = "nsslapd-pluginEnabled nsslapd-pluginarg0";
+
+ #
+ # Get the main plugin entry
+ #
+ $searchAccPolicy = DSUtil::ldapsrch(%srch);
+ open (LDAP1, "$searchAccPolicy |");
+ while (<LDAP1>) {
+ s/\n //g;
+ if( /^nsslapd-pluginenabled: on/i) {
+ $enabled = 1;
+ } elsif (/^nsslapd-pluginarg0: (.*)/i) {
+ $configentry = $1;
+ }
+ }
+ close(LDAP1);
+
+ if ($enabled == 0){
+ # Not using acct policy plugin, no reason to continue.
+ return (0, 0, 0, 0);
+ }
+
+ #
+ # Get the plugin config entry
+ #
+ $srch{base} = $configentry;
+ $srch{filter} = "(objectclass=top)";
+ $srch{scope} = "base";
+ $srch{attrs} = "stateattrname altstateattrname specattrname limitattrname";
+ $searchAccPolicy = DSUtil::ldapsrch(%srch);
+ open (LDAP1, "$searchAccPolicy |");
+ while (<LDAP1>) {
+ s/\n //g;
+ if( /^stateattrname: (.*)/i) {
+ $stateattr = $1;
+ } elsif (/^altstateattrname: (.*)/i) {
+ $altstateattr = $1;
+ } elsif (/^specattrname: (.*)/i) {
+ $cosspecattr = $1;
+ } elsif (/^limitattrname: (.*)/i) {
+ $limitattr = $1;
+ }
+ }
+ close(LDAP1);
+
+ #
+ # Now, get the DN for the cos template from the entry
+ #
+ $srch{base} = $entry;
+ $srch{filter} = "(objectclass=*)";
+ $srch{scope} = "base";
+ $srch{attrs} = "$cosspecattr";
+ $searchAccPolicy= DSUtil::ldapsrch(%srch);
+ open (LDAP1, "$searchAccPolicy |");
+ while (<LDAP1>) {
+ s/\n //g;
+ if (/^$cosspecattr: (.*)/i){
+ $templateDN = $1;
+ }
+ }
+ close(LDAP1);
+
+ #
+ # Get the inactivity limit from the template]
+ #
+ $srch{base} = $templateDN;
+ $srch{filter} = "($limitattr=*)";
+ $srch{scope} = "base";
+ $srch{attrs} = "$limitattr";
+ my @result = DSUtil::ldapsrch_ext(%srch);
+ if ($#result > 1){
+ if ($result[1] =~ /^$limitattr: *([0-9]+)/i){
+ $limit = $1;
+ }
+ }
+
+ return ($enabled, $stateattr, $altstateattr, $limit);
+}
+
+#
+# Return a friendly time string for the client
+#
+sub get_time_from_epoch
+{
+ my $sec = shift;
+ my $result = "";
+ my $add_space = 0;
+
+ if (int($sec/(24*60*60))){
+ $result = int($sec/(24*60*60)) . " days";
+ $add_space = 1;
+ }
+ if (($sec/(60*60))%24){
+ if ($add_space){
+ $result = $result . ", ";
+ }
+ $add_space = 1;
+ $result = $result . ($sec/(60*60))%24 . " hours";
+ }
+ if ( ($sec/60)%60){
+ if ($add_space){
+ $result = $result . ", ";
+ }
+ $add_space = 1;
+ $result = $result . ($sec/60)%60 . " minutes";
+ }
+ if ($sec%60){
+ if ($add_space){
+ $result = $result . ", ";
+ }
+ $result = $result . $sec%60 . " seconds";
+ }
+ return $result;
+}
+
+#
+# Given a string in generalized time format, convert it to ascii time
+#
+sub get_time_from_gentime
+{
+ my $zstr = shift;
+ return "n/a" if (! $zstr);
+ my ($year, $mon, $day, $hour, $min, $sec) =
+ ($zstr =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
+ my $time = timegm($sec, $min, $hour, $day, ($mon-1), $year);
+ ($sec, $min, $hour, $day, $mon, $year) = localtime($time);
+ $mon++;
+ $year += 1900;
+ foreach ($sec, $min, $hour, $day, $mon) {
+ $_ = "0".$_ if ($_ < 10);
+ }
+
+ return "$mon/$day/$year $hour:$min:$sec";
+}
+
+#
+# Print Verbose output about the entry
+#
+sub printVerbose
+{
+ my %dsinfo = %{$_[0]};
+ my $suffix = $_[1];
+ my $entry = $_[2];
+ my $createtime = $_[3];
+ my $modifytime = $_[4];
+ my $lastlogintime = $_[5];
+ my $state = $_[6];
+ my $limit = $_[7];
+ my $usingAcct = $_[8];
+
+ out("Entry: $entry\n");
+ out("Entry Creation Date: $createtime (" . get_time_from_gentime($createtime) . ")\n");
+ out("Entry Modification Date: $modifytime (" . get_time_from_gentime($modifytime) . ")\n");
+ if ($lastlogintime ne ""){
+ out("Last Login Date: $lastlogintime (" . get_time_from_gentime($lastlogintime) . ")\n");
+ }
+ if($usingAcct){
+ if ($limit){
+ out("Inactivity Limit: $limit seconds (" . get_time_from_epoch($limit) . ")\n");
+ if ($lastlogintime ne ""){
+ my $remaining_time = getTimeToInactivity($lastlogintime, $limit);
+ if($remaining_time < 0){
+ out("Time Until Inactive: -\n");
+ # We only display elapsed time if the account was locked by inactivity
+ if($state =~ /inactivity limit exceeded/){
+ my $elapsed_time = getTimeSinceInactive($lastlogintime, $limit);
+ out("Time Since Inactivated: $elapsed_time seconds (" . get_time_from_epoch($elapsed_time) . ")\n");
+ } else {
+ out("Time Since Inactive: -\n");
+ }
+ } else {
+ out("Time Until Inactive: $remaining_time seconds (" . get_time_from_epoch($remaining_time) . ")\n");
+ out("Time Since Inactive: -\n");
+ }
+ }
+ }
+ }
+ out("Entry State: $state\n\n");
+}
+
+#
+# Just strip any unneeded spaces from the DN
+#
+sub normalizeDN
+{
+ my $entry = shift;
+ my $result = "";
+ my $part = "";
+
+ @suffix=split /([,])/,$entry;
+ $result="";
+ foreach $part (@suffix){
+ $part=~s/^ +//;
+ $part=~ tr/A-Z/a-z/;
+ $result="$result$part";
+ }
+ return $result;
+}
+
+#
+# Get the suffix from the entry
+#
+sub getSuffix
+{
+ my $entry = shift;
+ my $cont = 0;
+ my @suffixN = normalizeDN($entry);
+ my @suffix = split /([,])/,$entry;
+
+ while ($cont == 0){
+ # Look if suffix is the suffix of the entry
+ # ldapsearch -s one -b "cn=mapping tree,cn=config" "cn=\"uid=jvedder,ou=People,dc=example,dc=com\""
+ #
+ debug("\tSuffix from the entry: #@suffixN#\n");
+ $info{base} = "cn=mapping tree, cn=config";
+ $info{filter} = "cn=\"@suffixN\"";
+ $info{scope} = "one";
+ $info{attrs} = "cn";
+ @mapping = DSUtil::ldapsrch_ext(%info);
+ my $retCode = $?;
+ if ( $retCode != 0 ){
+ $retCode = $?>>8;
+ exit $retCode;
+ }
+
+ # If we get a result, remove the dn:
+ # dn: cn="o=sun.com",cn=mapping tree,cn=config
+ # cn: "dc=example,dc=com"
+ #
+ shift @mapping;
+
+ foreach $res (@mapping){
+ # Break the string cn: "o=sun.com" into pieces
+ @cn = split(/ /,$res);
+
+ # And remove the cn: part
+ shift @cn;
+
+ # Now compare the suffix we extract from the mapping tree
+ # with the suffix derived from the entry
+ debug("\tSuffix from mapping tree: #@cn#\n");
+ if ( @cn eq @suffixN ){
+ debug("Found matching suffix\n");
+ $cont = 1;
+ }
+ }
+
+ if ( $cont == 0 ){
+ # Remove the current rdn to try another suffix
+ shift @suffix;
+
+ my $result="";
+ foreach $part (@suffix){
+ $part =~ s/^ +//;
+ $part =~ tr/A-Z/a-z/;
+ $result = "$result$part";
+ }
+ @suffixN = $result;
+
+ debug("\t\tNothing found => go up one level in rdn #@suffix#\n");
+ $len = @suffix;
+ if ( $len == 0 ){
+ debug("Can not find suffix. Problem\n");
+ $cont=2;
+ }
+ }
+ } # while cont = 0
+ if ( $cont == 2){
+ out("Can not find suffix for entry $entry\n");
+ exit 100;
+ }
+ return @suffixN
}
-debug("Running ** $cmd ** $operation\n");
+###############################
+# MAIN ROUTINE
+###############################
+
+
+my $state="activated";
+my $acct_policy_enabled;
+my $stateattr;
+my $altstateattr;
+my $limit;
+my $filter = 0;
+my $basedn = 0;
+my $scope = "sub";
+my $keep_processing = 0;
+my $only_inactive = 0;
+my $inactive_timeframe = 0;
+my @entries;
# Process the command line arguments
while( $arg = shift){
@@ -372,6 +739,18 @@ while( $arg = shift){
$entry= shift @ARGV;
} elsif($arg eq "-Z"){
$servid= shift @ARGV;
+ } elsif($arg eq "-b"){
+ $basedn= shift @ARGV;
+ } elsif($arg eq "-s"){
+ $scope= shift @ARGV;
+ } elsif($arg eq "-f"){
+ $filter= shift @ARGV;
+ } elsif($arg eq "-i"){
+ $only_inactive = 1;
+ } elsif($arg eq "-g"){
+ $inactive_timeframe = shift @ARGV;
+ } elsif($arg eq "-V"){
+ $verbose = 1;
} elsif ($arg eq "-P") {
$protocol = shift @ARGV;
} else {
@@ -389,291 +768,271 @@ while( $arg = shift){
$info{rootdnpw} = DSUtil::get_password_from_file($rootpw, $pwfile);
$info{protocol} = $protocol;
$info{args} = "-c -a";
-if($entry eq ""){
+if($entry eq "" and (!$basedn or !$filter)){
usage();
exit 1;
}
#
-# Check the actual existence of the entry to inactivate/activate
-# and at the same time, validate the various parm: port, host, rootdn, rootpw
+# Check if we have a filter, and gather the dn's
#
-$info{base} = $entry;
-$info{filter} = "(objectclass=*)";
-$info{scope} = "base";
-$info{attrs} = "dn";
-@exist=DSUtil::ldapsrch_ext(%info);
-$retCode1=$?;
-if ( $retCode1 != 0 ){
- $retCode1=$?>>8;
- exit $retCode1;
-}
-
-$info{filter} = "(&(objectclass=LDAPsubentry)(objectclass=nsRoleDefinition))";
-@isRole = DSUtil::ldapsrch_ext(%info);
-$nbLineRole=@isRole;
-$retCode2=$?;
-if ( $retCode2 != 0 ){
- $retCode2=$?>>8;
- exit $retCode2;
-}
-
-if ( $nbLineRole > 0 ){
- debug("Groups of users\n");
- $role=1;
+if ($basedn && $filter){
+ $info{base} = $basedn;
+ $info{filter} = $filter;
+ $info{scope} = $scope;
+ $info{attrs} = "dn";
+
+ @users=DSUtil::ldapsrch_ext(%info);
+ $retCode1=$?;
+ if ( $retCode1 != 0 ){
+ $retCode1=$?>>8;
+ exit $retCode1;
+ }
+ my $i = 0;
+ my $c = 0;
+ while($#users > 0 && $users[$i]){
+ if($users[$i] =~ /^dn: (.*)/i){
+ $entries[$c] = $1;
+ $c++;
+ }
+ $i++;
+ }
+ if ($c > 1){
+ # Mark that we are processing multiple entries
+ $keep_processing = 1;
+ }
} else {
- debug("Single user\n");
- $single=1;
-}
-
-#
-# First of all, check the existence of the nsaccountlock attribute in the entry
-#
-$isLocked=0;
-if ( $single == 1 ){
+ # Single entry
+ #
+ # Check the actual existence of the entry
+ # and at the same time, validate the various
+ # parm: port, host, rootdn, rootpw
+ #
+ $info{base} = $entry;
$info{filter} = "(objectclass=*)";
- $info{attrs} = "nsaccountlock";
- $searchAccountLock= DSUtil::ldapsrch(%info);
- open (LDAP1, "$searchAccountLock |");
- while (<LDAP1>) {
- s/\n //g;
- if (/^nsaccountlock: (.*)\n/) {
- $L_currentvalue = $1;
- $L_currentvalue=~ tr/A-Z/a-z/;
- if ( $L_currentvalue eq "true"){
- $isLocked=1;
- } elsif ( $L_currentvalue eq "false" ){
- $isLocked=0;
- }
- }
+ $info{scope} = "base";
+ $info{attrs} = "dn";
+ @exist=DSUtil::ldapsrch_ext(%info);
+ $retCode1=$?;
+ if ( $retCode1 != 0 ){
+ $retCode1=$?>>8;
+ exit $retCode1;
}
- close(LDAP1);
-}
-debug("Is the entry already locked? ==> $isLocked\n");
-
-#
-# Get the suffix name of that entry
-#
-
-# Remove the space at the beginning (just in case...)
-# -I "uid=jvedder , ou=People , o=sun.com"
-@suffix=split /([,])/,$entry;
-$result="";
-foreach $part (@suffix){
- $part=~s/^ +//;
- $part=~ tr/A-Z/a-z/;
- $result="$result$part";
+ $entries[0] = $entry;
}
-@suffixN=$result;
-debug("Entry to $operation: #@suffix#\n");
-debug("Entry to $operation: #@suffixN#\n");
-
-# Get the suffix
-$cont=0;
-while ($cont == 0){
- # Look if suffix is the suffix of the entry
- # ldapsearch -s one -b "cn=mapping tree,cn=config" "cn=\"uid=jvedder,ou=People,o=sun.com\""
+for(my $i = 0; $i <= $#entries; $i++){
#
- debug("\tSuffix from the entry: #@suffixN#\n");
- $info{base} = "cn=mapping tree, cn=config";
- $info{filter} = "cn=\"@suffixN\"";
- $info{scope} = "one";
- $info{attrs} = "cn";
- @mapping = DSUtil::ldapsrch_ext(%info);
- $retCode=$?;
- if ( $retCode != 0 ){
- $retCode=$?>>8;
- exit $retCode;
- }
-
- # If we get a result, remove the dn:
- # dn: cn="o=sun.com",cn=mapping tree,cn=config
- # cn: "o=sun.com"
+ # Process each entry
#
- shift @mapping;
-
- foreach $res (@mapping){
- # Break the string cn: "o=sun.com" into pieces
- @cn= split(/ /,$res);
+ $entry = $entries[$i];
- # And remove the cn: part
- shift @cn;
-
- # Now compare the suffix we extract from the mapping tree
- # with the suffix derived from the entry
- debug("\tSuffix from mapping tree: #@cn#\n");
- if ( @cn eq @suffixN ){
- debug("Found matching suffix\n");
- $cont=1;
- }
+ #
+ # Determine if we are deadling with a entry or a role
+ #
+ $info{base} = $entry;
+ $info{filter} = "(&(objectclass=LDAPsubentry)(objectclass=nsRoleDefinition))";
+ @isRole = DSUtil::ldapsrch_ext(%info);
+ $nbLineRole=@isRole;
+ $retCode2=$?;
+ if ( $retCode2 != 0 ){
+ $retCode2=$?>>8;
+ exit $retCode2;
}
- if ( $cont == 0 ){
- # Remove the current rdn to try another suffix
- shift @suffix;
-
- $result="";
- foreach $part (@suffix){
- $part=~ s/^ +//;
- $part=~ tr/A-Z/a-z/;
- $result="$result$part";
- }
- @suffixN=$result;
-
- debug("\t\tNothing found => go up one level in rdn #@suffix#\n");
- $len=@suffix;
- if ( $len == 0 ){
- debug("Can not find suffix. Problem\n");
- $cont=2;
- }
+ if ( $nbLineRole > 0 ){
+ debug("Groups of users\n");
+ $role=1;
+ } else {
+ debug("Single user\n");
+ $single=1;
}
-}
-if ( $cont == 2){
- out("Can not find suffix for entry $entry\n");
- exit 100;
-}
-if ( $operation eq "inactivate" ){
#
- # Now that we have the suffix and we know if we deal with a single entry or
- # a role, just try to create the COS and roles associated.
+ # Gather the Account Ppoliy PLugin information(if available)
#
- $role1="dn: cn=nsManagedDisabledRole,@suffixN\n" .
- "objectclass: LDAPsubentry\n" .
- "objectclass: nsRoleDefinition\n" .
- "objectclass: nsSimpleRoleDefinition\n" .
- "objectclass: nsManagedRoleDefinition\n" .
- "cn: nsManagedDisabledRole\n\n";
- $role2="dn: cn=nsDisabledRole,@suffixN\n" .
- "objectclass: top\n" .
- "objectclass: LDAPsubentry\n" .
- "objectclass: nsRoleDefinition\n" .
- "objectclass: nsComplexRoleDefinition\n" .
- "objectclass: nsNestedRoleDefinition\n" .
- "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n" .
- "cn: nsDisabledRole\n\n";
- $cos1="dn: cn=nsAccountInactivationTmp,@suffixN\n" .
- "objectclass: top\n" .
- "objectclass: nsContainer\n\n";
- $cos2="dn: cn=\"cn=nsDisabledRole,@suffixN\",cn=nsAccountInactivationTmp,@suffixN\n" .
- "objectclass: top\n" .
- "objectclass: extensibleObject\n" .
- "objectclass: costemplate\n" .
- "objectclass: ldapsubentry\n" .
- "cosPriority: 1\n" .
- "nsAccountLock: true\n\n";
- $cos3=(
- "dn: cn=nsAccountInactivation_cos,@suffixN\n",
- "objectclass: top\n",
- "objectclass: LDAPsubentry\n",
- "objectclass: cosSuperDefinition\n",
- "objectclass: cosClassicDefinition\n",
- "cosTemplateDn: cn=nsAccountInactivationTmp,@suffixN\n",
- "cosSpecifier: nsRole\n",
- "cosAttribute: nsAccountLock operational\n\n" );
- $all = $role1 . $role2 . $cos1 . $cos2 . $cos3;
- DSUtil::ldapmod($all, %info);
- if ( $? != 0 ){
- $retCode=$?>>8;
- if ( $retCode == 68 ){
- debug("Entry $current already exists, ignore error\n");
- } else {
- # Probably a more serious problem.
- # Exit with LDAP error
- exit $retCode;
- }
- } else {
- debug("Roles/cos created\n");
- }
-}
+ ($acct_policy_enabled, $stateattr, $altstateattr, $limit) = getAcctPolicy(\%info, $entry);
-$skipManaged=0;
-$skipDisabled=0;
-$directLocked=0;
-
-$nsDisabledRole="cn=nsDisabledRole,@suffixN";
-$nsDisabledRole=~ tr/A-Z/a-z/;
-
-$nsManagedDisabledRole="cn=nsManagedDisabledRole,@suffixN";
-$nsManagedDisabledRole=~ tr/A-Z/a-z/;
+ #
+ # First of all, check the existence of the nsaccountlock attribute in the entry
+ #
+ $isLocked = 0;
+ my $lastlogintime = "";
+ my $altlogintime = "";
+ my $createtime = "";
+ my $modifytime = "";
+
+ if ( $single == 1 ){
+ $info{filter} = "(objectclass=*)";
+ $info{attrs} = "nsaccountlock lastLoginTime createtimestamp modifytimestamp";
+ $info{scope} = "base";
+ $searchAccountLock= DSUtil::ldapsrch(%info);
+ open (LDAP1, "$searchAccountLock |");
+ while (<LDAP1>) {
+ s/\n //g;
+ if (/^nsaccountlock: (.*)\n/i) {
+ $L_currentvalue = $1;
+ $L_currentvalue=~ tr/A-Z/a-z/;
+ if ( $L_currentvalue eq "true"){
+ $isLocked=1;
+ } elsif ( $L_currentvalue eq "false" ){
+ $isLocked=0;
+ }
+ }
+ if (/^$stateattr: (.*)\n/i) {
+ $lastlogintime = $1;
+ }
+ if (/^$altstateattr: (.*)\n/i) {
+ $altlogintime = $1;
+ }
+ if (/^createtimestamp: (.*)\n/i) {
+ $createtime = $1;
+ }
+ if (/^modifyTimeStamp: (.*)\n/i) {
+ $modifytime = $1;
+ }
+ }
+ close(LDAP1);
-if ( $operation eq "inactivate" ){
- # Go through all the roles part of nsdisabledrole to check if the entry
- # is a member of one of those roles
- $ret=indirectLock("LDAP00", $entry, $nsDisabledRole);
- if ( $ret == 0 ) {
- if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ){
- # indirect lock
- out("$entry already $state through $throughRole.\n");
- } else {
- # direct lock
- out("$entry already $state.\n");
+ if($lastlogintime eq ""){
+ $lastlogintime = $altlogintime;
}
- exit 100;
- } elsif ( $isLocked == 1 ){
- # the entry is not locked through a role, may be nsaccountlock is "hardcoded" ?
- out("$entry already $state (probably directly).\n");
- exit 103;
}
-} elsif ( $operation eq "activate" || $operation eq "get status of" ){
- $skipManaged=$single;
- $skipDisabled=$role;
+ debug("Is the entry already locked? ==> $isLocked\n");
- $ret=indirectLock("LDAP00",$entry, $nsDisabledRole);
-
- if ( $ret == 0 ){
- # undirectly locked
+ #
+ # Get the suffix of the entry
+ #
+ @suffixN = getSuffix($entry);
+
+ $skipManaged = $single;
+ $skipDisabled = $role;
+ $directLocked = 0;
+ $nsDisabledRole = "cn=nsDisabledRole,@suffixN";
+ $nsDisabledRole =~ tr/A-Z/a-z/;
+ $nsManagedDisabledRole = "cn=nsManagedDisabledRole,@suffixN";
+ $nsManagedDisabledRole =~ tr/A-Z/a-z/;
+
+ $ret = indirectLock("LDAP00", $entry, $nsDisabledRole);
+ if ( $ret == 0 && $inactive_timeframe == 0){
+ # indirectly locked
if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ){
- if ( $operation eq "activate" ){
- out("$entry inactivated through $throughRole. Can not activate it individually.\n");
- exit 100;
+ if ($verbose){
+ printVerbose(\%info, "@suffixN", $entry, $createtime,
+ $modifytime, $lastlogintime,
+ "inactivated through $throughRole", $limit,
+ $acct_policy_enabled);
} else {
- out("$entry inactivated through $throughRole.\n");
- exit 104;
+ out("$entry - inactivated through $throughRole.\n");
}
+ if($keep_processing){
+ next;
+ }
+ exit 104;
}
debug("$entry locked individually\n");
-
- if ( $operation ne "activate" ){
- out("$entry inactivated.\n");
- exit 103;
+ if ($verbose){
+ printVerbose(\%info, "@suffixN", $entry, $createtime,
+ $modifytime, $lastlogintime, "inactivated", $limit,
+ $acct_policy_enabled);
+ } else {
+ out("$entry - inactivated.\n");
}
+ if($keep_processing){
+ next;
+ }
+ exit 103;
} elsif ( $directLocked == 0 ){
- if ( $operation eq "activate" && $isLocked != 1 ){
- out("$entry $already $state.\n");
- exit 100;
- } elsif ( $isLocked != 1 ){
- out("$entry $already $state.\n");
+ if ( $isLocked != 1 ){
+ #
+ # We are not locked by account lockout, but we could be locked by
+ # the Account Policy Plugin (inactivity)
+ #
+ if($acct_policy_enabled && $lastlogintime ne ""){
+ #
+ # Now check the Acount Policy Plugin inactivity limits
+ #
+ if(checkForInactivity($lastlogintime, $limit)){
+ if ($inactive_timeframe > 0){
+ # We are only looking for active entries that are about to expire
+ next;
+ }
+ # Account is inactive by inactivity!
+ if($verbose){
+ printVerbose(\%info, "@suffixN", $entry, $createtime,
+ $modifytime, $lastlogintime,
+ "inactivated (inactivity limit exceeded)",
+ $limit, $acct_policy_enabled);
+ } else {
+ out("$entry - inactivated (inactivity limit exceeded).\n");
+ }
+ if($keep_processing){
+ next;
+ }
+ exit 103;
+ } elsif (checkForUpcomingInactivity($lastlogintime, $limit, $inactive_timeframe)){
+ if($verbose){
+ printVerbose(\%info, "@suffixN", $entry, $createtime,
+ $modifytime, $lastlogintime,
+ "activated",
+ $limit, $acct_policy_enabled);
+ } else {
+ out("$entry - activated\n");
+ }
+ if($keep_processing){
+ next;
+ }
+ exit 0;
+ }
+ }
+ if(!$only_inactive and $inactive_timeframe == 0){
+ if($verbose){
+ printVerbose(\%info, "@suffixN", $entry, $createtime,
+ $modifytime, $lastlogintime, $state, $limit,
+ $acct_policy_enabled);
+ } else {
+ out("$entry - $state.\n");
+ }
+ }
+ if($keep_processing){
+ next;
+ }
exit 102;
} else {
# not locked using our schema, but nsaccountlock is probably present
- out("$entry inactivated (probably directly).\n");
+ if ($inactive_timeframe > 0){
+ # We are only looking for active entries that are about to expire,
+ # so move on to the next entry
+ next;
+ }
+ if($verbose){
+ printVerbose(\%info, "@suffixN", $entry, $createtime,
+ $modifytime, $lastlogintime,
+ "inactivated (probably directly)", $limit,
+ $acct_policy_enabled);
+ } else {
+ out("$entry - inactivated (probably directly).\n");
+ }
+ if($keep_processing){
+ next;
+ }
exit 103;
}
- } elsif ( $operation ne "activate" ){
- out("$entry inactivated.\n");
+ } else {
+ if ($inactive_timeframe > 0){
+ # We are only looking for active entries that are about to expire
+ next;
+ }
+ if($verbose){
+ printVerbose(\%info, "@suffixN", $entry, $createtime,
+ $modifytime, $lastlogintime, "inactivated", $limit,
+ $acct_policy_enabled);
+ } else {
+ out("$entry - inactivated.\n");
+ }
+ if($keep_processing){
+ next;
+ }
exit 103;
}
- # else Locked directly, juste unlock it!
- debug("$entry locked individually\n");
-}
-
-#
-# Inactivate/activate the entry
-#
-if ( $single == 1 ){
- $record = "dn: $entry\n" . "changetype: modify\n" . "$modrole: nsRoleDN\n" . "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n";
-} else {
- $record = "dn: cn=nsDisabledRole,@suffixN\n" . "changetype: modify\n" . "$modrole: nsRoleDN\n" . "nsRoleDN: $entry\n";
-}
-$info{args} = "-c";
-DSUtil::ldapmod($record, %info);
-if( $? != 0 ){
- debug("$modrole, $entry\n");
- $retCode=$?>>8;
- exit $retCode;
-}
-
-out("$entry $state.\n");
-exit 0;
+}
\ No newline at end of file
diff --git a/ldap/admin/src/scripts/ns-activate.pl.in b/ldap/admin/src/scripts/ns-activate.pl.in
index ff1c3ba..6e5ecc7 100644
--- a/ldap/admin/src/scripts/ns-activate.pl.in
+++ b/ldap/admin/src/scripts/ns-activate.pl.in
@@ -2,7 +2,7 @@
#
# BEGIN COPYRIGHT BLOCK
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
-# Copyright (C) 2013 Red Hat, Inc.
+# Copyright (C) 2016 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
@@ -12,14 +12,16 @@
use lib qw(@perlpath@);
use DSUtil;
+use Time::Local;
+use POSIX qw(strftime);
DSUtil::libpath_add("@nss_libdir@");
DSUtil::libpath_add("/usr/lib");
$ENV{'PATH'} = "@ldaptool_bindir@:/usr/bin:/usr/lib64/mozldap/";
$ENV{'SHLIB_PATH'} = "$ENV{'LD_LIBRARY_PATH'}";
-$single = 0;
-$role = 0;
+my $single = 0;
+my $role = 0;
###############################
# SUB-ROUTINES
@@ -28,8 +30,8 @@ $role = 0;
sub usage
{
print (STDERR "ns-activate.pl [-Z serverID] [-D rootdn] { -w password | -w - | -j filename } \n");
- print (STDERR " [-p port] [-h host] [-P protocol] -I DN-to-$operation\n\n");
- print (STDERR "May be used to $operation a user or a domain of users\n\n");
+ print (STDERR " [-p port] [-h host] [-P protocol] -I DN-to-activate\n\n");
+ print (STDERR "May be used to activate a user or a domain of users\n\n");
print (STDERR "Arguments:\n");
print (STDERR " -? - Display usage\n");
print (STDERR " -D rootdn - Provide a Directory Manager DN\n");
@@ -40,7 +42,7 @@ sub usage
print (STDERR " -p port - Provide a port\n");
print (STDERR " -h host - Provide a host name'\n");
print (STDERR " -P protocol - STARTTLS, LDAPS, LDAPI, LDAP (default: uses most secure protocol available)\n");
- print (STDERR " -I DN-to-$operation - Single entry DN or role DN to $operation\n");
+ print (STDERR " -I DN-to-activate - Single entry DN or role DN to activate\n");
}
sub debug
@@ -318,6 +320,130 @@ sub checkScope
}
}
+#
+# Check if an account is locked by inactivity
+# Take the lastlogintime (which is in Generalized Time), and convert it to its
+# EPOCH time. Then compare this to the current time and the inactivity limit
+#
+sub checkForInactivity
+{
+ my $gentime_lastlogin = shift;
+ my $limit = shift;
+
+ if ($limit == 0){
+ return 0;
+ }
+ my ($year, $mon, $day, $hour, $min, $sec) =
+ ($gentime_lastlogin =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
+ my $lastlogin = timegm($sec, $min, $hour, $day, ($mon-1), $year); # EPOCH time
+ my $now = time(); # EPOCH time
+
+ if (($now - $lastlogin) > $limit){
+ # Account has be inactive for too long
+ return 1;
+ }
+ # Account is fine and active
+ return 0;
+}
+
+#
+# Return various components of the acct policy
+#
+sub getAcctPolicy
+{
+ my %srch = %{$_[0]};
+ my $entry = $_[1];
+
+ my $enabled = 0;
+ my $stateattr = 0;
+ my $altstateattr = 0;
+ my $cosspecattr = 0;
+ my $limitattr = 0;
+ my $limit = 0;
+ my $configentry = 0;
+ my $templateDN = "";
+
+ $srch{base} = "cn=Account Policy Plugin,cn=plugins,cn=config";
+ $srch{filter} = "(&(objectclass=top)(nsslapd-pluginarg0=*))";
+ $srch{scope} = "base";
+ $srch{attrs} = "nsslapd-pluginEnabled nsslapd-pluginarg0";
+
+ #
+ # Get the main plugin entry
+ #
+ $searchAccPolicy = DSUtil::ldapsrch(%srch);
+ open (LDAP1, "$searchAccPolicy |");
+ while (<LDAP1>) {
+ s/\n //g;
+ if( /^nsslapd-pluginenabled: on/i) {
+ $enabled = 1;
+ } elsif (/^nsslapd-pluginarg0: (.*)/i) {
+ $configentry = $1;
+ }
+ }
+ close(LDAP1);
+
+ if ($enabled == 0){
+ # Not using acct policy plugin, no reason to continue.
+ return (0, 0, 0, 0);
+ }
+
+ #
+ # Get the plugin config entry
+ #
+ $srch{base} = $configentry;
+ $srch{filter} = "(objectclass=top)";
+ $srch{scope} = "base";
+ $srch{attrs} = "stateattrname altstateattrname specattrname limitattrname";
+ $searchAccPolicy = DSUtil::ldapsrch(%srch);
+ open (LDAP1, "$searchAccPolicy |");
+ while (<LDAP1>) {
+ s/\n //g;
+ if( /^stateattrname: (.*)/i) {
+ $stateattr = $1;
+ } elsif (/^altstateattrname: (.*)/i) {
+ $altstateattr = $1;
+ } elsif (/^specattrname: (.*)/i) {
+ $cosspecattr = $1;
+ } elsif (/^limitattrname: (.*)/i) {
+ $limitattr = $1;
+ }
+ }
+ close(LDAP1);
+
+ #
+ # Now, get the DN for the cos template from the entry
+ #
+ $srch{base} = $entry;
+ $srch{filter} = "(objectclass=*)";
+ $srch{scope} = "base";
+ $srch{attrs} = "$cosspecattr";
+ $searchAccPolicy= DSUtil::ldapsrch(%srch);
+ open (LDAP1, "$searchAccPolicy |");
+ while (<LDAP1>) {
+ s/\n //g;
+ if (/^$cosspecattr: (.*)/i){
+ $templateDN = $1;
+ }
+ }
+ close(LDAP1);
+
+ #
+ # Get the inactivity limit from the template]
+ #
+ $srch{base} = $templateDN;
+ $srch{filter} = "($limitattr=*)";
+ $srch{scope} = "base";
+ $srch{attrs} = "$limitattr";
+ my @result = DSUtil::ldapsrch_ext(%srch);
+ if ($#result > 1){
+ if ($result[1] =~ /^$limitattr: *([0-9]+)/i){
+ $limit = $1;
+ }
+ }
+
+ return ($enabled, $stateattr, $altstateattr, $limit);
+}
###############################
# MAIN ROUTINE
@@ -325,32 +451,12 @@ sub checkScope
# Generated variable
-# Determine which command we are running
-if ( $0 =~ /ns-inactivate(.pl)?$/ ){
- $cmd="ns-inactivate.pl";
- $operation="inactivate";
- $state="inactivated";
- $modrole="add";
- $already="already";
-} elsif ( $0 =~ /ns-activate(.pl)?$/ ){
- $cmd="ns-activate.pl";
- $operation="activate";
- $state="activated";
- $modrole="delete";
- $already="already";
-} elsif ( $0 =~ /ns-accountstatus(.pl)?$/ ){
- $cmd="ns-accountstatus.pl";
- $operation="get status of";
- $state="activated";
- # no need for $modrole as no operation is performed
- $already="";
-
-} else {
- out("$0: unknown command\n");
- exit 100;
-}
-
-debug("Running ** $cmd ** $operation\n");
+my $state="activated";
+my $already="already";
+my $acct_policy_enabled;
+my $stateattr;
+my $altstateattr;
+my $limit;
# Process the command line arguments
while( $arg = shift)
@@ -395,6 +501,11 @@ if($entry eq ""){
}
#
+# Gather the Account Ppoliy PLugin information(if available)
+#
+($acct_policy_enabled, $stateattr, $altstateattr, $limit) = getAcctPolicy(\%info, $entry);
+
+#
# Check the actual existence of the entry to inactivate/activate
# and at the same time, validate the various parm: port, host, rootdn, rootpw
#
@@ -430,14 +541,17 @@ if ( $nbLineRole > 0 ){
# First of all, check the existence of the nsaccountlock attribute in the entry
#
$isLocked=0;
+my $lastlogintime = "";
+my $altlogintime = "";
+
if ( $single == 1 ){
$info{filter} = "(objectclass=*)";
- $info{attrs} = "nsaccountlock";
+ $info{attrs} = "nsaccountlock $stateattr $altstateattr";
$searchAccountLock= DSUtil::ldapsrch(%info);
open (LDAP1, "$searchAccountLock |");
while (<LDAP1>) {
s/\n //g;
- if (/^nsaccountlock: (.*)\n/) {
+ if (/^nsaccountlock: (.*)\n/i) {
$L_currentvalue = $1;
$L_currentvalue=~ tr/A-Z/a-z/;
if ( $L_currentvalue eq "true"){
@@ -445,6 +559,10 @@ if ( $single == 1 ){
} elsif ( $L_currentvalue eq "false" ){
$isLocked=0;
}
+ } elsif (/^$stateattr: (.*)\n/i) {
+ $lastlogintime = $1;
+ } elsif (/^$altstateattr: (.*)\n/i) {
+ $altlogintime = $1;
}
}
close(LDAP1);
@@ -466,8 +584,8 @@ foreach $part (@suffix){
}
@suffixN=$result;
-debug("Entry to $operation: #@suffix#\n");
-debug("Entry to $operation: #@suffixN#\n");
+debug("Entry to activate: #@suffix#\n");
+debug("Entry to activate: #@suffixN#\n");
# Get the suffix
$cont=0;
@@ -534,145 +652,88 @@ if ( $cont == 2){
exit 100;
}
-if ( $operation eq "inactivate" ){
- #
- # Now that we have the suffix and we know if we deal with a single entry or
- # a role, just try to create the COS and roles associated.
- #
- $role1="dn: cn=nsManagedDisabledRole,@suffixN\n" .
- "objectclass: LDAPsubentry\n" .
- "objectclass: nsRoleDefinition\n" .
- "objectclass: nsSimpleRoleDefinition\n" .
- "objectclass: nsManagedRoleDefinition\n" .
- "cn: nsManagedDisabledRole\n\n";
- $role2="dn: cn=nsDisabledRole,@suffixN\n" .
- "objectclass: top\n" .
- "objectclass: LDAPsubentry\n" .
- "objectclass: nsRoleDefinition\n" .
- "objectclass: nsComplexRoleDefinition\n" .
- "objectclass: nsNestedRoleDefinition\n" .
- "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n" .
- "cn: nsDisabledRole\n\n";
- $cos1="dn: cn=nsAccountInactivationTmp,@suffixN\n" .
- "objectclass: top\n" .
- "objectclass: nsContainer\n\n";
- $cos2="dn: cn=\"cn=nsDisabledRole,@suffixN\",cn=nsAccountInactivationTmp,@suffixN\n" .
- "objectclass: top\n" .
- "objectclass: extensibleObject\n" .
- "objectclass: costemplate\n" .
- "objectclass: ldapsubentry\n" .
- "cosPriority: 1\n" .
- "nsAccountLock: true\n\n";
- $cos3="dn: cn=nsAccountInactivation_cos,@suffixN\n" .
- "objectclass: top\n" .
- "objectclass: LDAPsubentry\n" .
- "objectclass: cosSuperDefinition\n" .
- "objectclass: cosClassicDefinition\n" .
- "cosTemplateDn: cn=nsAccountInactivationTmp,@suffixN\n" .
- "cosSpecifier: nsRole\n" .
- "cosAttribute: nsAccountLock operational\n\n";
- $all=$role1 . $role2 . $cos1 . $cos2 . $cos3;
-
- $info{args} = "-c -a";
- DSUtil::ldapmod($all[$i], %info);
- if ( $? != 0 ){
- $retCode=$?>>8;
- if ( $retCode == 68 ){
- debug("Entry already exists, ignore error\n");
- } else {
- # Probably a more serious problem.
- # Exit with LDAP error
- exit $retCode;
- }
- } else {
- debug("Role/cos entries created\n");
- }
-}
-
$skipManaged=0;
$skipDisabled=0;
$directLocked=0;
-
+$inactiveLocked = 0;
$nsDisabledRole="cn=nsDisabledRole,@suffixN";
$nsDisabledRole=~ tr/A-Z/a-z/;
-
$nsManagedDisabledRole="cn=nsManagedDisabledRole,@suffixN";
$nsManagedDisabledRole=~ tr/A-Z/a-z/;
-
-if ( $operation eq "inactivate" ){
- # Go through all the roles part of nsdisabledrole to check if the entry
- # is a member of one of those roles
- $ret=indirectLock("LDAP00", $entry, $nsDisabledRole);
- if ( $ret == 0 ){
- if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ){
- # indirect lock
- out("$entry already $state through $throughRole.\n");
- } else {
- # direct lock
- out("$entry already $state.\n");
- }
+$skipManaged=$single;
+$skipDisabled=$role;
+
+$ret = indirectLock("LDAP00",$entry, $nsDisabledRole);
+if ( $ret == 0 ){
+ # indirectly locked
+ if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ){
+ out("$entry inactivated through $throughRole. Can not activate it individually.\n");
exit 100;
- } elsif ( $isLocked == 1 ){
- # the entry is not locked through a role, may be nsaccountlock is "hardcoded" ?
- out("$entry already $state (probably directly).\n");
- exit 103;
}
-} elsif ( $operation eq "activate" || $operation eq "get status of" ){
- $skipManaged=$single;
- $skipDisabled=$role;
-
- $ret=indirectLock("LDAP00",$entry, $nsDisabledRole);
-
- if ( $ret == 0 ){
- # undirectly locked
- if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ){
- if ( $operation eq "activate" ){
- out("$entry inactivated through $throughRole. Can not activate it individually.\n");
+ debug("$entry locked individually\n");
+} elsif ( $directLocked == 0 ){
+ if ( $isLocked != 1 ){
+ # The user is not "inactivated", but we need to check for account
+ # inactivity before saying the account is actually active
+ if($acct_policy_enabled){
+ #
+ # Now check the Acount Policy Plugin inactivity limits
+ #
+ my $logintime;
+ if ($lastlogintime ne ""){
+ $logintime = $lastlogintime;
+ } else {
+ $logintime = $altlogintime;
+ }
+ if(checkForInactivity($logintime, $limit) == 0){
+ # The user truly is active
+ out("$entry $already $state.\n");
exit 100;
- } else {
- out("$entry inactivated through $throughRole.\n");
- exit 104;
}
+ $inactiveLocked = 1;
}
- debug("$entry locked individually\n");
+ }
+}
+# else Locked directly, just unlock it!
+debug("$entry locked individually\n");
- if ( $operation ne "activate" ){
- out("$entry inactivated.\n");
- exit 103;
- }
- } elsif ( $directLocked == 0 ){
- if ( $operation eq "activate" && $isLocked != 1 ){
- out("$entry $already $state.\n");
- exit 100;
- } elsif ( $isLocked != 1 ) {
- out("$entry $already $state.\n");
- exit 102;
- } else {
- # not locked using our schema, but nsaccountlock is probably present
- out("$entry inactivated (probably directly).\n");
- exit 103;
- }
- } elsif ( $operation ne "activate" ){
- out("$entry inactivated.\n");
- exit 103;
+if($inactiveLocked == 0 and $acct_policy_enabled){
+ #
+ # Now check the Acount Policy Plugin inactivity limits
+ #
+ my $logintime;
+ if ($lastlogintime ne ""){
+ $logintime = $lastlogintime;
+ } else {
+ $logintime = $altlogintime;
+ }
+ if(checkForInactivity($logintime, $limit)){
+ $inactiveLocked = 1;
}
- # else Locked directly, juste unlock it!
- debug("$entry locked individually\n");
}
#
-# Inactivate/activate the entry
+# Activate the entry
#
if ( $single == 1 ){
- $record = "dn: $entry\n" . "changetype: modify\n" . "$modrole: nsRoleDN\n" . "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n";
+ $record = "dn: $entry\n" . "changetype: modify\n";
+ if ($isLocked or $directLocked){
+ # Remove the role
+ $record = $record . "delete: nsRoleDN\n" . "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n-\n";
+ }
+ if ($inactiveLocked) {
+ # Reset the lastlogintime to active the user
+ my $newlogintime = strftime "%Y%m%d%H%M%SZ", gmtime;
+ $record = $record . "replace: lastlogintime\n" . "lastlogintime: " . $newlogintime . "\n";
+ }
} else {
- $record = "dn: cn=nsDisabledRole,@suffixN\n" . "changetype: modify\n" . "$modrole: nsRoleDN\n" . "nsRoleDN: $entry\n";
+ $record = "dn: cn=nsDisabledRole,@suffixN\n" . "changetype: modify\n" . "delete: nsRoleDN\n" . "nsRoleDN: $entry\n";
}
$info{args} = "-c";
DSUtil::ldapmod($record, %info);
if( $? != 0 ){
- debug("$modrole, $entry\n");
+ debug("delete, $entry\n");
$retCode=$?>>8;
exit $retCode;
}
diff --git a/ldap/admin/src/scripts/ns-inactivate.pl.in b/ldap/admin/src/scripts/ns-inactivate.pl.in
index 659a5d5..af7e09b 100644
--- a/ldap/admin/src/scripts/ns-inactivate.pl.in
+++ b/ldap/admin/src/scripts/ns-inactivate.pl.in
@@ -12,6 +12,7 @@
use lib qw(@perlpath@);
use DSUtil;
+use File::Spec;
DSUtil::libpath_add("@nss_libdir@");
DSUtil::libpath_add("/usr/lib");
@@ -27,8 +28,8 @@ $role = 0;
sub usage
{
- print (STDERR "$cmd [-Z serverID] [-D rootdn] { -w password | -w - | -j filename } \n");
- print (STDERR " [-p port] [-h host] [-P] -I DN-to-$operation\n\n");
+ print (STDERR "ns-inactivate.pl [-Z serverID] [-D rootdn] { -w password | -w - | -j filename } \n");
+ print (STDERR " [-p port] [-h host] [-P] -I DN-to-inactivate\n\n");
print (STDERR "May be used to $operation a user or a domain of users\n\n");
print (STDERR "Arguments:\n");
print (STDERR " -? - Display usage\n");
@@ -40,7 +41,7 @@ sub usage
print (STDERR " -p port - Provide a port\n");
print (STDERR " -h host - Provide a host name\n");
print (STDERR " -P protocol - STARTTLS, LDAPS, LDAPI, LDAP (default: uses most secure protocol available)\n");
- print (STDERR " -I DN-to-$operation - Single entry DN or role DN to $operation\n");
+ print (STDERR " -I DN-to-inactivate - Single entry DN or role DN to inactivate\n");
}
sub debug
@@ -325,32 +326,10 @@ sub checkScope
# Generated variable
-# Determine which command we are running
-if ( $0 =~ /ns-inactivate(.pl)?$/ ){
- $cmd="ns-inactivate.pl";
- $operation="inactivate";
- $state="inactivated";
- $modrole="add";
- $already="already";
-} elsif ( $0 =~ /ns-activate(.pl)?$/ ){
- $cmd="ns-activate.pl";
- $operation="activate";
- $state="activated";
- $modrole="delete";
- $already="already";
-} elsif ( $0 =~ /ns-accountstatus(.pl)?$/ ){
- $cmd="ns-accountstatus.pl";
- $operation="get status of";
- $state="activated";
- # no need for $modrole as no operation is performed
- $already="";
-
-} else {
- out("$0: unknown command\n");
- exit 100;
-}
-
-debug("Running ** $cmd ** $operation\n");
+$cmd="ns-inactivate.pl";
+$state="inactivated";
+$modrole="add";
+$already="already";
# Process the command line arguments
while( $arg = shift)
@@ -537,59 +516,65 @@ if ( $cont == 2){
exit 100;
}
-if ( $operation eq "inactivate" ){
- #
- # Now that we have the suffix and we know if we deal with a single entry or
- # a role, just try to create the COS and roles associated.
- #
- $role1="dn: cn=nsManagedDisabledRole,@suffixN\n" .
- "objectclass: LDAPsubentry\n" .
- "objectclass: nsRoleDefinition\n" .
- "objectclass: nsSimpleRoleDefinition\n" .
- "objectclass: nsManagedRoleDefinition\n" .
- "cn: nsManagedDisabledRole\n\n";
- $role2="dn: cn=nsDisabledRole,@suffixN\n" .
- "objectclass: top\n" .
- "objectclass: LDAPsubentry\n" .
- "objectclass: nsRoleDefinition\n" .
- "objectclass: nsComplexRoleDefinition\n" .
- "objectclass: nsNestedRoleDefinition\n" .
- "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n" .
- "cn: nsDisabledRole\n\n";
- $cos1="dn: cn=nsAccountInactivationTmp,@suffixN\n" .
- "objectclass: top\n" .
- "objectclass: nsContainer\n\n";
- $cos2="dn: cn=\"cn=nsDisabledRole,@suffixN\",cn=nsAccountInactivationTmp,@suffixN\n" .
- "objectclass: top\n" .
- "objectclass: extensibleObject\n" .
- "objectclass: costemplate\n" .
- "objectclass: ldapsubentry\n" .
- "cosPriority: 1\n" .
- "nsAccountLock: true\n\n";
- $cos3="dn: cn=nsAccountInactivation_cos,@suffixN\n" .
- "objectclass: top\n" .
- "objectclass: LDAPsubentry\n" .
- "objectclass: cosSuperDefinition\n" .
- "objectclass: cosClassicDefinition\n" .
- "cosTemplateDn: cn=nsAccountInactivationTmp,@suffixN\n" .
- "cosSpecifier: nsRole\n" .
- "cosAttribute: nsAccountLock operational\n\n";
- $all=$role1 . $role2 . $cos1 . $cos2 . $cos3;
-
- $info{args} = "-c -a";
- DSUtil::ldapmod($all, %info);
- if ( $? != 0 ){
- $retCode=$?>>8;
- if ( $retCode == 68 ){
- debug("Entry already exists, ignore error\n");
- } else {
- # Probably a more serious problem.
- # Exit with LDAP error
- exit $retCode;
- }
+#
+# Now that we have the suffix and we know if we deal with a single entry or
+# a role, just try to create the COS and roles associated.
+#
+$role1="dn: cn=nsManagedDisabledRole,@suffixN\n" .
+ "objectclass: LDAPsubentry\n" .
+ "objectclass: nsRoleDefinition\n" .
+ "objectclass: nsSimpleRoleDefinition\n" .
+ "objectclass: nsManagedRoleDefinition\n" .
+ "cn: nsManagedDisabledRole\n\n";
+$role2="dn: cn=nsDisabledRole,@suffixN\n" .
+ "objectclass: top\n" .
+ "objectclass: LDAPsubentry\n" .
+ "objectclass: nsRoleDefinition\n" .
+ "objectclass: nsComplexRoleDefinition\n" .
+ "objectclass: nsNestedRoleDefinition\n" .
+ "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n" .
+ "cn: nsDisabledRole\n\n";
+$cos1="dn: cn=nsAccountInactivationTmp,@suffixN\n" .
+ "objectclass: top\n" .
+ "objectclass: nsContainer\n\n";
+$cos2="dn: cn=\"cn=nsDisabledRole,@suffixN\",cn=nsAccountInactivationTmp,@suffixN\n" .
+ "objectclass: top\n" .
+ "objectclass: extensibleObject\n" .
+ "objectclass: costemplate\n" .
+ "objectclass: ldapsubentry\n" .
+ "cosPriority: 1\n" .
+ "nsAccountLock: true\n\n";
+$cos3="dn: cn=nsAccountInactivation_cos,@suffixN\n" .
+ "objectclass: top\n" .
+ "objectclass: LDAPsubentry\n" .
+ "objectclass: cosSuperDefinition\n" .
+ "objectclass: cosClassicDefinition\n" .
+ "cosTemplateDn: cn=nsAccountInactivationTmp,@suffixN\n" .
+ "cosSpecifier: nsRole\n" .
+ "cosAttribute: nsAccountLock operational\n\n";
+$all=$role1 . $role2 . $cos1 . $cos2 . $cos3;
+
+# Turn off stderr for now to stop error 68's from printing during the ldapmod
+open my $saveout, ">&STDERR";
+open STDERR, '>', File::Spec->devnull();
+
+$info{args} = "-c -a";
+DSUtil::ldapmod($all, %info);
+
+# Turn STDERR back on
+open STDERR, ">&", $saveout;
+
+if ( $? != 0 ){
+ $retCode=$?>>8;
+ if ( $retCode == 68 ){
+ debug("Entry already exists, ignore error\n");
} else {
- debug("Roles/cos entries created\n");
+ # Probably a more serious problem.
+ # Exit with LDAP error
+ exit $retCode;
}
+} else {
+ debug("Roles/cos entries created\n");
}
$skipManaged=0;
@@ -602,69 +587,26 @@ $nsDisabledRole=~ tr/A-Z/a-z/;
$nsManagedDisabledRole="cn=nsManagedDisabledRole,@suffixN";
$nsManagedDisabledRole=~ tr/A-Z/a-z/;
-if ( $operation eq "inactivate" ){
- # Go through all the roles part of nsdisabledrole to check if the entry
- # is a member of one of those roles
- $ret=indirectLock("LDAP00", $entry, $nsDisabledRole);
- if ( $ret == 0 ){
- if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ){
- # indirect lock
- out("$entry already $state through $throughRole.\n");
- } else {
- # direct lock
- out("$entry already $state.\n");
- }
- exit 100;
- } elsif ( $isLocked == 1 ){
- # the entry is not locked through a role, may be nsaccountlock is "hardcoded" ?
- out("$entry already $state (probably directly).\n");
- exit 103;
- }
-} elsif ( $operation eq "activate" || $operation eq "get status of" ){
- $skipManaged=$single;
- $skipDisabled=$role;
-
- $ret=indirectLock("LDAP00",$entry, $nsDisabledRole);
-
- if ( $ret == 0 ){
- # undirectly locked
- if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ){
- if ( $operation eq "activate" ){
- out("$entry inactivated through $throughRole. Can not activate it individually.\n");
- exit 100;
- } else {
- out("$entry inactivated through $throughRole.\n");
- exit 104;
- }
- }
- debug("$entry locked individually\n");
-
- if ( $operation ne "activate" ){
- out("$entry inactivated.\n");
- exit 103;
- }
- } elsif ( $directLocked == 0 ){
- if ( $operation eq "activate" && $isLocked != 1 ){
- out("$entry $already $state.\n");
- exit 100;
- } elsif ( $isLocked != 1 ){
- out("$entry $already $state.\n");
- exit 102;
- } else {
- # not locked using our schema, but nsaccountlock is probably present
- out("$entry inactivated (probably directly).\n");
- exit 103;
- }
- } elsif ( $operation ne "activate" ){
- out("$entry inactivated.\n");
- exit 103;
+# Go through all the roles part of nsdisabledrole to check if the entry
+# is a member of one of those roles
+$ret = indirectLock("LDAP00", $entry, $nsDisabledRole);
+if ( $ret == 0 ){
+ if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ){
+ # indirect lock
+ out("$entry already $state through $throughRole.\n");
+ } else {
+ # direct lock
+ out("$entry already $state.\n");
}
- # else Locked directly, juste unlock it!
- debug("$entry locked individually\n");
+ exit 100;
+} elsif ( $isLocked == 1 ){
+ # the entry is not locked through a role, may be nsaccountlock is "hardcoded" ?
+ out("$entry already $state (probably directly).\n");
+ exit 103;
}
#
-# Inactivate/activate the entry
+# Inactivate the entry
#
if ( $single == 1 ){
$record = "dn: $entry\n" . "changetype: modify\n" . "$modrole: nsRoleDN\n" . "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n";
diff --git a/man/man8/ns-accountstatus.pl.8 b/man/man8/ns-accountstatus.pl.8
index 821b71f..be3a8e9 100644
--- a/man/man8/ns-accountstatus.pl.8
+++ b/man/man8/ns-accountstatus.pl.8
@@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
-.TH NS-ACCOUNTSTATUS.PL 8 "Mar 5, 2013"
+.TH NS-ACCOUNTSTATUS.PL 8 "Feb 8, 2016"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@@ -18,7 +18,8 @@
.SH NAME
ns-accountstatus.pl - Directory Server perl script for checking the status of entries.
.SH SYNOPSIS
-ns-accountstatus.pl [\-Z serverID] [\-D rootdn] { \-w password | \-w \- | \-j filename } [\-p port] [\-h host] [\-P protocol] \-I DN
+ns-accountstatus.pl [\-Z serverID] [\-D rootdn] { \-w password | \-w \- | \-j filename } [\-p port] [\-h host] [\-P protocol] {\-I DN |
+ \-b basedn \-f filter [\-s scope]} [\-i] [\-g seconds]
.SH DESCRIPTION
Provides account status information to establish whether an entry or group of entries is inactivated.
.SH OPTIONS
@@ -55,12 +56,38 @@ Host name of the Directory Server.
.TP
.B \fB\-p\fR \fIport\fR
Port number of the Directory Server.
+.TP
+.B \fB\-p\fR \fIport\fR
+Port number of the Directory Server.
+.TP
+.B \fB\-p\fR \fIport\fR
+Port number of the Directory Server.
+.TP
+.B \fB\-b\fR \fIbasedn\fR
+The suffix DN from which to search from.
+.TP
+.B \fB\-f\fR \fIfilter\fR
+The search filter used to find user entries.
+.TP
+.B \fB\-s\fR \fIscope\fR
+The search scope. "base", "one, "sub". Default is "sub"
+.TP
+.B \fB\-i\fR
+.br
+Only list entries that are inactivated.
+.TP
+.B \fB\-g\fR \fIseconds\fR
+Only display entries that will become inactive within the timeframe.
+
.SH EXAMPLE
.TP
ns-accountstatus.pl \-Z instance3 \-D 'cn=directory manager' \-w password \-I 'uid=user,ou=people,dc=example,dc=com'
.TP
+ns-accountstatus.pl \-Z instance3 \-D 'cn=directory manager' \-w password \-b 'dc=example,dc=com' \-f "(uid=*)"
+.TP
+ns-accountstatus.pl \-Z instance3 \-D 'cn=directory manager' \-w password \-b 'dc=example,dc=com' \-f "(uid=*)" -g 86400
+.TP
ns-accountstatus.pl \-w password \-I 'uid=user,ou=people,dc=example,dc=com' \-P STARTTLS
-
Note: security must be enabled to use protocol STARTTLS. If STARTTLS is not available it will default to next strongest/available protocol automatically.
.SH DIAGNOSTICS
Exit status is zero if no errors occur. Errors result in a
@@ -71,4 +98,4 @@ ns-accountstatus.pl was written by the 389 Project.
.SH "REPORTING BUGS"
Report bugs to https://fedorahosted.org/389/newticket.
.SH COPYRIGHT
-Copyright \(co 2013 Red Hat, Inc.
+Copyright \(co 2016 Red Hat, Inc.
8 years, 2 months
dirsrvtests/tickets
by thierry bordaz
dirsrvtests/tickets/ticket48270_test.py | 177 ++++++++++++++++++++++++++++++++
1 file changed, 177 insertions(+)
New commits:
commit e033d4b3fff788dcb94957a07fcaf78171499ddf
Author: Thierry Bordaz <tbordaz(a)redhat.com>
Date: Mon Feb 8 15:04:33 2016 +0100
Ticket 48270: test case
diff --git a/dirsrvtests/tickets/ticket48270_test.py b/dirsrvtests/tickets/ticket48270_test.py
new file mode 100644
index 0000000..a1822f2
--- /dev/null
+++ b/dirsrvtests/tickets/ticket48270_test.py
@@ -0,0 +1,177 @@
+import os
+import sys
+import time
+import ldap
+import logging
+#import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from lib389.utils import *
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+installation1_prefix = None
+
+NEW_ACCOUNT = "new_account"
+MAX_ACCOUNTS = 20
+
+MIXED_VALUE="/home/mYhOmEdIrEcToRy"
+LOWER_VALUE="/home/myhomedirectory"
+HOMEDIRECTORY_INDEX = 'cn=homeDirectory,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config'
+HOMEDIRECTORY_CN="homedirectory"
+MATCHINGRULE = 'nsMatchingRule'
+UIDNUMBER_INDEX = 'cn=uidnumber,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config'
+UIDNUMBER_CN="uidnumber"
+
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+#(a)pytest.fixture(scope="module")
+def topology(request):
+ global installation1_prefix
+ if installation1_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+
+ # Creating standalone instance ...
+ standalone = DirSrv(verbose=False)
+ if installation1_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+ instance_standalone = standalone.exists()
+ if instance_standalone:
+ standalone.delete()
+ standalone.create()
+ standalone.open()
+
+ # Delete each instance in the end
+ def fin():
+ standalone.delete()
+ #request.addfinalizer(fin)
+
+ # Clear out the tmp dir
+ standalone.clearTmpDir(__file__)
+
+ return TopologyStandalone(standalone)
+
+def test_ticket48270_init(topology):
+ log.info("Initialization: add dummy entries for the tests")
+ for cpt in range(MAX_ACCOUNTS):
+ name = "%s%d" % (NEW_ACCOUNT, cpt)
+ topology.standalone.add_s(Entry(("uid=%s,%s" % (name, SUFFIX), {
+ 'objectclass': "top posixAccount".split(),
+ 'uid': name,
+ 'cn': name,
+ 'uidnumber': str(111),
+ 'gidnumber': str(222),
+ 'homedirectory': "/home/tbordaz_%d" % cpt})))
+
+
+def test_ticket48270_homeDirectory_indexed_cis(topology):
+ log.info("\n\nindex homeDirectory in caseIgnoreIA5Match and caseExactIA5Match")
+ try:
+ ent = topology.standalone.getEntry(HOMEDIRECTORY_INDEX, ldap.SCOPE_BASE)
+ except ldap.NO_SUCH_OBJECT:
+ topology.standalone.add_s(Entry((HOMEDIRECTORY_INDEX, {
+ 'objectclass': "top nsIndex".split(),
+ 'cn': HOMEDIRECTORY_CN,
+ 'nsSystemIndex': 'false',
+ 'nsIndexType': 'eq'})))
+ #log.info("attach debugger")
+ #time.sleep(60)
+
+ IGNORE_MR_NAME='caseIgnoreIA5Match'
+ EXACT_MR_NAME='caseExactIA5Match'
+ mod = [(ldap.MOD_REPLACE, MATCHINGRULE, (IGNORE_MR_NAME, EXACT_MR_NAME))]
+ topology.standalone.modify_s(HOMEDIRECTORY_INDEX, mod)
+
+ #topology.standalone.stop(timeout=10)
+ log.info("successfully checked that filter with exact mr , a filter with lowercase eq is failing")
+ #assert topology.standalone.db2index(bename=DEFAULT_BENAME, suffixes=None, attrs=['homeDirectory'])
+ #topology.standalone.start(timeout=10)
+ args = {TASK_WAIT: True}
+ topology.standalone.tasks.reindex(suffix=SUFFIX, attrname='homeDirectory', args=args)
+
+ log.info("Check indexing succeeded with a specified matching rule")
+ file_path = os.path.join(topology.standalone.prefix, "var/log/dirsrv/slapd-%s/errors" % topology.standalone.serverid)
+ file_obj = open(file_path, "r")
+
+ # Check if the MR configuration failure occurs
+ regex = re.compile("unknown or invalid matching rule")
+ while True:
+ line = file_obj.readline()
+ found = regex.search(line)
+ if ((line == '') or (found)):
+ break
+
+ if (found):
+ log.info("The configuration of a specific MR fails")
+ log.info(line)
+ #assert not found
+
+def test_ticket48270_homeDirectory_mixed_value(topology):
+ # Set a homedirectory value with mixed case
+ name = "uid=%s1,%s" % (NEW_ACCOUNT, SUFFIX)
+ mod = [(ldap.MOD_REPLACE, 'homeDirectory', MIXED_VALUE)]
+ topology.standalone.modify_s(name, mod)
+
+def test_ticket48270_extensible_search(topology):
+ name = "uid=%s1,%s" % (NEW_ACCOUNT, SUFFIX)
+
+ # check with the exact stored value
+ log.info("Default: can retrieve an entry filter syntax with exact stored value")
+ ent = topology.standalone.getEntry(name, ldap.SCOPE_BASE, "(homeDirectory=%s)" % MIXED_VALUE)
+ log.info("Default: can retrieve an entry filter caseExactIA5Match with exact stored value")
+ ent = topology.standalone.getEntry(name, ldap.SCOPE_BASE, "(homeDirectory:caseExactIA5Match:=%s)" % MIXED_VALUE)
+
+ # check with a lower case value that is different from the stored value
+ log.info("Default: can not retrieve an entry filter syntax match with lowered stored value")
+ try:
+ ent = topology.standalone.getEntry(name, ldap.SCOPE_BASE, "(homeDirectory=%s)" % LOWER_VALUE)
+ assert ent is None
+ except ldap.NO_SUCH_OBJECT:
+ pass
+ log.info("Default: can not retrieve an entry filter caseExactIA5Match with lowered stored value")
+ try:
+ ent = topology.standalone.getEntry(name, ldap.SCOPE_BASE, "(homeDirectory:caseExactIA5Match:=%s)" % LOWER_VALUE)
+ assert ent is None
+ except ldap.NO_SUCH_OBJECT:
+ pass
+ log.info("Default: can retrieve an entry filter caseIgnoreIA5Match with lowered stored value")
+ ent = topology.standalone.getEntry(name, ldap.SCOPE_BASE, "(homeDirectory:caseIgnoreIA5Match:=%s)" % LOWER_VALUE)
+
+def test_ticket48270(topology):
+ """Write your testcase here...
+
+ Also, if you need any testcase initialization,
+ please, write additional fixture for that(include finalizer).
+ """
+
+ log.info('Test complete')
+
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ global installation1_prefix
+ installation1_prefix = '/home/tbordaz/install_master'
+ topo = topology(True)
+ test_ticket48270_init(topo)
+ test_ticket48270_homeDirectory_indexed_cis(topo)
+ test_ticket48270_homeDirectory_mixed_value(topo)
+ test_ticket48270_extensible_search(topo)
+
+# CURRENT_FILE = os.path.realpath(__file__)
+# pytest.main("-s %s" % CURRENT_FILE)
\ No newline at end of file
8 years, 2 months
ldap/servers
by thierry bordaz
ldap/servers/slapd/plugin_mr.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
New commits:
commit 375288632674fced396304f3abf8c9c55b04b6b1
Author: Thierry Bordaz <tbordaz(a)redhat.com>
Date: Fri Feb 5 15:10:42 2016 +0100
Ticket 48270: fail to index an attribute with a specific matching rule
Bug Description:
During index configuration, if a new rule type matching rule is added
(attribute 'nsMatchingRule') it creates an indexer.
If the indexer was not already registered (plugin_mr_bind),
In a first step it tries to find/call, for the specified matching rule, an indexer_create callback of
all the registered matching rule plugins .
If no indexer_create function exist or match the specified matching rule, then it tries to find
a registered matching rule plugins that matches the specified matching rule (plg_mr_names).
The problem occurs in the first step, because it uses 'rc' for intermediate returned code and
can erronously believe the first step was successful although no indexer_create was found.
So it skips the second step and no matching rule plugin is found.
Fix Description:
The fix consist to avoid using the 'rc' return code in intermediate slapi-pblock-get/set
https://fedorahosted.org/389/ticket/48270
Reviewed by: Noriko Hosoi (Thank you sooo much Noriko !!)
Platforms tested: F17
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/slapd/plugin_mr.c b/ldap/servers/slapd/plugin_mr.c
index 39639e9..d25fca9 100644
--- a/ldap/servers/slapd/plugin_mr.c
+++ b/ldap/servers/slapd/plugin_mr.c
@@ -170,22 +170,25 @@ slapi_mr_indexer_create (Slapi_PBlock* opb)
for (mrp = get_plugin_list(PLUGIN_LIST_MATCHINGRULE); mrp != NULL; mrp = mrp->plg_next)
{
IFP indexFn = NULL;
+ IFP indexSvFn = NULL;
Slapi_PBlock pb;
memcpy (&pb, opb, sizeof(Slapi_PBlock));
- if (!(rc = slapi_pblock_set (&pb, SLAPI_PLUGIN, mrp)) &&
- !(rc = slapi_pblock_get (&pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) &&
- createFn != NULL &&
- !(rc = createFn (&pb)) &&
- ((!(rc = slapi_pblock_get (&pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn)) &&
- indexFn != NULL) ||
- (!(rc = slapi_pblock_get (&pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexFn)) &&
- indexFn != NULL)))
- {
- /* Success: this plugin can handle it. */
- memcpy (opb, &pb, sizeof(Slapi_PBlock));
- plugin_mr_bind (oid, mrp); /* for future reference */
- rc = 0; /* success */
- break;
+ slapi_pblock_set(&pb, SLAPI_PLUGIN, mrp);
+ if (slapi_pblock_get(&pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) {
+ /* plugin not a matchingrule type */
+ continue;
+ }
+ if (createFn && !createFn(&pb)) {
+ slapi_pblock_get(&pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn);
+ slapi_pblock_get(&pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn);
+ if (indexFn || indexSvFn) {
+ /* Success: this plugin can handle it. */
+ memcpy(opb, &pb, sizeof (Slapi_PBlock));
+ plugin_mr_bind(oid, mrp); /* for future reference */
+ rc = 0; /* success */
+ break;
+ }
+
}
}
if (rc != 0) {
8 years, 2 months
ldap/servers
by Noriko Hosoi
ldap/servers/slapd/features.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 0cf249e9e497caa05f3abc5f4e8090c1df91ccab
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Sun Feb 7 16:08:56 2016 -0800
Ticket 48363 - Support for rfc3673 '+' to return operational attributes
Description: commit 08c40e8a35a3611a0ac3ca30a86d40a17676ba84 had a copy&
paste error. Replacing slapi_rwlock_unlock with slapi_rwlock_rdlock.
diff --git a/ldap/servers/slapd/features.c b/ldap/servers/slapd/features.c
index 64a2825..a4e8872 100644
--- a/ldap/servers/slapd/features.c
+++ b/ldap/servers/slapd/features.c
@@ -44,7 +44,7 @@ slapi_register_supported_feature( char *featureoid )
int
slapi_get_supported_features_copy( char ***ftroidsp )
{
- slapi_rwlock_unlock(supported_features_lock);
+ slapi_rwlock_rdlock(supported_features_lock);
if ( ftroidsp != NULL ) {
*ftroidsp = charray_dup(supported_features);
}
8 years, 2 months
wrappers/systemd.template.service.in
by William Brown
wrappers/systemd.template.service.in | 4 ++++
1 file changed, 4 insertions(+)
New commits:
commit 4e39b5bd17f1e1a306496e0bbb51943fc665186d
Author: William Brown <firstyear(a)redhat.com>
Date: Mon Jan 25 14:51:45 2016 +1000
Ticket 48147 - Install section for dirsrv@.service template
Bug Description: The commands systemctl enable dirsrv(a)inst.service do not
currently operate. This is because of a missing Install section
Fix Description: Add the install section to the .service template.
https://fedorahosted.org/389/ticket/48147
Author: wibrown
Review by: mreynolds (thanks!)
diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in
index 9432cb0..f0aa287 100644
--- a/wrappers/systemd.template.service.in
+++ b/wrappers/systemd.template.service.in
@@ -26,3 +26,7 @@ ExecStopPost=/bin/rm -f @localstatedir@/run/@package_name(a)/slapd-%i.pid
# if you need to set other directives e.g. LimitNOFILE=8192
# set them in this file
.include @initconfigdir@/@package_name@.systemd
+
+[Install]
+WantedBy=dirsrv.target
+
8 years, 2 months
2 commits - dirsrvtests/tickets ldap/servers
by Noriko Hosoi
dirsrvtests/tickets/ticket48295_test.py | 212 ++++++++++++++++++++++++
ldap/servers/plugins/linkedattrs/linked_attrs.c | 20 ++
2 files changed, 232 insertions(+)
New commits:
commit 63b8ecee2d6d24c5de5d7b826a5bb47bc83ee45d
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Mon Dec 21 17:27:06 2015 -0800
Ticket #48295 - CI test: added test cases for ticket 48295
Description: Entry cache is not rolled back -- Linked Attributes
plug-in - wrong behaviour when adding valid and broken links
diff --git a/dirsrvtests/tickets/ticket48295_test.py b/dirsrvtests/tickets/ticket48295_test.py
new file mode 100644
index 0000000..13a7f88
--- /dev/null
+++ b/dirsrvtests/tickets/ticket48295_test.py
@@ -0,0 +1,212 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import os
+import sys
+import time
+import ldap
+import logging
+import pytest
+import shutil
+from lib389 import DirSrv, Entry, tools
+from lib389 import DirSrvTools
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+
+log = logging.getLogger(__name__)
+
+installation_prefix = None
+
+LINKEDATTR_PLUGIN = 'cn=Linked Attributes,cn=plugins,cn=config'
+MANAGER_LINK = 'cn=Manager Link,' + LINKEDATTR_PLUGIN
+OU_PEOPLE = 'ou=People,' + DEFAULT_SUFFIX
+LINKTYPE = 'directReport'
+MANAGEDTYPE = 'manager'
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+(a)pytest.fixture(scope="module")
+def topology(request):
+ '''
+ This fixture is used to standalone topology for the 'module'.
+ '''
+ global installation_prefix
+
+ if installation_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation_prefix
+
+ standalone = DirSrv(verbose=False)
+
+ # Args for the standalone instance
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+
+ # Get the status of the instance and restart it if it exists
+ instance_standalone = standalone.exists()
+
+ # Remove the instance
+ if instance_standalone:
+ standalone.delete()
+
+ # Create the instance
+ standalone.create()
+
+ # Used to retrieve configuration information (dbdir, confdir...)
+ standalone.open()
+
+ # clear the tmp directory
+ standalone.clearTmpDir(__file__)
+
+ # Here we have standalone instance up and running
+ return TopologyStandalone(standalone)
+
+
+def _header(topology, label):
+ topology.standalone.log.info("###############################################")
+ topology.standalone.log.info("####### %s" % label)
+ topology.standalone.log.info("###############################################")
+
+def check_attr_val(topology, dn, attr, expected, revert):
+ try:
+ centry = topology.standalone.search_s(dn, ldap.SCOPE_BASE, 'uid=*')
+ if centry:
+ val = centry[0].getValue(attr)
+ if val:
+ if val.lower() == expected.lower():
+ if revert:
+ log.info('Value of %s %s exists, which should not.' % (attr, expected))
+ assert False
+ else:
+ log.info('Value of %s is %s' % (attr, expected))
+ else:
+ if revert:
+ log.info('NEEDINFO: Value of %s is not %s, but %s' % (attr, expected, val))
+ else:
+ log.info('Value of %s is not %s, but %s' % (attr, expected, val))
+ assert False
+ else:
+ if revert:
+ log.info('Value of %s does not expectedly exist' % attr)
+ else:
+ log.info('Value of %s does not exist' % attr)
+ assert False
+ else:
+ log.fatal('Failed to get %s' % dn)
+ assert False
+ except ldap.LDAPError as e:
+ log.fatal('Failed to search ' + dn + ': ' + e.message['desc'])
+ assert False
+
+
+def _48295_init(topology):
+ """
+ Set up Linked Attribute
+ """
+ _header(topology, 'Testing Ticket 48295 - Entry cache is not rolled back -- Linked Attributes plug-in - wrong behaviour when adding valid and broken links')
+
+ log.info('Enable Dynamic plugins, and the linked Attrs plugin')
+ try:
+ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-dynamic-plugins', 'on')])
+ except ldap.LDAPError as e:
+ ldap.fatal('Failed to enable dynamic plugin!' + e.message['desc'])
+ assert False
+
+ try:
+ topology.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)
+ except ValueError as e:
+ ldap.fatal('Failed to enable linked attributes plugin!' + e.message['desc'])
+ assert False
+
+ log.info('Add the plugin config entry')
+ try:
+ topology.standalone.add_s(Entry((MANAGER_LINK, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'Manager Link',
+ 'linkType': LINKTYPE,
+ 'managedType': MANAGEDTYPE
+ })))
+ except ldap.LDAPError as e:
+ log.fatal('Failed to add linked attr config entry: error ' + e.message['desc'])
+ assert False
+
+ log.info('Add 2 entries: manager1 and employee1')
+ try:
+ topology.standalone.add_s(Entry(('uid=manager1,%s' % OU_PEOPLE, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'manager1'})))
+ except ldap.LDAPError as e:
+ log.fatal('Add manager1 failed: error ' + e.message['desc'])
+ assert False
+
+ try:
+ topology.standalone.add_s(Entry(('uid=employee1,%s' % OU_PEOPLE, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'employee1'})))
+ except ldap.LDAPError as e:
+ log.fatal('Add employee1 failed: error ' + e.message['desc'])
+ assert False
+
+ log.info('PASSED')
+
+
+def _48295_run(topology):
+ """
+ Add 2 linktypes - one exists, another does not
+ """
+
+ _header(topology, 'Add 2 linktypes to manager1 - one exists, another does not to make sure the managed entry does not have managed type.')
+ try:
+ topology.standalone.modify_s('uid=manager1,%s' % OU_PEOPLE,
+ [(ldap.MOD_ADD, LINKTYPE, 'uid=employee1,%s' % OU_PEOPLE),
+ (ldap.MOD_ADD, LINKTYPE, 'uid=doNotExist,%s' % OU_PEOPLE)])
+ except ldap.UNWILLING_TO_PERFORM:
+ log.info('Add uid=employee1 and uid=doNotExist expectedly failed.')
+ pass
+
+ log.info('Check managed attribute does not exist.')
+ check_attr_val(topology, 'uid=employee1,%s' % OU_PEOPLE, MANAGEDTYPE, 'uid=manager1,%s' % OU_PEOPLE, True)
+
+ log.info('PASSED')
+
+
+def _48295_final(topology):
+ topology.standalone.delete()
+ log.info('All PASSED')
+
+
+def test_ticket48295(topology):
+ '''
+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
+ To run isolated without py.test, you need to
+ - edit this file and comment '@pytest.fixture' line before 'topology' function.
+ - set the installation prefix
+ - run this program
+ '''
+ global installation_prefix
+ installation_prefix = None
+
+ _48295_init(topology)
+
+ _48295_run(topology)
+
+ _48295_final(topology)
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
commit 088ddec90957ca2ef7a1c072f8fe834eabf46298
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Mon Dec 21 16:33:34 2015 -0800
Ticket #48295 - Entry cache is not rolled back -- Linked Attributes plug-in - wrong behaviour when adding valid and broken links
Bug Description: When multiple link attribute values are added or deleted
and if some of the op was successfully and one fails, the succeeded operation's
managed type appears in the managed entry although all of the link attribute
operation were rolled back. The managed type indeed does not exist in the
managed entry. That just in the entry cache. Once the server is restarted
the changes disappear.
Fix Description: If the first link attribute value operation fails, it stops
the operation and returns the failure. If the second or the later operation
fails, the succeeded operation up to the previous one are reverted.
https://fedorahosted.org/389/ticket/48295
Reviewed by mreynolds(a)redhat.com (Thank you, Mark!!)
diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.c b/ldap/servers/plugins/linkedattrs/linked_attrs.c
index 0d07a1f..27af287 100644
--- a/ldap/servers/plugins/linkedattrs/linked_attrs.c
+++ b/ldap/servers/plugins/linkedattrs/linked_attrs.c
@@ -1474,6 +1474,9 @@ linked_attrs_mod_backpointers(Slapi_PBlock *pb, char *linkdn, char *type,
} else if (rc != LDAP_SUCCESS) {
char *err_msg = NULL;
+ slapi_log_error(SLAPI_LOG_FATAL, LINK_PLUGIN_SUBSYSTEM,
+ "Linked Attrs Plugin: Failed to update link to target entry (%s) error %d",
+ targetdn, rc);
err_msg = PR_smprintf("Linked Attrs Plugin: Failed to update "
"link to target entry (%s) error %d",
targetdn, rc);
@@ -1481,6 +1484,23 @@ linked_attrs_mod_backpointers(Slapi_PBlock *pb, char *linkdn, char *type,
slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, err_msg);
PR_smprintf_free(err_msg);
slapi_sdn_free(&targetsdn);
+ if (i > 0) {
+ int j;
+ Slapi_ValueSet *undoVals = slapi_valueset_new();
+ /* undo 0..i-1 */
+ j = slapi_valueset_first_value(targetvals, &targetval);
+ do {
+ slapi_valueset_add_value(undoVals, targetval);
+ j = slapi_valueset_next_value(targetvals, j, &targetval);
+ } while (j < i);
+ if (LDAP_MOD_DELETE == modop) {
+ modop = LDAP_MOD_ADD;
+ } else {
+ modop = LDAP_MOD_DELETE;
+ }
+ rc = linked_attrs_mod_backpointers(pb, linkdn, type, scope, modop, undoVals);
+ slapi_valueset_free(undoVals);
+ }
rc = LDAP_UNWILLING_TO_PERFORM;
break;
}
8 years, 2 months
aclocal.m4 config.h.in configure dirsrvtests/create_test.py dirsrvtests/tickets ldap/servers Makefile.am Makefile.in
by William Brown
Makefile.am | 1
Makefile.in | 71 ++++-----
aclocal.m4 | 209 ++++++++--------------------
config.h.in | 3
configure | 238 +++++++++++++++++---------------
dirsrvtests/create_test.py | 12 -
dirsrvtests/tickets/ticket48363_test.py | 206 +++++++++++++++++++++++++++
ldap/servers/slapd/features.c | 54 +++++++
ldap/servers/slapd/main.c | 5
ldap/servers/slapd/proto-slap.h | 5
ldap/servers/slapd/result.c | 31 ++--
ldap/servers/slapd/rootdse.c | 13 +
ldap/servers/slapd/slapi-plugin.h | 21 ++
13 files changed, 560 insertions(+), 309 deletions(-)
New commits:
commit 08c40e8a35a3611a0ac3ca30a86d40a17676ba84
Author: William Brown <firstyear(a)redhat.com>
Date: Fri Jan 8 09:47:44 2016 +1000
Ticket 48363 - Support for rfc3673 '+' to return operational attributes
Bug Description: We should support rfc3673 to return operational attributes
in searches.
Fix Description: We implement the '+' operator as per [0].
Additionally, we need to add "supportedFeatures" as per [1]. As a result, we
have implemented both rfcs now.
This can be shown by adding '+' to any search.
We also add a test case that proves '+' works, that '*' works, and specific
named attributes work also. Acis are also correctly respected by this change,
even for operational attributes.
[0] https://tools.ietf.org/html/rfc3673
[1] https://tools.ietf.org/html/rfc3674
https://fedorahosted.org/389/ticket/48363
Author: wibrown
Review by: nhosoi (Thanks! )
diff --git a/Makefile.am b/Makefile.am
index 9b19bd4..57b6b52 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -966,6 +966,7 @@ libslapd_la_SOURCES = ldap/servers/slapd/add.c \
ldap/servers/slapd/errormap.c \
ldap/servers/slapd/eventq.c \
ldap/servers/slapd/factory.c \
+ ldap/servers/slapd/features.c \
ldap/servers/slapd/fileio.c \
ldap/servers/slapd/filter.c \
ldap/servers/slapd/filtercmp.c \
diff --git a/Makefile.in b/Makefile.in
index 87ba2f9..a2042b9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -20,17 +20,7 @@
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -103,6 +93,12 @@ noinst_PROGRAMS = makstrdb$(EXEEXT)
@SOLARIS_TRUE@am__append_2 = -lrt
@SOLARIS_TRUE@am__append_3 = ldap/servers/slapd/tools/ldclt/opCheck.c
subdir = .
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(srcdir)/config.h.in $(top_srcdir)/rpm/389-ds-base.spec.in \
+ depcomp $(dist_man_MANS) $(dist_noinst_DATA) \
+ $(dist_noinst_HEADERS) $(serverinc_HEADERS) README compile \
+ config.guess config.sub install-sh missing ltmain.sh
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -117,9 +113,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/systemd.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
- $(am__configure_deps) $(dist_noinst_DATA) \
- $(dist_noinst_HEADERS) $(serverinc_HEADERS) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
@@ -737,8 +730,9 @@ am__libslapd_la_SOURCES_DIST = ldap/servers/slapd/add.c \
ldap/servers/slapd/dse.c ldap/servers/slapd/dynalib.c \
ldap/servers/slapd/entry.c ldap/servers/slapd/entrywsi.c \
ldap/servers/slapd/errormap.c ldap/servers/slapd/eventq.c \
- ldap/servers/slapd/factory.c ldap/servers/slapd/fileio.c \
- ldap/servers/slapd/filter.c ldap/servers/slapd/filtercmp.c \
+ ldap/servers/slapd/factory.c ldap/servers/slapd/features.c \
+ ldap/servers/slapd/fileio.c ldap/servers/slapd/filter.c \
+ ldap/servers/slapd/filtercmp.c \
ldap/servers/slapd/filterentry.c \
ldap/servers/slapd/generation.c \
ldap/servers/slapd/getfilelist.c \
@@ -809,6 +803,7 @@ am_libslapd_la_OBJECTS = ldap/servers/slapd/libslapd_la-add.lo \
ldap/servers/slapd/libslapd_la-errormap.lo \
ldap/servers/slapd/libslapd_la-eventq.lo \
ldap/servers/slapd/libslapd_la-factory.lo \
+ ldap/servers/slapd/libslapd_la-features.lo \
ldap/servers/slapd/libslapd_la-fileio.lo \
ldap/servers/slapd/libslapd_la-filter.lo \
ldap/servers/slapd/libslapd_la-filtercmp.lo \
@@ -1260,10 +1255,6 @@ ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
AM_RECURSIVE_TARGETS = cscope
-am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
- $(srcdir)/config.h.in $(top_srcdir)/rpm/389-ds-base.spec.in \
- README compile config.guess config.sub depcomp install-sh \
- ltmain.sh missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -2367,8 +2358,9 @@ libslapd_la_SOURCES = ldap/servers/slapd/add.c \
ldap/servers/slapd/dse.c ldap/servers/slapd/dynalib.c \
ldap/servers/slapd/entry.c ldap/servers/slapd/entrywsi.c \
ldap/servers/slapd/errormap.c ldap/servers/slapd/eventq.c \
- ldap/servers/slapd/factory.c ldap/servers/slapd/fileio.c \
- ldap/servers/slapd/filter.c ldap/servers/slapd/filtercmp.c \
+ ldap/servers/slapd/factory.c ldap/servers/slapd/features.c \
+ ldap/servers/slapd/fileio.c ldap/servers/slapd/filter.c \
+ ldap/servers/slapd/filtercmp.c \
ldap/servers/slapd/filterentry.c \
ldap/servers/slapd/generation.c \
ldap/servers/slapd/getfilelist.c \
@@ -3242,6 +3234,7 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -3262,8 +3255,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
config.h: stamp-h1
- @test -f $@ || rm -f stamp-h1
- @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+ @if test ! -f $@; then rm -f stamp-h1; else :; fi
+ @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
@@ -4585,6 +4578,9 @@ ldap/servers/slapd/libslapd_la-eventq.lo: \
ldap/servers/slapd/libslapd_la-factory.lo: \
ldap/servers/slapd/$(am__dirstamp) \
ldap/servers/slapd/$(DEPDIR)/$(am__dirstamp)
+ldap/servers/slapd/libslapd_la-features.lo: \
+ ldap/servers/slapd/$(am__dirstamp) \
+ ldap/servers/slapd/$(DEPDIR)/$(am__dirstamp)
ldap/servers/slapd/libslapd_la-fileio.lo: \
ldap/servers/slapd/$(am__dirstamp) \
ldap/servers/slapd/$(DEPDIR)/$(am__dirstamp)
@@ -5769,6 +5765,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-errormap.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-eventq.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-factory.Plo(a)am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-features.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-fileio.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-filter.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-filtercmp.Plo(a)am__quote@
@@ -8037,6 +8034,13 @@ ldap/servers/slapd/libslapd_la-factory.lo: ldap/servers/slapd/factory.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libslapd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/slapd/libslapd_la-factory.lo `test -f 'ldap/servers/slapd/factory.c' || echo '$(srcdir)/'`ldap/servers/slapd/factory.c
+ldap/servers/slapd/libslapd_la-features.lo: ldap/servers/slapd/features.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libslapd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/slapd/libslapd_la-features.lo -MD -MP -MF ldap/servers/slapd/$(DEPDIR)/libslapd_la-features.Tpo -c -o ldap/servers/slapd/libslapd_la-features.lo `test -f 'ldap/servers/slapd/features.c' || echo '$(srcdir)/'`ldap/servers/slapd/features.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ldap/servers/slapd/$(DEPDIR)/libslapd_la-features.Tpo ldap/servers/slapd/$(DEPDIR)/libslapd_la-features.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ldap/servers/slapd/features.c' object='ldap/servers/slapd/libslapd_la-features.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libslapd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/slapd/libslapd_la-features.lo `test -f 'ldap/servers/slapd/features.c' || echo '$(srcdir)/'`ldap/servers/slapd/features.c
+
ldap/servers/slapd/libslapd_la-fileio.lo: ldap/servers/slapd/fileio.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libslapd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/slapd/libslapd_la-fileio.lo -MD -MP -MF ldap/servers/slapd/$(DEPDIR)/libslapd_la-fileio.Tpo -c -o ldap/servers/slapd/libslapd_la-fileio.lo `test -f 'ldap/servers/slapd/fileio.c' || echo '$(srcdir)/'`ldap/servers/slapd/fileio.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ldap/servers/slapd/$(DEPDIR)/libslapd_la-fileio.Tpo ldap/servers/slapd/$(DEPDIR)/libslapd_la-fileio.Plo
@@ -10349,16 +10353,10 @@ dist-xz: distdir
$(am__post_remove_distdir)
dist-tarZ: distdir
- @echo WARNING: "Support for distribution archives compressed with" \
- "legacy program 'compress' is deprecated." >&2
- @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
- @echo WARNING: "Support for shar distribution archives is" \
- "deprecated." >&2
- @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__post_remove_distdir)
@@ -10393,17 +10391,16 @@ distcheck: dist
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
- mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+ mkdir $(distdir)/_build $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
- && $(am__cd) $(distdir)/_build/sub \
- && ../../configure \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
- --srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
@@ -10731,8 +10728,6 @@ uninstall-man: uninstall-man1 uninstall-man8
uninstall-systemdsystemunitDATA uninstall-taskSCRIPTS \
uninstall-updateDATA uninstall-updateSCRIPTS
-.PRECIOUS: Makefile
-
clean-local:
-rm -rf dist
diff --git a/aclocal.m4 b/aclocal.m4
index 5a62115..5b32a97 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15 -*- Autoconf -*-
+# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -220,22 +220,7 @@ m4_popdef([pkg_default])
m4_popdef([pkg_description])
]) dnl PKG_NOARCH_INSTALLDIR
-
-# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
-# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-# -------------------------------------------
-# Retrieves the value of the pkg-config variable for the given module.
-AC_DEFUN([PKG_CHECK_VAR],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
-
-_PKG_CONFIG([$1], [variable="][$3]["], [$2])
-AS_VAR_COPY([$1], [pkg_cv_][$1])
-
-AS_VAR_IF([$1], [""], [$5], [$4])dnl
-])# PKG_CHECK_VAR
-
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -247,10 +232,10 @@ AS_VAR_IF([$1], [""], [$5], [$4])dnl
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.15'
+[am__api_version='1.13'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.15], [],
+m4_if([$1], [1.13.4], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -266,14 +251,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15])dnl
+[AM_AUTOMAKE_VERSION([1.13.4])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# Figure out how to run the assembler. -*- Autoconf -*-
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -293,7 +278,7 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -338,14 +323,15 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
-[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
])
# AM_COND_IF -*- Autoconf -*-
-# Copyright (C) 2008-2014 Free Software Foundation, Inc.
+# Copyright (C) 2008-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -382,7 +368,7 @@ fi[]dnl
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -413,7 +399,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -604,7 +590,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -680,7 +666,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -689,12 +675,6 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
-dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
-m4_define([AC_PROG_CC],
-m4_defn([AC_PROG_CC])
-[_AM_PROG_CC_C_O
-])
-
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
@@ -770,8 +750,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target (and possibly the TAP driver). The
-# system "awk" is bad on some platforms.
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -803,51 +783,6 @@ dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-
-# POSIX will say in a future version that running "rm -f" with no argument
-# is OK; and we want to be able to make that assumption in our Makefile
-# recipes. So use an aggressive probe to check that the usage we want is
-# actually supported "in the wild" to an acceptable degree.
-# See automake bug#10828.
-# To make any issue more visible, cause the running configure to be aborted
-# by default if the 'rm' program in use doesn't match our expectations; the
-# user can still override this though.
-if rm -f && rm -fr && rm -rf; then : OK; else
- cat >&2 <<'END'
-Oops!
-
-Your 'rm' program seems unable to run without file operands specified
-on the command line, even when the '-f' option is present. This is contrary
-to the behaviour of most rm programs out there, and not conforming with
-the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
-
-Please tell bug-automake(a)gnu.org about your system, including the value
-of your $PATH and any error possibly output before this message. This
-can help us improve future automake versions.
-
-END
- if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
- echo 'Configuration will proceed anyway, since you have set the' >&2
- echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
- echo >&2
- else
- cat >&2 <<'END'
-Aborting the configuration process, to ensure you take notice of the issue.
-
-You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
-
-If you want to complete the configuration process using your problematic
-'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
-to "yes", and re-run configure.
-
-END
- AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
- fi
-fi
-dnl The trailing newline in this macro's definition is deliberate, for
-dnl backward compatibility and to allow trailing 'dnl'-style comments
-dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
])
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
@@ -856,6 +791,7 @@ dnl mangled by Autoconf and run in a shell conditional statement.
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
@@ -877,7 +813,7 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -888,7 +824,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh+set}" != xset; then
+if test x"${install_sh}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -898,7 +834,7 @@ if test x"${install_sh+set}" != xset; then
fi
AC_SUBST([install_sh])])
-# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -920,7 +856,7 @@ AC_SUBST([am__leading_dot])])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -955,7 +891,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1003,9 +939,41 @@ AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+ [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1044,7 +1012,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1073,54 +1041,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# _AM_PROG_CC_C_O
-# ---------------
-# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
-# to automatically call this.
-AC_DEFUN([_AM_PROG_CC_C_O],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([compile])dnl
-AC_LANG_PUSH([C])dnl
-AC_CACHE_CHECK(
- [whether $CC understands -c and -o together],
- [am_cv_prog_cc_c_o],
- [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
- # Make sure it works both with $CC and with simple cc.
- # Following AC_PROG_CC_C_O, we do the test twice because some
- # compilers refuse to overwrite an existing .o file with -o,
- # though they will create one.
- am_cv_prog_cc_c_o=yes
- for am_i in 1 2; do
- if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
- && test -f conftest2.$ac_objext; then
- : OK
- else
- am_cv_prog_cc_c_o=no
- break
- fi
- done
- rm -f core conftest*
- unset am_i])
-if test "$am_cv_prog_cc_c_o" != yes; then
- # Losing compiler, so override with the script.
- # FIXME: It is wrong to rewrite CC.
- # But if we don't then we get into trouble of one sort or another.
- # A longer-term fix would be to have automake use am__CC in this case,
- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
- CC="$am_aux_dir/compile $CC"
-fi
-AC_LANG_POP([C])])
-
-# For backward compatibility.
-AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
-
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1139,7 +1060,7 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*-
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1220,7 +1141,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])
-# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1280,7 +1201,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1308,7 +1229,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1327,7 +1248,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
diff --git a/config.h.in b/config.h.in
index 918c13e..041a18f 100644
--- a/config.h.in
+++ b/config.h.in
@@ -354,6 +354,9 @@
/* no getdomainname */
#undef NO_DOMAINNAME
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
/* OS version */
#undef OSVERSION
diff --git a/configure b/configure
index c996da5..2a88f1a 100755
--- a/configure
+++ b/configure
@@ -2804,7 +2804,7 @@ cat >>confdefs.h <<_ACEOF
#define DS_PACKAGE_STRING "$PACKAGE_STRING"
_ACEOF
-am__api_version='1.15'
+am__api_version='1.13'
ac_aux_dir=
for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
@@ -3005,8 +3005,8 @@ test "$program_suffix" != NONE &&
ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
if test x"${MISSING+set}" != xset; then
case $am_aux_dir in
@@ -3025,7 +3025,7 @@ else
$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
fi
-if test x"${install_sh+set}" != xset; then
+if test x"${install_sh}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -3344,8 +3344,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
mkdir_p='$(MKDIR_P)'
-# We need awk for the "check" target (and possibly the TAP driver). The
-# system "awk" is bad on some platforms.
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AMTAR='$${TAR-tar}'
@@ -3446,48 +3446,6 @@ $as_echo "$am_cv_prog_tar_pax" >&6; }
-# POSIX will say in a future version that running "rm -f" with no argument
-# is OK; and we want to be able to make that assumption in our Makefile
-# recipes. So use an aggressive probe to check that the usage we want is
-# actually supported "in the wild" to an acceptable degree.
-# See automake bug#10828.
-# To make any issue more visible, cause the running configure to be aborted
-# by default if the 'rm' program in use doesn't match our expectations; the
-# user can still override this though.
-if rm -f && rm -fr && rm -rf; then : OK; else
- cat >&2 <<'END'
-Oops!
-
-Your 'rm' program seems unable to run without file operands specified
-on the command line, even when the '-f' option is present. This is contrary
-to the behaviour of most rm programs out there, and not conforming with
-the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
-
-Please tell bug-automake(a)gnu.org about your system, including the value
-of your $PATH and any error possibly output before this message. This
-can help us improve future automake versions.
-
-END
- if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
- echo 'Configuration will proceed anyway, since you have set the' >&2
- echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
- echo >&2
- else
- cat >&2 <<'END'
-Aborting the configuration process, to ensure you take notice of the issue.
-
-You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
-
-If you want to complete the configuration process using your problematic
-'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
-to "yes", and re-run configure.
-
-END
- as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
- fi
-fi
-
# define these for automake distdir
VERSION=$PACKAGE_VERSION
PACKAGE=$PACKAGE_TARNAME
@@ -4837,65 +4795,6 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
-$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
-if ${am_cv_prog_cc_c_o+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
- # Make sure it works both with $CC and with simple cc.
- # Following AC_PROG_CC_C_O, we do the test twice because some
- # compilers refuse to overwrite an existing .o file with -o,
- # though they will create one.
- am_cv_prog_cc_c_o=yes
- for am_i in 1 2; do
- if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
- ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } \
- && test -f conftest2.$ac_objext; then
- : OK
- else
- am_cv_prog_cc_c_o=no
- break
- fi
- done
- rm -f core conftest*
- unset am_i
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
-$as_echo "$am_cv_prog_cc_c_o" >&6; }
-if test "$am_cv_prog_cc_c_o" != yes; then
- # Losing compiler, so override with the script.
- # FIXME: It is wrong to rewrite CC.
- # But if we don't then we get into trouble of one sort or another.
- # A longer-term fix would be to have automake use am__CC in this case,
- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
- CC="$am_aux_dir/compile $CC"
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
depcc="$CC" am_compiler_list=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
@@ -5024,6 +4923,131 @@ else
fi
+if test "x$CC" != xcc; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
+$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
+$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
+fi
+set dummy $CC; ac_cc=`$as_echo "$2" |
+ sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } &&
+ test -f conftest2.$ac_objext && { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; };
+then
+ eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+ if test "x$CC" != xcc; then
+ # Test first that cc exists at all.
+ if { ac_try='cc -c conftest.$ac_ext >&5'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+ rm -f conftest2.*
+ if { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } &&
+ test -f conftest2.$ac_objext && { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; };
+ then
+ # cc works too.
+ :
+ else
+ # cc exists but doesn't like -o.
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+ fi
+ fi
+ fi
+else
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+
# By default we simply use the C compiler to build assembly code.
diff --git a/dirsrvtests/create_test.py b/dirsrvtests/create_test.py
index e3b89aa..7b06fdb 100755
--- a/dirsrvtests/create_test.py
+++ b/dirsrvtests/create_test.py
@@ -174,7 +174,9 @@ if len(sys.argv) > 0:
#
TEST.write('logging.getLogger(__name__).setLevel(logging.DEBUG)\n')
TEST.write('log = logging.getLogger(__name__)\n\n')
- TEST.write('installation1_prefix = None\n\n\n')
+
+ # We don't need the prefix anymore, it's worked out in lib389
+ # TEST.write('installation1_prefix = None\n\n\n')
#
# Write the replication or standalone classes
@@ -240,10 +242,10 @@ if len(sys.argv) > 0:
#
TEST.write('@pytest.fixture(scope="module")\n')
TEST.write('def topology(request):\n')
- TEST.write(' global installation1_prefix\n')
- TEST.write(' if installation1_prefix:\n')
- TEST.write(' args_instance[SER_DEPLOYED_DIR] = ' +
- 'installation1_prefix\n\n')
+ #TEST.write(' global installation1_prefix\n')
+ #TEST.write(' if installation1_prefix:\n')
+ #TEST.write(' args_instance[SER_DEPLOYED_DIR] = ' +
+ # 'installation1_prefix\n\n')
if repl_deployment:
#
diff --git a/dirsrvtests/tickets/ticket48363_test.py b/dirsrvtests/tickets/ticket48363_test.py
new file mode 100644
index 0000000..33245a1
--- /dev/null
+++ b/dirsrvtests/tickets/ticket48363_test.py
@@ -0,0 +1,206 @@
+import os
+import sys
+import time
+import ldap
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from lib389.utils import *
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+TEST_USER = 'uid=test,%s' % DEFAULT_SUFFIX
+# Well, it's better than "password" or "password1"
+TEST_PASS = 'banana cream pie'
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+(a)pytest.fixture(scope="module")
+def topology(request):
+
+ # Creating standalone instance ...
+ standalone = DirSrv(verbose=False)
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+ instance_standalone = standalone.exists()
+ if instance_standalone:
+ standalone.delete()
+ standalone.create()
+ standalone.open()
+
+ # Delete each instance in the end
+ def fin():
+ standalone.delete()
+ request.addfinalizer(fin)
+
+ # Clear out the tmp dir
+ standalone.clearTmpDir(__file__)
+
+ return TopologyStandalone(standalone)
+
+
+def test_ticket48363(topology):
+ """
+ Test the implementation of rfc3673, '+' for all operational attributes.
+
+ Please see: https://tools.ietf.org/html/rfc3673
+
+ """
+
+ # Test the implementation of the supportFeatures
+
+ # Section 2:
+ # Servers supporting this feature SHOULD publish the Object Identifier
+ # 1.3.6.1.4.1.4203.1.5.1 as a value of the 'supportedFeatures'
+ # [RFC3674] attribute in the root DSE.
+
+ results = topology.standalone.search_s('', ldap.SCOPE_BASE, 'objectClass=*', ['supportedFeatures'] )[0]
+ if results.hasAttr('supportedfeatures') is False:
+ assert False
+ if results.hasValue('supportedfeatures', '1.3.6.1.4.1.4203.1.5.1') is False:
+ assert False
+
+ # Section 2:
+ # The presence of the attribute description "+" (ASCII 43) in the list
+ # of attributes in a Search Request [RFC2251] SHALL signify a request
+ # for the return of all operational attributes.
+
+ # Test the two backends, rootdse, and a real ldbm backend
+
+ # Root DSE
+ results = topology.standalone.search_s('', ldap.SCOPE_BASE, 'objectClass=*', ['+'] )[0]
+ # There are a number of obvious ones in rootdse. These are:
+
+ rootdse_op_attrs = [
+ 'supportedExtension',
+ 'supportedControl',
+ 'supportedFeatures',
+ 'supportedSASLMechanisms',
+ 'supportedLDAPVersion',
+ 'vendorName',
+ 'vendorVersion',
+ ]
+
+ for opattr in rootdse_op_attrs:
+ if results.hasAttr(opattr) is False:
+ assert False
+
+ # LDBM backend
+ # We are going to examine the root of the suffix, as it's a good easy target
+ dc_op_attrs = [
+ 'nsuniqueid',
+ 'entrydn',
+ 'entryid',
+ 'aci',
+ ]
+ dc_user_attrs = [
+ 'objectClass',
+ 'dc',
+ ]
+
+ # We should show that the following work:
+
+ # '+'
+ results = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE, 'objectClass=*', ['+'] )[0]
+ for opattr in dc_op_attrs:
+ if results.hasAttr(opattr) is False:
+ assert False
+ for userattr in dc_user_attrs:
+ if results.hasAttr(userattr) is False:
+ assert True
+
+ # '+' '*'
+ results = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE, 'objectClass=*', ['+', '*'] )[0]
+ for opattr in dc_op_attrs:
+ if results.hasAttr(opattr) is False:
+ assert False
+ for userattr in dc_user_attrs:
+ if results.hasAttr(userattr) is False:
+ assert False
+
+ # Section 2:
+ # Client implementors should also note
+ # that certain operational attributes may be returned only if requested
+ # by name even when "+" is present.
+
+ # We do not currently have any types that are excluded.
+ # However, we should ensure that a search for "+ namedType" returns
+ # both all operational and the namedType
+
+ # '+' dc
+ results = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE, 'objectClass=*', ['+', 'dc'] )[0]
+ for opattr in dc_op_attrs:
+ if results.hasAttr(opattr) is False:
+ assert False
+ if results.hasAttr('dc') is False:
+ assert False
+ if results.hasAttr('objectclass') is False:
+ assert True
+
+ # '*' nsUniqueId
+ results = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE, 'objectClass=*', ['*', 'nsuniqueid'] )[0]
+ for userattr in dc_user_attrs:
+ if results.hasAttr(userattr) is False:
+ assert False
+ if results.hasAttr('nsuniqueid') is False:
+ assert False
+ if results.hasAttr('entrydn') is False:
+ assert True
+
+ # Section 2:
+ # As with all search requests, client implementors should note that
+ # results may not include all requested attributes due to access
+ # controls or other restrictions.
+
+ # Test that with a user with limit read aci, that these are enforced on
+ # the + request.
+
+ # Create the user
+ uentry = Entry(TEST_USER)
+ uentry.setValues('objectclass', 'top', 'extensibleobject')
+ uentry.setValues('uid', 'test')
+ uentry.setValues('userPassword', TEST_PASS)
+ topology.standalone.add_s(uentry)
+
+ # Give them a limited read aci: We may need to purge other acis
+ anonaci = '(targetattr!="userPassword")(version 3.0; acl "Enable anonymous access"; allow (read, search, compare) userdn="ldap:///anyone";)'
+ topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_DELETE, 'aci', anonaci)])
+
+ # Now we need to create an aci that allows anon/all read to only a few attrs
+ # Lets make one real, and one operational.
+
+ anonaci = '(targetattr="objectclass || dc || nsuniqueid")(version 3.0; acl "Enable anonymous access"; allow (read, search, compare) userdn="ldap:///anyone";)'
+ topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD, 'aci', anonaci)])
+
+ # bind as them, and test.
+ topology.standalone.simple_bind_s(TEST_USER, TEST_PASS)
+ results = topology.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE, 'objectClass=*', ['*', '+'] )[0]
+
+ if results.hasAttr('dc') is False:
+ assert False
+ if results.hasAttr('nsuniqueid') is False:
+ assert False
+ if results.hasAttr('entrydn') is False:
+ assert True
+
+ log.info('Test complete')
+
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
diff --git a/ldap/servers/slapd/features.c b/ldap/servers/slapd/features.c
new file mode 100644
index 0000000..64a2825
--- /dev/null
+++ b/ldap/servers/slapd/features.c
@@ -0,0 +1,54 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright (C) 2016 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * License: GPL (version 3 or any later version).
+ * See LICENSE for details.
+ * END COPYRIGHT BLOCK **/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* features.c - routines for dealing with supportedFeatures rfc3674 */
+
+#include <stdio.h>
+#include "slap.h"
+#include "slapi-plugin.h"
+
+int slapi_register_supported_feature( char *featureoid );
+static char **supported_features = NULL;
+static Slapi_RWLock *supported_features_lock = NULL;
+
+void
+init_features( void )
+{
+ supported_features_lock = slapi_new_rwlock();
+ if (supported_features_lock == NULL) {
+ slapi_log_error(SLAPI_LOG_FATAL, "startup",
+ "init_features: failed to create lock.\n");
+ exit(1);
+ }
+ slapi_register_supported_feature( LDAP_FEATURE_ALL_OP_ATTRS );
+}
+
+int
+slapi_register_supported_feature( char *featureoid )
+{
+ slapi_rwlock_wrlock(supported_features_lock);
+ charray_add( &supported_features, slapi_ch_strdup( featureoid ));
+ slapi_rwlock_unlock(supported_features_lock);
+ return LDAP_SUCCESS;
+}
+
+int
+slapi_get_supported_features_copy( char ***ftroidsp )
+{
+ slapi_rwlock_unlock(supported_features_lock);
+ if ( ftroidsp != NULL ) {
+ *ftroidsp = charray_dup(supported_features);
+ }
+ slapi_rwlock_unlock(supported_features_lock);
+ return LDAP_SUCCESS;
+}
+
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index b048dc5..1181628 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -702,6 +702,11 @@ main( int argc, char **argv)
init_controls();
/*
+ * Register the server features that we support.
+ */
+ init_features();
+
+ /*
* Initialize the global plugin list lock
*/
global_plugin_init();
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 7a2ddde..8a0bdd3 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -650,6 +650,11 @@ void *sym_load( char *libpath, char *symbol, char *plugin, int report_errors );
*/
void *sym_load_with_flags( char *libpath, char *symbol, char *plugin, int report_errors, PRBool load_now, PRBool load_global );
+/*
+ * features.c
+ */
+
+void init_features( void );
/*
* filter.c
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
index 5acff94..b5681ec 100644
--- a/ldap/servers/slapd/result.c
+++ b/ldap/servers/slapd/result.c
@@ -1119,7 +1119,7 @@ static const char *idds_map_attrt_v3(
/* Helper functions */
-static int send_all_attrs(Slapi_Entry *e,char **attrs,Slapi_Operation *op,Slapi_PBlock *pb,BerElement *ber,int attrsonly,int ldapversion, int real_attrs_only, int some_named_attrs)
+static int send_all_attrs(Slapi_Entry *e,char **attrs,Slapi_Operation *op,Slapi_PBlock *pb,BerElement *ber,int attrsonly,int ldapversion, int real_attrs_only, int some_named_attrs, int alloperationalattrs, int alluserattrs )
{
int i = 0;
int rc = 0;
@@ -1142,7 +1142,7 @@ static int send_all_attrs(Slapi_Entry *e,char **attrs,Slapi_Operation *op,Slapi_
vattr_flags |= SLAPI_VIRTUALATTRS_ONLY;
}
- if (some_named_attrs) {
+ if (some_named_attrs || alloperationalattrs) {
/*
* If the client listed some attribute types by name, one or
* more of the requested types MAY be operational. Inform the
@@ -1189,11 +1189,11 @@ static int send_all_attrs(Slapi_Entry *e,char **attrs,Slapi_Operation *op,Slapi_
name_to_return = current_type_name;
/* We only return operational attributes if the client is LDAPv2 and the attribute is one of a special set,
- OR if the client also requested the attribute by name. If it did, we use the specified name rather than
- the base name.
+ OR if all operational attrs are requested, OR if the client also requested the attribute by name.
+ If it did, we use the specified name rather than the base name.
*/
if ( current_type_flags & SLAPI_ATTR_FLAG_OPATTR ) {
- if ( LDAP_VERSION2 == ldapversion && LASTMODATTR( current_type_name) ) {
+ if ( (LDAP_VERSION2 == ldapversion && LASTMODATTR( current_type_name)) || alloperationalattrs ) {
sendit = 1;
} else {
for ( i = 0; attrs != NULL && attrs[i] != NULL; i++ ) {
@@ -1215,7 +1215,7 @@ static int send_all_attrs(Slapi_Entry *e,char **attrs,Slapi_Operation *op,Slapi_
/*
* it's a user attribute. send it.
*/
- } else {
+ } else if ( alluserattrs ) {
sendit = 1;
}
/* Now send to the client */
@@ -1474,7 +1474,10 @@ send_ldap_search_entry_ext(
Operation *op = pb->pb_op;
BerElement *ber = NULL;
int i, rc = 0, logit = 0;
- int alluserattrs, noattrs, some_named_attrs;
+ int alluserattrs;
+ int noattrs;
+ int some_named_attrs;
+ int alloperationalattrs;
Slapi_Operation *operation;
int real_attrs_only = 0;
LDAPControl **ctrlp = 0;
@@ -1557,15 +1560,17 @@ send_ldap_search_entry_ext(
/*
* in ldapv3, the special attribute "*" means all user attributes,
- * NULL means all user attributes, and "1.1" means no attributes.
+ * NULL means all user attributes, "1.1" means no attributes, and
+ * "+" means all operational attributes (rfc3673)
* operational attributes are only retrieved if they are named
- * specifically.
+ * specifically or when "+" is specified.
*/
/* figure out if we want all user attributes or no attributes at all */
alluserattrs = 0;
noattrs = 0;
some_named_attrs = 0;
+ alloperationalattrs = 0;
if ( attrs == NULL ) {
alluserattrs = 1;
} else {
@@ -1574,6 +1579,8 @@ send_ldap_search_entry_ext(
alluserattrs = 1;
} else if ( strcmp( LDAP_NO_ATTRS, attrs[i] ) == 0 ) {
noattrs = 1;
+ } else if ( strcmp( LDAP_ALL_OPERATIONAL_ATTRS, attrs[i] ) == 0 ) {
+ alloperationalattrs = 1;
} else {
some_named_attrs = 1;
}
@@ -1611,9 +1618,9 @@ send_ldap_search_entry_ext(
}
/* look through each attribute in the entry */
- if ( alluserattrs ) {
+ if ( alluserattrs || alloperationalattrs ) {
rc = send_all_attrs(e, attrs, op, pb, ber, attrsonly, conn->c_ldapversion,
- real_attrs_only, some_named_attrs);
+ real_attrs_only, some_named_attrs, alloperationalattrs, alluserattrs);
}
/* if the client explicitly specified a list of attributes look through each attribute requested */
@@ -2213,7 +2220,7 @@ encode_read_entry (Slapi_PBlock *pb, Slapi_Entry *e, char **attrs, int alluserat
/* Send all the attributes */
if ( alluserattrs ) {
rc = send_all_attrs(e, attrs, op, pb, ber, 0, conn->c_ldapversion,
- real_attrs_only, attr_count);
+ real_attrs_only, attr_count, 0, 1);
if(rc){
goto cleanup;
}
diff --git a/ldap/servers/slapd/rootdse.c b/ldap/servers/slapd/rootdse.c
index 9b30423..d839c92 100644
--- a/ldap/servers/slapd/rootdse.c
+++ b/ldap/servers/slapd/rootdse.c
@@ -25,6 +25,7 @@ static char *readonly_attributes[] = {
"supportedldapversion",
"supportedcontrol",
"supportedextension",
+ "supportedfeatures",
"supportedsaslmechanisms",
"dataversion",
"ref",
@@ -190,6 +191,18 @@ read_root_dse( Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *entryAfter, int *r
charray_free(strs);
}
+ /* supported features */
+ attrlist_delete( &e->e_attrs, "supportedFeatures");
+ if ( slapi_get_supported_features_copy( &strs ) == 0
+ && strs != NULL ) {
+ for ( i = 0; strs[i] != NULL; ++i ) {
+ val.bv_val = strs[i];
+ val.bv_len = strlen( strs[i] );
+ attrlist_merge( &e->e_attrs, "supportedFeatures", vals );
+ }
+ charray_free(strs);
+ }
+
/* supported sasl mechanisms */
attrlist_delete( &e->e_attrs, "supportedSASLMechanisms");
if (( strs = ids_sasl_listmech (pb)) != NULL ) {
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index d2b076b..bf4e8c2 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5585,11 +5585,11 @@ LDAPControl * slapi_dup_control( LDAPControl *ctrl );
#define SLAPI_OPERATION_ANY 0xFFFFFFFFUL
#define SLAPI_OPERATION_NONE 0x00000000UL
int slapi_get_supported_controls_copy( char ***ctrloidsp,
- unsigned long **ctrlopsp );
+ unsigned long **ctrlopsp );
int slapi_build_control( char *oid, BerElement *ber,
- char iscritical, LDAPControl **ctrlp );
+ char iscritical, LDAPControl **ctrlp );
int slapi_build_control_from_berval( char *oid, struct berval *bvp,
- char iscritical, LDAPControl **ctrlp );
+ char iscritical, LDAPControl **ctrlp );
/* Given an array of controls e.g. LDAPControl **ctrls, add the given
control to the end of the array, growing the array with realloc
@@ -5615,6 +5615,15 @@ void slapi_add_controls( LDAPControl ***ctrlsp, LDAPControl **newctrls, int copy
*/
char **slapi_get_supported_extended_ops_copy( void );
+/*
+ * routines for dealing with supported features
+ */
+
+#ifndef LDAP_FEATURE_ALL_OP_ATTRS
+#define LDAP_FEATURE_ALL_OP_ATTRS "1.3.6.1.4.1.4203.1.5.1"
+#endif
+
+int slapi_get_supported_features_copy( char ***ftroidsp );
/*
* bind, including SASL
@@ -7450,6 +7459,12 @@ char **slapi_str2charray_ext( char *str, char *brkstr, int allow_dups );
#endif
#endif
+/*
+ * As per rfc3673
+ */
+
+#define LDAP_ALL_OPERATIONAL_ATTRS "+"
+
#ifndef LDAP_SASL_EXTERNAL
#define LDAP_SASL_EXTERNAL "EXTERNAL" /* TLS/SSL extension */
#endif
8 years, 2 months
Branch '389-ds-base-1.3.4' - ldap/admin
by William Brown
ldap/admin/src/scripts/start-dirsrv.in | 2 +-
ldap/admin/src/scripts/template-bak2db.in | 3 +--
ldap/admin/src/scripts/template-db2bak.in | 5 ++---
ldap/admin/src/scripts/template-db2index.in | 5 ++---
ldap/admin/src/scripts/template-db2ldif.in | 3 +--
ldap/admin/src/scripts/template-dbverify.in | 5 ++---
ldap/admin/src/scripts/template-dn2rdn.in | 5 ++---
ldap/admin/src/scripts/template-ldif2db.in | 3 +--
ldap/admin/src/scripts/template-ldif2ldap.in | 5 ++---
ldap/admin/src/scripts/template-monitor.in | 5 ++---
ldap/admin/src/scripts/template-restoreconfig.in | 5 ++---
ldap/admin/src/scripts/template-saveconfig.in | 5 ++---
ldap/admin/src/scripts/template-suffix2instance.in | 5 ++---
ldap/admin/src/scripts/template-upgradedb.in | 3 +--
ldap/admin/src/scripts/template-upgradednformat.in | 5 ++---
ldap/admin/src/scripts/template-vlvindex.in | 3 +--
16 files changed, 26 insertions(+), 41 deletions(-)
New commits:
commit 099883cd270d574d16b458ee144069d3c82dec7b
Author: William Brown <firstyear(a)redhat.com>
Date: Sun Jan 31 14:27:13 2016 +1000
Ticket 48448 - dirsrv start-stop fail in certain shell environments.
Bug Description: Dirsrv fails to start and stop with certain shell environments
. This is due to the usage of the pattern
cd $SERVERBIN_DIR
./ns-slapd ...
Fix Description: Change all invocations of commands to use explicit paths:
$SERVERBIN_DIR/ns-slapd
https://fedorahosted.org/389/ticket/48448
Author: wibrown
Review by: nhosoi (Thanks!)
diff --git a/ldap/admin/src/scripts/start-dirsrv.in b/ldap/admin/src/scripts/start-dirsrv.in
index 458f0e8..513addb 100755
--- a/ldap/admin/src/scripts/start-dirsrv.in
+++ b/ldap/admin/src/scripts/start-dirsrv.in
@@ -70,7 +70,7 @@ start_instance() {
return 1
fi
else
- cd $SERVERBIN_DIR; ./ns-slapd -D $CONFIG_DIR -i $PIDFILE -w $STARTPIDFILE "$@"
+ $SERVERBIN_DIR/ns-slapd -D $CONFIG_DIR -i $PIDFILE -w $STARTPIDFILE "$@"
if [ $? -ne 0 ]; then
return 1
fi
diff --git a/ldap/admin/src/scripts/template-bak2db.in b/ldap/admin/src/scripts/template-bak2db.in
index 1725aba..01a12fa 100755
--- a/ldap/admin/src/scripts/template-bak2db.in
+++ b/ldap/admin/src/scripts/template-bak2db.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./bak2db "$@" -Z {{SERV-ID}}
+{{SERVERBIN-DIR}}/bak2db "$@" -Z {{SERV-ID}}
exit $?
diff --git a/ldap/admin/src/scripts/template-db2bak.in b/ldap/admin/src/scripts/template-db2bak.in
index 50fd5ed..70a4a2b 100755
--- a/ldap/admin/src/scripts/template-db2bak.in
+++ b/ldap/admin/src/scripts/template-db2bak.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./db2bak "$@" -Z {{SERV-ID}}
-exit $?
\ No newline at end of file
+{{SERVERBIN-DIR}}/db2bak "$@" -Z {{SERV-ID}}
+exit $?
diff --git a/ldap/admin/src/scripts/template-db2index.in b/ldap/admin/src/scripts/template-db2index.in
index a7a633d..9c7c5ec 100755
--- a/ldap/admin/src/scripts/template-db2index.in
+++ b/ldap/admin/src/scripts/template-db2index.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./db2index "$@" -Z {{SERV-ID}}
-exit $?
\ No newline at end of file
+{{SERVERBIN-DIR}}/db2index "$@" -Z {{SERV-ID}}
+exit $?
diff --git a/ldap/admin/src/scripts/template-db2ldif.in b/ldap/admin/src/scripts/template-db2ldif.in
index b85ffdc..3881911 100755
--- a/ldap/admin/src/scripts/template-db2ldif.in
+++ b/ldap/admin/src/scripts/template-db2ldif.in
@@ -1,6 +1,5 @@
#!/bin/sh
cwd=`pwd`
-cd {{SERVERBIN-DIR}}
-./db2ldif "$@" -Z {{SERV-ID}} -c $cwd
+{{SERVERBIN-DIR}}/db2ldif "$@" -Z {{SERV-ID}} -c $cwd
exit $?
diff --git a/ldap/admin/src/scripts/template-dbverify.in b/ldap/admin/src/scripts/template-dbverify.in
index 71e3e4e..abcc58e 100755
--- a/ldap/admin/src/scripts/template-dbverify.in
+++ b/ldap/admin/src/scripts/template-dbverify.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./dbverify "$@" -Z {{SERV-ID}}
-exit $?
\ No newline at end of file
+{{SERVERBIN-DIR}}/dbverify "$@" -Z {{SERV-ID}}
+exit $?
diff --git a/ldap/admin/src/scripts/template-dn2rdn.in b/ldap/admin/src/scripts/template-dn2rdn.in
index b3d8e82..9ecae08 100755
--- a/ldap/admin/src/scripts/template-dn2rdn.in
+++ b/ldap/admin/src/scripts/template-dn2rdn.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./dn2rdn "$@" -Z {{SERV-ID}}
-exit $?
\ No newline at end of file
+{{SERVERBIN-DIR}}/dn2rdn "$@" -Z {{SERV-ID}}
+exit $?
diff --git a/ldap/admin/src/scripts/template-ldif2db.in b/ldap/admin/src/scripts/template-ldif2db.in
index f3fa58e..f38fce3 100755
--- a/ldap/admin/src/scripts/template-ldif2db.in
+++ b/ldap/admin/src/scripts/template-ldif2db.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./ldif2db "$@" -Z {{SERV-ID}}
+{{SERVERBIN-DIR}}/ldif2db "$@" -Z {{SERV-ID}}
exit $?
diff --git a/ldap/admin/src/scripts/template-ldif2ldap.in b/ldap/admin/src/scripts/template-ldif2ldap.in
index 806ddcc..c785742 100755
--- a/ldap/admin/src/scripts/template-ldif2ldap.in
+++ b/ldap/admin/src/scripts/template-ldif2ldap.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./ldif2ldap "$@" -Z {{SERV-ID}}
-exit $?
\ No newline at end of file
+{{SERVERBIN-DIR}}/ldif2ldap "$@" -Z {{SERV-ID}}
+exit $?
diff --git a/ldap/admin/src/scripts/template-monitor.in b/ldap/admin/src/scripts/template-monitor.in
index 2f93337..c89bb8a 100755
--- a/ldap/admin/src/scripts/template-monitor.in
+++ b/ldap/admin/src/scripts/template-monitor.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./monitor "$@" -Z {{SERV-ID}}
-exit $?
\ No newline at end of file
+{{SERVERBIN-DIR}}/monitor "$@" -Z {{SERV-ID}}
+exit $?
diff --git a/ldap/admin/src/scripts/template-restoreconfig.in b/ldap/admin/src/scripts/template-restoreconfig.in
index f4b2d06..5109561 100755
--- a/ldap/admin/src/scripts/template-restoreconfig.in
+++ b/ldap/admin/src/scripts/template-restoreconfig.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./restoreconfig "$@" -Z {{SERV-ID}}
-exit $?
\ No newline at end of file
+{{SERVERBIN-DIR}}/restoreconfig "$@" -Z {{SERV-ID}}
+exit $?
diff --git a/ldap/admin/src/scripts/template-saveconfig.in b/ldap/admin/src/scripts/template-saveconfig.in
index c77cce1..7784e83 100755
--- a/ldap/admin/src/scripts/template-saveconfig.in
+++ b/ldap/admin/src/scripts/template-saveconfig.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./saveconfig "$@" -Z {{SERV-ID}}
-exit $?
\ No newline at end of file
+{{SERVERBIN-DIR}}/saveconfig "$@" -Z {{SERV-ID}}
+exit $?
diff --git a/ldap/admin/src/scripts/template-suffix2instance.in b/ldap/admin/src/scripts/template-suffix2instance.in
index 03bcba8..e29408d 100755
--- a/ldap/admin/src/scripts/template-suffix2instance.in
+++ b/ldap/admin/src/scripts/template-suffix2instance.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./suffix2instance "$@" -Z {{SERV-ID}}
-exit $?
\ No newline at end of file
+{{SERVERBIN-DIR}}/suffix2instance "$@" -Z {{SERV-ID}}
+exit $?
diff --git a/ldap/admin/src/scripts/template-upgradedb.in b/ldap/admin/src/scripts/template-upgradedb.in
index ce879bb..ae28ac2 100755
--- a/ldap/admin/src/scripts/template-upgradedb.in
+++ b/ldap/admin/src/scripts/template-upgradedb.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./upgradedb "$@" -Z {{SERV-ID}}
+{{SERVERBIN-DIR}}/upgradedb "$@" -Z {{SERV-ID}}
exit $?
diff --git a/ldap/admin/src/scripts/template-upgradednformat.in b/ldap/admin/src/scripts/template-upgradednformat.in
index 5fd8ef9..74c18e8 100755
--- a/ldap/admin/src/scripts/template-upgradednformat.in
+++ b/ldap/admin/src/scripts/template-upgradednformat.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./upgradednformat "$@" -Z {{SERV-ID}}
-exit $?
\ No newline at end of file
+{{SERVERBIN-DIR}}/upgradednformat "$@" -Z {{SERV-ID}}
+exit $?
diff --git a/ldap/admin/src/scripts/template-vlvindex.in b/ldap/admin/src/scripts/template-vlvindex.in
index 0249696..a7ffb40 100755
--- a/ldap/admin/src/scripts/template-vlvindex.in
+++ b/ldap/admin/src/scripts/template-vlvindex.in
@@ -1,5 +1,4 @@
#!/bin/sh
-cd {{SERVERBIN-DIR}}
-./vlvindex "$@" -Z {{SERV-ID}}
+{{SERVERBIN-DIR}}/vlvindex "$@" -Z {{SERV-ID}}
exit $?
8 years, 2 months