[Fedora-directory-commits] adminserver/admserv/cgi-src40 security.c, 1.18, 1.19
by Richard Allen Megginson
Author: rmeggins
Update of /cvs/dirsec/adminserver/admserv/cgi-src40
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv29896/adminserver/admserv/cgi-src40
Modified Files:
security.c
Log Message:
Resolves: bug 426439
Bug Description: Unable to load CRL file for a DS instance - when its placed under /etc/dirsrv/slapd-INSTANCE
Reviewed by: nhosoi (Thanks!)
Fix Description: The main problem was that it was not using the getSecurityDir function to get the security dir based on the SIE passed in. This function is called in main after getting the SIE. I changed the code to set this value in a static variable that can be used throughout the program.
In addition, I found and fixed some other bugs related to CRL handling:
1) The code did not work with ASCII CRLs generated by newer versions of crlutil which use the BEGIN CRL header. I added processing for that header type.
2) The code did not handle date/time in generalized time format. I added code to format the date/time based on the type of date/time stored in the CRL.
Platforms tested: RHEL5
Flag Day: no
Doc impact: no
Index: security.c
===================================================================
RCS file: /cvs/dirsec/adminserver/admserv/cgi-src40/security.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- security.c 11 Dec 2008 18:06:42 -0000 1.18
+++ security.c 15 Dec 2008 20:06:55 -0000 1.19
@@ -39,6 +39,7 @@
#include "certt.h"
#include "key.h"
#include "secport.h"
+#include "secder.h"
#include "plstr.h"
#include "prsystem.h"
@@ -102,6 +103,8 @@
#define X509CRLFOOTER "-----END X509 CRL-----"
#define CRLHEADER "-----BEGIN CERTIFICATE REVOCATION LIST-----\n"
#define CRLFOOTER "-----END CERTIFICATE REVOCATION LIST-----\n"
+#define NEWCRLHEADER "-----BEGIN CRL-----"
+#define NEWCRLFOOTER "-----END CRL-----"
/*#else
#define HEADER "-----BEGIN CERTIFICATE----\n"
#define FOOTER "\n-----END CERTIFICATE-----\n"
@@ -113,6 +116,8 @@
CERTCertDBHandle *certdb = NULL;
char line[BIG_LINE];
+static char *securitydir; /* based on the sie - security dir for ds or as */
+
#define RESOURCE_FILE "security"
/* main resource string */
@@ -385,6 +390,28 @@
}
}
+static char *
+formatDateTime(SECItem *timechoice)
+{
+ PRTime decodedTime = 0;
+
+ /* decode the time into the integral value */
+ if (SECSuccess != DER_DecodeTimeChoice(&decodedTime, timechoice)) {
+ return NULL;
+ }
+ switch (timechoice->type) {
+ case siUTCTime:
+ return DER_UTCTimeToAscii(timechoice);
+ break;
+ case siGeneralizedTime:
+ return CERT_GenTime2FormattedAscii(decodedTime, "%a %b %d %H:%M:%S %Y");
+ break;
+ default:
+ return NULL;
+ }
+
+ return NULL;
+}
/*
* Fingerprint (MD5) for a cert
*/
@@ -581,13 +608,13 @@
fprintf(stdout, "\t<TRUST>%d</TRUST>\n\t<AFTERDATE>%s</AFTERDATE>\n",
trustBit,
- processNullString((char*)DER_UTCTimeToAscii(&cert->validity.notAfter)));
+ processNullString((char*)formatDateTime(&cert->validity.notAfter)));
fprintf(stdout, "\t<FINGERPRINT>%s</FINGERPRINT>\n", processNullString(getMD5Fingerprint(cert)));
if (showDetail) {
fprintf(stdout, "\t<BEFOREDATE>%s</BEFOREDATE>\n",
- processNullString((char*)DER_UTCTimeToAscii(&cert->validity.notBefore)));
+ processNullString((char*)formatDateTime(&cert->validity.notBefore)));
fprintf(stdout, "\t<SERIAL>%s</SERIAL>\n", processNullString(Hexify((&cert->serialNumber))));
@@ -732,7 +759,7 @@
if (entry != NULL) {
fprintf(stdout, "\t<ENTRY%d>\n", x);
fprintf(stdout, "\t\t<SERIAL_NUMBER>%s</SERIAL_NUMBER>\n", processNullString(Hexify(&entry->serialNumber)));
- fprintf(stdout, "\t\t<REVOKE_DATE>%s</REVOKE_DATE>\n",DER_UTCTimeToAscii(&entry->revocationDate));
+ fprintf(stdout, "\t\t<REVOKE_DATE>%s</REVOKE_DATE>\n",formatDateTime(&entry->revocationDate));
fprintf(stdout, "\t</ENTRY%d>\n", x);
x++;
} else {
@@ -743,8 +770,8 @@
}
fprintf(stdout, "\t<LAST_UPDATE>%s</LAST_UPDATE>\n\t<NEXT_UPDATE>%s</NEXT_UPDATE>\n\t<TYPE>%s</TYPE>\n",
- DER_UTCTimeToAscii(&crl->crl.lastUpdate),
- DER_UTCTimeToAscii(&crl->crl.nextUpdate),
+ formatDateTime(&crl->crl.lastUpdate),
+ formatDateTime(&crl->crl.nextUpdate),
list_type==SEC_CRL_TYPE?"CRL":"CKL");
}
@@ -1496,13 +1523,12 @@
CERTSignedCrl *signed_crl, *excrl, *crl_rv = NULL;
SECItem derCrl;
char msg[BIG_LINE];
- char *secdir = util_get_security_dir();
char full_path[PATH_MAX];
int list_type = (type && !PORT_Strcmp(type, "CKL"))? SEC_KRL_TYPE : SEC_CRL_TYPE;
if (!filename || !*filename ||
!util_is_valid_path_string(filename) ||
- !util_verify_file_or_dir(secdir, PR_FILE_DIRECTORY, filename, -1, PR_FILE_FILE)) {
+ !util_verify_file_or_dir(securitydir, PR_FILE_DIRECTORY, filename, -1, PR_FILE_FILE)) {
/* invalid file */
PR_snprintf(msg, sizeof(msg), getResourceString(DBT_NO_FILE_EXISTS), filename);
errorRpt(FILE_ERROR, msg);
@@ -1511,7 +1537,7 @@
{/*try open the file*/
FILE *f;
- PR_snprintf(full_path, sizeof(full_path), "%s%c%s", secdir, FILE_PATHSEP, filename);
+ PR_snprintf(full_path, sizeof(full_path), "%s%c%s", securitydir, FILE_PATHSEP, filename);
if( !(f = fopen(full_path, "rb")) ) {
PR_snprintf(msg, sizeof(msg), getResourceString(DBT_NO_FILE_EXISTS), full_path);
@@ -1558,12 +1584,19 @@
if (begin == NULL) {
begin = (char*) PORT_Strstr((const char*)ascii, X509CRLHEADER);
headerlen = strlen(X509CRLHEADER);
+ if (begin == NULL) {
+ begin = (char*) PORT_Strstr((const char*)ascii, NEWCRLHEADER);
+ headerlen = strlen(NEWCRLHEADER);
+ }
} else {
headerlen = strlen(CRLHEADER);
}
if (end == NULL) {
end = (char*) PORT_Strstr((const char*)ascii, X509CRLFOOTER);
+ if (end == NULL) {
+ end = (char*) PORT_Strstr((const char*)ascii, NEWCRLFOOTER);
+ }
}
if ((begin != NULL) && (end != NULL)) {
@@ -1799,7 +1832,6 @@
static void moduleOperation(char* op) {
const char *binary = "modutil"; /* PATH and LD_LIBRARY_PATH must already be set correctly */
const char *install_dir = LIBDIR;
- const char *database_dir = util_get_security_dir();
char *filename, *filetype, *dllname;
char cmd[BIG_LINE];
char msg[BIG_LINE];
@@ -1813,7 +1845,7 @@
}
PR_snprintf(cmd, sizeof(cmd), "%s -dbdir %s -force -nocertdb -delete \"%s\" 2>&1",
binary,
- database_dir,
+ securitydir,
dllname);
} else if (!PORT_Strcmp(op, "add")) {
@@ -1821,9 +1853,9 @@
filename = getParameter("filename",getResourceString(DBT_MISSING_FILE));
filetype = getParameter("format",getResourceString(DBT_MISSING_FORMAT));
- /* see if filename exists in database_dir (securitydir) */
+ /* see if filename exists in securitydir */
if(!util_is_valid_path_string(filename) ||
- !util_verify_file_or_dir(database_dir, PR_FILE_DIRECTORY, filename, -1, PR_FILE_FILE)) {
+ !util_verify_file_or_dir(securitydir, PR_FILE_DIRECTORY, filename, -1, PR_FILE_FILE)) {
PR_snprintf(msg, sizeof(msg), getResourceString(DBT_NO_FILE_EXISTS), filename);
rpt_err(FILE_ERROR, msg, NULL, NULL);
}
@@ -1848,11 +1880,11 @@
binary,
filename,
install_dir,
- database_dir);
+ securitydir);
else if (!PORT_Strcmp(filetype, "dll"))
PR_snprintf(cmd, sizeof(cmd), "%s -dbdir %s -add \"%s\" -libfile %s -force -nocertdb 2>&1",
binary,
- database_dir,
+ securitydir,
dllname,
filename);
@@ -1931,7 +1963,6 @@
/* cgi env setup */
int _ai = ADMUTIL_Init();
char * m = getenv("REQUEST_METHOD");
- char *securitydir = NULL; /* looked up via sie */
char msg[BIG_LINE];
AdmldapInfo ldapInfo; /* our config */
int rc = 0;
15 years, 4 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd main.c, 1.28, 1.29
by Nathan Kinder
Author: nkinder
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv24077/ldap/servers/slapd
Modified Files:
main.c
Log Message:
Resolves: 430368
Summary: Add check for permissions on nsslapd-rundir at startup.
Index: main.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/main.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- main.c 4 Dec 2008 00:50:18 -0000 1.28
+++ main.c 15 Dec 2008 17:42:25 -0000 1.29
@@ -978,6 +978,17 @@
exit(1);
}
+ /* Ensure that we can read from and write to our rundir */
+ if (access(config_get_rundir(), R_OK | W_OK)) {
+ LDAPDebug(LDAP_DEBUG_ANY, "Unable to access nsslapd-rundir: %s\n",
+ slapd_system_strerror(errno), 0, 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "Ensure that user \"%s\" has read and write "
+ "permissions on %s\n",
+ slapdFrontendConfig->localuser, config_get_rundir(), 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "Shutting down.\n", 0, 0, 0);
+ exit(1);
+ }
+
/*
* Detach ourselves from the terminal (unless running in debug mode).
* We must detach before we start any threads since detach forks() on
15 years, 4 months
[Fedora-directory-commits] ldapserver/ldap/servers/plugins/replication windows_protocol_util.c, 1.43, 1.44
by Richard Allen Megginson
Author: rmeggins
Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/replication
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv30518/ldapserver/ldap/servers/plugins/replication
Modified Files:
windows_protocol_util.c
Log Message:
Resolves: bug 476127
Bug Description: rhds80 seg fault - pass sync - entry missing userPassword ?
Reviewed by: nkinder (Thanks!)
Fix Description: The fix is pretty obvious - just make sure we don't deref a NULL. The reason for the NULL is due to a sequence of more than one modify for the userPassword attribute, where one of the mods is a replace with no value or a delete of the attribute. The bug has the details about how to reproduce. One thing I don't know is what client is generating this sequence of operations . . .
Platforms tested: RHEL5
Flag Day: no
Doc impact: no
QA impact: should be covered by regular nightly and manual testing
New Tests integrated into TET: none
Index: windows_protocol_util.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/windows_protocol_util.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- windows_protocol_util.c 5 Dec 2008 22:41:52 -0000 1.43
+++ windows_protocol_util.c 15 Dec 2008 15:59:41 -0000 1.44
@@ -1812,7 +1812,8 @@
} else
{
/* password mods are treated specially */
- if (0 == slapi_attr_type_cmp(attr_type, PSEUDO_ATTR_UNHASHEDUSERPASSWORD, SLAPI_TYPE_CMP_SUBTYPE) )
+ if ((0 == slapi_attr_type_cmp(attr_type, PSEUDO_ATTR_UNHASHEDUSERPASSWORD, SLAPI_TYPE_CMP_SUBTYPE)) &&
+ mod && mod->mod_bvalues && mod->mod_bvalues[0] && mod->mod_bvalues[0]->bv_val)
{
char *password_value = NULL;
password_value = mod->mod_bvalues[0]->bv_val;
15 years, 4 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd snmp_collator.c, 1.18, 1.19
by Nathan Kinder
Author: nkinder
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv12604/ldap/servers/slapd
Modified Files:
snmp_collator.c
Log Message:
Resolves: 437049
Summary: Log error to errors log when we have a problem writing stats file.
Index: snmp_collator.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/snmp_collator.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- snmp_collator.c 5 Dec 2008 22:41:52 -0000 1.18
+++ snmp_collator.c 12 Dec 2008 23:38:54 -0000 1.19
@@ -440,8 +440,8 @@
{
if (err != EEXIST) /* Ignore if file already exists */
{
- LDAPDebug( LDAP_DEBUG_ANY, "Failed to open stats file (%s) (error %d).\n",
- szStatsFile, err, 0 );
+ slapi_log_error(SLAPI_LOG_FATAL, "snmp collator", "Failed to open stats file (%s) "
+ "(error %d): %s.\n", szStatsFile, err, slapd_system_strerror(err));
exit(1);
}
}
15 years, 4 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd/back-ldbm dblayer.c, 1.34, 1.35 cache.c, 1.8, 1.9
by Noriko Hosoi
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv21242
Modified Files:
dblayer.c cache.c
Log Message:
Resolves: #178248
Summary: db backend entry cache settings field "Memory available for cache" boundaries
Fix Description:
db_strtoul: check the input string. If the string starts with '-', returning
the error ERANGE -- the same error as the larger the upper limit is passed.
cache.c: the minimum entry cache size defined in cache.c was 200000, which is
different from the info on the Configuration Command File Reference Guide:
Valid Range: 500 kilobytes to 4 gigabytes for 32-bit platforms and 500
kilobytes to 2^64-1 for 64-bit platforms
Adjusting the define to the doc.
Index: dblayer.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/dblayer.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- dblayer.c 20 Nov 2008 17:30:58 -0000 1.34
+++ dblayer.c 12 Dec 2008 21:09:31 -0000 1.35
@@ -3875,10 +3875,20 @@
unsigned long db_strtoul(const char *str, int *err)
{
- unsigned long val, result, multiplier = 1;
+ unsigned long val = 0, result, multiplier = 1;
char *p;
errno = 0;
+ /*
+ * manpage of strtoul: Negative values are considered valid input and
+ * are silently converted to the equivalent unsigned long int value.
+ */
+ /* We don't want to make it happen. */
+ for (p = str; p && *p && (*p == ' ' || *p == '\t'); p++) ;
+ if ('-' == *p) {
+ if (err) *err = ERANGE;
+ return val;
+ }
val = strtoul(str, &p, 10);
if (errno != 0) {
if (err) *err = errno;
Index: cache.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/cache.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- cache.c 11 Nov 2008 21:31:41 -0000 1.8
+++ cache.c 12 Dec 2008 21:09:31 -0000 1.9
@@ -50,7 +50,7 @@
#endif
/* cache can't get any smaller than this (in bytes) */
-#define MINCACHESIZE (size_t)200000
+#define MINCACHESIZE (size_t)512000
/* don't let hash be smaller than this # of slots */
#define MINHASHSIZE 1024
15 years, 4 months
[Fedora-directory-commits] ldapserver/ldap/admin/src/scripts repl-monitor.pl.in, NONE, 1.1 repl-monitor.pl, 1.2, NONE
by Nathan Kinder
Author: nkinder
Update of /cvs/dirsec/ldapserver/ldap/admin/src/scripts
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv14514
Added Files:
repl-monitor.pl.in
Removed Files:
repl-monitor.pl
Log Message:
Resolves: 250535
Summary: Make repl-monitor.pl a template to pass in correct perl environment.
--- NEW FILE repl-monitor.pl.in ---
#!@perlexec@
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2007 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
##############################################################################
#
# FILE: repl-monitor.pl
#
# SYNOPSIS:
# repl-monitor.pl -f configuration-file [-h host] [-p port] [-r]
# [-u refresh-url] [-t refresh-interval]
#
# repl-monitor.pl -v
#
# DESCRIPTION:
# Given an LDAP replication "supplier" server, crawl over all the ldap
# servers via direct or indirect replication agreements.
# For each master replica discovered, display the maxcsn of the master
# and the replication status of all its lower level replicas.
# All output is in HTML.
#
# OPTIONS:
# -f configuration-file
# The configuration file contains the sections for the connection
# parameters, the server alias, and the thresholds for different colors
# when display the time lags between consumers and master.
# If the Admin Server is running on Windows, the configuration-file
# name may have format "D:/opt/replmon.conf".
#
# The connection parameter section consists of the section name
# followed by one of more connection parameter entries:
#
# [connection]
# host:port:binddn:bindpwd:bindcert
# host:port=shadowport:binddn:bindpwd:bindcert
# ...
#
# where host:port default (*:*) to that in a replication agreement,
# binddn default (*) to "cn=Directory Manager", and bindcert is the
# pathname of cert db if you want the script to connect to the server
# via SSL. If bindcert is omitted, the connection will be simple
# bind.
# "port=shadowport" means to use shadowport instead of port if port
# is specified in the replication agreement. This is useful when
# for example, ssl port is specified in a replication agreement,
# but you can't access the cert db from the machine where this
# script is running. So you could let the script to map the ssl
# port to a non-ssl port and use the simple bind.
#
# A server may have a dedicated or a share entry in the connection
# section. The script will find out the most matched entry for a given
# server. For example, if all the ldap servers except host1 share the
# same binddn and bindpassword, the connection section then just need
# two entries:
#
# [connection]
# *:*:binddn:bindpassword:
# host1:*:binddn:bindpassword:
#
# If a host:port is assigned an alias, then the alias instead of
# host:port will be displayed in The output file. Each host:port
# can have only one alias. But each alias may be used by more than
# one host:port.
#
# [alias]
# alias = host:port
# ...
#
# CSN time lags between masters and consumers might be displayed in
# different colors based on their range. The thresholds for different
# colors may be specified in color section:
#
# [color]
# lowmark (in minutes) = color
# ...
#
# If the color section or color entry is missing, the default color
# set is: green for [0-5) minutes lag, yellow [5-60), and red 60 and more.
#
# -h host
# Initial replication supplier's host. Default to the current host.
#
# -p port
# Initial replication supplier's port. Default to 389.
#
# -r If specified, -r causes the routine to be entered without printing
# HTML header information. This is suitable when making multiple calls
# to this routine (e.g. when specifying multiple, different, "unrelated"
# supplier servers) and expecting a single HTML output.
#
# -t refresh-interval
# Specify the refresh interval in seconds. This option has to be
# jointly used with option -u.
#
# -u refresh-url
# The output HTML file may invoke a CGI program periodically. If
# this CGI program in turn calls this script, the effect is that
# the output HTML file would automatically refresh itself. This
# is useful for continuing monitoring. See also option -t.
#
# -v Print out the version of this script
#
# DIAGNOSTICS:
# There are several ways to invoke this script if you got error
# "Can't locate Mozilla/LDAP/Conn.pm in @INC", or
# "usage: Undefined variable":
#
# 0. Prerequisite: NSPR, NSS, Mozilla LDAP C SDK, PerLDAP
#
# 1. Run this perl script via repl-monitor, which sets up LD_LIBRARY_PATH
# $ repl-monitor
#
# 2. If 1 does not work, try invoking this script as follows.
# Assuming <MYPERLDIR> contains Mozilla/LDAP:
# perl -I <MYPERLDIR> repl-monitor.pl
#
#############################################################################
# enable the use of our bundled perldap with our bundled ldapsdk libraries
# all of this nonsense can be omitted if the mozldapsdk and perldap are
# installed in the operating system locations (e.g. /usr/lib /usr/lib/perl5)
# this script is always invoked by repl-monitor-cgi.pl, which sets all of these
# If using this script standalone, be sure to set the shared lib path and
# the path to the perldap modules.
use lib qw(@perlpath@);
$usage = "\nusage: $0 -f configuration-file [-h host] [-p port] [-r] [-u refresh-url] [-t refresh-interval]\n\nor : $0 -v\n";
use Getopt::Std; # parse command line arguments
use Mozilla::LDAP::Conn; # LDAP module for Perl
use Mozilla::LDAP::Utils qw(normalizeDN); # LULU, utilities.
use Mozilla::LDAP::API qw(:api :ssl :apiv3 :constant); # Direct access to C API
use Time::Local; # to convert GMT Z strings to localtime
#
# Global variables
#
$product = "Directory Server Replication Monitor";
$version = "Version 1.0";
#
# ldap servers given or discovered from the replication agreements:
# @servers = (host:port=shadowport:binddn:password:cert_db)
#
# entries read from the connection section of the configuration file:
# @allconnections = (host:port=shadowport:binddn:password:cert_db)
#
# aliases of ldap servers read from the configuration file:
# %allaliases{$host:$port}= (alias)
#
# replicas discovered on all ldap servers
# @allreplicas = (server#:replicaroot:replicatype:serverid:replicadn)
#
# ruvs retrieved from all replicas
# @allruvs{replica#:masterid} = (rawcsn:decimalcsn;mon/day/year hh:mi:ss)
#
# agreements discovered on all ldap supplier servers:
# @allagreements = (supplier_replica#:consumer#:conntype:schedule:status)
# the array may take another format after the consumer replicas are located:
# @allagreements = (supplier_replica#:consumer_replica#:conntype:schedule:status)
#
#main
{
# turn off buffered I/O
$| = 1;
# Check for legal options
if (!getopts('h:p:f:ru:t:v')) {
print $usage;
exit -1;
}
if ($opt_v) {
print "$product - $version\n";
exit;
}
$interval = $opt_t;
$interval = 300 if ( !$interval || $interval <= 0 );
# Get current date/time
$nowraw = localtime();
($wday, $mm, $dd, $tt, $yy) = split(/ /, $nowraw);
$now = "$wday $mm $dd $yy $tt";
# if no -r (Reenter and skip html header), print html header
if (!$opt_r) {
# print the HTML header
&print_html_header;
} else {
# print separator for new replication set
print "<hr width=90% size=3><br>\n";
}
exit -1 if &validateArgs < 0;
exit if &read_cfg_file ($opt_f) < 0;
# Start with the given host and port
# The index names in %ld are defined in Mozilla::LDAP::Utils::ldapArgs()
&add_server ("$ld{host}:$ld{port}:$ld{bind}:$ld{pswd}:$ld{cert}");
$serveridx = 0;
while ($serveridx <= $#servers) {
if (&get_replicas ($serveridx) != 0 && $serveridx == 0) {
my ($host, $port, $binddn) = split (/:/, $servers[0]);
print("Login to $host:$port as \"$binddn\" failed\n");
exit;
}
$serveridx++;
}
&find_consumer_replicas;
&process_suppliers;
# All done! - well, for the current invokation only
# print "</body></html>\n";
exit;
}
sub validateArgs
{
my ($rc) = 0;
%ld = Mozilla::LDAP::Utils::ldapArgs();
if (!$opt_v && !$opt_f) {
print "<p>Error: Missing configuration file.\n";
print "<p>If you need help on the configuration file, Please go back and click the Help button.\n";
#print $usage; # Don't show usage in CGI
$rc = -1;
}
elsif (!$opt_h) {
chop ($ld{"host"} = `hostname`);
}
return $rc;
}
sub read_cfg_file
{
my ($fn) = @_;
unless (open(CFGFILEHANDLE, $fn)) {
print "<p>Error: Can't open \"$fn\": $!.\n";
print "<p>If you need help on the configuration file, Please go back and click the Help button.\n";
return -1;
}
$section = 0;
while (<CFGFILEHANDLE>) {
next if (/^\s*\#/ || /^\s*$/);
chop ($_);
if (m/^\[(.*)\]/) {
$section = $1;
}
else {
if ( $section =~ /conn/i ) {
push (@allconnections, $_);
}
elsif ( $section =~ /alias/i ) {
m/^\s*(\S.*)\s*=\s*(\S+)/;
$allaliases {$2} = $1;
}
elsif ( $section =~ /color/i ) {
m/^\s*(-?\d+)\s*=\s*(\S+)/;
$allcolors {$1} = $2;
}
}
}
if ( ! keys (%allcolors) ) {
$allcolors {0} = "#ccffcc"; #apple green
$allcolors {5} = "#ffffcc"; #cream yellow
$allcolors {60} = "#ffcccc"; #pale pink
}
@colorkeys = sort (keys (%allcolors));
close (CFGFILEHANDLE);
return 0;
}
sub get_replicas
{
my ($serveridx) = @_;
my ($conn, $host, $port, $shadowport, $binddn, $bindpwd, $bindcert);
my ($others);
my ($replica, $replicadn);
my ($ruv, $replicaroot, $replicatype, $serverid, $masterid, $maxcsn);
my ($type, $flag, $i);
my ($myridx, $ridx, $cidx);
#
# Bind to the server
#
($host, $port, $binddn, $bindpwd, $bindcert) = split (/:/, "$servers[$serveridx]", 5);
($port, $shadowport) = split (/=/, $port);
$shadowport = $port if !$shadowport;
$conn = new Mozilla::LDAP::Conn ($host, $shadowport, "$binddn", $bindpwd, $bindcert);
return -1 if (!$conn);
#
# Get all the replica on the server
#
$myridx = $#allreplicas + 1;
$replica = $conn->search ("cn=mapping tree,cn=config",
"sub",
"(objectClass=nsDS5Replica)", 0,
qw(nsDS5ReplicaRoot nsDS5ReplicaType nsDS5Flags nsDS5ReplicaId));
while ($replica) {
$replicadn = $replica->getDN;
$replicaroot = normalizeDN ($replica->{nsDS5ReplicaRoot}[0]);
$type = $replica->{nsDS5ReplicaType}[0];
$flag = $replica->{nsDS5Flags}[0];
$serverid = $replica->{nsDS5ReplicaId}[0];
# flag = 0: change log is not created
# type = 2: read only replica
# type = 3: updatable replica
$replicatype = $flag == 0 ? "consumer" : ($type == 2 ? "hub" : "master");
push (@allreplicas, "$serveridx:$replicaroot:$replicatype:$serverid:$replicadn");
$replica = $conn->nextEntry ();
}
#
# Get ruv for each replica
#
for ($ridx = $myridx; $ridx <= $#allreplicas; $ridx++) {
$replicaroot = $1 if ($allreplicas[$ridx] =~ /^\d+:([^:]*)/);
# do a one level search with nsuniqueid in the filter - this will force the use of the
# nsuniqueid index instead of the entry dn index, which seems to be unreliable in
# heavily loaded servers
$ruv = $conn->search($replicaroot, "one",
"(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectClass=nsTombstone))",
0, qw(nsds50ruv nsruvReplicaLastModified));
next if !$ruv; # this should be an error case . . .
for ($ruv->getValues('nsds50ruv')) {
if (m/\{replica\s+(\d+).+?\}\s*\S+\s*(\S+)/i) {
$masterid = $1;
$maxcsn = &to_decimal_csn ($2);
$allruvs {"$ridx:$masterid"} = "$2:$maxcsn";
}
}
for ($ruv->getValues('nsruvReplicaLastModified')) {
if (m/\{replica\s+(\d+).+?\}\s*(\S+)/i) {
$masterid = $1;
$lastmodifiedat = hex($2);
my ($sec, $min, $hour, $mday, $mon, $year) = localtime ($lastmodifiedat);
$mon++;
$year += 1900;
$hour = "0".$hour if ($hour < 10);
$min = "0".$min if ($min < 10);
$sec = "0".$sec if ($sec < 10);
$allruvs {"$ridx:$masterid"} .= ";$mon/$mday/$year $hour:$min:$sec";
}
}
}
#
# Get all agreements for each supplier replica
#
for ($ridx = $myridx; $ridx <= $#allreplicas; $ridx++) {
$_ = $allreplicas[$ridx];
# Skip consumers
next if m/:consumer:/i;
m/:([^:]*)$/;
$replicadn = $1;
my @attrlist = qw(cn nsds5BeginReplicaRefresh nsds5replicaUpdateInProgress
nsds5ReplicaLastInitStatus nsds5ReplicaLastInitStart
nsds5ReplicaLastInitEnd nsds5replicaReapActive
nsds5replicaLastUpdateStart nsds5replicaLastUpdateEnd
nsds5replicaChangesSentSinceStartup nsds5replicaLastUpdateStatus
nsds5ReplicaHost
nsds5ReplicaPort nsDS5ReplicaBindMethod nsds5ReplicaUpdateSchedule);
$agreement = $conn->search("$replicadn", "sub", "(objectClass=nsDS5ReplicationAgreement)",
0, @attrlist);
while ($agreement) {
my %agmt = ();
# Push consumer to server stack if we have not already
$host = ($agreement->getValues('nsDS5ReplicaHost'))[0];
$port = ($agreement->getValues('nsDS5ReplicaPort'))[0];
$cidx = &add_server ("$host:$port");
for (@attrlist) {
$agmt{$_} = ($agreement->getValues($_))[0];
}
if ($agmt{nsDS5ReplicaBindMethod} =~ /simple/i) {
$agmt{nsDS5ReplicaBindMethod} = 'n';
}
if (!$agmt{nsds5ReplicaUpdateSchedule} ||
($agmt{nsds5ReplicaUpdateSchedule} eq '0000-2359 0123456') ||
($agmt{nsds5ReplicaUpdateSchedule} eq '*') ||
($agmt{nsds5ReplicaUpdateSchedule} eq '* *')) {
$agmt{nsds5ReplicaUpdateSchedule} = 'always in sync';
}
$agmt{ridx} = $ridx;
$agmt{cidx} = $cidx;
push @allagreements, \%agmt;
$agreement = $conn->nextEntry ();
}
}
$conn->close;
return 0;
}
#
# Initially, the agreements have consumer host:port info instead of
# replica info. This routine will find the consumer replica info
#
sub find_consumer_replicas
{
my ($m_ridx); # index of master's replica
my ($s_ridx); # index of supplier's replica
my ($c_ridx); # index of consumer's replica
my ($c_sidx); # index of consumer server
my ($remainder); #
my ($s_replicaroot); # supplier replica root
my ($c_replicaroot); # consumer replica root
my ($j, $val);
#
# Loop through every agreement defined on the current supplier replica
#
foreach (@allagreements) {
$s_ridx = $_->{ridx};
$c_sidx = $_->{cidx};
$s_replicaroot = $1 if ($allreplicas[$s_ridx] =~ /^\d+:([^:]*)/);
$c_replicaroot = "";
# $c_ridx will be assigned to -$c_sidx
# if the condumer is not accessible
# $c_sidx will not be zero since it's
# not the first server.
$c_ridx = -$c_sidx; # $c_sidx will not be zero
# Loop through consumer's replicas and find
# the counter part for the current supplier
# replica
for ($j = 0; $j <= $#allreplicas; $j++) {
# Get a replica on consumer
# I'm not sure what's going on here, but possibly could be made
# much simpler with normalizeDN and/or ldap_explode_dn
if ($allreplicas[$j] =~ /^$c_sidx:([^:]*)/) {
$val = $1;
# We need to find out the consumer
# replica that matches the supplier
# replicaroot most.
if ($s_replicaroot =~ /^.*$val$/i &&
length ($val) >= length ($c_replicaroot)) {
$c_ridx = $j;
# Avoid case-sensitive comparison
last if (length($s_replicaroot) == length($val));
$c_replicaroot = $val;
}
}
}
$_->{ridx} = $s_ridx;
$_->{cidx} = $c_ridx;
}
}
sub process_suppliers
{
my ($ridx, $mid, $maxcsn);
$mid = "";
$last_sidx = -1; # global variable for print html page
for ($ridx = 0; $ridx <= $#allreplicas; $ridx++) {
# Skip consumers and hubs
next if $allreplicas[$ridx] !~ /:master:(\d+):/i;
$mid = $1;
# Skip replicas without agreements defined yet
next if (! grep {$_->{ridx} == $ridx} @allagreements);
$maxcsn = &print_master_header ($ridx, $mid);
if ( "$maxcsn" != "none" ) {
&print_consumer_header ();
&print_consumers ($ridx, $mid);
}
&print_supplier_end;
}
if ($mid eq "") {
print "<p>The server is not a master or it has no replication agreement\n";
}
}
sub print_master_header
{
my ($ridx, $mid) = @_;
my ($myruv) = $allruvs {"$ridx:$mid"};
my ($maxcsnval) = split ( /;/, "$myruv" );
my ($maxcsn) = &to_string_csn ($maxcsnval);
my ($sidx, $replicaroot, $replicatype, $serverid) = split (/:/, $allreplicas[$ridx]);
# Print the master name
if ( $last_sidx != $sidx ) {
my ($ldapurl) = &get_ldap_url ($sidx, $sidx);
&print_legend if ( $last_sidx < 0);
print "<p><p><hr><p>\n";
print "\n<p><center class=page-subtitle><font color=#0099cc>\n";
print "Master:  $ldapurl</center>\n";
$last_sidx = $sidx;
}
# Print the current replica info onthe master
print "\n<p><table border=0 cellspacing=1 cellpadding=6 cols=10 width=100% class=bgColor9>\n";
print "\n<tr><td colspan=10><center>\n";
print "<font class=areatitle>Replica ID: </font>";
print "<font class=text28>$serverid</font>\n";
print "<font class=areatitle>Replica Root: </font>";
print "<font class=text28>$replicaroot</font>\n";
print "<font class=areatitle>Max CSN: </font>";
print "<font class=text28>$maxcsn</font>\n";
return $maxcsn;
}
sub print_consumer_header
{
#Print the header of consumer
print "\n<tr class=bgColor16>\n";
print "<th nowrap>Receiver</th>\n";
print "<th nowrap>Time Lag</th>\n";
print "<th nowrap>Max CSN</th>\n";
print "<th nowrap>Last Modify Time</th>\n";
print "<th nowrap>Supplier</th>\n";
print "<th nowrap>Sent/Skipped</th>\n";
print "<th nowrap>Update Status</th>\n";
print "<th nowrap>Update Started</th>\n";
print "<th nowrap>Update Ended</th>\n";
print "<th nowrap colspan=2>Schedule</th>\n";
print "<th nowrap>SSL?</th>\n";
print "</tr>\n";
}
sub print_consumers
{
my ($m_ridx, $mid) = @_;
my ($ignore, $m_replicaroot) = split (/:/, $allreplicas[$m_ridx]);
my (@consumers, @ouragreements, @myagreements);
my ($s_ridx, $c_ridx, $conntype, $schedule, $status);
my ($c_maxcsn_str, $lag, $markcolor);
my ($c_replicaroot, $c_replicatype);
my ($first_entry);
my ($nrows);
my ($found);
undef @ouragreements;
# Collect all the consumer replicas for the current master replica
push (@consumers, $m_ridx);
foreach (@consumers) {
$s_ridx = $_;
for (@allagreements) {
next if ($_->{ridx} != $s_ridx);
$c_ridx = $_->{cidx};
next if $c_ridx == $m_ridx;
push @ouragreements, $_;
$found = 0;
foreach (@consumers) {
if ($_ == $c_ridx) {
$found = 1;
last;
}
}
push (@consumers, $c_ridx) if !$found;
}
}
# Print each consumer replica
my ($myruv) = $allruvs {"$m_ridx:$mid"};
my ($m_maxcsn) = split ( /;/, "$myruv" );
foreach (@consumers) {
$c_ridx = $_;
next if $c_ridx == $m_ridx;
if ($c_ridx >= 0) {
$myruv = $allruvs {"$c_ridx:$mid"};
($c_maxcsn, $c_lastmodified) = split ( /;/, "$myruv" );
($c_maxcsn_str, $lag, $markcolor) = &cacl_time_lag ($m_maxcsn, $c_maxcsn);
$c_maxcsn_str =~ s/ /\<br\>/;
($c_sidx, $c_replicaroot, $c_replicatype) = split (/:/, $allreplicas[$c_ridx]);
$c_replicaroot = "same as master" if $m_replicaroot eq $c_replicaroot;
}
else {
# $c_ridx is actually -$c_sidx when c is not available
$c_sidx = -$c_ridx;
$c_maxcsn_str = "_";
$lag = "n/a";
$markcolor = red;
$c_replicaroot = "_";
$c_replicatype = "_";
}
$nrows = 0;
foreach (@ouragreements) {
next if ($_->{cidx} != $c_ridx);
$nrows++;
}
$first_entry = 1;
foreach (@ouragreements) {
next if ($_->{cidx} != $c_ridx);
$s_ridx = $_->{ridx};
$conntype = $_->{nsDS5ReplicaBindMethod};
$status = $_->{nsds5replicaLastUpdateStatus};
$schedule = $_->{nsds5ReplicaUpdateSchedule};
$s_sidx = $1 if $allreplicas [$s_ridx] =~ /^(\d+):/;
$s_ldapurl = &get_ldap_url ($s_sidx, "n/a");
# Print out the consumer's replica and ruvs
print "\n<tr class=bgColor13>\n";
if ($first_entry) {
$first_entry = 0;
$c_ldapurl = &get_ldap_url ($c_sidx, $conntype);
print "<td rowspan=$nrows width=5% class=bgColor5>$c_ldapurl<BR>Type: $c_replicatype</td>\n";
print "<td rowspan=$nrows width=5% nowrap bgcolor=$markcolor><center>$lag</center></td>\n";
print "<td rowspan=$nrows width=15% nowrap>$c_maxcsn_str</td>\n";
print "<td rowspan=$nrows width=15% nowrap>$c_lastmodified</td>\n";
}
print "<td width=5% nowrap><center>$s_ldapurl</center></td>\n";
my $changecount = $_->{nsds5replicaChangesSentSinceStartup};
if ( $changecount =~ /^$mid:(\d+)\/(\d+) / || $changecount =~ / $mid:(\d+)\/(\d+) / ) {
$changecount = "$1 / $2";
}
elsif ( $changecount =~ /^(\d+)$/ ) {
$changecount = $changecount . " / " . "$_->{nsds5replicaChangesSkippedSinceStartup}";
}
else {
$changecount = "0 / 0";
}
print "<td width=3% nowrap>$changecount</td>\n";
my $redfontstart = "";
my $redfontend = "";
if ($status =~ /error/i) {
$redfontstart = "<font color='red'>";
$redfontend = "</font>";
}
elsif ($status =~ /^(\d+) /) {
if ( $1 != 0 ) {
# warning
$redfontstart = "<font color='#FF7777'>";
$redfontend = "</font>";
}
}
print "<td width=20% nowrap>$redfontstart$status$redfontend</td>\n";
print "<td nowrap>", &format_z_time($_->{nsds5replicaLastUpdateStart}), "</td>\n";
print "<td nowrap>", &format_z_time($_->{nsds5replicaLastUpdateEnd}), "</td>\n";
if ( $schedule =~ /always/i ) {
print "<td colspan=2 width=10% nowrap>$schedule</td>\n";
}
else {
my ($ndays, @days);
$schedule =~ /(\d\d)(\d\d)-(\d\d)(\d\d) (\d+)/;
print "<td width=10% nowrap>$1:$2-$3:$4</td>\n";
$ndays = $5;
$ndays =~ s/(\d)/$1,/g;
@days = (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[eval $ndays];
print "<td width=10% nowrap>@days</td>\n";
}
print "<td width=3% nowrap class=bgColor5>$conntype</td>\n";
}
}
}
sub cacl_time_lag
{
my ($s_maxcsn, $c_maxcsn) = @_;
my ($markcolor);
my ($csn_str);
my ($s_tm, $c_tm, $lag_tm, $lag_str, $hours, $minute);
$csn_str = &to_string_csn ($c_maxcsn);
if ($s_maxcsn && !$c_maxcsn) {
$lag_str = "- ?:??:??";
$markcolor = &get_color (36000); # assume consumer has big latency
}
elsif (!$s_maxcsn && $c_maxcsn) {
$lag_str = "+ ?:??:??";
$markcolor = &get_color (1); # consumer is ahead of supplier
}
elsif ($s_maxcsn le $c_maxcsn) {
$lag_str = "0:00:00";
$markcolor = &get_color (0);
}
else {
my ($rawcsn, $decimalcsn) = split (/:/, $s_maxcsn);
($s_tm) = split(/ /, $decimalcsn);
($rawcsn, $decimalcsn) = split (/:/, $c_maxcsn);
($c_tm) = split(/ /, $decimalcsn);
if ($s_tm > $c_tm) {
$lag_tm = $s_tm - $c_tm;
$lag_str = "- ";
$markcolor = &get_color ($lag_tm);
}
else {
$lag_tm = $c_tm - $s_tm;
$lag_str = "+ ";
$markcolor = $allcolors{ $colorkeys[0] }; # no delay
}
$hours = int ($lag_tm / 3600);
$lag_str .= "$hours:";
$lag_tm = $lag_tm % 3600;
$minutes = int ($lag_tm / 60);
$minutes = "0".$minutes if ($minutes < 10);
$lag_str .= "$minutes:";
$lag_tm = $lag_tm % 60;
$lag_tm = "0".$lag_tm if ($lag_tm < 10);
$lag_str .= "$lag_tm";
}
return ($csn_str, $lag_str, $markcolor);
}
#
# The subroutine would append a new entry to the end of
# @servers if the host and port are new to @servers.
#
sub add_server
{
my ($host, $port, $binddn, $bindpwd, $bindcert) = split (/:/, "@_");
my ($shadowport) = $port;
my ($domainpattern) = '\.[^:]+';
my ($i);
# Remove the domain name from the host name
my ($hostnode) = $host;
$hostnode = $1 if $host =~ /^(\w+)\./;
# new host:port
if ($binddn eq "" || $bindpwd eq "" && $bindcert eq "") {
#
# Look up connection parameter in the order of
# host:port
# host:*
# *:port
# *:*
#
my (@myconfig, $h, $p, $d, $w, $c);
(@myconfig = grep (/^$hostnode($domainpattern)*:$port\D/i, @allconnections)) ||
(@myconfig = grep (/^$hostnode($domainpattern)*:\*:/i, @allconnections)) ||
(@myconfig = grep (/^\*:$port\D/, @allconnections)) ||
(@myconfig = grep (/^\*:\*\D/, @allconnections));
if ($#myconfig >= 0) {
($h, $p, $d, $w, $c) = split (/:/, $myconfig[0]);
($p, $shadowport) = split (/=/, $p);
$p = "" if $p eq "*";
$c = "" if $c eq "*";
}
if ($binddn eq "" || $binddn eq "*") {
if ($d eq "" || $d eq "*") {
$binddn = "cn=Directory Manager";
}
else {
$binddn = $d;
}
}
$bindpwd = $w if ($bindpwd eq "" || $bindpwd eq "*");
$bindcert = $c if ($bindcert eq "" || $bindcert eq "*");
}
for ($i = 0; $i <= $#servers; $i++) {
return $i if ($servers[$i] =~ /$hostnode($domainpattern)*:\d*=$shadowport\D/i);
}
if ($shadowport) {
push (@servers, "$host:$port=$shadowport:$binddn:$bindpwd:$bindcert");
} else {
push (@servers, "$host:$port:$binddn:$bindpwd:$bindcert");
}
return $i;
}
sub get_ldap_url
{
my ($sidx, $conntype) = @_;
my ($host, $port) = split(/:/, $servers[$sidx]);
my ($shadowport);
($port, $shadowport) = split (/=/, $port);
my ($protocol, $ldapurl);
if ($port eq 636 && $conntype eq "0" || $conntype =~ /SSL/i) {
$protocol = ldaps;
}
else {
$protocol = ldap;
}
my ($instance) = $allaliases { "$host:$port" };
$instance = "$host:$port" if !$instance;
if ($conntype eq "n/a") {
$ldapurl = $instance;
}
else {
$ldapurl = "<a href=\"$protocol://$host:$port/\">$instance</a>";
}
return $ldapurl;
}
sub to_decimal_csn
{
my ($maxcsn) = @_;
if (!$maxcsn || $maxcsn eq "") {
return "none";
}
my ($tm, $seq, $masterid, $subseq) = unpack("a8 a4 a4 a4", $maxcsn);
$tm = hex($tm);
$seq = hex($seq);
$masterid = hex($masterid);
$subseq = hex($subseq);
return "$tm $seq $masterid $subseq";
}
sub to_string_csn
{
my ($rawcsn, $decimalcsn) = split(/:/, "@_");
if (!$rawcsn || $rawcsn eq "") {
return "none";
}
my ($tm, $seq, $masterid, $subseq) = split(/ /, $decimalcsn);
my ($sec, $min, $hour, $mday, $mon, $year) = localtime($tm);
$mon++;
$year += 1900;
foreach ($sec, $min, $hour, $mday, $mon) {
$_ = "0".$_ if ($_ < 10);
}
my ($csnstr) = "$mon/$mday/$year $hour:$min:$sec";
$csnstr .= " $seq $subseq" if ( $seq != 0 || $subseq != 0 );
return "$rawcsn ($csnstr)";
}
sub get_color
{
my ($lag_minute) = @_;
$lag_minute /= 60;
my ($color) = $allcolors { $colorkeys[0] };
foreach (@colorkeys) {
last if ($lag_minute < $_);
$color = $allcolors {$_};
}
return $color;
}
# subroutine to remove escaped encoding
sub unescape
{
#my ($_) = @_;
tr/+/ /;
s/%(..)/pack("c",hex($1))/ge;
$_;
}
sub print_html_header
{
# print the HTML header
print "Content-type: text/html\n\n";
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\"><html>\n";
print "<head><title>Replication Status</title>\n";
# print "<link type=text/css rel=stylesheet href=\"master-style.css\">\n";
print "<style text/css>\n";
print "Body, p, table, td, ul, li {color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 12px;}\n";
print "A {color:blue; text-decoration: none;}\n";
print "BODY {font-family: arial, helvetica, sans-serif}\n";
print "P {font-family: arial, helvetica, sans-serif}\n";
print "TH {font-weight: bold; font-family: arial, helvetica, sans-serif}\n";
print "TD {font-family: arial, helvetica, sans-serif}\n";
print ".bgColor1 {background-color: #003366;}\n";
print ".bgColor4 {background-color: #cccccc;}\n";
print ".bgColor5 {background-color: #999999;}\n";
print ".bgColor9 {background-color: #336699;}\n";
print ".bgColor13 {background-color: #ffffff;}\n";
print ".bgColor16 {background-color: #6699cc;}\n";
print ".text8 {color: #0099cc; font-size: 11px; font-weight: bold;}\n";
print ".text28 {color: #ffcc33; font-size: 12px; font-weight: bold;}\n";
print ".areatitle {font-weight: bold; color: #ffffff; font-family: arial, helvetica, sans-serif}\n";
print ".page-title {font-weight: bold; font-size: larger; font-family: arial, helvetica, sans-serif}\n";
print ".page-subtitle {font-weight: bold; font-family: arial, helvetica, sans-serif}\n";
print "</style></head>\n<body class=bgColor4>\n";
if ($opt_u) {
print "<meta http-equiv=refresh content=$interval; URL=$opt_u>\n";
}
print "<table border=0 cellspacing=0 cellpadding=10 width=100% class=bgColor1>\n";
print "<tr><td><font class=text8>$now</font></td>\n";
print "<td align=center class=page-title><font color=#0099CC>";
print "Directory Server Replication Status</font>\n";
if ($opt_u) {
print "<br><font class=text8>(This page updates every $interval seconds)</font>\n";
}
print "</td><td align=right valign=center width=25%><font class=text8>$version";
print "</font></td></table>\n";
}
sub print_legend
{
my ($nlegends) = $#colorkeys + 1;
print "\n<center><p><font class=page-subtitle color=#0099cc>Time Lag Legend:</font><p>\n";
print "<table cellpadding=6 cols=$nlegends width=40%>\n<tr>\n";
my ($i, $j);
for ($i = 0; $i < $nlegends - 1; $i++) {
$j = $colorkeys[$i];
print "\n<td bgcolor=$allcolors{$j}><center>within $colorkeys[$i+1] min</center></td>\n";
}
$j = $colorkeys[$i];
print "\n<td bgcolor=$allcolors{$j}><center>over $colorkeys[$i] min</center></td>\n";
print "\n<td bgcolor=red><center>server n/a</center></td>\n";
print "</table></center>\n";
}
sub print_supplier_end
{
print "</table>\n";
}
# given a string in generalized time format, convert to ascii time
sub format_z_time
{
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";
}
--- repl-monitor.pl DELETED ---
15 years, 4 months
[Fedora-directory-commits] mod_admserv mod_admserv.c,1.36,1.37
by Nathan Kinder
Author: nkinder
Update of /cvs/dirsec/mod_admserv
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv5402
Modified Files:
mod_admserv.c
Log Message:
Resolves: 215788
Summary: Fixed copyright block.
Index: mod_admserv.c
===================================================================
RCS file: /cvs/dirsec/mod_admserv/mod_admserv.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- mod_admserv.c 9 Dec 2008 15:23:46 -0000 1.36
+++ mod_admserv.c 12 Dec 2008 19:45:05 -0000 1.37
@@ -1,4 +1,7 @@
-/* Copyright 2002-2004 The Apache Software Foundation
+/** BEGIN COPYRIGHT BLOCK
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,8 +14,8 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
-
+ *
+ * END COPYRIGHT BLOCK **/
/*
* mod_admserv.c: Provides communication link between Console and Directory.
*
15 years, 4 months
[Fedora-directory-commits] directoryconsole/src/com/netscape/admin/dirserv dirserv.properties, 1.9, 1.10
by Richard Allen Megginson
Author: rmeggins
Update of /cvs/dirsec/directoryconsole/src/com/netscape/admin/dirserv
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv26442/directoryconsole/src/com/netscape/admin/dirserv
Modified Files:
dirserv.properties
Log Message:
Resolves: bug 238762
Bug Description: Support "auto" for "Import cache size" in the LDBM Plug-in Settings
Reviewed by: nhosoi (Thanks!)
Fix Description: Added a check box for "use auto cache size". If this is checked, a value of -1 will be saved for nsslapd-import-cache-autosize which will tell the server to use the default auto cache value. If this is not checked, a value of 0 will be saved which will tell the server to use the number from nsslapd-import-cachesize. If the check box is checked, the import cachesize field will be disabled. Here are a couple of screen shots.
https://bugzilla.redhat.com/attachment.cgi?id=326699
https://bugzilla.redhat.com/attachment.cgi?id=326700
Platforms tested: RHEL5
Flag Day: no
Doc impact: yes - will have to document the new UI
Index: dirserv.properties
===================================================================
RCS file: /cvs/dirsec/directoryconsole/src/com/netscape/admin/dirserv/dirserv.properties,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- dirserv.properties 2 Dec 2008 15:27:37 -0000 1.9
+++ dirserv.properties 12 Dec 2008 18:35:37 -0000 1.10
@@ -1488,6 +1488,8 @@
pldbmsetting-importCacheSize-ttip= Size of cache used for import
pldbmsetting-importCacheSize-unit-label=bytes
pldbmsetting-importCacheSize-columns=15
+pldbmsetting-autoCacheSize-label=Use Import Cache Auto-Size
+pldbmsetting-autoCacheSize-ttip=If import cache auto-size is used, the server will automatically figure out the optimal amount of memory to use
#
15 years, 4 months
[Fedora-directory-commits] directoryconsole/src/com/netscape/admin/dirserv/panel LDBMPluginSettingPanel.java, 1.1.1.1, 1.2
by Richard Allen Megginson
Author: rmeggins
Update of /cvs/dirsec/directoryconsole/src/com/netscape/admin/dirserv/panel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv26442/directoryconsole/src/com/netscape/admin/dirserv/panel
Modified Files:
LDBMPluginSettingPanel.java
Log Message:
Resolves: bug 238762
Bug Description: Support "auto" for "Import cache size" in the LDBM Plug-in Settings
Reviewed by: nhosoi (Thanks!)
Fix Description: Added a check box for "use auto cache size". If this is checked, a value of -1 will be saved for nsslapd-import-cache-autosize which will tell the server to use the default auto cache value. If this is not checked, a value of 0 will be saved which will tell the server to use the number from nsslapd-import-cachesize. If the check box is checked, the import cachesize field will be disabled. Here are a couple of screen shots.
https://bugzilla.redhat.com/attachment.cgi?id=326699
https://bugzilla.redhat.com/attachment.cgi?id=326700
Platforms tested: RHEL5
Flag Day: no
Doc impact: yes - will have to document the new UI
Index: LDBMPluginSettingPanel.java
===================================================================
RCS file: /cvs/dirsec/directoryconsole/src/com/netscape/admin/dirserv/panel/LDBMPluginSettingPanel.java,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- LDBMPluginSettingPanel.java 18 Jul 2005 00:55:58 -0000 1.1.1.1
+++ LDBMPluginSettingPanel.java 12 Dec 2008 18:35:38 -0000 1.2
@@ -20,6 +20,8 @@
package com.netscape.admin.dirserv.panel;
import java.awt.*;
+import java.awt.event.ActionEvent;
+
import javax.swing.*;
import javax.swing.border.*;
import com.netscape.admin.dirserv.*;
@@ -37,7 +39,7 @@
*/
public class LDBMPluginSettingPanel extends BlankPanel {
- public LDBMPluginSettingPanel(IDSModel model, String dnEntry) {
+ public LDBMPluginSettingPanel(IDSModel model, String dnEntry) {
super(model, "pldbmsetting",true);
_helpToken = "configuration-database-plugin-setting-help";
_dnEntry = dnEntry;
@@ -75,6 +77,10 @@
_lRootDatabaseLoc = makeJLabel(_section,"RootDatabaseLoc");
_lRootDatabaseLoc.setLabelFor(_tfRootDatabaseLoc);
+ /* add check box for autocache size */
+ _cbAutoCacheSize = makeJCheckBox(_section,"autoCacheSize", false);
+
+ /* import cache size field */
_tfImportCacheSize = makeJTextField(_section,"importCacheSize");
_lImportCacheSize = makeJLabel( _section,"importCacheSize" );
_lImportCacheSize.setLabelFor(_tfImportCacheSize);
@@ -110,6 +116,10 @@
_lRootDatabaseLoc, false, isLocal());
entries.add(_dnEntry, DB_FILE_LOC_ATTR_NAME, fileEntry);
setComponentTable(_tfRootDatabaseLoc, fileEntry);
+
+ DSEntryBoolean autoDSEntry = new DSEntryBoolean(null, _cbAutoCacheSize, "-1", "0");
+ entries.add(_dnEntry, IMPORT_AUTO_CACHE_SIZE_ATTR_NAME, autoDSEntry);
+ setComponentTable(_cbAutoCacheSize, autoDSEntry);
DSEntryLong importsizeDSEntry = new DSEntryLong(null,
_tfImportCacheSize, _lImportCacheSize,
@@ -125,12 +135,38 @@
addEntryField( panel, _lMaxCacheSize, _tfMaxCacheSize, lMaxCacheSizeUnit );
addEntryField( panel, _lLookLimit, _tfLookLimit, lLookLimitUnit );
addEntryField( panel, _lModeFile, _tfModeFile, lModeFileUnit );
+ addEntryField( panel, new JLabel(""), _cbAutoCacheSize, new JLabel("") );
addEntryField( panel, _lImportCacheSize, _tfImportCacheSize,
lImportCacheSizeUnit);
addBottomGlue();
_isInitialized = true;
}
-
+
+ private void enableCacheSize() {
+ boolean enabled = !_cbAutoCacheSize.isSelected();
+ _tfImportCacheSize.setEnabled(enabled);
+ _lImportCacheSize.setEnabled(enabled);
+ }
+ /* (non-Javadoc)
+ * @see com.netscape.admin.dirserv.panel.BlankPanel#refresh()
+ */
+ public boolean refresh() {
+ // TODO Auto-generated method stub
+ boolean status = super.refresh();
+ enableCacheSize();
+ return status;
+ }
+
+ /* (non-Javadoc)
+ * @see com.netscape.admin.dirserv.panel.BlankPanel#actionPerformed(java.awt.event.ActionEvent)
+ */
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource().equals(_cbAutoCacheSize)) {
+ enableCacheSize();
+ }
+ super.actionPerformed(e);
+ }
+
private JTextField _tfMaxCacheSize;
private JLabel _lMaxCacheSize;
@@ -142,6 +178,8 @@
private JTextField _tfRootDatabaseLoc;
private JLabel _lRootDatabaseLoc;
+
+ private JCheckBox _cbAutoCacheSize;
private JTextField _tfImportCacheSize;
private JLabel _lImportCacheSize;
@@ -156,6 +194,8 @@
"nsslapd-directory";
private static final String DB_IMPORT__CACHE_SIZE_ATTR_NAM =
"nsslapd-import-cachesize";
+ private static final String IMPORT_AUTO_CACHE_SIZE_ATTR_NAME =
+ "nsslapd-import-cache-autosize";
private static final long LIMIT_MIN_VAL = -1;
private static final long LIMIT_MAX_VAL = Long.MAX_VALUE;
private static final long CACHE_SIZE_NUM_MIN_VAL = 500000;
15 years, 4 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd/back-ldbm filterindex.c, 1.7, 1.8
by Noriko Hosoi
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv12405/back-ldbm
Modified Files:
filterindex.c
Log Message:
Resolves: #475899
Summary: extensible filter having range operation crashes the server (comment#7)
Description: As Rich suggested, set the pb->pb_op to glob_pb->pb_op to catch
the abandon request in case the underlying operation is interrupted.
Index: filterindex.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/filterindex.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- filterindex.c 5 Dec 2008 21:03:52 -0000 1.7
+++ filterindex.c 12 Dec 2008 01:21:53 -0000 1.8
@@ -335,7 +335,7 @@
{
char *type;
IDList *idl;
- int unindexed = 0;
+ int unindexed = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 );
@@ -379,6 +379,7 @@
IDList* idl = NULL;
Slapi_PBlock* pb = slapi_pblock_new();
int mrOP = 0;
+ Slapi_Operation *op = NULL;
LDAPDebug (LDAP_DEBUG_TRACE, "=> extensible_candidates\n", 0, 0, 0);
if ( ! slapi_mr_filter_index (f, pb) && !slapi_pblock_get (pb, SLAPI_PLUGIN_MR_QUERY_OPERATOR, &mrOP))
{
@@ -389,13 +390,18 @@
case SLAPI_OP_EQUAL:
case SLAPI_OP_GREATER_OR_EQUAL:
case SLAPI_OP_GREATER:
- {
+ {
IFP mrINDEX = NULL;
void* mrOBJECT = NULL;
struct berval** mrVALUES = NULL;
char* mrOID = NULL;
char* mrTYPE = NULL;
+ /* set the pb->pb_op to glob_pb->pb_op to catch the abandon req.
+ * in case the operation is interrupted. */
+ slapi_pblock_get (glob_pb, SLAPI_OPERATION, &op);
+ slapi_pblock_set (pb, SLAPI_OPERATION, op);
+
slapi_pblock_get (pb, SLAPI_PLUGIN_MR_INDEX_FN, &mrINDEX);
slapi_pblock_get (pb, SLAPI_PLUGIN_OBJECT, &mrOBJECT);
slapi_pblock_get (pb, SLAPI_PLUGIN_MR_VALUES, &mrVALUES);
@@ -493,6 +499,8 @@
idl = idl_allids (be); /* all entries are candidates */
}
return_idl:
+ op = NULL;
+ slapi_pblock_set (pb, SLAPI_OPERATION, op);
slapi_pblock_destroy (pb);
LDAPDebug (LDAP_DEBUG_TRACE, "<= extensible_candidates %lu\n",
(u_long)IDL_NIDS(idl), 0, 0);
@@ -746,7 +754,7 @@
if ( (ftype == LDAP_FILTER_AND) && ((idl == NULL) ||
(idl_length(idl) <= FILTER_TEST_THRESHOLD))) {
break; /* We can exit the loop now, since the candidate list is small already */
- }
+ }
} else if ( ftype == LDAP_FILTER_AND ) {
if (isnot) {
IDList *new_idl = NULL;
15 years, 4 months