## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.
-SUBDIRS= slapd slurpd
+SUBDIRS= slapd
+++ /dev/null
-Design Notes: slurpd
-
-This new version differs significantly from previous versions:
-
-- It uses a multithreaded, single-process model. Previous versions forked
- a separate process for each replica. This new design should facilitate
- porting to NT, and is more straightforward.
-
-- Only one copy of the replication log is made. Previous versions made
-one copy of the replication log for each replica
-
-- This newer version is more object-oriented. Although still written in
- ANSI C (and compilable on k&r compilers), it encapsulates within the
- major data structures the methods used to access "private" data.
-
-General design overview:
-
-The main data structure in slurpd is a replication queue (struct rq).
-The rq data structure is currently implemented as a linked list of
-replication entries (struct re). The rq structure contains member functions
-used to initialize, add to, remove, and return the next re struct.
-
-In addition to the rq structure, there is one ri (replication information)
-struct for each replica. The ri struct encapsulates all information
-about a particular replica, e.g. hostname, port, bind dn. The single
-public member function, ri_process, is called to begin processing
-the replication entries in the queue.
-
-There is also a status structure (struct st) which contains the timestamp
-of the last successful replication operation for each replica. The
-contents of the st struct are flushed to disk after every successful
-operation. This disk file is read upon startup, and is used to allow
-slapd to "pick up where it left off".
-
-Threading notes:
-
-The LDAP liblthread quasi-pthreads interface is used for threading. At
-this point, machines which do not support pthreads, sun threads or lwp
-will probably not be able to run slurpd. Given the current threading
-method, discussed in the next paragraph, it will probably be necessary to
-have a separate hunk of code which handles non-threaded architectures
-(or we might just not worry about it). This needs further discussion.
-
-Upon startup, command-line arguments and the slapd configuration file
-are processed. One thread is started for each replica. Thread replicas,
-when no more work exists, wait on a condition variable, and the main
-thread's file manager routine broadcasts on this condition variable
-when new work is added to the queue.
-
-Additional notes:
- See doc/devel/replication-notes.txt
+++ /dev/null
-# Makefile.in for slurpd
-# $OpenLDAP$
-## This work is part of OpenLDAP Software <http://www.openldap.org/>.
-##
-## Copyright 1998-2007 The OpenLDAP Foundation.
-## All rights reserved.
-##
-## Redistribution and use in source and binary forms, with or without
-## modification, are permitted only as authorized by the OpenLDAP
-## Public License.
-##
-## A copy of this license is available in the file LICENSE in the
-## top-level directory of the distribution or, alternatively, at
-## <http://www.OpenLDAP.org/license.html>.
-
-PROGRAMS = slurpd
-XPROGRAMS = sslurpd
-
-XSRCS = version.c
-
-NT_SRCS = nt_svc.c
-NT_OBJS = nt_svc.o ../../libraries/liblutil/slapdmsg.res
-
-SRCS = admin.c args.c ch_malloc.c config.c \
- fm.c globals.c ldap_op.c lock.c main.c re.c \
- reject.c replica.c replog.c ri.c rq.c sanity.c st.c \
- $(@PLAT@_SRCS)
-OBJS = admin.o args.o ch_malloc.o config.o \
- fm.o globals.o ldap_op.o lock.o main.o re.o \
- reject.o replica.o replog.o ri.o rq.o sanity.o st.o \
- $(@PLAT@_OBJS)
-
-LDAP_INCDIR= ../../include
-LDAP_LIBDIR= ../../libraries
-
-BUILD_OPT = "--enable-slurpd"
-BUILD_SRV = @BUILD_SLURPD@
-
-all-local-srv: $(PROGRAMS)
-
-# $(LTHREAD_LIBS) must be last!
-XLIBS = $(SLURPD_L)
-XXLIBS = $(SLURPD_LIBS) $(SECURITY_LIBS) $(LUTIL_LIBS)
-XXXLIBS = $(LTHREAD_LIBS)
-
-slurpd: version.o
- $(LTLINK) -o $@ $(OBJS) version.o $(LIBS)
-
-sslurpd: version.o
- $(LTLINK) -static -o $@ $(OBJS) version.o $(LIBS)
-
-version.c: Makefile
- @-$(RM) $@
- $(MKVERSION) -s -n Versionstr slurpd > $@
-
-version.o: version.c $(OBJS) $(SLURPD_L)
-
-install-local-srv: FORCE
- -$(MKDIR) $(DESTDIR)$(libexecdir)
- @-$(INSTALL) -m 700 -d $(DESTDIR)$(localstatedir)/openldap-slurp
- @( \
- for prg in $(PROGRAMS); do \
- $(LTINSTALL) $(INSTALLFLAGS) $(STRIP) -m 755 $$prg$(EXEEXT) \
- $(DESTDIR)$(libexecdir); \
- done \
- )
-
+++ /dev/null
-Written by Ganesan Rajagopal <rganesan@debian.org> and placed in the public
-domain.
-
-Replication in OpenLDAP
------------------------
-
-Please read "Section 10. Replication with slurpd" in the OpenLDAP guide for
-an overview and configuration of single-master replication. This document
-describes the internals of the replication mechanism.
-
-slapd/repl.c contains routines add_replica_info() and
-add_replica_suffix(). add_replica_info() adds a new host to the list of
-replicas for a backend. add_replica_info() returns a number for the
-replica. add_replica_suffix() must then be called with the replica number to
-add a suffix that is hosted on this replica. add_replica_info() and add_replica_suffix() do not lock the
-replog_mutex.
-
-Replicas are specified in the slapd.conf file. When slapd/config.c sees a
-"replica" line in slapd.conf, it calls add_replica_info() with the host
-specified in the "host=" directive and then calls add_replica_suffix() with
-the replica number and and the suffix specified in the "suffix="
-directive.
-
-slapd writes out a replication log file containing LDIF change records for
-each configured replica for a suffix. The change records are generated for
-add, modify, delete and modrdn operations. A function called replog() is
-called at the end of the routines do_add (slapd/add.c),
-do_modify(slapd/modify.c), do_delete(slapd/delete.c) and
-do_modrdn(slapd/modrnd.c) to write out the change records.
-
-In master/slave replication, updates are not allowed on slave
-replicas. Therefore replog() is not called if the suffix is configured with
-a updatedn (which indicates that this is a slave replica), instead a
-referral is returned back to the client. If multi-master replication is
-enabled, replog() is always called whenever any of the above updates happen
-unless the dn which is making the change is the updatedn. When the dn making
-the change is the same as the updatedn, it is assumed that this entry is
-being replicated by a slurpd instance on another host. (Note: For this
-reason, the updatedn must not be a "regular" admin/user object in
-multi-master replication).
-
-The function replog() in slapd/repl.c generates the actual change
-records. Each change record is preceded by the list of replicas to which
-this change record needs to be replicated, the time when this change
-happened and the dn this change applies to. The pseudo code for replog() is
-follows
-
-1. Check that a replog exists.
-2. Lock the replog mutex.
-3. Open and lock the replog file.
-4. Normalize the dn for the entry and write out a "replica:" entry for each
- replica with a matching suffix.
-5. Write out the the timestamp and the dn for the entry.
-6. Depending on the type of change, write out an appropriate changetype
- record.
-7. Close the replication log
-8. Unlock the replog mutex
-
-slurpd has a file manager routine (function fm()) which watches for any
-change in the replication log. Whenever fm() detects a change in the
-replication log it locks the log, appends the records to slurpd's private
-copy of the replication log and truncates the log. See the slurpd/DESIGN
-file for a description of how slurpd works.
-
-slapd can be configured to write out a replication log even if no replicas
-are configured. In this case the administrator has to truncate the
-replication log manually (under a lock!).
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-/*
- * admin.c - routines for performing administrative tasks, e.g. on-the-fly
- * reconfiguration of slurpd.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/stdlib.h>
-
-#include <ac/signal.h>
-
-#include "slurp.h"
-#include "globals.h"
-
-
-/*
- * Eventually, do_admin will be the entry point for performing
- * administrative tasks. General idea: put commands in a file
- * somewhere, send slurpd a USR2 signal. The handler for
- * USR2 (this routine) reads the file and takes some action.
- *
- * For right now, this routine has been hijacked for debugging. When
- * slurpd receives a USR2 signal, it will dump its replication
- * queue to the disk file given by SLURPD_DUMPFILE.
- */
-RETSIGTYPE
-do_admin( int sig )
-{
- sglob->rq->rq_dump( sglob->rq );
- (void) SIGNAL_REINSTALL( sig, do_admin );
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-/*
- * args.c - process command-line arguments, and set appropriate globals.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-#include <ac/string.h>
-#include <ac/time.h>
-#include <ac/unistd.h>
-
-#include <ldap.h>
-#include <lutil.h>
-
-#include "slurp.h"
-#include "globals.h"
-
-
-static void
-usage( char *name )
-{
- fprintf( stderr, "usage: %s\t[-d debug-level] [-s syslog-level]\n", name );
- fprintf( stderr, "\t\t[-f slapd-config-file] [-r replication-log-file]\n" );
- fprintf( stderr, "\t\t[-t tmp-dir] [-o]\n" );
- fprintf( stderr, "\t\t[-n service-name]\n" );
-}
-
-
-
-/*
- * Interpret argv, and fill in any appropriate globals.
- */
-int
-doargs(
- int argc,
- char **argv,
- Globals *g
-)
-{
- int i;
- int rflag = 0;
-
- g->myname = strdup( lutil_progname( "slurpd", argc, argv ));
-
- while ( (i = getopt( argc, argv, "d:f:n:or:t:V" )) != EOF ) {
- switch ( i ) {
- case 'd': { /* set debug level and 'do not detach' flag */
- int level;
- g->no_detach = 1;
- if ( optarg[0] == '?' ) {
-#ifdef LDAP_DEBUG
- printf( "Debug levels:\n" );
- printf( "\tLDAP_DEBUG_TRACE\t%d\n",
- LDAP_DEBUG_TRACE );
- printf( "\tLDAP_DEBUG_PACKETS\t%d\n",
- LDAP_DEBUG_PACKETS );
- printf( "\tLDAP_DEBUG_ARGS\t\t%d\n",
- LDAP_DEBUG_ARGS );
- printf( "\tLDAP_DEBUG_CONNS\t%d\n",
- LDAP_DEBUG_CONNS );
- printf( "\tLDAP_DEBUG_BER\t\t%d\n",
- LDAP_DEBUG_BER );
- printf( "\tLDAP_DEBUG_FILTER\t%d\n",
- LDAP_DEBUG_FILTER );
- printf( "\tLDAP_DEBUG_CONFIG\t%d\n",
- LDAP_DEBUG_CONFIG );
- printf( "\tLDAP_DEBUG_ACL\t\t%d\n",
- LDAP_DEBUG_ACL );
- printf( "\tLDAP_DEBUG_ANY\t\t%d\n",
- LDAP_DEBUG_ANY );
- puts( "\tThe -d flag also prevents slurpd from detaching." );
-#endif /* LDAP_DEBUG */
- puts( "\tDebugging is disabled. -d 0 prevents slurpd from detaching." );
- return( -1 );
- }
-#ifdef LDAP_DEBUG
- if ( lutil_atoix( &level, optarg, 0 ) != 0 ) {
- fprintf( stderr, "unable to parse debug flag \"%s\".\n", optarg );
- usage( g->myname );
- return( -1 );
- }
- ldap_debug |= level;
-#else /* !LDAP_DEBUG */
- if ( lutil_atoi( &level, optarg ) != 0 || level != 0 )
- /* can't enable debugging - not built with debug code */
- fputs( "must compile with LDAP_DEBUG for debugging\n",
- stderr );
-#endif /* LDAP_DEBUG */
- } break;
- case 'f': /* slapd config file */
- LUTIL_SLASHPATH( optarg );
- g->slapd_configfile = strdup( optarg );
- break;
- case 'n': /* NT service name */
- if ( g->serverName ) free( g->serverName );
- g->serverName = strdup( optarg );
- break;
- case 'o':
- g->one_shot_mode = 1;
- break;
- case 'r': /* slapd replog file */
- LUTIL_SLASHPATH( optarg );
- snprintf( g->slapd_replogfile, sizeof g->slapd_replogfile,
- "%s", optarg );
- rflag++;
- break;
- case 't': { /* dir to use for our copies of replogs */
- size_t sz;
- LUTIL_SLASHPATH( optarg );
- g->slurpd_rdir = (char *)malloc (sz = (strlen(optarg) + sizeof(LDAP_DIRSEP "replica")));
- snprintf(g->slurpd_rdir, sz,
- "%s" LDAP_DIRSEP "replica", optarg);
- } break;
- case 'V':
- (g->version)++;
- break;
- default:
- usage( g->myname );
- return( -1 );
- }
- }
-
- if ( g->one_shot_mode && !rflag ) {
- fprintf( stderr, "If -o flag is given, -r flag must also be given.\n" );
- usage( g->myname );
- return( -1 );
- }
-
- /* Set location/name of our private copy of the slapd replog file */
- snprintf( g->slurpd_replogfile, sizeof g->slurpd_replogfile,
- "%s" LDAP_DIRSEP "%s", g->slurpd_rdir,
- DEFAULT_SLURPD_REPLOGFILE );
-
- /* Set location/name of the slurpd status file */
- snprintf( g->slurpd_status_file, sizeof g->slurpd_status_file,
- "%s" LDAP_DIRSEP "%s", g->slurpd_rdir,
- DEFAULT_SLURPD_STATUS_FILE );
-
- ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &ldap_debug);
- ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &ldap_debug);
- ldif_debug = ldap_debug;
-
-#ifdef LOG_LOCAL4
- openlog( g->myname, OPENLOG_OPTIONS, LOG_LOCAL4 );
-#elif LOG_DEBUG
- openlog( g->myname, OPENLOG_OPTIONS );
-#endif
-
- return 0;
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-#define CH_FREE 1
-
-/*
- * ch_malloc.c - malloc() and friends, with check for NULL return.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-#include <ac/socket.h>
-
-#include "../slapd/slap.h"
-
-
-#ifndef CSRIMALLOC
-
-/*
- * Just like malloc, except we check the returned value and exit
- * if anything goes wrong.
- */
-void *
-ch_malloc(
- ber_len_t size
-)
-{
- void *new;
-
- if ( (new = (void *) ber_memalloc( size )) == NULL ) {
- fprintf( stderr, "malloc of %lu bytes failed\n",
- (long) size );
- exit( EXIT_FAILURE );
- }
-
- return( new );
-}
-
-
-
-
-/*
- * Just like realloc, except we check the returned value and exit
- * if anything goes wrong.
- */
-void *
-ch_realloc(
- void *block,
- ber_len_t size
-)
-{
- void *new;
-
- if ( block == NULL ) {
- return( ch_malloc( size ) );
- }
-
- if ( size == 0 ) {
- ch_free( block );
- }
-
- if ( (new = (void *) ber_memrealloc( block, size )) == NULL ) {
- fprintf( stderr, "realloc of %lu bytes failed\n",
- (long) size );
- exit( EXIT_FAILURE );
- }
-
- return( new );
-}
-
-
-
-
-/*
- * Just like calloc, except we check the returned value and exit
- * if anything goes wrong.
- */
-void *
-ch_calloc(
- ber_len_t nelem,
- ber_len_t size
-)
-{
- void *new;
-
- if ( (new = (void *) ber_memcalloc( nelem, size )) == NULL ) {
- fprintf( stderr, "calloc of %lu elems of %lu bytes failed\n",
- (long) nelem, (long) size );
- exit( EXIT_FAILURE );
- }
-
- return( new );
-}
-
-/*
- * Just like strdup, except we check the returned value and exit
- * if anything goes wrong.
- */
-char *
-ch_strdup(
- const char *string
-)
-{
- char *new;
-
- if ( (new = ber_strdup( string )) == NULL ) {
- fprintf( stderr, "ch_strdup: duplication of \"%s\" failed\n",
- string );
- exit( EXIT_FAILURE );
- }
-
- return( new );
-}
-
-/*
- * Just like free, except we check to see if p is null.
- */
-void
-ch_free(
- void *p
-)
-{
- if ( p != NULL ) {
- ber_memfree( p );
- }
- return;
-}
-
-#endif
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * Portions Copyright 2003 Mark Benson.
- * Portions Copyright 2002 John Morrissey.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP). Additional signficant contributors
- * include:
- * John Morrissey
- * Mark Benson
- */
-
-
-/*
- * config.c - configuration file handling routines
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-#include <ac/string.h>
-#include <ac/socket.h>
-#include <ac/ctype.h>
-
-#include <ldap.h>
-#include <lutil.h>
-
-#include "slurp.h"
-#include "globals.h"
-
-#define ARGS_STEP 512
-
-/* Forward declarations */
-static void add_replica LDAP_P(( char **, int ));
-static int parse_replica_line LDAP_P(( char **, int, Ri *));
-static void parse_line LDAP_P(( char * ));
-static char *slurpd_getline LDAP_P(( FILE * ));
-static char *strtok_quote LDAP_P(( char *, char * ));
-
-int cargc = 0, cargv_size = 0;
-char **cargv;
-/* current config file line # */
-static int lineno;
-
-char *slurpd_pid_file = NULL;
-char *slurpd_args_file = NULL;
-
-/*
- * Read the slapd config file, looking only for config options we're
- * interested in. Since we haven't detached from the controlling
- * terminal yet, we just perror() and fprintf here.
- */
-int
-slurpd_read_config(
- char *fname
-)
-{
- FILE *fp;
- char *line;
-
-#define GOT_REPLOG_NO (0)
-#define GOT_REPLOG_ONE (1)
-#define GOT_REPLOG_YES (2)
-#define GOT_REPLOG_DONE (3)
-#define GOT_REPLOG_MASK (0xF)
-#define GOT_REPLOG(i) ((i) & GOT_REPLOG_MASK)
-#define GOT_REPLOG_SET(i,v) ((i) = ((i) & ~GOT_REPLOG_MASK) | ((v) & GOT_REPLOG_MASK))
-
-#define GOT_REPLOG_PID (0x10)
-#define GOT_REPLOG_ARGS (0x20)
-#define GOT_REPLOG_INTERVAL (0x40)
- int got_replog = GOT_REPLOG_NO;
-
- /*
- * replica-pidfile and replica-argsfile can appear before any replog;
- * in this case they're global (legacy behavior); otherwise, since
- * each replog needs a slurpd, they can appear after a replogfile line;
- * in that case, the replog specific values are used.
- */
-
- if ( cargv == NULL ) {
- cargv = ch_calloc( ARGS_STEP + 1, sizeof(*cargv) );
- cargv_size = ARGS_STEP + 1;
- }
-
- Debug( LDAP_DEBUG_CONFIG, "Config: opening config file \"%s\"\n",
- fname, 0, 0 );
-
- if ( (fp = fopen( fname, "r" )) == NULL ) {
- perror( fname );
- exit( EXIT_FAILURE );
- }
-
- lineno = 0;
- while ( (line = slurpd_getline( fp )) != NULL ) {
- /* skip comments and blank lines */
- if ( line[0] == '#' || line[0] == '\0' ) {
- continue;
- }
-
- Debug( LDAP_DEBUG_CONFIG, "Config: (%s)\n", line, 0, 0 );
-
- parse_line( line );
-
- if ( cargc < 1 ) {
- fprintf( stderr, "line %d: bad config line (ignored)\n", lineno );
- continue;
- }
-
- /* replication log file to which changes are appended */
- if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
- /*
- * if slapd_replogfile has a value, the -r option was given,
- * so use that value. If slapd_replogfile has length == 0,
- * then we should use the value in the config file we're reading.
- */
- if ( cargc < 2 ) {
- fprintf( stderr,
- "line %d: missing filename in \"replogfile ",
- lineno );
- fprintf( stderr, "<filename>\" line\n" );
- exit( EXIT_FAILURE );
-
- } else if ( cargc > 2 && *cargv[2] != '#' ) {
- fprintf( stderr,
- "line %d: extra cruft at the end of \"replogfile %s\"",
- lineno, cargv[1] );
- fprintf( stderr, "line (ignored)\n" );
- }
-
- LUTIL_SLASHPATH( cargv[1] );
- if ( sglob->slapd_replogfile[0] == '\0' ) {
- strcpy( sglob->slapd_replogfile, cargv[1] );
- GOT_REPLOG_SET(got_replog, GOT_REPLOG_YES);
-
- } else {
- if ( strcmp( sglob->slapd_replogfile, cargv[1] ) == 0 ) {
- GOT_REPLOG_SET(got_replog, GOT_REPLOG_YES);
-
- } else if ( GOT_REPLOG(got_replog) == GOT_REPLOG_YES ) {
- GOT_REPLOG_SET(got_replog, GOT_REPLOG_DONE);
-
- } else {
- GOT_REPLOG_SET(got_replog, GOT_REPLOG_ONE);
- }
- }
-
- } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
- add_replica( cargv, cargc );
-
- /* include another config file */
- } else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
- char *savefname;
- int savelineno;
-
- if ( cargc < 2 ) {
- Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing filename in \"include <filename>\" line\n",
- fname, lineno, 0 );
-
- fclose( fp );
- return( 1 );
- }
- LUTIL_SLASHPATH( cargv[1] );
- savefname = strdup( cargv[1] );
- savelineno = lineno;
-
- if ( slurpd_read_config( savefname ) != 0 ) {
- fclose( fp );
- return( 1 );
- }
-
- free( savefname );
- lineno = savelineno - 1;
-
- } else if ( strcasecmp( cargv[0], "replica-pidfile" ) == 0 ) {
- if ( cargc < 2 ) {
- Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing file name in \"replica-pidfile <file>\" line\n",
- fname, lineno, 0 );
-
- fclose( fp );
- return( 1 );
- }
-
- switch ( GOT_REPLOG(got_replog) ) {
- case GOT_REPLOG_YES:
- Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
- "got replog specific replica-pidfile \"%s\".\n",
- fname, lineno, cargv[1] );
- case GOT_REPLOG_NO:
- LUTIL_SLASHPATH( cargv[1] );
- if ( slurpd_pid_file != NULL ) {
- ch_free( slurpd_pid_file );
- }
- slurpd_pid_file = ch_strdup( cargv[1] );
- got_replog |= GOT_REPLOG_PID;
- break;
-
- default:
- Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
- "replica-pidfile \"%s\" not mine.\n",
- fname, lineno, cargv[1] );
- break;
- }
-
- } else if ( strcasecmp( cargv[0], "replica-argsfile" ) == 0 ) {
- if ( cargc < 2 ) {
- Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing file name in \"argsfile <file>\" line\n",
- fname, lineno, 0 );
-
- fclose( fp );
- return( 1 );
- }
-
- switch ( GOT_REPLOG(got_replog) ) {
- case GOT_REPLOG_YES:
- Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
- "got replog specific replica-argsfile \"%s\".\n",
- fname, lineno, cargv[1] );
- case GOT_REPLOG_NO:
- LUTIL_SLASHPATH( cargv[1] );
- if ( slurpd_args_file != NULL ) {
- ch_free( slurpd_args_file );
- }
- slurpd_args_file = ch_strdup( cargv[1] );
- got_replog |= GOT_REPLOG_ARGS;
- break;
-
- default:
- Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
- "replica-argsfile \"%s\" not mine.\n",
- fname, lineno, cargv[1] );
- break;
- }
-
- } else if ( strcasecmp( cargv[0], "replicationinterval" ) == 0 ) {
- int c;
-
- if ( cargc < 2 ) {
- Debug( LDAP_DEBUG_ANY, "%s: line %d: missing interval in "
- "\"replicationinterval <seconds>\" line\n",
- fname, lineno, 0 );
- fclose( fp );
- return( 1 );
- }
-
- if ( lutil_atoi( &c, cargv[1] ) != 0 || c < 1 ) {
- Debug( LDAP_DEBUG_ANY, "%s: line %d: invalid interval "
- "(%d) in \"replicationinterval <seconds>\" line\n",
- fname, lineno, c );
-
- fclose( fp );
- return( 1 );
- }
-
- switch ( GOT_REPLOG(got_replog) ) {
- case GOT_REPLOG_YES:
- Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
- "got replog specific replicationinterval \"%s\".\n",
- fname, lineno, cargv[1] );
- case GOT_REPLOG_NO:
- sglob->no_work_interval = c;
- got_replog |= GOT_REPLOG_INTERVAL;
- break;
-
- default:
- Debug( LDAP_DEBUG_CONFIG, "%s: line %d: "
- "replicationinterval \"%s\" not mine.\n",
- fname, lineno, cargv[1] );
- break;
- }
- }
- }
-
- fclose( fp );
- Debug( LDAP_DEBUG_CONFIG,
- "Config: ** configuration file successfully read and parsed\n",
- 0, 0, 0 );
- return 0;
-}
-
-
-
-
-/*
- * Parse one line of input.
- */
-static void
-parse_line(
- char *line
-)
-{
- char * token;
-
- cargc = 0;
- for ( token = strtok_quote( line, " \t" ); token != NULL;
- token = strtok_quote( NULL, " \t" ) )
- {
- if ( cargc == cargv_size - 1 ) {
- char **tmp;
- tmp = ch_realloc( cargv, (cargv_size + ARGS_STEP) *
- sizeof(*cargv) );
- if (tmp == NULL) {
- cargc = 0;
- return;
- }
- cargv = tmp;
- cargv_size += ARGS_STEP;
- }
-
- cargv[cargc++] = token;
- }
- cargv[cargc] = NULL;
-}
-
-
-
-
-static char *
-strtok_quote(
- char *line,
- char *sep
-)
-{
- int inquote;
- char *tmp;
- static char *next;
-
- if ( line != NULL ) {
- next = line;
- }
- while ( *next && strchr( sep, *next ) ) {
- next++;
- }
-
- if ( *next == '\0' ) {
- next = NULL;
- return( NULL );
- }
- tmp = next;
-
- for ( inquote = 0; *next; ) {
- switch ( *next ) {
- case '"':
- if ( inquote ) {
- inquote = 0;
- } else {
- inquote = 1;
- }
- AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
- break;
-
- case '\\':
- if ( next[1] )
- AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
- next++; /* dont parse the escaped character */
- break;
-
- default:
- if ( ! inquote ) {
- if ( strchr( sep, *next ) != NULL ) {
- *next++ = '\0';
- return( tmp );
- }
- }
- next++;
- break;
- }
- }
-
- return( tmp );
-}
-
-#define CATLINE( buf ) { \
- int len; \
- len = strlen( buf ); \
- while ( lcur + len + 1 > lmax ) { \
- lmax += BUFSIZ; \
- line = (char *) ch_realloc( line, lmax ); \
- } \
- strcpy( line + lcur, buf ); \
- lcur += len; \
-}
-
-
-
-/*
- * Get a line of input.
- */
-static char *
-slurpd_getline(
- FILE *fp
-)
-{
- char *p;
- static char buf[BUFSIZ];
- static char *line;
- static int lmax, lcur;
-
- lcur = 0;
- CATLINE( buf );
- while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
- if ( (p = strchr( buf, '\n' )) != NULL ) {
- if( p > buf && p[-1] == '\r' ) --p;
- *p = '\0';
- }
- lineno++;
- if ( ! isspace( (unsigned char) buf[0] ) ) {
- return( line );
- }
-
- /* change leading whitespace to space */
- buf[0] = ' ';
-
- CATLINE( buf );
- }
- buf[0] = '\0';
-
- return( line[0] ? line : NULL );
-}
-
-
-/*
- * Add a node to the array of replicas.
- */
-static void
-add_replica(
- char **cargv,
- int cargc
-)
-{
- int nr;
-
- nr = ++sglob->num_replicas;
- sglob->replicas = (Ri **) ch_realloc( sglob->replicas,
- ( nr + 1 ) * sizeof( Re * ));
- if ( sglob->replicas == NULL ) {
- fprintf( stderr, "out of memory, add_replica\n" );
- exit( EXIT_FAILURE );
- }
- sglob->replicas[ nr ] = NULL;
-
- if ( Ri_init( &(sglob->replicas[ nr - 1 ])) < 0 ) {
- fprintf( stderr, "out of memory, Ri_init\n" );
- exit( EXIT_FAILURE );
- }
- if ( parse_replica_line( cargv, cargc,
- sglob->replicas[ nr - 1] ) < 0 ) {
- /* Something bad happened - back out */
- fprintf( stderr,
- "Warning: failed to add replica \"%s:%d - ignoring replica\n",
- sglob->replicas[ nr - 1 ]->ri_hostname == NULL ?
- "(null)" : sglob->replicas[ nr - 1 ]->ri_hostname,
- sglob->replicas[ nr - 1 ]->ri_port );
- sglob->replicas[ nr - 1] = NULL;
- sglob->num_replicas--;
- } else {
- Debug( LDAP_DEBUG_CONFIG,
- "Config: ** successfully added replica \"%s:%d\"\n",
- sglob->replicas[ nr - 1 ]->ri_hostname == NULL ?
- "(null)" : sglob->replicas[ nr - 1 ]->ri_hostname,
- sglob->replicas[ nr - 1 ]->ri_port, 0 );
- sglob->replicas[ nr - 1]->ri_stel =
- sglob->st->st_add( sglob->st,
- sglob->replicas[ nr - 1 ] );
- if ( sglob->replicas[ nr - 1]->ri_stel == NULL ) {
- fprintf( stderr, "Failed to add status element structure\n" );
- exit( EXIT_FAILURE );
- }
- }
-}
-
-
-
-/*
- * Parse a "replica" line from the config file. replica lines should be
- * in the following format:
- * replica host=<hostname:portnumber> binddn=<binddn>
- * bindmethod="simple" credentials=<creds>
- *
- * where:
- * <hostname:portnumber> describes the host name and port number where the
- * replica is running,
- *
- * <binddn> is the DN to bind to the replica slapd as,
- *
- * bindmethod is "simple", and
- *
- * <creds> are the credentials (e.g. password) for binddn. <creds> are
- * only used for bindmethod=simple.
- *
- * The "replica" config file line may be split across multiple lines. If
- * a line begins with whitespace, it is considered a continuation of the
- * previous line.
- */
-#define GOT_HOST 1
-#define GOT_DN 2
-#define GOT_METHOD 4
-#define GOT_ALL ( GOT_HOST | GOT_DN | GOT_METHOD )
-#define GOT_MECH 8
-
-static int
-parse_replica_line(
- char **cargv,
- int cargc,
- Ri *ri
-)
-{
- int gots = 0;
- int i;
- char *hp, *val;
- LDAPURLDesc *ludp;
-
- for ( i = 1; i < cargc; i++ ) {
- if ( !strncasecmp( cargv[ i ], HOSTSTR, sizeof( HOSTSTR ) - 1 ) ) {
- if ( gots & GOT_HOST ) {
- fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
- fprintf( stderr, "file, too many host or uri names specified, line %d\n",
- lineno );
- return -1;
- }
- val = cargv[ i ] + sizeof( HOSTSTR ); /* '\0' string terminator accounts for '=' */
- if (( hp = strchr( val, ':' )) != NULL ) {
- *hp = '\0';
- hp++;
- if ( lutil_atoi( &ri->ri_port, hp ) != 0 ) {
- fprintf( stderr, "unable to parse port \"%s\", line %d\n",
- hp, lineno );
- return -1;
- }
- }
- if ( ri->ri_port <= 0 ) {
- ri->ri_port = LDAP_PORT;
- }
- ri->ri_hostname = strdup( val );
- gots |= GOT_HOST;
- } else if ( !strncasecmp( cargv[ i ], URISTR, sizeof( URISTR ) - 1 ) ) {
- if ( gots & GOT_HOST ) {
- fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
- fprintf( stderr, "file, too many host or uri names specified, line %d\n",
- lineno );
- return -1;
- }
- if ( ldap_url_parse( cargv[ i ] + sizeof( URISTR ), &ludp ) != LDAP_SUCCESS ) {
- fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
- fprintf( stderr, "file, bad uri format specified, line %d\n",
- lineno );
- return -1;
- }
- if (ludp->lud_host == NULL) {
- fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
- fprintf( stderr, "file, missing uri hostname, line %d\n",
- lineno );
- ldap_free_urldesc( ludp );
- return -1;
- }
- ri->ri_hostname = strdup ( ludp->lud_host );
- ri->ri_port = ludp->lud_port;
- ri->ri_uri = strdup ( cargv[ i ] + sizeof( URISTR ) );
- ldap_free_urldesc( ludp );
- gots |= GOT_HOST;
- } else if ( !strncasecmp( cargv[ i ],
- ATTRSTR, sizeof( ATTRSTR ) - 1 ) ) {
- /* ignore it */ ;
- } else if ( !strncasecmp( cargv[ i ],
- SUFFIXSTR, sizeof( SUFFIXSTR ) - 1 ) ) {
- /* ignore it */ ;
- } else if ( !strncasecmp( cargv[i], STARTTLSSTR, sizeof(STARTTLSSTR)-1 )) {
- val = cargv[ i ] + sizeof( STARTTLSSTR );
- if( !strcasecmp( val, CRITICALSTR ) ) {
- ri->ri_tls = TLS_CRITICAL;
- } else {
- ri->ri_tls = TLS_ON;
- }
- } else if ( !strncasecmp( cargv[ i ], TLSSTR, sizeof( TLSSTR ) - 1 ) ) {
- val = cargv[ i ] + sizeof( TLSSTR );
- if( !strcasecmp( val, CRITICALSTR ) ) {
- ri->ri_tls = TLS_CRITICAL;
- } else {
- ri->ri_tls = TLS_ON;
- }
- } else if ( !strncasecmp( cargv[ i ],
- BINDDNSTR, sizeof( BINDDNSTR ) - 1 ) ) {
- val = cargv[ i ] + sizeof( BINDDNSTR );
- ri->ri_bind_dn = strdup( val );
- gots |= GOT_DN;
- } else if ( !strncasecmp( cargv[ i ], BINDMETHSTR,
- sizeof( BINDMETHSTR ) - 1 ) ) {
- val = cargv[ i ] + sizeof( BINDMETHSTR );
- if ( !strcasecmp( val, SIMPLESTR )) {
- ri->ri_bind_method = LDAP_AUTH_SIMPLE;
- gots |= GOT_METHOD;
- } else if ( !strcasecmp( val, SASLSTR )) {
- ri->ri_bind_method = LDAP_AUTH_SASL;
- gots |= GOT_METHOD;
- } else {
- ri->ri_bind_method = -1;
- }
- } else if ( !strncasecmp( cargv[ i ],
- SASLMECHSTR, sizeof( SASLMECHSTR ) - 1 ) ) {
- val = cargv[ i ] + sizeof( SASLMECHSTR );
- gots |= GOT_MECH;
- ri->ri_saslmech = strdup( val );
- } else if ( !strncasecmp( cargv[ i ],
- CREDSTR, sizeof( CREDSTR ) - 1 ) ) {
- val = cargv[ i ] + sizeof( CREDSTR );
- ri->ri_password = strdup( val );
- } else if ( !strncasecmp( cargv[ i ],
- SECPROPSSTR, sizeof( SECPROPSSTR ) - 1 ) ) {
- val = cargv[ i ] + sizeof( SECPROPSSTR );
- ri->ri_secprops = strdup( val );
- } else if ( !strncasecmp( cargv[ i ],
- REALMSTR, sizeof( REALMSTR ) - 1 ) ) {
- val = cargv[ i ] + sizeof( REALMSTR );
- ri->ri_realm = strdup( val );
- } else if ( !strncasecmp( cargv[ i ],
- AUTHCSTR, sizeof( AUTHCSTR ) - 1 ) ) {
- val = cargv[ i ] + sizeof( AUTHCSTR );
- ri->ri_authcId = strdup( val );
- } else if ( !strncasecmp( cargv[ i ],
- OLDAUTHCSTR, sizeof( OLDAUTHCSTR ) - 1 ) ) {
- /* Old authcID is provided for some backwards compatibility */
- val = cargv[ i ] + sizeof( OLDAUTHCSTR );
- ri->ri_authcId = strdup( val );
- } else if ( !strncasecmp( cargv[ i ],
- AUTHZSTR, sizeof( AUTHZSTR ) - 1 ) ) {
- val = cargv[ i ] + sizeof( AUTHZSTR );
- ri->ri_authzId = strdup( val );
- } else {
- fprintf( stderr,
- "Error: parse_replica_line: unknown keyword \"%s\"\n",
- cargv[ i ] );
- }
- }
-
- if ( ri->ri_bind_method == LDAP_AUTH_SASL) {
- if ((gots & GOT_MECH) == 0) {
- fprintf( stderr, "Error: \"replica\" line needs SASLmech flag in " );
- fprintf( stderr, "slapd config file, line %d\n", lineno );
- return -1;
- }
- } else if ( gots != GOT_ALL ) {
- fprintf( stderr, "Error: Malformed \"replica\" line in slapd " );
- fprintf( stderr, "config file, line %d\n", lineno );
- return -1;
- }
- return 0;
-}
-
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-/*
- * fm.c - file management routines.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-#include <ac/string.h>
-#include <ac/signal.h>
-#include <ac/socket.h>
-#include <ac/unistd.h>
-
-#include "slurp.h"
-#include "globals.h"
-#include "lutil.h"
-
-
-/*
- * Forward references
- */
-static char *get_record LDAP_P(( FILE * ));
-static void populate_queue LDAP_P(( char *f ));
-
-
-/*
- * Main file manager routine. Watches for new data to be appended to the
- * slapd replication log. When new data is appended, fm does the following:
- * - appends the data to slurpd's private copy of the replication log.
- * - truncates the slapd replog
- * - adds items to the internal queue of replication work to do
- * - signals the replication threads to let them know new work has arrived.
- */
-void *
-fm(
- void *arg
-)
-{
- int rc;
- int i;
- fd_set readfds;
-
- /* Set up our signal handlers:
- * SIG{TERM,INT,HUP} causes a shutdown
- */
- (void) SIGNAL( SIGTERM, slurp_set_shutdown );
- (void) SIGNAL( SIGINT, slurp_set_shutdown );
-#ifdef SIGHUP
- (void) SIGNAL( SIGHUP, slurp_set_shutdown );
-#endif
-#if defined(SIGBREAK)
- (void) SIGNAL( SIGBREAK, slurp_set_shutdown );
-#endif
-
- if ( sglob->one_shot_mode ) {
- if ( file_nonempty( sglob->slapd_replogfile )) {
- populate_queue( sglob->slapd_replogfile );
- }
- printf( "Processing in one-shot mode:\n" );
- printf( "%d total replication records in file,\n",
- sglob->rq->rq_getcount( sglob->rq, RQ_COUNT_ALL ));
- printf( "%d replication records to process.\n",
- sglob->rq->rq_getcount( sglob->rq, RQ_COUNT_NZRC ));
- return NULL;
- }
- /*
- * There may be some leftover replication records in our own
- * copy of the replication log. If any exist, add them to the
- * queue.
- */
- if ( file_nonempty( sglob->slurpd_replogfile )) {
- populate_queue( sglob->slurpd_replogfile );
- }
-
- FD_ZERO( &readfds );
-
- while ( !sglob->slurpd_shutdown ) {
- if ( file_nonempty( sglob->slapd_replogfile )) {
- /* New work found - copy to slurpd replog file */
- Debug( LDAP_DEBUG_ARGS, "new work in %s\n",
- sglob->slapd_replogfile, 0, 0 );
- if (( rc = copy_replog( sglob->slapd_replogfile,
- sglob->slurpd_replogfile )) == 0 ) {
- populate_queue( sglob->slurpd_replogfile );
- } else {
- if ( rc < 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "Fatal error while copying replication log\n",
- 0, 0, 0 );
- sglob->slurpd_shutdown = 1;
- }
- }
- } else {
- struct timeval tv;
-
- FD_SET( sglob->wake_sds[0], &readfds );
- tv.tv_sec = sglob->no_work_interval;
- tv.tv_usec = 0;
-
- rc = select( sglob->wake_sds[0]+1, &readfds, NULL, NULL, &tv );
- }
-
- /* Garbage-collect queue */
- sglob->rq->rq_gc( sglob->rq );
-
- /* Trim replication log file, if needed */
- if ( sglob->rq->rq_needtrim( sglob->rq )) {
- FILE *fp, *lfp;
- if (( rc = acquire_lock( sglob->slurpd_replogfile, &fp,
- &lfp )) < 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: cannot acquire lock on \"%s\" for trimming\n",
- sglob->slurpd_replogfile, 0, 0 );
- } else {
- sglob->rq->rq_write( sglob->rq, fp );
- (void) relinquish_lock( sglob->slurpd_replogfile, fp, lfp );
- }
- }
- }
- sglob->rq->rq_lock( sglob->rq ); /* lock queue */
- ldap_pvt_thread_cond_broadcast( &(sglob->rq->rq_more) ); /* wake repl threads */
- for ( i = 0; i < sglob->num_replicas; i++ ) {
- (sglob->replicas[ i ])->ri_wake( sglob->replicas[ i ]);
- }
- sglob->rq->rq_unlock( sglob->rq ); /* unlock queue */
- Debug( LDAP_DEBUG_ARGS, "fm: exiting\n", 0, 0, 0 );
- return NULL;
-}
-
-
-
-
-/*
- * Set a global flag which signals that we're shutting down.
- */
-RETSIGTYPE
-slurp_set_shutdown(int sig)
-{
-#if HAVE_NT_SERVICE_MANAGER && SIGBREAK
- if (is_NT_Service && sig == SIGBREAK) {
- /* empty */;
- } else
-#endif
- {
- sglob->slurpd_shutdown = 1; /* set flag */
- tcp_write( sglob->wake_sds[1], "0", 1); /* wake up file mgr */
- }
-
- (void) SIGNAL_REINSTALL( sig, slurp_set_shutdown ); /* reinstall handlers */
-}
-
-
-
-
-/*
- * A do-nothing signal handler.
- */
-RETSIGTYPE
-do_nothing(int sig)
-{
- (void) SIGNAL_REINSTALL( sig, do_nothing );
-}
-
-
-
-
-/*
- * Open the slurpd replication log, seek to our last known position, and
- * process any pending replication entries.
- */
-static void
-populate_queue(
- char *f
-)
-{
- FILE *fp, *lfp;
- char *p;
-
- if ( acquire_lock( f, &fp, &lfp ) < 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "error: can't lock file \"%s\": %s\n",
- f, sys_errlist[ errno ], 0 );
- return;
- }
-
- /*
- * Read replication records from fp and append them the
- * the queue.
- */
- if ( fseek( fp, sglob->srpos, 0 ) < 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "error: can't seek to offset %ld in file \"%s\"\n",
- sglob->srpos, f, 0 );
- } else {
- while (( p = get_record( fp )) != NULL ) {
- if ( sglob->rq->rq_add( sglob->rq, p ) < 0 ) {
- char *t;
- /* Print an error message. Only print first line. */
- if (( t = strchr( p, '\n' )) != NULL ) {
- *t = '\0';
- }
- Debug( LDAP_DEBUG_ANY,
- "error: malformed replog entry (begins with \"%s\")\n",
- p, 0, 0 );
- }
- free( p );
- ldap_pvt_thread_yield();
- }
- sglob->srpos = ftell( fp );
- }
- (void) relinquish_lock( f, fp, lfp );
-}
-
-
-
-
-/*
- * Get the next "record" from the file pointed to by fp. A "record"
- * is delimited by two consecutive newlines. Returns NULL on EOF.
- */
-static char *
-get_record(
- FILE *fp
-)
-{
- int len;
- static char line[BUFSIZ];
- char *buf = NULL;
- static int lcur, lmax;
-
- lcur = lmax = 0;
-
- while (( fgets( line, sizeof(line), fp ) != NULL ) &&
- (( len = strlen( line )) > 1 )) {
-
- while ( lcur + len + 1 > lmax ) {
- lmax += BUFSIZ;
- buf = (char *) ch_realloc( buf, lmax );
- }
- strcpy( buf + lcur, line );
- lcur += len;
- }
- return( buf );
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-/*
- * globals.c - initialization code for global data
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-#include <ac/string.h>
-
-#include "slurp.h"
-#include "globals.h"
-
-Globals *sglob;
-static Globals glob;
-
-int ldap_syslog = 0;
-#ifdef LOG_DEBUG
-int ldap_syslog_level = LOG_DEBUG;
-#else
-int ldap_syslog_level = 0;
-#endif
-int ldap_debug = 0;
-
-/*
- * Initialize the globals
- */
-Globals *
-init_globals( void )
-{
- Globals *g;
-
- g = &glob;
-
- g->wake_sds[0] = -1;
- g->wake_sds[1] = -1;
-
-#ifdef HAVE_NT_SERVICE_MANAGER
- g->slapd_configfile = ".\\slapd.conf";
- g->slurpd_rdir = ".\\replica";
-#else
- g->slapd_configfile = SLAPD_DEFAULT_CONFIGFILE;
- g->slurpd_rdir = DEFAULT_SLURPD_REPLICA_DIR "/replica";
-#endif
-
- g->no_work_interval = DEFAULT_NO_WORK_INTERVAL;
- g->slurpd_shutdown = 0;
- g->num_replicas = 0;
- g->replicas = NULL;
- g->slapd_replogfile[ 0 ] = '\0';
- g->slurpd_replogfile[ 0 ] = '\0';
- g->slurpd_status_file[ 0 ] = '\0';
- g->one_shot_mode = 0;
- g->no_detach = 0;
- g->myname = NULL;
- g->serverName = NULL;
- g->srpos = 0L;
- g->version = 0;
- if ( St_init( &(g->st)) < 0 ) {
- fprintf( stderr, "Cannot initialize status data\n" );
- exit( EXIT_FAILURE );
- }
- ldap_pvt_thread_mutex_init( &(g->rej_mutex) );
- if ( Rq_init( &(g->rq)) < 0 ) {
- fprintf( stderr, "Cannot initialize queue\n" );
- exit( EXIT_FAILURE );
- }
-
- return g;
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-#ifndef SLURPD_GLOBALS_H
-#define SLURPD_GLOBALS_H 1
-
-/*
- * globals.h - definition of structure holding global data.
- */
-
-#include "slurp.h"
-
-LDAP_BEGIN_DECL
-
-typedef struct globals {
- /* Thread ID for file manager thread */
- ldap_pvt_thread_t fm_tid;
- /* pipe/socket used to wake manager from signal handler */
- int wake_sds[2];
- /* The name of the slapd config file (which is also our config file) */
- char *slapd_configfile;
- /* How long the master slurpd sleeps when there's no work to do */
- int no_work_interval;
- /* We keep running until slurpd_shutdown is nonzero. HUP signal set this */
- sig_atomic_t slurpd_shutdown;
- /* Number of replicas we're servicing */
- int num_replicas;
- /* Array of pointers to replica info */
- Ri **replicas;
- /* Directory where our replica files are written/read */
- char *slurpd_rdir;
- /* Name of slurpd status file (timestamp of last replog */
- char slurpd_status_file[ MAXPATHLEN ];
- /* Name of the replication log slapd is writing (and we are reading) */
- char slapd_replogfile[ MAXPATHLEN ];
- /* Name of local copy of replogfile we maintain */
- char slurpd_replogfile[ MAXPATHLEN ];
- /* Non-zero if we were given a replog file to process on command-line */
- int one_shot_mode;
- /* Non-zero if we should not detach the process */
- int no_detach;
- /* Name of program */
- char *myname;
- /* NT service name */
- char *serverName;
- /* Current offset into slurpd replica logfile */
- off_t srpos;
- /* mutex to serialize access to reject file */
- ldap_pvt_thread_mutex_t rej_mutex;
- /* pointer to status struct */
- St *st;
- /* Pointer to replication queue */
- Rq *rq;
- /* Non-zero if we shall print the version */
- int version;
-} Globals;
-
-
-extern Globals *sglob;
-
-LDAP_END_DECL
-
-#endif /* SLURPD_GLOBALS_H */
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * Portions Copyright 2003 Mark Benson.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP). Additional significant contributors
- * include:
- * Mark Benson
- */
-
-/*
- * ldap_op.c - routines to perform LDAP operations
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-
-#include <ac/errno.h>
-#include <ac/string.h>
-#include <ac/ctype.h>
-#include <ac/time.h>
-#include <ac/unistd.h>
-
-#define LDAP_DEPRECATED 1
-#include <ldap.h>
-#include "lutil_ldap.h"
-#include "slurp.h"
-
-/* Forward references */
-static struct berval **make_singlevalued_berval LDAP_P(( char *, int ));
-static int op_ldap_add LDAP_P(( Ri *, Re *, char **, int * ));
-static int op_ldap_modify LDAP_P(( Ri *, Re *, char **, int * ));
-static int op_ldap_delete LDAP_P(( Ri *, Re *, char **, int * ));
-static int op_ldap_modrdn LDAP_P(( Ri *, Re *, char **, int * ));
-static LDAPMod *alloc_ldapmod LDAP_P(( void ));
-static void free_ldapmod LDAP_P(( LDAPMod * ));
-static void free_ldmarr LDAP_P(( LDAPMod ** ));
-static int getmodtype LDAP_P(( char * ));
-#ifdef SLAPD_UNUSED
-static void dump_ldm_array LDAP_P(( LDAPMod ** ));
-#endif
-static int do_bind LDAP_P(( Ri *, int * ));
-static int do_unbind LDAP_P(( Ri * ));
-
-
-/*
- * Determine the type of ldap operation being performed and call the
- * appropriate routine.
- * - If successful, returns DO_LDAP_OK
- * - If a retryable error occurs, ERR_DO_LDAP_RETRYABLE is returned.
- * The caller should wait a while and retry the operation.
- * - If a fatal error occurs, ERR_DO_LDAP_FATAL is returned. The caller
- * should reject the operation and continue with the next replication
- * entry.
- */
-int
-do_ldap(
- Ri *ri,
- Re *re,
- char **errmsg,
- int *errfree
-)
-{
- int retry = 2;
- *errmsg = NULL;
- *errfree = 0;
-
- do {
- int lderr;
- if ( ri->ri_ldp == NULL ) {
- lderr = do_bind( ri, &lderr );
-
- if ( lderr != BIND_OK ) {
- return DO_LDAP_ERR_RETRYABLE;
- }
- }
-
- switch ( re->re_changetype ) {
- case T_ADDCT:
- lderr = op_ldap_add( ri, re, errmsg, errfree );
- if ( lderr != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: ldap_add_s failed adding DN \"%s\": %s\n",
- re->re_dn, *errmsg && (*errmsg)[0] ?
- *errmsg : ldap_err2string( lderr ), 0 );
- }
- break;
-
- case T_MODIFYCT:
- lderr = op_ldap_modify( ri, re, errmsg, errfree );
- if ( lderr != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: ldap_modify_s failed modifying DN \"%s\": %s\n",
- re->re_dn, *errmsg && (*errmsg)[0] ?
- *errmsg : ldap_err2string( lderr ), 0 );
- }
- break;
-
- case T_DELETECT:
- lderr = op_ldap_delete( ri, re, errmsg, errfree );
- if ( lderr != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: ldap_delete_s failed deleting DN \"%s\": %s\n",
- re->re_dn, *errmsg && (*errmsg)[0] ?
- *errmsg : ldap_err2string( lderr ), 0 );
- }
- break;
-
- case T_MODRDNCT:
- lderr = op_ldap_modrdn( ri, re, errmsg, errfree );
- if ( lderr != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: ldap_modrdn_s failed modifying DN \"%s\": %s\n",
- re->re_dn, *errmsg && (*errmsg)[0] ?
- *errmsg : ldap_err2string( lderr ), 0 );
- }
- break;
-
- default:
- Debug( LDAP_DEBUG_ANY,
- "Error: do_ldap: bad op \"%d\", DN \"%s\"\n",
- re->re_changetype, re->re_dn, 0 );
- return DO_LDAP_ERR_FATAL;
- }
-
- /*
- * Analyze return code. If ok, just return. If LDAP_SERVER_DOWN,
- * we may have been idle long enough that the remote slapd timed
- * us out. Rebind and try again.
- */
- switch( lderr ) {
- case LDAP_SUCCESS:
- return DO_LDAP_OK;
-
- default:
- return DO_LDAP_ERR_FATAL;
-
- case LDAP_SERVER_DOWN: /* server went down */
- (void) do_unbind( ri );
- retry--;
- }
- } while ( retry > 0 );
-
- return DO_LDAP_ERR_RETRYABLE;
-}
-
-
-
-/*
- * Perform an ldap add operation.
- */
-static int
-op_ldap_add(
- Ri *ri,
- Re *re,
- char **errmsg,
- int *errfree
-)
-{
- Mi *mi;
- int nattrs, rc = 0, i;
- LDAPMod *ldm, **ldmarr;
- int lderr = 0;
-
- nattrs = i = 0;
- ldmarr = NULL;
-
- /*
- * Construct a null-terminated array of LDAPMod structs.
- */
- mi = re->re_mods;
- while ( mi[ i ].mi_type != NULL ) {
- ldm = alloc_ldapmod();
- ldmarr = ( LDAPMod ** ) ch_realloc( ldmarr,
- ( nattrs + 2 ) * sizeof( LDAPMod * ));
- ldmarr[ nattrs ] = ldm;
- ldm->mod_op = LDAP_MOD_BVALUES;
- ldm->mod_type = mi[ i ].mi_type;
- ldm->mod_bvalues =
- make_singlevalued_berval( mi[ i ].mi_val, mi[ i ].mi_len );
- i++;
- nattrs++;
- }
-
- if ( ldmarr != NULL ) {
- ldmarr[ nattrs ] = NULL;
-
- /* Perform the operation */
- Debug( LDAP_DEBUG_ARGS, "replica %s:%d - add dn \"%s\"\n",
- ri->ri_hostname, ri->ri_port, re->re_dn );
- rc = ldap_add_s( ri->ri_ldp, re->re_dn, ldmarr );
-
- ldap_get_option( ri->ri_ldp, LDAP_OPT_RESULT_CODE, &lderr);
- ldap_get_option( ri->ri_ldp, LDAP_OPT_DIAGNOSTIC_MESSAGE, errmsg);
- *errfree = 1;
-
- } else {
- *errmsg = "No modifications to do";
- Debug( LDAP_DEBUG_ANY,
- "Error: op_ldap_add: no mods to do (%s)!\n", re->re_dn, 0, 0 );
- }
- free_ldmarr( ldmarr );
- return( lderr );
-}
-
-
-
-
-/*
- * Perform an ldap modify operation.
- */
-#define AWAITING_OP -1
-static int
-op_ldap_modify(
- Ri *ri,
- Re *re,
- char **errmsg,
- int *errfree
-)
-{
- Mi *mi;
- int state; /* This code is a simple-minded state machine */
- int nvals; /* Number of values we're modifying */
- int nops; /* Number of LDAPMod structs in ldmarr */
- LDAPMod *ldm = NULL, **ldmarr;
- int i, len;
- char *type, *value;
- int rc = 0;
-
- state = AWAITING_OP;
- nvals = 0;
- nops = 0;
- ldmarr = NULL;
-
- if ( re->re_mods == NULL ) {
- *errmsg = "No arguments given";
- Debug( LDAP_DEBUG_ANY, "Error: op_ldap_modify: no arguments\n",
- 0, 0, 0 );
- return -1;
- }
-
- /*
- * Construct a null-terminated array of LDAPMod structs.
- */
- for ( mi = re->re_mods, i = 0; mi[ i ].mi_type != NULL; i++ ) {
- type = mi[ i ].mi_type;
- value = mi[ i ].mi_val;
- len = mi[ i ].mi_len;
- switch ( getmodtype( type )) {
- case T_MODSEP:
- state = T_MODSEP; /* Got a separator line "-\n" */
- continue;
- case T_MODOPADD:
- state = T_MODOPADD;
- ldmarr = ( LDAPMod ** )
- ch_realloc(ldmarr, (( nops + 2 ) * ( sizeof( LDAPMod * ))));
- ldmarr[ nops ] = ldm = alloc_ldapmod();
- ldm->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
- ldm->mod_type = value;
- nvals = 0;
- nops++;
- break;
- case T_MODOPREPLACE:
- state = T_MODOPREPLACE;
- ldmarr = ( LDAPMod ** )
- ch_realloc(ldmarr, (( nops + 2 ) * ( sizeof( LDAPMod * ))));
- ldmarr[ nops ] = ldm = alloc_ldapmod();
- ldm->mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
- ldm->mod_type = value;
- nvals = 0;
- nops++;
- break;
- case T_MODOPDELETE:
- state = T_MODOPDELETE;
- ldmarr = ( LDAPMod ** )
- ch_realloc(ldmarr, (( nops + 2 ) * ( sizeof( LDAPMod * ))));
- ldmarr[ nops ] = ldm = alloc_ldapmod();
- ldm->mod_op = LDAP_MOD_DELETE | LDAP_MOD_BVALUES;
- ldm->mod_type = value;
- nvals = 0;
- nops++;
- break;
- case T_MODOPINCREMENT:
- state = T_MODOPINCREMENT;
- ldmarr = ( LDAPMod ** )
- ch_realloc(ldmarr, (( nops + 2 ) * ( sizeof( LDAPMod * ))));
- ldmarr[ nops ] = ldm = alloc_ldapmod();
- ldm->mod_op = LDAP_MOD_INCREMENT | LDAP_MOD_BVALUES;
- ldm->mod_type = value;
- nvals = 0;
- nops++;
- break;
- default:
- if ( state == AWAITING_OP ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: op_ldap_modify: unknown mod type \"%s\"\n",
- type, 0, 0 );
- continue;
- }
-
- assert( ldm != NULL );
-
- /*
- * We should have an attribute: value pair here.
- * Construct the mod_bvalues part of the ldapmod struct.
- */
- if ( strcasecmp( type, ldm->mod_type )) {
- Debug( LDAP_DEBUG_ANY,
- "Error: malformed modify op, %s: %s (expecting %s:)\n",
- type, value, ldm->mod_type );
- continue;
- }
- ldm->mod_bvalues = ( struct berval ** )
- ch_realloc( ldm->mod_bvalues,
- ( nvals + 2 ) * sizeof( struct berval * ));
- ldm->mod_bvalues[ nvals + 1 ] = NULL;
- ldm->mod_bvalues[ nvals ] = ( struct berval * )
- ch_malloc( sizeof( struct berval ));
- ldm->mod_bvalues[ nvals ]->bv_val = value;
- ldm->mod_bvalues[ nvals ]->bv_len = len;
- nvals++;
- }
- }
- ldmarr[ nops ] = NULL;
-
- if ( nops > 0 ) {
- /* Actually perform the LDAP operation */
- Debug( LDAP_DEBUG_ARGS, "replica %s:%d - modify dn \"%s\"\n",
- ri->ri_hostname, ri->ri_port, re->re_dn );
- rc = ldap_modify_s( ri->ri_ldp, re->re_dn, ldmarr );
- ldap_get_option( ri->ri_ldp, LDAP_OPT_DIAGNOSTIC_MESSAGE, errmsg);
- *errfree = 1;
- }
- free_ldmarr( ldmarr );
- return( rc );
-}
-
-
-
-
-/*
- * Perform an ldap delete operation.
- */
-static int
-op_ldap_delete(
- Ri *ri,
- Re *re,
- char **errmsg,
- int *errfree
-)
-{
- int rc;
-
- Debug( LDAP_DEBUG_ARGS, "replica %s:%d - delete dn \"%s\"\n",
- ri->ri_hostname, ri->ri_port, re->re_dn );
- rc = ldap_delete_s( ri->ri_ldp, re->re_dn );
- ldap_get_option( ri->ri_ldp, LDAP_OPT_DIAGNOSTIC_MESSAGE, errmsg);
- *errfree = 1;
-
- return( rc );
-}
-
-
-
-
-/*
- * Perform an ldap modrdn operation.
- */
-#define GOT_NEWRDN 0x1
-#define GOT_DELOLDRDN 0x2
-#define GOT_NEWSUP 0x4
-
-#define GOT_MODDN_REQ (GOT_NEWRDN|GOT_DELOLDRDN)
-#define GOT_ALL_MODDN(f) (((f) & GOT_MODDN_REQ) == GOT_MODDN_REQ)
-static int
-op_ldap_modrdn(
- Ri *ri,
- Re *re,
- char **errmsg,
- int *errfree
-)
-{
- int rc = 0;
- Mi *mi;
- int i;
- int lderr = 0;
- int state = 0;
- int drdnflag = -1;
- char *newrdn = NULL;
- char *newsup = NULL;
-
- if ( re->re_mods == NULL ) {
- *errmsg = "No arguments given";
- Debug( LDAP_DEBUG_ANY, "Error: op_ldap_modrdn: no arguments\n",
- 0, 0, 0 );
- return -1;
- }
-
- /*
- * Get the arguments: should see newrdn: and deleteoldrdn: args.
- */
- for ( mi = re->re_mods, i = 0; mi[ i ].mi_type != NULL; i++ ) {
- if ( !strcmp( mi[ i ].mi_type, T_NEWRDNSTR )) {
- if( state & GOT_NEWRDN ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: op_ldap_modrdn: multiple newrdn arg \"%s\"\n",
- mi[ i ].mi_val, 0, 0 );
- *errmsg = "Multiple newrdn argument";
- return -1;
- }
-
- newrdn = mi[ i ].mi_val;
- state |= GOT_NEWRDN;
-
- } else if ( !strcmp( mi[ i ].mi_type, T_DELOLDRDNSTR )) {
- if( state & GOT_DELOLDRDN ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: op_ldap_modrdn: multiple deleteoldrdn arg \"%s\"\n",
- mi[ i ].mi_val, 0, 0 );
- *errmsg = "Multiple newrdn argument";
- return -1;
- }
-
- state |= GOT_DELOLDRDN;
- if ( !strcmp( mi[ i ].mi_val, "0" )) {
- drdnflag = 0;
- } else if ( !strcmp( mi[ i ].mi_val, "1" )) {
- drdnflag = 1;
- } else {
- Debug( LDAP_DEBUG_ANY,
- "Error: op_ldap_modrdn: bad deleteoldrdn arg \"%s\"\n",
- mi[ i ].mi_val, 0, 0 );
- *errmsg = "Incorrect argument to deleteoldrdn";
- return -1;
- }
-
- } else if ( !strcmp( mi[ i ].mi_type, T_NEWSUPSTR )) {
- if( state & GOT_NEWSUP ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: op_ldap_modrdn: multiple newsuperior arg \"%s\"\n",
- mi[ i ].mi_val, 0, 0 );
- *errmsg = "Multiple newsuperior argument";
- return -1;
- }
-
- newsup = mi[ i ].mi_val;
- state |= GOT_NEWSUP;
-
- } else {
- Debug( LDAP_DEBUG_ANY, "Error: op_ldap_modrdn: bad type \"%s\"\n",
- mi[ i ].mi_type, 0, 0 );
- *errmsg = "Bad value in replication log entry";
- return -1;
- }
- }
-
- /*
- * Punt if we don't have all the args.
- */
- if ( !GOT_ALL_MODDN(state) ) {
- Debug( LDAP_DEBUG_ANY, "Error: op_ldap_modrdn: missing arguments\n",
- 0, 0, 0 );
- *errmsg = "Missing argument: requires \"newrdn\" and \"deleteoldrdn\"";
- return -1;
- }
-
-#ifdef LDAP_DEBUG
- if ( ldap_debug & LDAP_DEBUG_ARGS ) {
- char buf[ 256 ];
- char *buf2;
- int buf2len = strlen( re->re_dn ) + strlen( mi->mi_val ) + 11;
-
- snprintf( buf, sizeof(buf), "%s:%d", ri->ri_hostname, ri->ri_port );
-
- buf2 = (char *) ch_malloc( buf2len );
- snprintf( buf2, buf2len, "(\"%s\" -> \"%s\")", re->re_dn, mi->mi_val );
-
- Debug( LDAP_DEBUG_ARGS,
- "replica %s - modify rdn %s (flag: %d)\n",
- buf, buf2, drdnflag );
- free( buf2 );
- }
-#endif /* LDAP_DEBUG */
-
- assert( newrdn != NULL );
-
- /* Do the modrdn */
- rc = ldap_rename2_s( ri->ri_ldp, re->re_dn, newrdn, newsup, drdnflag );
-
- ldap_get_option( ri->ri_ldp, LDAP_OPT_RESULT_CODE, &lderr);
- ldap_get_option( ri->ri_ldp, LDAP_OPT_DIAGNOSTIC_MESSAGE, errmsg);
- *errfree = 1;
- return( lderr );
-}
-
-
-
-/*
- * Allocate and initialize an ldapmod struct.
- */
-static LDAPMod *
-alloc_ldapmod( void )
-{
- LDAPMod *ldm;
-
- ldm = ( struct ldapmod * ) ch_malloc( sizeof ( struct ldapmod ));
- ldm->mod_type = NULL;
- ldm->mod_bvalues = ( struct berval ** ) NULL;
- return( ldm );
-}
-
-
-
-/*
- * Free an ldapmod struct associated mod_bvalues. NOTE - it is assumed
- * that mod_bvalues and mod_type contain pointers to the same block of memory
- * pointed to by the repl struct. Therefore, it's not freed here.
- */
-static void
-free_ldapmod(
-LDAPMod *ldm )
-{
- int i;
-
- if ( ldm == NULL ) {
- return;
- }
- if ( ldm->mod_bvalues != NULL ) {
- for ( i = 0; ldm->mod_bvalues[ i ] != NULL; i++ ) {
- free( ldm->mod_bvalues[ i ] );
- }
- free( ldm->mod_bvalues );
- }
- free( ldm );
- return;
-}
-
-
-/*
- * Free an an array of LDAPMod pointers and the LDAPMod structs they point
- * to.
- */
-static void
-free_ldmarr(
-LDAPMod **ldmarr )
-{
- int i;
-
- for ( i = 0; ldmarr[ i ] != NULL; i++ ) {
- free_ldapmod( ldmarr[ i ] );
- }
- free( ldmarr );
-}
-
-
-/*
- * Create a berval with a single value.
- */
-static struct berval **
-make_singlevalued_berval(
-char *value,
-int len )
-{
- struct berval **p;
-
- p = ( struct berval ** ) ch_malloc( 2 * sizeof( struct berval * ));
- p[ 0 ] = ( struct berval * ) ch_malloc( sizeof( struct berval ));
- p[ 1 ] = NULL;
- p[ 0 ]->bv_val = value;
- p[ 0 ]->bv_len = len;
- return( p );
-}
-
-
-/*
- * Given a modification type (string), return an enumerated type.
- * Avoids ugly copy in op_ldap_modify - lets us use a switch statement
- * there.
- */
-static int
-getmodtype(
-char *type )
-{
- if ( !strcmp( type, T_MODSEPSTR )) {
- return( T_MODSEP );
- }
- if ( !strcmp( type, T_MODOPADDSTR )) {
- return( T_MODOPADD );
- }
- if ( !strcmp( type, T_MODOPREPLACESTR )) {
- return( T_MODOPREPLACE );
- }
- if ( !strcmp( type, T_MODOPDELETESTR )) {
- return( T_MODOPDELETE );
- }
- if ( !strcmp( type, T_MODOPINCREMENTSTR )) {
- return( T_MODOPINCREMENT );
- }
- return( T_ERR );
-}
-
-
-/*
- * Perform an LDAP unbind operation. If replica is NULL, or the
- * repl_ldp is NULL, just return LDAP_SUCCESS. Otherwise, unbind,
- * set the ldp to NULL, and return the result of the unbind call.
- */
-static int
-do_unbind(
- Ri *ri
-)
-{
- int rc = LDAP_SUCCESS;
-
- if (( ri != NULL ) && ( ri->ri_ldp != NULL )) {
- rc = ldap_unbind( ri->ri_ldp );
- if ( rc != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: do_unbind: ldap_unbind failed for %s:%d: %s\n",
- ri->ri_hostname, ri->ri_port, ldap_err2string( rc ) );
- }
- ri->ri_ldp = NULL;
- }
- return rc;
-}
-
-
-
-/*
- * Perform an LDAP bind operation to the replication site given
- * by replica. If replica->repl_ldp is non-NULL, then we unbind
- * from the replica before rebinding. It should be safe to call
- * this to re-connect if the replica's connection goes away
- * for some reason.
- *
- * Returns 0 on success, -1 if an LDAP error occurred, and a return
- * code > 0 if some other error occurred, e.g. invalid bind method.
- * If an LDAP error occurs, the LDAP error is returned in lderr.
- */
-static int
-do_bind(
- Ri *ri,
- int *lderr
-)
-{
- int ldrc;
- int do_tls;
-
- *lderr = 0;
-
- if ( ri == NULL ) {
- Debug( LDAP_DEBUG_ANY, "Error: do_bind: null ri ptr\n", 0, 0, 0 );
- return( BIND_ERR_BADRI );
- }
-
- do_tls = ri->ri_tls;
-
-retry:
- if ( ri->ri_ldp != NULL ) {
- ldrc = ldap_unbind( ri->ri_ldp );
- if ( ldrc != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: do_bind: ldap_unbind failed: %s\n",
- ldap_err2string( ldrc ), 0, 0 );
- }
- ri->ri_ldp = NULL;
- }
-
- if ( ri->ri_uri != NULL ) { /* new URI style */
- Debug( LDAP_DEBUG_ARGS, "Initializing session to %s\n",
- ri->ri_uri, 0, 0 );
-
- ldrc = ldap_initialize( &(ri->ri_ldp), ri->ri_uri);
-
- if (ldrc != LDAP_SUCCESS) {
- Debug( LDAP_DEBUG_ANY, "Error: ldap_initialize(0, %s) failed: %s\n",
- ri->ri_uri, ldap_err2string(ldrc), 0 );
- return( BIND_ERR_OPEN );
- }
- } else { /* old HOST style */
- Debug( LDAP_DEBUG_ARGS, "Initializing session to %s:%d\n",
- ri->ri_hostname, ri->ri_port, 0 );
-
- ri->ri_ldp = ldap_init( ri->ri_hostname, ri->ri_port );
- if ( ri->ri_ldp == NULL ) {
- Debug( LDAP_DEBUG_ANY, "Error: ldap_init(%s, %d) failed: %s\n",
- ri->ri_hostname, ri->ri_port, sys_errlist[ errno ] );
- return( BIND_ERR_OPEN );
- }
- }
-
- { /* set version 3 */
- int err, version = LDAP_VERSION3;
- err = ldap_set_option(ri->ri_ldp,
- LDAP_OPT_PROTOCOL_VERSION, &version);
-
- if( err != LDAP_OPT_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: ldap_set_option(%s, LDAP_OPT_VERSION, 3) failed!\n",
- ri->ri_hostname, NULL, NULL );
-
- ldap_unbind( ri->ri_ldp );
- ri->ri_ldp = NULL;
- return BIND_ERR_VERSION;
- }
- }
-
- /*
- * Set ldap library options to (1) not follow referrals, and
- * (2) restart the select() system call.
- */
- {
- int err;
- err = ldap_set_option(ri->ri_ldp, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
-
- if( err != LDAP_OPT_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: ldap_set_option(%s,REFERRALS, OFF) failed!\n",
- ri->ri_hostname, NULL, NULL );
- ldap_unbind( ri->ri_ldp );
- ri->ri_ldp = NULL;
- return BIND_ERR_REFERRALS;
- }
- }
- ldap_set_option(ri->ri_ldp, LDAP_OPT_RESTART, LDAP_OPT_ON);
-
- if( do_tls ) {
- int err = ldap_start_tls_s(ri->ri_ldp, NULL, NULL);
-
- if( err != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY,
- "%s: ldap_start_tls failed: %s (%d)\n",
- ri->ri_tls == TLS_CRITICAL ? "Error" : "Warning",
- ldap_err2string( err ), err );
-
- if( ri->ri_tls == TLS_CRITICAL ) {
- *lderr = err;
- ldap_unbind( ri->ri_ldp );
- ri->ri_ldp = NULL;
- return BIND_ERR_TLS_FAILED;
- }
- do_tls = TLS_OFF;
- goto retry;
- }
- }
-
- switch ( ri->ri_bind_method ) {
- case LDAP_AUTH_SIMPLE:
- /*
- * Bind with a plaintext password.
- */
- Debug( LDAP_DEBUG_ARGS, "bind to %s:%d as %s (simple)\n",
- ri->ri_hostname, ri->ri_port, ri->ri_bind_dn );
- ldrc = ldap_simple_bind_s( ri->ri_ldp, ri->ri_bind_dn,
- ri->ri_password );
- if ( ldrc != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: ldap_simple_bind_s for %s:%d failed: %s\n",
- ri->ri_hostname, ri->ri_port, ldap_err2string( ldrc ));
- *lderr = ldrc;
- ldap_unbind( ri->ri_ldp );
- ri->ri_ldp = NULL;
- return( BIND_ERR_SIMPLE_FAILED );
- }
- break;
-
- case LDAP_AUTH_SASL:
- Debug( LDAP_DEBUG_ARGS, "bind to %s as %s via %s (SASL)\n",
- ri->ri_hostname,
- ri->ri_authcId ? ri->ri_authcId : "-",
- ri->ri_saslmech );
-
-#ifdef HAVE_CYRUS_SASL
- if( ri->ri_secprops != NULL ) {
- int err = ldap_set_option(ri->ri_ldp,
- LDAP_OPT_X_SASL_SECPROPS, ri->ri_secprops);
-
- if( err != LDAP_OPT_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: ldap_set_option(%s,SECPROPS,\"%s\") failed!\n",
- ri->ri_hostname, ri->ri_secprops, NULL );
- ldap_unbind( ri->ri_ldp );
- ri->ri_ldp = NULL;
- return BIND_ERR_SASL_FAILED;
- }
- }
-
- {
- void *defaults = lutil_sasl_defaults( ri->ri_ldp, ri->ri_saslmech,
- ri->ri_realm, ri->ri_authcId, ri->ri_password, ri->ri_authzId );
-
- ldrc = ldap_sasl_interactive_bind_s( ri->ri_ldp, ri->ri_bind_dn,
- ri->ri_saslmech, NULL, NULL,
- LDAP_SASL_QUIET, lutil_sasl_interact, defaults );
-
- lutil_sasl_freedefs( defaults );
- if ( ldrc != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY, "Error: LDAP SASL for %s:%d failed: %s\n",
- ri->ri_hostname, ri->ri_port, ldap_err2string( ldrc ));
- *lderr = ldrc;
- ldap_unbind( ri->ri_ldp );
- ri->ri_ldp = NULL;
- return( BIND_ERR_SASL_FAILED );
- }
- }
- break;
-#else
- Debug( LDAP_DEBUG_ANY,
- "Error: do_bind: SASL not supported %s:%d\n",
- ri->ri_hostname, ri->ri_port, NULL );
- ldap_unbind( ri->ri_ldp );
- ri->ri_ldp = NULL;
- return( BIND_ERR_BAD_ATYPE );
-#endif
-
- default:
- Debug( LDAP_DEBUG_ANY,
- "Error: do_bind: unknown auth type \"%d\" for %s:%d\n",
- ri->ri_bind_method, ri->ri_hostname, ri->ri_port );
- ldap_unbind( ri->ri_ldp );
- ri->ri_ldp = NULL;
- return( BIND_ERR_BAD_ATYPE );
- }
-
- {
- int err;
- LDAPControl c;
- LDAPControl *ctrls[2];
- ctrls[0] = &c;
- ctrls[1] = NULL;
-
- c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
- c.ldctl_value.bv_val = NULL;
- c.ldctl_value.bv_len = 0;
- c.ldctl_iscritical = 0;
-
- err = ldap_set_option(ri->ri_ldp, LDAP_OPT_SERVER_CONTROLS, &ctrls);
-
- if( err != LDAP_OPT_SUCCESS ) {
- Debug( LDAP_DEBUG_ANY, "Error: "
- "ldap_set_option(%s, SERVER_CONTROLS, ManageDSAit) failed!\n",
- ri->ri_hostname, NULL, NULL );
- ldap_unbind( ri->ri_ldp );
- ri->ri_ldp = NULL;
- return BIND_ERR_MANAGEDSAIT;
- }
- }
-
- return( BIND_OK );
-}
-
-
-
-
-
-/*
- * For debugging. Print the contents of an ldmarr array.
- */
-#ifdef SLAPD_UNUSED
-static void
-dump_ldm_array(
- LDAPMod **ldmarr
-)
-{
- int i, j;
- LDAPMod *ldm;
- struct berval *b;
- char *msgbuf;
-
- for ( i = 0; ldmarr[ i ] != NULL; i++ ) {
- ldm = ldmarr[ i ];
- Debug( LDAP_DEBUG_TRACE,
- "Trace (%ld): *** ldmarr[ %d ] contents:\n",
- (long) getpid(), i, 0 );
- Debug( LDAP_DEBUG_TRACE,
- "Trace (%ld): *** ldm->mod_op: %d\n",
- (long) getpid(), ldm->mod_op, 0 );
- Debug( LDAP_DEBUG_TRACE,
- "Trace (%ld): *** ldm->mod_type: %s\n",
- (long) getpid(), ldm->mod_type, 0 );
- if ( ldm->mod_bvalues != NULL ) {
- for ( j = 0; ( b = ldm->mod_bvalues[ j ] ) != NULL; j++ ) {
- msgbuf = ch_malloc( b->bv_len + 512 );
- sprintf( msgbuf, "***** bv[ %d ] len = %ld, val = <%s>",
- j, b->bv_len, b->bv_val );
- Debug( LDAP_DEBUG_TRACE,
- "Trace (%ld):%s\n", (long) getpid(), msgbuf, 0 );
- free( msgbuf );
- }
- }
- }
-}
-#endif
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-/*
- * lock.c - routines to open and apply an advisory lock to a file
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/param.h>
-#include <ac/string.h>
-#include <ac/socket.h>
-#include <ac/time.h>
-#include <ac/unistd.h>
-
-#ifdef HAVE_SYS_FILE_H
-#include <sys/file.h>
-#endif
-
-#include "slurp.h"
-
-
-FILE *
-lock_fopen(
- const char *fname,
- const char *type,
- FILE **lfp
-)
-{
- FILE *fp;
- char buf[MAXPATHLEN];
-
- /* open the lock file */
- snprintf( buf, sizeof buf, "%s.lock", fname );
-
- if ( (*lfp = fopen( buf, "w" )) == NULL ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: could not open \"%s\"\n", buf, 0, 0 );
- return( NULL );
- }
-
- /* acquire the lock */
- ldap_lockf( fileno(*lfp) );
-
- /* open the log file */
- if ( (fp = fopen( fname, type )) == NULL ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: could not open \"%s\"\n", fname, 0, 0 );
- ldap_unlockf( fileno(*lfp) );
- fclose( *lfp );
- *lfp = NULL;
- return( NULL );
- }
-
- return( fp );
-}
-
-
-
-int
-lock_fclose(
- FILE *fp,
- FILE *lfp
-)
-{
- int rc = fclose( fp );
-
- /* unlock */
- ldap_unlockf( fileno(lfp) );
- fclose( lfp );
-
- return( rc );
-}
-
-
-
-/*
- * Apply an advisory lock on a file. Just calls lock_fopen()
- */
-int
-acquire_lock(
- const char *file,
- FILE **rfp,
- FILE **lfp
-)
-{
- if (( *rfp = lock_fopen( file, "r+", lfp )) == NULL ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: acquire_lock(%ld): Could not acquire lock on \"%s\"\n",
- (long) getpid(), file, 0);
- return( -1 );
- }
- return( 0 );
-}
-
-
-
-/*
- * Relinquish a lock on a file. Calls lock_fclose() and also removes the
- * lock file.
- */
-int
-relinquish_lock(
- const char *file,
- FILE *rfp,
- FILE *lfp
-)
-{
- if ( lock_fclose( rfp, lfp ) == EOF ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: relinquish_lock (%ld): Error closing \"%s\"\n",
- (long) getpid(), file, 0 );
- return( -1 );
- }
- return( 0 );
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP). Additional significant contributors
- * include:
- * Howard Chu
- */
-
-
-/*
- * main.c - main routine for slurpd.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include <ac/stdlib.h>
-#include <ac/unistd.h>
-
-#include "slurp.h"
-#include "globals.h"
-#include "lutil.h"
-
-#include <ldap_pvt.h>
-
-#ifdef HAVE_NT_SERVICE_MANAGER
-#define MAIN_RETURN(x) return
-#define SERVICE_EXIT( e, n ) do { \
- if ( is_NT_Service ) { \
- lutil_ServiceStatus.dwWin32ExitCode = (e); \
- lutil_ServiceStatus.dwServiceSpecificExitCode = (n); \
- } \
-} while ( 0 )
-#else
-#define SERVICE_EXIT( e, n )
-#define MAIN_RETURN(x) return(x)
-#endif
-
-#ifndef HAVE_MKVERSION
-const char Versionstr[] =
- OPENLDAP_PACKAGE " " OPENLDAP_VERSION " Standalone LDAP Replicator (slurpd)";
-#endif
-
-#ifdef HAVE_NT_SERVICE_MANAGER
-void WINAPI ServiceMain( DWORD argc, LPTSTR *argv )
-#else
-int main( int argc, char **argv )
-#endif
-{
-#ifdef NO_THREADS
- /* Haven't yet written the non-threaded version */
- fputs( "slurpd currently requires threads support\n", stderr );
- return( 1 );
-#else
-
- int i, rc = 0;
-
- /* initialize thread package */
- ldap_pvt_thread_initialize();
-
- /*
- * Create and initialize globals. init_globals() also initializes
- * the main replication queue.
- */
- if (( sglob = init_globals()) == NULL ) {
- fprintf( stderr, "Out of memory initializing globals\n" );
- SERVICE_EXIT( ERROR_NOT_ENOUGH_MEMORY, 0 );
- rc = 1;
- goto stop;
- }
-
-#ifdef HAVE_NT_SERVICE_MANAGER
- {
- int *i;
- char *newConfigFile;
- char *regService = NULL;
-
- if ( is_NT_Service ) {
- sglob->serverName = argv[0];
- lutil_CommenceStartupProcessing( sglob->serverName, slurp_set_shutdown );
- if ( strcmp(sglob->serverName, SERVICE_NAME) )
- regService = sglob->serverName;
- }
-
- i = (int*)lutil_getRegParam( regService, "DebugLevel" );
- if ( i != NULL )
- {
- ldap_debug = *i;
- Debug( LDAP_DEBUG_ANY, "new debug level from registry is: %d\n", ldap_debug, 0, 0 );
- }
-
- newConfigFile = (char*)lutil_getRegParam( regService, "ConfigFile" );
- if ( newConfigFile != NULL )
- {
- sglob->slapd_configfile = newConfigFile;
- Debug ( LDAP_DEBUG_ANY, "new config file from registry is: %s\n", sglob->slapd_configfile, 0, 0 );
-
- }
- }
-#endif
-
- /*
- * Process command-line args and fill in globals.
- */
- if ( doargs( argc, argv, sglob ) < 0 ) {
- SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 15 );
- rc = 1;
- goto stop;
- }
-
- if ( sglob->version ) {
- fprintf(stderr, "%s\n", Versionstr);
- if (sglob->version > 1 ) {
- rc = 1;
- goto stop;
- }
- }
-
- Debug ( LDAP_DEBUG_ANY, "%s\n", Versionstr, 0, 0 );
-
- /*
- * Read slapd config file and initialize Re (per-replica) structs.
- */
- if ( slurpd_read_config( sglob->slapd_configfile ) < 0 ) {
- fprintf( stderr,
- "Errors encountered while processing config file \"%s\"\n",
- sglob->slapd_configfile );
- SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 );
- rc = 1;
- goto stop;
- }
-
-#ifdef HAVE_TLS
- if( ldap_pvt_tls_init() || ldap_pvt_tls_init_def_ctx( 0 ) ) {
- rc = 0;
- /* See if we actually need TLS */
- for ( i=0; i < sglob->num_replicas; i++ ) {
- if ( sglob->replicas[i]->ri_tls || ( sglob->replicas[i]->ri_uri &&
- !strncmp( sglob->replicas[i]->ri_uri, "ldaps:", 6 ))) {
- rc = 1;
- break;
- }
- }
- if ( rc ) {
- fprintf( stderr, "TLS Initialization failed.\n" );
- SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 );
- goto stop;
- }
- }
-#endif
-
- /*
- * Make sure our directory exists
- */
- if ( mkdir(sglob->slurpd_rdir, 0755) == -1 && errno != EEXIST) {
- perror(sglob->slurpd_rdir);
- SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 16 );
- rc = 1;
- goto stop;
- }
-
- /*
- * Get any saved state information off the disk.
- */
- if ( sglob->st->st_read( sglob->st )) {
- fprintf( stderr, "Malformed slurpd status file \"%s\"\n",
- sglob->slurpd_status_file );
- SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 17 );
- rc = 1;
- goto stop;
- }
-
- /*
- * All readonly data should now be initialized.
- * Check for any fatal error conditions before we get started
- */
- if ( sanity() < 0 ) {
- SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 18 );
- rc = 1;
- goto stop;
- }
-
-
- /*
- * Detach from the controlling terminal
- * unless the -d flag is given or in one-shot mode.
- */
-#ifndef HAVE_WINSOCK
- if ( ! (sglob->no_detach || sglob->one_shot_mode) ) {
- lutil_detach( 0, 0 );
- }
-#endif
-
- /*
- * don't open pid/args file in one-shot mode (ITS#4152)
- *
- * bail out if files were specified but cannot be opened (ITS#4074)
- */
- if ( !sglob->one_shot_mode) {
- if ( slurpd_pid_file != NULL ) {
- FILE *fp = fopen( slurpd_pid_file, "w" );
-
- if ( fp == NULL ) {
- int save_errno = errno;
-
- fprintf( stderr, "unable to open pid file "
- "\"%s\": %d (%s)\n",
- slurpd_pid_file,
- save_errno, strerror( save_errno ) );
-
- free( slurpd_pid_file );
- slurpd_pid_file = NULL;
-
- rc = 1;
- goto stop;
- }
-
- fprintf( fp, "%d\n", (int) getpid() );
- fclose( fp );
- }
-
- if ( slurpd_args_file != NULL ) {
- FILE *fp = fopen( slurpd_args_file, "w" );
-
- if ( fp == NULL ) {
- int save_errno = errno;
-
- fprintf( stderr, "unable to open args file "
- "\"%s\": %d (%s)\n",
- slurpd_args_file,
- save_errno, strerror( save_errno ) );
-
- free( slurpd_args_file );
- slurpd_pid_file = NULL;
-
- rc = 1;
- goto stop;
- }
-
- for ( i = 0; i < argc; i++ ) {
- fprintf( fp, "%s ", argv[i] );
- }
- fprintf( fp, "\n" );
- fclose( fp );
- }
- }
-
- if ( (rc = lutil_pair( sglob->wake_sds )) < 0 ) {
- SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 16 );
- rc = 1;
- goto stop;
- }
-
-#ifdef HAVE_NT_EVENT_LOG
- if (is_NT_Service) lutil_LogStartedEvent( sglob->serverName, ldap_debug, sglob->slapd_configfile, "n/a" );
-#endif
-
- /*
- * Start the main file manager thread (in fm.c).
- */
- if ( ldap_pvt_thread_create( &(sglob->fm_tid),
- 0, fm, (void *) NULL ) != 0 )
- {
- Debug( LDAP_DEBUG_ANY, "file manager ldap_pvt_thread_create failed\n",
- 0, 0, 0 );
- SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 21 );
- rc = 1;
- goto stop;
-
- }
-
- /*
- * wait for fm to finish if in oneshot mode
- */
- if ( sglob->one_shot_mode ) {
- ldap_pvt_thread_join( sglob->fm_tid, (void *) NULL );
- }
-
- /*
- * Start threads - one thread for each replica
- */
- for ( i = 0; sglob->replicas[ i ] != NULL; i++ ) {
- start_replica_thread( sglob->replicas[ i ]);
- }
-
-#ifdef HAVE_NT_SERVICE_MANAGER
- if ( started_event ) ldap_pvt_thread_cond_signal( &started_event );
-#endif
-
- /*
- * Wait for the fm thread to finish.
- */
- if ( !sglob->one_shot_mode ) {
- ldap_pvt_thread_join( sglob->fm_tid, (void *) NULL );
- }
-
- /*
- * Wait for the replica threads to finish.
- */
- for ( i = 0; sglob->replicas[ i ] != NULL; i++ ) {
- ldap_pvt_thread_join( sglob->replicas[ i ]->ri_tid, (void *) NULL );
- }
-
-stop:
-#ifdef HAVE_NT_SERVICE_MANAGER
- if (is_NT_Service) {
- ldap_pvt_thread_cond_destroy( &started_event );
- lutil_LogStoppedEvent( sglob->serverName );
- lutil_ReportShutdownComplete();
- }
-#endif
- /* destroy the thread package */
- ldap_pvt_thread_destroy();
-
-#ifdef HAVE_TLS
- ldap_pvt_tls_destroy();
-#endif
-
- Debug( LDAP_DEBUG_ANY, "slurpd: terminated.\n", 0, 0, 0 );
-
- if ( slurpd_pid_file != NULL ) {
- unlink( slurpd_pid_file );
- }
- if ( slurpd_args_file != NULL ) {
- unlink( slurpd_args_file );
- }
-
-
- MAIN_RETURN(rc);
-#endif /* !NO_THREADS */
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-#include <stdio.h>
-#include <ac/string.h>
-#include <ac/stdlib.h>
-#include "slurp.h"
-#include "lutil.h"
-
-#ifdef HAVE_NT_SERVICE_MANAGER
-
-/* in main.c */
-void WINAPI ServiceMain( DWORD argc, LPTSTR *argv );
-
-int main( int argc, LPTSTR *argv )
-{
- int length;
- char filename[MAX_PATH], *fname_start;
-
- /*
- * Because the service was registered as SERVICE_WIN32_OWN_PROCESS,
- * the lpServiceName element of the SERVICE_TABLE_ENTRY will be
- * ignored.
- */
-
- SERVICE_TABLE_ENTRY DispatchTable[] = {
- { "", (LPSERVICE_MAIN_FUNCTION) ServiceMain },
- { NULL, NULL }
- };
-
- /*
- * set the service's current directory to the installation directory
- * for the service. this way we don't have to write absolute paths
- * in the configuration files
- */
- GetModuleFileName( NULL, filename, sizeof( filename ) );
- fname_start = strrchr( filename, *LDAP_DIRSEP );
-
- if ( argc > 1 ) {
- if ( _stricmp( "install", argv[1] ) == 0 )
- {
- char *svcName = SERVICE_NAME;
- char *displayName = "OpenLDAP Replication Service";
- BOOL auto_start = FALSE;
-
- if ( (argc > 2) && (argv[2] != NULL) )
- svcName = argv[2];
-
- if ( argc > 3 && argv[3])
- displayName = argv[3];
-
- if ( argc > 4 && stricmp(argv[4], "auto") == 0)
- auto_start = TRUE;
-
- strcat(filename, " service");
- if ( !lutil_srv_install(svcName, displayName, filename, auto_start) )
- {
- fputs( "service failed installation ...\n", stderr );
- return EXIT_FAILURE;
- }
- fputs( "service has been installed ...\n", stderr );
- return EXIT_SUCCESS;
- }
-
- if ( _stricmp( "remove", argv[1] ) == 0 )
- {
- char *svcName = SERVICE_NAME;
- if ( (argc > 2) && (argv[2] != NULL) )
- svcName = argv[2];
- if ( !lutil_srv_remove(svcName, filename) )
- {
- fputs( "failed to remove the service ...\n", stderr );
- return EXIT_FAILURE;
- }
- fputs( "service has been removed ...\n", stderr );
- return EXIT_SUCCESS;
- }
- if ( _stricmp( "service", argv[1] ) == 0 )
- {
- is_NT_Service = 1;
- *fname_start = '\0';
- SetCurrentDirectory( filename );
- }
- }
-
- if (is_NT_Service)
- {
- StartServiceCtrlDispatcher(DispatchTable);
- } else
- {
- ServiceMain( argc, argv );
- }
-
- return EXIT_SUCCESS;
-}
-
-#endif
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-#ifndef _PROTO_SLURP
-#define _PROTO_SLURP
-
-#include <ldap_cdefs.h>
-
-struct globals;
-
-/* admin.c */
-RETSIGTYPE do_admin LDAP_P((int sig));
-
-/* args.c */
-int doargs LDAP_P((int argc, char **argv, struct globals *g));
-
-/* ch_malloc.c */
-#ifdef CSRIMALLOC
-#define ch_malloc malloc
-#define ch_realloc realloc
-#define ch_calloc calloc
-#define ch_strdup strdup
-#define ch_free free
-#else
-void *ch_malloc LDAP_P((ber_len_t size));
-void *ch_realloc LDAP_P((void *block, ber_len_t size));
-void *ch_calloc LDAP_P((ber_len_t nelem, ber_len_t size));
-char *ch_strdup LDAP_P((const char *str));
-void ch_free LDAP_P((void *p));
-#endif
-
-/* config.c */
-int slurpd_read_config LDAP_P((char *fname));
-
-extern char *slurpd_pid_file;
-extern char *slurpd_args_file;
-
-/* ch_malloc.c */
-void ch_free LDAP_P(( void *p ));
-
-/* fm.c */
-void *fm LDAP_P((void *arg));
-RETSIGTYPE do_nothing LDAP_P((int i));
-RETSIGTYPE slurp_set_shutdown LDAP_P((int));
-
-/* globals.c */
-extern struct globals *sglob;
-extern int ldap_syslog;
-extern int ldap_syslog_level;
-extern int ldap_debug;
-extern struct globals *init_globals LDAP_P((void));
-
-/* ldap_op.c */
-int do_ldap LDAP_P((Ri *ri, Re *re, char **errmsg, int *errfree));
-
-/* lock.c */
-FILE *lock_fopen LDAP_P((const char *fname, const char *type, FILE **lfp));
-int lock_fclose LDAP_P((FILE *fp, FILE *lfp));
-int acquire_lock LDAP_P((const char *file, FILE **rfp, FILE **lfp));
-int relinquish_lock LDAP_P((const char *file, FILE *rfp, FILE *lfp));
-
-/* reject.c */
-void write_reject LDAP_P((Ri *ri, Re *re, int lderr, char *errmsg));
-
-/* replica.c */
-int start_replica_thread LDAP_P((Ri *ri));
-
-/* replog.c */
-int copy_replog LDAP_P((char *src, char *dst));
-int file_nonempty LDAP_P((char *filename));
-
-/* sanity.c */
-int sanity LDAP_P((void));
-
-/* st.c */
-int St_init LDAP_P((St **st));
-
-/* tsleep.c */
-int tsleep LDAP_P((time_t interval));
-#if defined( HAVE_LWP )
-void start_lwp_scheduler LDAP_P(( void ));
-#endif
-
-/*main.c */
-extern const char Versionstr[];
-
-#endif /* _PROTO_SLURP */
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-/*
- * re.c - routines which deal with Re (Replication entry) structures.
- * An Re struct is an in-core representation of one replication to
- * be performed, along with member functions which are called by other
- * routines. The Re struct is defined in slurp.h.
- */
-
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-#include <ac/errno.h>
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/ctype.h>
-
-#include "../slapd/slap.h"
-
-#include "slurp.h"
-#include "globals.h"
-#include "lutil.h"
-
-/* Forward references */
-static Rh *get_repl_hosts LDAP_P(( char *, int *, char ** ));
-static int gettype LDAP_P(( char * ));
-static int getchangetype LDAP_P(( char * ));
-static int Re_parse LDAP_P(( Re *re, char *replbuf ));
-static void Re_dump LDAP_P(( Re *re, FILE *fp ));
-static void warn_unknown_replica LDAP_P(( char *, int port ));
-
-/* Globals, scoped within this file */
-static int nur = 0; /* Number of unknown replicas */
-static Rh *ur = NULL; /* array of unknown replica names */
-
-
-/*
- * Return the next Re in a linked list.
- */
-static Re *
-Re_getnext(
- Re *re
-)
-{
- return(( re == NULL ) ? NULL : re->re_next );
-}
-
-
-
-
-/*
- * Free an Re
- * ??? Something should apparently return nonzero here, but I dont know what.
- */
-static int
-Re_free(
- Re *re
-)
-{
- Rh *rh;
- Mi *mi;
- int i;
-
- if ( re == NULL ) {
- return 0;
- }
- if ( re->re_refcnt > 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "Warning: freeing re (dn: %s) with nonzero refcnt\n",
- re->re_dn, 0, 0 );
- }
-
- ldap_pvt_thread_mutex_destroy( &re->re_mutex );
-
- if (( rh = re->re_replicas ) != NULL ) {
- for ( i = 0; rh[ i ].rh_hostname != NULL; i++ ) {
- free( rh[ i ].rh_hostname );
- }
- free( rh );
- }
- ch_free( re->re_dn );
- if (( mi = re->re_mods ) != NULL ) {
- for ( i = 0; mi[ i ].mi_type != NULL; i++ ) {
- free( mi[ i ].mi_type );
- ch_free( mi[ i ].mi_val );
- }
- free( mi );
- }
- free( re );
- return 0;
-}
-
-
-
-
-/*
- * Read a buffer of data from a replication log file and fill in
- * an (already allocated) Re.
- */
-
-#define BEGIN 0
-#define GOT_DN 1
-#define GOT_TIME 2
-#define GOT_CHANGETYPE 4
-#define GOT_ALL ( GOT_DN | GOT_TIME | GOT_CHANGETYPE )
-
-static int
-Re_parse(
- Re *re,
- char *replbuf
-)
-{
- int state;
- int nml;
- char *buf, *rp, *p;
- size_t buflen;
- char *type, *value;
- ber_len_t len;
- int nreplicas;
-
- if ( re == NULL ) {
- Debug( LDAP_DEBUG_ANY, "Re_parse: error: re is NULL\n", 0, 0, 0 );
- return -1;
- }
- if ( replbuf == NULL ) {
- Debug( LDAP_DEBUG_ANY, "Re_parse: error: replbuf is NULL\n", 0, 0, 0 );
- return -1;
- }
-
- state = BEGIN;
- nml = 0; /* number of modification information entries */
- rp = replbuf;
-
- re->re_replicas = get_repl_hosts( replbuf, &nreplicas, &rp );
- re->re_refcnt = sglob->num_replicas;
-
- for (;;) {
- if (( state == GOT_ALL ) || ( buf = ldif_getline( &rp )) == NULL ) {
- break;
- }
- /*
- * If we're processing a rejection log, then the first line
- * of each replication record will begin with "ERROR" - just
- * ignore it.
- */
- if ( strncmp( buf, ERROR_STR, strlen( ERROR_STR )) == 0 ) {
- continue;
- }
- buflen = strlen( buf );
- if ( ldif_parse_line( buf, &type, &value, &len ) < 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: Re_parse: malformed replog file\n",
- 0, 0, 0 );
- return -1;
- }
- switch ( gettype( type )) {
- case T_CHANGETYPE:
- re->re_changetype = getchangetype( value );
- state |= GOT_CHANGETYPE;
- break;
- case T_TIME: {
- unsigned long t;
-
- if (( p = strchr( value, '.' )) != NULL ) {
- /* there was a sequence number */
- *p++ = '\0';
- }
- if ( lutil_atoul( &t, value ) != 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: Re_parse: unable to parse timestamp \"%s\"\n",
- value, 0, 0 );
- return -1;
- }
- re->re_timestamp = (time_t)t;
- if ( p != NULL && isdigit( (unsigned char) *p )
- && lutil_atoi( &re->re_seq, p ) != 0 )
- {
- Debug( LDAP_DEBUG_ANY,
- "Error: Re_parse: unable to parse sequence number \"%s\"\n",
- p, 0, 0 );
- return -1;
- }
- state |= GOT_TIME;
- } break;
- case T_DN:
- re->re_dn = ch_malloc( len + 1 );
- AC_MEMCPY( re->re_dn, value, len );
- re->re_dn[ len ]='\0';
- state |= GOT_DN;
- break;
- default:
- if ( !( state == GOT_ALL )) {
- Debug( LDAP_DEBUG_ANY,
- "Error: Re_parse: bad type <%s>\n",
- type, 0, 0 );
- free( type );
- free( value );
- return -1;
- }
- }
- free( type );
- free( value );
- }
-
- if ( state != GOT_ALL ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: Re_parse: malformed replog file\n",
- 0, 0, 0 );
- return -1;
- }
-
- for (;;) {
- char *const dash = "-";
-
- if (( buf = ldif_getline( &rp )) == NULL ) {
- break;
- }
- buflen = strlen( buf );
- if (( buflen == 1 ) && ( buf[ 0 ] == '-' )) {
- type = dash;
- value = NULL;
- } else {
- if ( ldif_parse_line( buf, &type, &value, &len ) < 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: malformed replog line \"%s\"\n",
- buf, 0, 0 );
- return -1;
- }
- }
- re->re_mods = ( Mi *) ch_realloc( (char *) re->re_mods,
- sizeof( Mi ) * ( nml + 2 ));
- re->re_mods[ nml ].mi_type = strdup( type );
- if ( value != NULL ) {
- re->re_mods[ nml ].mi_val = ch_malloc( len + 1 );
- AC_MEMCPY( re->re_mods[ nml ].mi_val, value, len );
- re->re_mods[ nml ].mi_val[ len ] = '\0';
- re->re_mods[ nml ].mi_len = len;
- } else {
- re->re_mods[ nml ].mi_val = NULL;
- re->re_mods[ nml ].mi_len = 0;
- }
- re->re_mods[ nml + 1 ].mi_type = NULL;
- re->re_mods[ nml + 1 ].mi_val = NULL;
- nml++;
-
- if ( type != dash )
- free( type );
- if ( value != NULL )
- free( value );
- }
- return 0;
-}
-
-
-
-/*
- * Extract the replication hosts from a repl buf. Check to be sure that
- * each replica host and port number are ones we know about (that is, they're
- * in the slapd config file we read at startup). Without that information
- * from the config file, we won't have the appropriate credentials to
- * make modifications. If there are any unknown replica names, don't
- * add them the the Re struct. Instead, log a warning message.
- */
-static Rh *
-get_repl_hosts(
- char *replbuf,
- int *r_nreplicas,
- char **r_rp
-)
-{
- char *type, *value, *line, *p;
- Rh *rh = NULL;
- int nreplicas;
- ber_len_t len;
- int port;
- int repl_ok;
- int i;
-
- if ( replbuf == NULL ) {
- return( NULL );
- }
-
- nreplicas = 0;
-
- /*
- * Get the host names of the replicas
- */
- *r_nreplicas = 0;
- *r_rp = replbuf;
- for (;;) {
- /* If this is a reject log, we need to skip over the ERROR: line */
- if ( !strncmp( *r_rp, ERROR_STR, strlen( ERROR_STR ))) {
- line = ldif_getline( r_rp );
- if ( line == NULL ) {
- break;
- }
- }
- if ( strncasecmp( *r_rp, "replica:", 7 )) {
- break;
- }
- line = ldif_getline( r_rp );
- if ( line == NULL ) {
- break;
- }
- if ( ldif_parse_line( line, &type, &value, &len ) < 0 ) {
- return( NULL );
- }
- port = LDAP_PORT;
- if (( p = strchr( value, ':' )) != NULL ) {
- *p = '\0';
- p++;
- if ( *p != '\0' && lutil_atoi( &port, p ) != 0 ) {
- return( NULL );
- }
- }
-
- /* Verify that we've heard of this replica before */
- repl_ok = 0;
- for ( i = 0; i < sglob->num_replicas; i++ ) {
- if ( strcmp( sglob->replicas[ i ]->ri_hostname, value )) {
- continue;
- }
- if ( sglob->replicas[ i ]->ri_port == port ) {
- repl_ok = 1;
- break;
- }
- }
- free( type );
- if ( !repl_ok ) {
- warn_unknown_replica( value, port );
- free( value );
- continue;
- }
-
- rh = (Rh *) ch_realloc((char *) rh, ( nreplicas + 2 ) * sizeof( Rh ));
- if ( rh == NULL ) {
- Debug( LDAP_DEBUG_ANY, "Out of memory in get_repl_hosts\n",
- 0, 0, 0 );
- return NULL;
- }
- rh[ nreplicas ].rh_hostname = strdup( value );
- rh[ nreplicas ].rh_port = port;
- nreplicas++;
-
- free( value );
- }
-
- if ( nreplicas == 0 ) {
- return( NULL );
- }
-
- rh[ nreplicas ].rh_hostname = NULL;
- *r_nreplicas = nreplicas;
-
- return( rh );
-}
-
-
-
-
-
-/*
- * Convert "type" to an int.
- */
-static int
-gettype(
- char *type
-)
-{
- if ( !strcmp( type, T_CHANGETYPESTR )) {
- return( T_CHANGETYPE );
- }
- if ( !strcmp( type, T_TIMESTR )) {
- return( T_TIME );
- }
- if ( !strcmp( type, T_DNSTR )) {
- return( T_DN );
- }
- return( T_ERR );
-}
-
-
-
-/*
- * Convert "changetype" to an int.
- */
-static int
-getchangetype(
- char *changetype
-)
-{
- if ( !strcmp( changetype, T_ADDCTSTR )) {
- return( T_ADDCT );
- }
- if ( !strcmp( changetype, T_MODIFYCTSTR )) {
- return( T_MODIFYCT );
- }
- if ( !strcmp( changetype, T_DELETECTSTR )) {
- return( T_DELETECT );
- }
- if ( !strcmp( changetype, T_MODRDNCTSTR )) {
- return( T_MODRDNCT );
- }
- return( T_ERR );
-}
-
-
-
-
-#if 0
-/*
- * Find the first line which is not a "replica:" line in buf.
- * Returns a pointer to the line. Returns NULL if there are
- * only "replica:" lines in buf.
- */
-static char *
-skip_replica_lines(
- char *buf
-)
-{
- char *p = buf;
- for (;;) {
- if ( strncasecmp( p, "replica:", 8 )) {
- return( p );
- }
- while (( *p != '\0' ) && ( *p != '\n' )) {
- p++;
- }
- if ( *p == '\0' ) {
- return ( NULL );
- } else {
- p++;
- }
- }
-}
-#endif /* 0 */
-
-
-
-
-/*
- * For debugging purposes: dump the contents of a replication entry.
- * to the given stream.
- */
-static void
-Re_dump(
- Re *re,
- FILE *fp
-)
-{
- int i;
- Mi *mi;
-
- if ( re == NULL ) {
- Debug( LDAP_DEBUG_TRACE, "Re_dump: re is NULL\n", 0, 0, 0 );
- return;
- }
- fprintf( fp, "Re_dump: ******\n" );
- fprintf( fp, "re_refcnt: %d\n", re->re_refcnt );
- fprintf( fp, "re_timestamp: %ld\n", (long) re->re_timestamp );
- fprintf( fp, "re_seq: %d\n", re->re_seq );
- for ( i = 0; re->re_replicas && re->re_replicas[ i ].rh_hostname != NULL;
- i++ ) {
- fprintf( fp, "re_replicas[%d]: %s:%d\n",
- i, re->re_replicas[ i ].rh_hostname,
- re->re_replicas[ i ].rh_port );
- }
- fprintf( fp, "re_dn: %s\n", re->re_dn );
- switch ( re->re_changetype ) {
- case T_ADDCT:
- fprintf( fp, "re_changetype: add\n" );
- break;
- case T_MODIFYCT:
- fprintf( fp, "re_changetype: modify\n" );
- break;
- case T_DELETECT:
- fprintf( fp, "re_changetype: delete\n" );
- break;
- case T_MODRDNCT:
- fprintf( fp, "re_changetype: modrdn\n" );
- break;
- default:
- fprintf( fp, "re_changetype: (unknown, type = %d\n",
- re->re_changetype );
- }
- if ( re->re_mods == NULL ) {
- fprintf( fp, "re_mods: (none)\n" );
- } else {
- mi = re->re_mods;
- fprintf( fp, "re_mods:\n" );
- for ( i = 0; mi[ i ].mi_type != NULL; i++ ) {
- fprintf( fp, " %s, \"%s\", (%d bytes)\n",
- mi[ i ].mi_type,
- mi[ i ].mi_val == NULL ? "(null)" : mi[ i ].mi_val,
- mi[ i ].mi_len );
- }
- }
- return;
-}
-
-
-/*
- * Given an Ri, an Re, and a file pointer, write a replication record to
- * the file pointer. If ri is NULL, then include all replicas in the
- * output. If ri is non-NULL, then only include a single "replica:" line
- * (used when writing rejection records). Returns 0 on success, -1
- * on failure. Note that Re_write will not write anything out if the
- * refcnt is zero.
- */
-static int
-Re_write(
- Ri *ri,
- Re *re,
- FILE *fp )
-{
- int i;
- char *s;
- int rc = 0;
-
- if ( re == NULL || fp == NULL ) {
- Debug( LDAP_DEBUG_ANY, "Internal error: Re_write: NULL argument\n",
- 0, 0, 0 );
- return -1;
- }
-
- if ( re->re_refcnt < 1 ) {
- return 0; /* this is not an error */
- }
-
- if ( ri != NULL ) { /* write a single "replica:" line */
- if ( ri->ri_port != 0 ) {
- rc = fprintf( fp, "replica: %s:%d\n", ri->ri_hostname,
- ri->ri_port );
- } else {
- rc = fprintf( fp, "replica: %s\n", ri->ri_hostname );
- }
- if ( rc < 0 ) {
- rc = -1;
- goto bad;
- }
- rc = 0;
-
- } else { /* write multiple "replica:" lines */
- for ( i = 0; re->re_replicas && re->re_replicas[ i ].rh_hostname != NULL; i++ ) {
- if ( fprintf( fp, "replica: %s:%d\n",
- re->re_replicas[ i ].rh_hostname,
- re->re_replicas[ i ].rh_port ) < 0 ) {
- rc = -1;
- goto bad;
- }
- }
- }
- if ( fprintf( fp, "time: %ld.%d\n", (long) re->re_timestamp, re->re_seq ) < 0 ) {
- rc = -1;
- goto bad;
- }
- if ( fprintf( fp, "dn: %s\n", re->re_dn ) < 0 ) {
- rc = -1;
- goto bad;
- }
- if ( fprintf( fp, "changetype: " ) < 0 ) {
- rc = -1;
- goto bad;
- }
- switch ( re->re_changetype ) {
- case T_ADDCT:
- s = T_ADDCTSTR;
- break;
- case T_MODIFYCT:
- s = T_MODIFYCTSTR;
- break;
- case T_DELETECT:
- s = T_DELETECTSTR;
- break;
- case T_MODRDNCT:
- s = T_MODRDNCTSTR;
- break;
- default:
- s = "IllegalModifyType!!!";
- }
- if ( fprintf( fp, "%s\n", s ) < 0 ) {
- rc = -1;
- goto bad;
- }
- for ( i = 0; (( re->re_mods != NULL ) &&
- ( re->re_mods[ i ].mi_type != NULL )); i++ ) {
- if ( !strcmp( re->re_mods[ i ].mi_type, T_MODSEPSTR )) {
- if ( fprintf( fp, "%s\n", T_MODSEPSTR ) < 0 ) {
- rc = -1;
- goto bad;
- }
- } else {
- char *obuf;
- obuf = ldif_put( LDIF_PUT_VALUE,
- re->re_mods[ i ].mi_type,
- re->re_mods[ i ].mi_val ? re->re_mods[ i ].mi_val : "",
- re->re_mods[ i ].mi_len );
- if ( fputs( obuf, fp ) < 0 ) {
- rc = -1;
- free( obuf );
- goto bad;
- } else {
- ber_memfree( obuf );
- }
- }
- }
- if ( fprintf( fp, "\n" ) < 0 ) {
- rc = -1;
- goto bad;
- }
- if ( fflush( fp ) != 0 ) {
- rc = -1;
- goto bad;
- }
-bad:
- if ( rc != 0 ) {
- Debug( LDAP_DEBUG_ANY, "Error while writing: %s\n",
- sys_errlist[ errno ], 0, 0 );
- }
- return rc;
-}
-
-
-
-
-/*
- * Decrement the refcnt. Locking handled internally.
- */
-static int
-Re_decrefcnt(
- Re *re
-)
-{
- re->re_lock( re );
- re->re_refcnt--;
- re->re_unlock( re );
- return 0;
-}
-
-
-
-/*
- * Get the refcnt. Locking handled internally.
- */
-static int
-Re_getrefcnt(
- Re *re
-)
-{
- int ret;
-
- re->re_lock( re );
- ret = re->re_refcnt;
- re->re_unlock( re );
- return ret;
-}
-
-
-
-
-
-/*
- * Lock this replication entry
- */
-static int
-Re_lock(
- Re *re
-)
-{
- return( ldap_pvt_thread_mutex_lock( &re->re_mutex ));
-}
-
-
-
-
-/*
- * Unlock this replication entry
- */
-static int
-Re_unlock(
- Re *re
-)
-{
- return( ldap_pvt_thread_mutex_unlock( &re->re_mutex ));
-}
-
-
-
-
-/*
- * Instantiate and initialize an Re.
- */
-int
-Re_init(
- Re **re
-)
-{
- /* Instantiate */
- (*re) = (Re *) malloc( sizeof( Re ));
- if ( *re == NULL ) {
- return -1;
- }
-
- /* Fill in the member function pointers */
- (*re)->re_free = Re_free;
- (*re)->re_getnext = Re_getnext;
- (*re)->re_parse = Re_parse;
- (*re)->re_write = Re_write;
- (*re)->re_dump = Re_dump;
- (*re)->re_lock = Re_lock;
- (*re)->re_unlock = Re_unlock;
- (*re)->re_decrefcnt = Re_decrefcnt;
- (*re)->re_getrefcnt = Re_getrefcnt;
-
- /* Initialize private data */
- (*re)->re_refcnt = sglob->num_replicas;
- (*re)->re_timestamp = (time_t) 0L;
- (*re)->re_replicas = NULL;
- (*re)->re_dn = NULL;
- (*re)->re_changetype = 0;
- (*re)->re_seq = 0;
- (*re)->re_mods = NULL;
- (*re)->re_next = NULL;
-
- ldap_pvt_thread_mutex_init( &((*re)->re_mutex) );
- return 0;
-}
-
-
-
-
-/*
- * Given a host and port, generate a warning message iff we haven't already
- * generated a message for this host:port combination.
- */
-static void
-warn_unknown_replica(
- char *host,
- int port
-)
-{
- int found = 0;
- int i;
-
- for ( i = 0; i < nur; i++ ) {
- if ( strcmp( ur[ i ].rh_hostname, host )) {
- continue;
- }
- if ( ur[ i ].rh_port == port ) {
- found = 1;
- break;
- }
- }
- if ( !found ) {
- Debug( LDAP_DEBUG_ANY,
- "Warning: unknown replica %s:%d found in replication log\n",
- host, port, 0 );
- nur++;
- ur = (Rh *) ch_realloc( (char *) ur, ( nur * sizeof( Rh )));
- ur[ nur - 1 ].rh_hostname = strdup( host );
- ur[ nur - 1 ].rh_port = port;
- }
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-
-/*
- * reject.c - routines to write replication records to reject files.
- * An Re struct is writted to a reject file if it cannot be propagated
- * to a replica LDAP server.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-#include <ac/string.h>
-#include <ac/errno.h>
-#include <ac/unistd.h>
-
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "slurp.h"
-#include "globals.h"
-
-#include "lber_pvt.h"
-#include "lutil.h"
-
-#ifdef _WIN32
-#define PORTSEP ","
-#else
-#define PORTSEP ":"
-#endif
-
-/*
- * Write a replication record to a reject file. The reject file has the
- * same name as the replica's private copy of the file but with ".rej"
- * appended (e.g. "/usr/tmp/<hostname>:<port>.rej")
- *
- * If errmsg is non-NULL, use that as the error message in the reject
- * file. Otherwise, use ldap_err2string( lderr ).
- */
-void
-write_reject(
- Ri *ri,
- Re *re,
- int lderr,
- char *errmsg
-)
-{
- char rejfile[ MAXPATHLEN ];
- FILE *rfp, *lfp;
- int rc;
-
- ldap_pvt_thread_mutex_lock( &sglob->rej_mutex );
- snprintf( rejfile, sizeof rejfile, "%s" LDAP_DIRSEP "%s" PORTSEP "%d.rej",
- sglob->slurpd_rdir, ri->ri_hostname, ri->ri_port );
-
- if ( access( rejfile, F_OK ) < 0 ) {
- /* Doesn't exist - try to create */
- int rjfd;
- if (( rjfd = open( rejfile, O_RDWR|O_APPEND|O_CREAT|O_EXCL,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP )) < 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: write_reject: Cannot create \"%s\": %s\n",
- rejfile, sys_errlist[ errno ], 0 );
- ldap_pvt_thread_mutex_unlock( &sglob->rej_mutex );
- return;
- } else {
- close( rjfd );
- }
- }
- if (( rc = acquire_lock( rejfile, &rfp, &lfp )) < 0 ) {
- Debug( LDAP_DEBUG_ANY, "Error: cannot open reject file \"%s\"\n",
- rejfile, 0, 0 );
- } else {
- struct berval bv = BER_BVNULL,
- errstrbv,
- errmsgbv = BER_BVNULL;
- char *ptr;
-
- ber_str2bv( ldap_err2string( lderr ), 0, 0, &errstrbv );
- if ( errmsg && *errmsg ) {
- ber_str2bv( errmsg, 0, 0, &errmsgbv );
- bv.bv_len = errstrbv.bv_len
- + STRLENOF( ": " ) + errmsgbv.bv_len;
-
- ptr = bv.bv_val = ber_memalloc( bv.bv_len + 1 );
- ptr = lutil_strcopy( ptr, errstrbv.bv_val );
- ptr = lutil_strcopy( ptr, ": " );
- ptr = lutil_strcopy( ptr, errmsgbv.bv_val );
-
- } else {
- bv = errstrbv;
- }
-
- fseek( rfp, 0, 2 );
-
- ptr = ldif_put( LDIF_PUT_VALUE, ERROR_STR, bv.bv_val, bv.bv_len );
- if ( bv.bv_val != errstrbv.bv_val ) {
- ber_memfree( bv.bv_val );
- }
- if ( ptr == NULL ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: cannot convert error message(s) \"%s%s%s\" "
- "into LDIF format\n",
- errstrbv.bv_val,
- BER_BVISNULL( &errmsgbv ) ? "" : ": ",
- BER_BVISNULL( &errmsgbv ) ? "" : errmsgbv.bv_val );
- return;
- }
-
- fputs( ptr, rfp );
- ber_memfree( ptr );
-
- if ((rc = re->re_write( ri, re, rfp )) < 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: cannot write reject file \"%s\"\n",
- rejfile, 0, 0 );
- }
- (void) relinquish_lock( rejfile, rfp, lfp );
- Debug( LDAP_DEBUG_ANY,
- "Error: ldap operation failed, data written to \"%s\"\n",
- rejfile, 0, 0 );
- }
- ldap_pvt_thread_mutex_unlock( &sglob->rej_mutex );
- return;
-}
-
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-
-/*
- * replica.c - code to start up replica threads.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/stdlib.h>
-
-#include "slurp.h"
-#include "globals.h"
-
-/*
- * Just invoke the Ri's process() member function, and log the start and
- * finish.
- */
-static void *
-replicate(
- void *ri_arg
-)
-{
- Ri *ri = (Ri *) ri_arg;
-
- Debug( LDAP_DEBUG_ARGS, "begin replication thread for %s:%d\n",
- ri->ri_hostname, ri->ri_port, 0 );
-
- ri->ri_process( ri );
-
- Debug( LDAP_DEBUG_ARGS, "end replication thread for %s:%d\n",
- ri->ri_hostname, ri->ri_port, 0 );
- return NULL;
-}
-
-
-
-/*
- * Start a detached thread for the given replica.
- */
-int
-start_replica_thread(
- Ri *ri
-)
-{
- /* POSIX_THREADS or compatible */
- if ( ldap_pvt_thread_create( &(ri->ri_tid), 0, replicate,
- (void *) ri ) != 0 ) {
- Debug( LDAP_DEBUG_ANY, "replica \"%s:%d\" ldap_pvt_thread_create failed\n",
- ri->ri_hostname, ri->ri_port, 0 );
- return -1;
- }
-
- return 0;
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-
-/*
- * replog.c - routines which read and write replication log files.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-#include <ac/errno.h>
-#include <ac/param.h>
-#include <ac/string.h>
-#include <ac/syslog.h>
-#include <ac/time.h>
-#include <ac/unistd.h>
-
-#include <sys/stat.h>
-
-#include <fcntl.h>
-
-#include "slurp.h"
-#include "globals.h"
-
-/*
- * Copy the replication log. Returns 0 on success, 1 if a temporary
- * error occurs, and -1 if a fatal error occurs.
- */
-int
-copy_replog(
- char *src,
- char *dst
-)
-{
- int rc = 0;
- FILE *rfp; /* replog fp */
- FILE *lfp; /* replog lockfile fp */
- FILE *dfp; /* duplicate replog fp */
- FILE *dlfp; /* duplicate replog lockfile fp */
- static char buf[ MAXPATHLEN ];
- static char rbuf[ 1024 ];
- char *p;
-
- Debug( LDAP_DEBUG_ARGS,
- "copy replog \"%s\" to \"%s\"\n",
- src, dst, 0 );
-
- /*
- * Make sure the destination directory is writable. If not, exit
- * with a fatal error.
- */
- strcpy( buf, src );
- if (( p = strrchr( buf, LDAP_DIRSEP[0] )) == NULL ) {
- strcpy( buf, "." );
- } else {
- *p = '\0';
- }
- if ( access( buf, W_OK ) < 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: copy_replog (%ld): Directory %s is not writable\n",
- (long) getpid(), buf, 0 );
- return( -1 );
- }
- strcpy( buf, dst );
- if (( p = strrchr( buf, LDAP_DIRSEP[0] )) == NULL ) {
- strcpy( buf, "." );
- } else {
- *p = '\0';
- }
- if ( access( buf, W_OK ) < 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: copy_replog (%ld): Directory %s is not writable\n",
- (long) getpid(), buf, 0 );
- return( -1 );
- }
-
- /* lock src */
- rfp = lock_fopen( src, "r", &lfp );
- if ( rfp == NULL ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: copy_replog: Can't lock replog \"%s\" for read: %s\n",
- src, sys_errlist[ errno ], 0 );
- return( 1 );
- }
-
- /* lock dst */
- dfp = lock_fopen( dst, "a", &dlfp );
- if ( dfp == NULL ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: copy_replog: Can't lock replog \"%s\" for write: %s\n",
- dst, sys_errlist[ errno ], 0 );
- lock_fclose( rfp, lfp );
- return( 1 );
- }
-
- /*
- * Make our own private copy of the replication log.
- */
- while (( p = fgets( rbuf, sizeof( rbuf ), rfp )) != NULL ) {
- fputs( rbuf, dfp );
- }
- /* Only truncate the source file if we're not in one-shot mode */
- if ( !sglob->one_shot_mode ) {
- /* truncate replication log */
- truncate( src, (off_t) 0 );
- }
-
- if ( lock_fclose( dfp, dlfp ) == EOF ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: copy_replog: Error closing \"%s\"\n",
- dst, 0, 0 );
- }
- if ( lock_fclose( rfp, lfp ) == EOF ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: copy_replog: Error closing \"%s\"\n",
- src, 0, 0 );
- }
- return( rc );
-}
-
-
-
-
-/*
- * Return 1 if the given file exists and has a nonzero size,
- * 0 if it is empty or nonexistent.
- */
-int
-file_nonempty(
- char *filename
-)
-{
- static struct stat stbuf;
-
- if ( stat( filename, &stbuf ) < 0 ) {
- return( 0 );
- } else {
- return( stbuf.st_size > (off_t ) 0 );
- }
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-/*
- * ri.c - routines used to manipulate Ri structures. An Ri (Replica
- * information) struct contains all information about one replica
- * instance. The Ri struct is defined in slurp.h
- */
-
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-#include <ac/string.h>
-#include <ac/signal.h>
-
-#include "slurp.h"
-#include "globals.h"
-
-
-/* Forward references */
-static int ismine LDAP_P(( Ri *, Re * ));
-static int isnew LDAP_P(( Ri *, Re * ));
-
-
-/*
- * Process any unhandled replication entries in the queue.
- */
-static int
-Ri_process(
- Ri *ri
-)
-{
- Rq *rq = sglob->rq;
- Re *re = NULL, *new_re = NULL;
- int rc ;
- char *errmsg;
- int errfree;
-
- (void) SIGNAL( LDAP_SIGUSR1, do_nothing );
-#ifdef SIGPIPE
- (void) SIGNAL( SIGPIPE, SIG_IGN );
-#endif
- if ( ri == NULL ) {
- Debug( LDAP_DEBUG_ANY, "Error: Ri_process: ri == NULL!\n", 0, 0, 0 );
- return -1;
- }
-
- /*
- * Startup code. See if there's any work to do. If not, wait on the
- * rq->rq_more condition variable.
- */
- rq->rq_lock( rq );
- while ( !sglob->slurpd_shutdown &&
- (( re = rq->rq_gethead( rq )) == NULL )) {
- /* No work */
- if ( sglob->one_shot_mode ) {
- /* give up if in one shot mode */
- rq->rq_unlock( rq );
- return 0;
- }
- /* wait on condition variable */
- ldap_pvt_thread_cond_wait( &rq->rq_more, &rq->rq_mutex );
- }
-
- /*
- * When we get here, there's work in the queue, and we have the
- * queue locked. re should be pointing to the head of the queue.
- */
- rq->rq_unlock( rq );
- while ( !sglob->slurpd_shutdown ) {
- if ( re != NULL ) {
- if ( !ismine( ri, re )) {
- /* The Re doesn't list my host:port */
- Debug( LDAP_DEBUG_TRACE,
- "Replica %s:%d, skip repl record for %s (not mine)\n",
- ri->ri_hostname, ri->ri_port, re->re_dn );
- } else if ( !isnew( ri, re )) {
- /* This Re is older than my saved status information */
- Debug( LDAP_DEBUG_TRACE,
- "Replica %s:%d, skip repl record for %s (old)\n",
- ri->ri_hostname, ri->ri_port, re->re_dn );
- } else {
- rc = do_ldap( ri, re, &errmsg, &errfree );
- switch ( rc ) {
- case DO_LDAP_ERR_RETRYABLE:
- ldap_pvt_thread_sleep( RETRY_SLEEP_TIME );
- Debug( LDAP_DEBUG_ANY,
- "Retrying operation for DN %s on replica %s:%d\n",
- re->re_dn, ri->ri_hostname, ri->ri_port );
- continue;
- break;
- case DO_LDAP_ERR_FATAL: {
- /* Non-retryable error. Write rejection log. */
- int ld_errno = 0;
- ldap_get_option(ri->ri_ldp, LDAP_OPT_RESULT_CODE, &ld_errno);
- write_reject( ri, re, ld_errno, errmsg );
- /* Update status ... */
- (void) sglob->st->st_update( sglob->st, ri->ri_stel, re );
- /* ... and write to disk */
- (void) sglob->st->st_write( sglob->st );
- } break;
- default:
- /* LDAP op completed ok - update status... */
- (void) sglob->st->st_update( sglob->st, ri->ri_stel, re );
- /* ... and write to disk */
- (void) sglob->st->st_write( sglob->st );
- break;
- }
- if ( errfree && errmsg ) {
- ch_free( errmsg );
- }
- }
- } else {
- Debug( LDAP_DEBUG_ANY, "Error: re is null in Ri_process\n",
- 0, 0, 0 );
- }
- rq->rq_lock( rq );
- while ( !sglob->slurpd_shutdown &&
- ((new_re = re->re_getnext( re )) == NULL )) {
- if ( sglob->one_shot_mode ) {
- rq->rq_unlock( rq );
- return 0;
- }
- /* No work - wait on condition variable */
- ldap_pvt_thread_cond_wait( &rq->rq_more, &rq->rq_mutex );
- }
- re->re_decrefcnt( re );
- re = new_re;
- rq->rq_unlock( rq );
- if ( sglob->slurpd_shutdown ) {
- if ( ri->ri_ldp ) {
- ldap_unbind_ext( ri->ri_ldp, NULL, NULL );
- ri->ri_ldp = NULL;
- }
- return 0;
- }
- }
- return 0;
-}
-
-
-/*
- * Wake a replication thread which may be sleeping.
- * Send it a LDAP_SIGUSR1.
- */
-static void
-Ri_wake(
- Ri *ri
-)
-{
- if ( ri == NULL ) {
- return;
- }
- ldap_pvt_thread_kill( ri->ri_tid, LDAP_SIGUSR1 );
-}
-
-
-
-/*
- * Allocate and initialize an Ri struct.
- */
-int
-Ri_init(
- Ri **ri
-)
-{
- (*ri) = ( Ri * ) calloc( 1, sizeof( Ri ));
- if ( *ri == NULL ) {
- return -1;
- }
-
- /* Initialize member functions */
- (*ri)->ri_process = Ri_process;
- (*ri)->ri_wake = Ri_wake;
-
- /* Initialize private data */
- (*ri)->ri_hostname = NULL;
- (*ri)->ri_uri = NULL;
- (*ri)->ri_ldp = NULL;
- (*ri)->ri_bind_dn = NULL;
- (*ri)->ri_password = NULL;
- (*ri)->ri_authcId = NULL;
- (*ri)->ri_curr = NULL;
-
- return 0;
-}
-
-
-
-
-/*
- * Return 1 if the hostname and port in re match the hostname and port
- * in ri, otherwise return zero.
- */
-static int
-ismine(
- Ri *ri,
- Re *re
-)
-{
- Rh *rh;
- int i;
-
- if ( ri == NULL || re == NULL || ri->ri_hostname == NULL ||
- re->re_replicas == NULL ) {
- return 0;
- }
- rh = re->re_replicas;
- for ( i = 0; rh[ i ].rh_hostname != NULL; i++ ) {
- if ( !strcmp( rh[ i ].rh_hostname, ri->ri_hostname) &&
- rh[ i ].rh_port == ri->ri_port ) {
- return 1;
- }
- }
- return 0;
-}
-
-
-
-
-/*
- * Return 1 if the Re's timestamp/seq combination are greater than the
- * timestamp and seq in the Ri's ri_stel member. In other words, if we
- * find replication entries in the log which we've already processed,
- * don't process them. If the re is "old," return 0.
- * No check for NULL pointers is done.
- */
-static int
-isnew(
- Ri *ri,
- Re *re
-)
-{
- long x;
- int ret;
-
- /* Lock the St struct to avoid a race */
- sglob->st->st_lock( sglob->st );
- x = re->re_timestamp - ri->ri_stel->last;
- if ( x > 0 ) {
- /* re timestamp is newer */
- ret = 1;
- } else if ( x < 0 ) {
- ret = 0;
- } else {
- /* timestamps were equal */
- if ( re->re_seq > ri->ri_stel->seq ) {
- /* re seq is newer */
- ret = 1;
- } else {
- ret = 0;
- }
- }
- sglob->st->st_unlock( sglob->st );
- return ret;
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-/*
- * rq.c - routines used to manage the queue of replication entries.
- * An Rq (Replication queue) struct contains a linked list of Re
- * (Replication entry) structures.
- *
- * Routines wishing to access the replication queue should do so through
- * the Rq struct's member functions, e.g. rq->rq_gethead() and friends.
- * For example, Re structs should be added to the queue by calling
- * the rq_add() member function.
- *
- * Access to the queue is serialized by a mutex. Member functions which do
- * not do their own locking should only be called after locking the queue
- * using the rq_lock() member function. The queue should be unlocked with
- * the rq_unlock() member function.
- *
- * Note that some member functions handle their own locking internally.
- * Callers should not lock the queue before calling these functions.
- * See the comment block for each function below.
- *
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <sys/stat.h>
-
-#include <ac/stdlib.h>
-#include <ac/string.h>
-#include <ac/unistd.h> /* get ftruncate() */
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#include "slurp.h"
-#include "globals.h"
-
-/*
- * Lock the replication queue.
- */
-static int
-Rq_lock(
- Rq *rq
-)
-{
- return( ldap_pvt_thread_mutex_lock( &rq->rq_mutex ));
-}
-
-
-/*
- * Unlock the replication queue.
- */
-static int
-Rq_unlock(
- Rq *rq
-)
-{
- return( ldap_pvt_thread_mutex_unlock( &rq->rq_mutex ));
-}
-
-
-
-/*
- * Return the head of the queue. Callers should lock the queue before
- * calling this routine.
- */
-static Re *
-Rq_gethead(
- Rq *rq
-)
-{
- return( rq == NULL ? NULL : rq->rq_head );
-}
-
-
-/*
- * Return the next item in the queue. Callers should lock the queue before
- * calling this routine.
- */
-static Re *
-Rq_getnext(
- Re *re
-)
-{
- if ( re == NULL ) {
- return NULL;
- } else {
- return( re->re_getnext( re ));
- }
-}
-
-
-/*
- * Delete the item at the head of the list. The queue should be locked
- * by the caller before calling this routine.
- */
-static int
-Rq_delhead(
- Rq *rq
-)
-{
- Re *savedhead;
- int rc;
-
- if ( rq == NULL ) {
- return( -1 );
- }
-
- savedhead = rq->rq_head;
- if ( savedhead == NULL ) {
- return( 0 );
- }
-
- if ( savedhead->re_getrefcnt( savedhead ) != 0 ) {
- Debug( LDAP_DEBUG_ANY, "Warning: attempt to delete when refcnt != 0\n",
- 0, 0, 0 );
- return( -1 );
- }
-
- rq->rq_head = rq->rq_head->re_getnext( rq->rq_head );
- rc = savedhead->re_free( savedhead );
- rq->rq_nre--; /* decrement count of Re's in queue */
- return( rc );
-}
-
-
-/*
- * Add an entry to the tail of the replication queue. Locking is handled
- * internally. When items are added to the queue, this routine wakes
- * up any threads which are waiting for more work by signaling on the
- * rq->rq_more condition variable.
- */
-static int
-Rq_add(
- Rq *rq,
- char *buf
-)
-{
- Re *re;
- int wasempty = 0;
-
- /* Lock the queue */
- rq->rq_lock( rq );
-
- /* Create a new Re */
- if ( Re_init( &re ) < 0 ) {
- rq->rq_unlock( rq );
- return -1;
- }
-
- /* parse buf and fill in the re struct */
- if ( re->re_parse( re, buf ) < 0 ) {
- re->re_free( re );
- rq->rq_unlock( rq );
- return -1;
- }
-
- /* Insert into queue */
- if ( rq->rq_head == NULL ) {
- rq->rq_head = re;
- rq->rq_tail = re;
- wasempty = 1;
- } else {
- rq->rq_tail->re_next = re;
- }
-
- /* set the sequence number */
- re->re_seq = 0;
- if ( !wasempty && ( rq->rq_tail->re_timestamp == re->re_timestamp )) {
- /*
- * Our new re has the same timestamp as the tail's timestamp.
- * Increment the seq number in the tail and use it as our seq number.
- */
- re->re_seq = rq->rq_tail->re_seq + 1;
- }
- rq->rq_tail = re;
-
- /* Increment count of items in queue */
- rq->rq_nre++;
- /* wake up any threads waiting for more work */
- ldap_pvt_thread_cond_broadcast( &rq->rq_more );
-
- /* ... and unlock the queue */
- rq->rq_unlock( rq );
-
- return 0;
-}
-
-
-/*
- * Garbage-collect the replication queue. Locking is handled internally.
- */
-static void
-Rq_gc(
- Rq *rq
-)
-{
- if ( rq == NULL ) {
- Debug( LDAP_DEBUG_ANY, "Rq_gc: rq is NULL!\n", 0, 0, 0 );
- return;
- }
- rq->rq_lock( rq );
- while (( rq->rq_head != NULL ) &&
- ( rq->rq_head->re_getrefcnt( rq->rq_head ) == 0 )) {
- rq->rq_delhead( rq );
- rq->rq_ndel++; /* increment count of deleted entries */
- }
- rq->rq_unlock( rq );
- return;
-}
-
-
-/*
- * For debugging: dump the contents of the replication queue to a file.
- * Locking is handled internally.
- */
-static void
-Rq_dump(
- Rq *rq
-)
-{
- Re *re;
- FILE *fp;
- int tmpfd;
-
- if ( rq == NULL ) {
- Debug( LDAP_DEBUG_ANY, "Rq_dump: rq is NULL!\n", 0, 0, 0 );
- return;
- }
-
- if (unlink(SLURPD_DUMPFILE) == -1 && errno != ENOENT) {
- Debug( LDAP_DEBUG_ANY, "Rq_dump: \"%s\" exists, and cannot unlink\n",
- SLURPD_DUMPFILE, 0, 0 );
- return;
- }
- if (( tmpfd = open(SLURPD_DUMPFILE, O_CREAT|O_RDWR|O_EXCL, 0600)) == -1) {
- Debug( LDAP_DEBUG_ANY, "Rq_dump: cannot open \"%s\" for write\n",
- SLURPD_DUMPFILE, 0, 0 );
- return;
- }
- if (( fp = fdopen( tmpfd, "w" )) == NULL ) {
- Debug( LDAP_DEBUG_ANY, "Rq_dump: cannot fdopen \"%s\" for write\n",
- SLURPD_DUMPFILE, 0, 0 );
- return;
- }
-
- rq->rq_lock( rq );
- for ( re = rq->rq_gethead( rq ); re != NULL; re = rq->rq_getnext( re )) {
- re->re_dump( re, fp );
- }
- rq->rq_unlock( rq );
- fclose( fp );
- return;
-}
-
-
-/*
- * Write the contents of a replication queue to a file. Returns zero if
- * successful, -1 if not. Handles queue locking internally. Callers should
- * provide an open file pointer, which should refer to a locked file.
- */
-static int
-Rq_write(
- Rq *rq,
- FILE *fp
-)
-{
- Re *re;
- time_t now;
-
- if ( rq == NULL ) {
- return -1;
- }
-
- Debug( LDAP_DEBUG_ARGS, "re-write on-disk replication log\n",
- 0, 0, 0 );
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
- fseek( fp, 0L, SEEK_SET ); /* Go to beginning of file */
- rq->rq_lock( rq );
-
- for ( re = rq->rq_gethead( rq ); re != NULL; re = rq->rq_getnext( re )) {
- if ( re->re_write( NULL, re, fp ) < 0 ) {
- fflush( fp );
- rq->rq_unlock( rq );
- return -1;
- }
- }
- fflush( fp );
- sglob->srpos = ftell( fp ); /* update replog file position */
- /* and truncate to correct len */
- if ( ftruncate( fileno( fp ), sglob->srpos ) < 0 ) {
- Debug( LDAP_DEBUG_ANY, "Error truncating replication log: %s\n",
- sys_errlist[ errno ], 0, 0 );
- }
- rq->rq_ndel = 0; /* reset count of deleted re's */
- time( &now );
- rq->rq_lasttrim = now; /* reset last trim time */
- rq->rq_unlock( rq );
- return 0;
-}
-
-
-/*
- * Check to see if the private slurpd replication log needs trimming.
- * The current criteria are:
- * - The last trim was more than 5 minutes ago, *and*
- * - We've finished with at least 50 replication log entries since the
- * last time we re-wrote the replication log.
- *
- * Return 1 if replogfile should be trimmed, 0 if not.
- * Any different policy should be implemented by replacing this function.
- */
-static int
-Rq_needtrim(
- Rq *rq
-)
-{
- int rc = 0;
- time_t now;
-
- if ( rq == NULL ) {
- return 0;
- }
-
- rq->rq_lock( rq );
-
- time( &now );
-
- if ( now > ( rq->rq_lasttrim + TRIMCHECK_INTERVAL )) {
- rc = ( rq->rq_ndel >= 50 );
- } else {
- rc = 0;
- }
- rq->rq_unlock( rq );
- return rc;
-}
-
-
-/*
- * Return counts of Re structs in the queue.
- */
-static int
-Rq_getcount(
- Rq *rq,
- int type
-)
-{
- int count = 0;
- Re *re;
-
- if ( rq == NULL ) {
- return 0;
- }
-
- rq->rq_lock( rq );
- if ( type == RQ_COUNT_ALL ) {
- count = rq->rq_nre;
- } else {
- for ( re = rq->rq_gethead( rq ); re != NULL;
- re = rq->rq_getnext( re )) {
- if ( type == RQ_COUNT_NZRC ) {
- if ( re->re_getrefcnt( re ) > 0 ) {
- count++;
- }
- }
- }
- }
- rq->rq_unlock( rq );
- return count;
-}
-
-
-/*
- * Allocate and initialize an Rq object.
- */
-int
-Rq_init(
- Rq **rq
-)
-{
- /* Instantiate the struct */
- (*rq) = (Rq *) malloc( sizeof( Rq ));
- if ( *rq == NULL ) {
- return -1;
- }
-
- /* Fill in all the function pointers */
- (*rq)->rq_gethead = Rq_gethead;
- (*rq)->rq_getnext = Rq_getnext;
- (*rq)->rq_delhead = Rq_delhead;
- (*rq)->rq_add = Rq_add;
- (*rq)->rq_gc = Rq_gc;
- (*rq)->rq_lock = Rq_lock;
- (*rq)->rq_unlock = Rq_unlock;
- (*rq)->rq_dump = Rq_dump;
- (*rq)->rq_needtrim = Rq_needtrim;
- (*rq)->rq_write = Rq_write;
- (*rq)->rq_getcount = Rq_getcount;
-
- /* Initialize private data */
- ldap_pvt_thread_mutex_init( &((*rq)->rq_mutex) );
- ldap_pvt_thread_cond_init( &((*rq)->rq_more) );
- (*rq)->rq_head = NULL;
- (*rq)->rq_tail = NULL;
- (*rq)->rq_nre = 0;
- (*rq)->rq_ndel = 0;
- (*rq)->rq_lasttrim = (time_t) 0L;
-
- return 0;
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-
-/*
- * sanity.c - perform sanity checks on the environment at startup time,
- * and report any errors before we disassociate from the controlling tty,
- * start up our threads, and do other stuff which makes it hard to give
- * feedback to the users.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-#include <ac/unistd.h>
-#include <ac/string.h>
-
-#include "slurp.h"
-#include "globals.h"
-
-#define FC_DIRBAD 1
-#define FC_DIRUNREAD 2
-#define FC_DIRUNWRITE 4
-#define FC_FILEBAD 8
-#define FC_FILEUNREAD 16
-#define FC_FILEUNWRITE 32
-
-
-/*
- * Forward declarations
- */
-static unsigned int filecheck LDAP_P(( char * ));
-
-
-
-/*
- * Take a look around to catch any fatal errors. For example, make sure the
- * destination directory for our working files exists, check that all
- * pathnames make sense, and so on. Returns 0 is everything's ok,
- # -1 if there's something wrong which will keep us from functioning
- * correctly.
- *
- * We do all these checks at startup so we can print a reasonable error
- * message on stderr before we disassociate from the controlling tty. This
- * keeps some fatal error messages from "disappearing" into syslog.
- */
-
-int
-sanity( void )
-{
- int err = 0;
- int rc;
-
- /*
- * Are there any replicas listed in the slapd config file?
- */
- if ( sglob->replicas == NULL ) {
- fprintf( stderr, "No replicas in slapd.conf file \"%s\"!\n",
- sglob->slapd_configfile );
- err++;
- }
-
- /*
- * Make sure the directory housing the slapd replogfile exists, and
- * that the slapd replogfile is readable, if it exists.
- */
- if ( sglob->slapd_replogfile == NULL ) {
- fprintf( stderr, "Fatal error: no \"replogfile\" "
- "slapd.conf directive given\n" );
- err++;
- } else {
- rc = filecheck( sglob->slapd_replogfile );
- if ( rc & FC_DIRBAD ) {
- fprintf( stderr, "Error: %s: directory specified in "
- "\"replogfile\" slapd.conf directive does not exist\n",
- sglob->slapd_replogfile );
- err++;
- } else if ( rc & FC_DIRUNREAD ) {
- fprintf( stderr, "Error: %s: directory specified in "
- "\"replogfile\" slapd.conf directive is not readable\n",
- sglob->slapd_replogfile );
- err++;
- } else if (!( rc & FC_FILEBAD) && ( rc & FC_FILEUNREAD )) {
- fprintf( stderr, "Error: %s: file specified in "
- "\"replogfile\" slapd.conf directive is not readable\n",
- sglob->slapd_replogfile );
- err++;
- }
- }
-
- /*
- * Make sure the directory for the slurpd replogfile is there, and
- * that the slurpd replogfile is readable and writable, if it exists.
- */
- if ( sglob->slurpd_replogfile == NULL ) {
- fprintf( stderr, "Fatal error: no \"replogfile\" directive given\n" );
- err++;
- } else {
- rc = filecheck( sglob->slurpd_replogfile );
- if ( rc & FC_DIRBAD ) {
- fprintf( stderr, "Error: %s: slurpd \"replogfile\" "
- "directory does not exist\n",
- sglob->slurpd_replogfile );
- err++;
- } else if ( rc & FC_DIRUNREAD ) {
- fprintf( stderr, "Error: %s: slurpd \"replogfile\" "
- "directory not readable\n",
- sglob->slurpd_replogfile );
- err++;
- } else if ( !( rc & FC_FILEBAD ) && ( rc & FC_FILEUNREAD )) {
- fprintf( stderr, "Error: %s: slurpd \"replogfile\" not readable\n",
- sglob->slurpd_replogfile );
- err++;
- } else if ( !( rc & FC_FILEBAD ) && ( rc & FC_FILEUNWRITE )) {
- fprintf( stderr, "Error: %s: slurpd \"replogfile\" not writeable\n",
- sglob->slurpd_replogfile );
- err++;
- }
- }
-
- /*
- * Make sure that the directory for the slurpd status file is there, and
- * that the slurpd status file is writable, if it exists.
- */
- rc = filecheck( sglob->slurpd_status_file );
- if ( rc & FC_DIRBAD ) {
- fprintf( stderr, "Error: %s: status directory does not exist\n",
- sglob->slurpd_status_file );
- err++;
- } else if ( rc & FC_DIRUNREAD ) {
- fprintf( stderr, "Error: %s: status directory not readable\n",
- sglob->slurpd_status_file );
- err++;
- } else if ( !( rc & FC_FILEBAD ) && ( rc & FC_FILEUNREAD )) {
- fprintf( stderr, "Error: %s: status file not readable\n",
- sglob->slurpd_status_file );
- err++;
- } else if ( !( rc & FC_FILEBAD ) && ( rc & FC_FILEUNWRITE )) {
- fprintf( stderr, "Error: %s: status file not writeable\n",
- sglob->slurpd_status_file );
- err++;
- }
-
- return ( err == 0 ? 0 : -1 );
-}
-
-
-
-/*
- * Check for the existence of the file and directory leading to the file.
- * Returns a bitmask which is the logical OR of the following flags:
- *
- * FC_DIRBAD: directory containing "f" does not exist.
- * FC_DIRUNREAD: directory containing "f" exists but is not readable.
- * FC_DIRUNWRITE: directory containing "f" exists but is not writable.
- * FC_FILEBAD: "f" does not exist.
- * FC_FILEUNREAD: "f" exists but is unreadable.
- * FC_FILEUNWRITE: "f" exists but is unwritable.
- *
- * The calling routine is responsible for determining which, if any, of
- * the returned flags is a problem for a particular file.
- */
-static unsigned int
-filecheck(
- char *f
-)
-{
- char dir[ MAXPATHLEN ];
- char *p;
- unsigned int ret = 0;
-
- snprintf( dir, sizeof dir, "%s", f );
- p = strrchr( dir, LDAP_DIRSEP[0] );
- if ( p != NULL ) {
- *p = '\0';
- }
- if ( access( dir, F_OK ) < 0 ) {
- ret |= FC_DIRBAD;
- }
- if ( access( dir, R_OK ) < 0 ) {
- ret |= FC_DIRUNREAD;
- }
- if ( access( dir, W_OK ) < 0 ) {
- ret |= FC_DIRUNWRITE;
- }
- if ( access( f, F_OK ) < 0 ) {
- ret |= FC_FILEBAD;
- }
- if ( access( f, R_OK ) < 0 ) {
- ret |= FC_FILEUNREAD;
- }
- if ( access( f, W_OK ) < 0 ) {
- ret |= FC_FILEUNWRITE;
- }
-
- return ret;
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-/* slurp.h - Standalone Ldap Update Replication Daemon (slurpd) */
-
-#ifndef _SLURPD_H_
-#define _SLURPD_H_
-
-#if !defined(HAVE_WINSOCK) && !defined(LDAP_SYSLOG)
-#define LDAP_SYSLOG 1
-#endif
-
-#include <ac/errno.h>
-#include <ac/param.h>
-#include <ac/signal.h>
-#include <ac/syslog.h>
-#include <ac/time.h>
-
-#include <sys/types.h>
-
-#include <ldap.h>
-
-#undef ldap_debug
-#define ldap_debug slurp_debug
-#include "ldap_log.h"
-
-#include "ldap_pvt_thread.h"
-#include "ldap_defaults.h"
-#include "ldif.h"
-
-#ifdef HAVE_WINSOCK
- /* should be moved to portable.h.nt */
-#define ftruncate(a,b) _chsize(a,b)
-#define truncate(a,b) _lclose( _lcreat(a, 0))
-#define mkdir(a,b) mkdir(a)
-#define S_IRGRP 0
-#define S_IWGRP 0
-#ifndef F_OK
-#define F_OK 0
-#endif
-#ifndef W_OK
-#define W_OK 2
-#endif
-#ifndef R_OK
-#define R_OK 4
-#endif
-#ifndef S_IRUSR
-#define S_IRUSR S_IREAD
-#endif
-#ifndef S_IWUSR
-#define S_IWUSR S_IWRITE
-#endif
-#endif
-
-#undef SERVICE_NAME
-#define SERVICE_NAME OPENLDAP_PACKAGE "-slurpd"
-
-/* Default directory for slurpd's private copy of replication logs */
-#define DEFAULT_SLURPD_REPLICA_DIR LDAP_RUNDIR LDAP_DIRSEP "openldap-slurp"
-
-/* Default name for slurpd's private copy of the replication log */
-#define DEFAULT_SLURPD_REPLOGFILE "slurpd.replog"
-
-/* Name of file which stores saved slurpd state info, for restarting */
-#define DEFAULT_SLURPD_STATUS_FILE "slurpd.status"
-
-/* slurpd dump file - contents of rq struct are written here (debugging) */
-#define SLURPD_DUMPFILE LDAP_TMPDIR LDAP_DIRSEP "slurpd.dump"
-
-/* Amount of time to sleep if no more work to do */
-#define DEFAULT_NO_WORK_INTERVAL 3
-
-/* The time we wait between checks to see if the replog file needs trimming */
-#define TRIMCHECK_INTERVAL ( 60 * 5 )
-
-/* Only try to trim slurpd replica files larger than this size */
-#define MIN_TRIM_FILESIZE ( 10L * 1024L )
-
-/* Maximum line length we can read from replication log */
-#define REPLBUFLEN 256
-
-/* TLS flags */
-#define TLS_OFF 0
-#define TLS_ON 1
-#define TLS_CRITICAL 2
-
-/* Rejection records are prefaced with this string */
-#define ERROR_STR "ERROR"
-
-/* Strings found in replication entries */
-#define T_CHANGETYPESTR "changetype"
-#define T_CHANGETYPE 1
-#define T_TIMESTR "time"
-#define T_TIME 2
-#define T_DNSTR "dn"
-#define T_DN 3
-
-#define T_ADDCTSTR "add"
-#define T_ADDCT 4
-#define T_MODIFYCTSTR "modify"
-#define T_MODIFYCT 5
-#define T_DELETECTSTR "delete"
-#define T_DELETECT 6
-#define T_MODRDNCTSTR "modrdn"
-#define T_MODDNCTSTR "moddn"
-#define T_RENAMECTSTR "rename"
-#define T_MODRDNCT 7
-
-#define T_MODOPADDSTR "add"
-#define T_MODOPADD 8
-#define T_MODOPREPLACESTR "replace"
-#define T_MODOPREPLACE 9
-#define T_MODOPDELETESTR "delete"
-#define T_MODOPDELETE 10
-#define T_MODOPINCREMENTSTR "increment"
-#define T_MODOPINCREMENT 11
-#define T_MODSEPSTR "-"
-#define T_MODSEP 12
-
-#define T_NEWRDNSTR "newrdn"
-#define T_DELOLDRDNSTR "deleteoldrdn"
-#define T_NEWSUPSTR "newsuperior"
-
-#define T_ERR -1
-
-/* Config file keywords */
-#define HOSTSTR "host"
-#define URISTR "uri"
-#define ATTRSTR "attr"
-#define SUFFIXSTR "suffix"
-#define BINDDNSTR "binddn"
-#define BINDMETHSTR "bindmethod"
-#define SIMPLESTR "simple"
-#define SASLSTR "sasl"
-#define CREDSTR "credentials"
-#define OLDAUTHCSTR "bindprincipal"
-#define AUTHCSTR "authcID"
-#define AUTHZSTR "authzID"
-#define SASLMECHSTR "saslmech"
-#define REALMSTR "realm"
-#define SECPROPSSTR "secprops"
-#define STARTTLSSTR "starttls"
-#define TLSSTR "tls"
-#define CRITICALSTR "critical"
-
-#define REPLICA_SLEEP_TIME ( 10 )
-
-/* Enumeration of various types of bind failures */
-#define BIND_OK 0
-#define BIND_ERR_BADLDP 1
-#define BIND_ERR_OPEN 2
-#define BIND_ERR_BAD_ATYPE 3
-#define BIND_ERR_SIMPLE_FAILED 4
-#define BIND_ERR_BADRI 6
-#define BIND_ERR_VERSION 7
-#define BIND_ERR_REFERRALS 8
-#define BIND_ERR_MANAGEDSAIT 9
-#define BIND_ERR_SASL_FAILED 10
-#define BIND_ERR_TLS_FAILED 11
-
-/* Return codes for do_ldap() */
-#define DO_LDAP_OK 0
-#define DO_LDAP_ERR_RETRYABLE 1
-#define DO_LDAP_ERR_FATAL 2
-
-/*
- * Types of counts one can request from the Rq rq_getcount()
- * member function
- */
-/* all elements */
-#define RQ_COUNT_ALL 1
-/* all elements with nonzero refcnt */
-#define RQ_COUNT_NZRC 2
-
-/* Amount of time, in seconds, for a thread to sleep when it encounters
- * a retryable error in do_ldap().
- */
-#define RETRY_SLEEP_TIME 60
-
-
-LDAP_BEGIN_DECL
-
-/*
- * ****************************************************************************
- * Data types for replication queue and queue elements.
- * ****************************************************************************
- */
-
-
-/*
- * Replica host information. An Ri struct will contain an array of these,
- * with one entry for each replica. The end of the array is signaled
- * by a NULL value in the rh_hostname field.
- */
-typedef struct rh {
- char *rh_hostname; /* replica hostname */
- int rh_port; /* replica port */
-} Rh;
-
-
-/*
- * Per-replica information.
- *
- * Notes:
- * - Private data should not be manipulated expect by Ri member functions.
- */
-typedef struct ri Ri;
-struct ri {
- /* Private data */
- char *ri_hostname; /* canonical hostname of replica */
- int ri_port; /* port where slave slapd running */
- char *ri_uri; /* e.g. "ldaps://ldap-1.example.com:636" */
- LDAP *ri_ldp; /* LDAP struct for this replica */
- int ri_tls; /* TLS: 0=no, 1=yes, 2=critical */
- int ri_bind_method; /* AUTH_SIMPLE or AUTH_SASL */
- char *ri_bind_dn; /* DN to bind as when replicating */
- char *ri_password; /* Password for any method */
- char *ri_secprops; /* SASL security properties */
- char *ri_realm; /* realm for any mechanism */
- char *ri_authcId; /* authentication ID for any mechanism */
- char *ri_authzId; /* authorization ID for any mechanism */
- char *ri_saslmech; /* SASL mechanism to use */
- struct re *ri_curr; /* current repl entry being processed */
- struct stel *ri_stel; /* pointer to Stel for this replica */
- unsigned long
- ri_seq; /* seq number of last repl */
- ldap_pvt_thread_t ri_tid; /* ID of thread for this replica */
-
- /* Member functions */
- int (*ri_process) LDAP_P(( Ri * )); /* process the next repl entry */
- void (*ri_wake) LDAP_P(( Ri * )); /* wake up a sleeping thread */
-};
-
-
-
-/*
- * Information about one particular modification to make. This data should
- * be considered private to routines in re.c, and to routines in ri.c.
- */
-typedef struct mi {
- /* Private data */
- char *mi_type; /* attr or type */
- char *mi_val; /* value */
- int mi_len; /* length of mi_val */
-} Mi;
-
-
-
-/*
- * Information about one particular replication entry. Only routines in
- * re.c and rq.c should touch the private data. Other routines should
- * only use member functions.
- */
-typedef struct re Re;
-struct re {
- /* Private data */
- ldap_pvt_thread_mutex_t
- re_mutex; /* mutex for this Re */
- int re_refcnt; /* ref count, 0 = done */
- time_t re_timestamp; /* timestamp of this re */
- int re_seq; /* sequence number */
- Rh *re_replicas; /* array of replica info */
- char *re_dn; /* dn of entry being modified */
- int re_changetype; /* type of modification */
- Mi *re_mods; /* array of modifications to make */
- struct re *re_next; /* pointer to next element */
-
- /* Public functions */
- int (*re_free) LDAP_P(( Re * )); /* free an re struct */
- Re *(*re_getnext) LDAP_P(( Re * )); /* return next Re in linked list */
- int (*re_parse) LDAP_P(( Re *, char * )); /* parse replication log entry */
- int (*re_write) LDAP_P(( Ri *, Re *, FILE * )); /* write repl. log entry */
- void (*re_dump) LDAP_P(( Re *, FILE * )); /* debugging - print contents */
- int (*re_lock) LDAP_P(( Re * )); /* lock this re */
- int (*re_unlock) LDAP_P(( Re * )); /* unlock this re */
- int (*re_decrefcnt) LDAP_P(( Re * )); /* decrement the refcnt */
- int (*re_getrefcnt) LDAP_P(( Re * )); /* get the refcnt */
-};
-
-
-
-
-/*
- * Definition for the queue of replica information. Private data is
- * private to rq.c. Other routines should only touch public data or
- * use member functions. Note that although we have a member function
- * for locking the queue's mutex, we need to expose the rq_mutex
- * variable so routines in ri.c can use it as a mutex for the
- * rq_more condition variable.
- */
-typedef struct rq Rq;
-struct rq {
-
- /* Private data */
- Re *rq_head; /* pointer to head */
- Re *rq_tail; /* pointer to tail */
- int rq_nre; /* total number of Re's in queue */
- int rq_ndel; /* number of deleted Re's in queue */
- time_t rq_lasttrim; /* Last time we trimmed file */
-
- /* Public data */
- ldap_pvt_thread_mutex_t
- rq_mutex; /* mutex for whole queue */
- ldap_pvt_thread_cond_t
- rq_more; /* condition var - more work added */
-
- /* Member functions */
- Re * (*rq_gethead) LDAP_P(( Rq * )); /* get the element at head */
- Re * (*rq_getnext) LDAP_P(( Re * )); /* get the next element */
- int (*rq_delhead) LDAP_P(( Rq * )); /* delete the element at head */
- int (*rq_add) LDAP_P(( Rq *, char * )); /* add at tail */
- void (*rq_gc) LDAP_P(( Rq * )); /* garbage-collect queue */
- int (*rq_lock) LDAP_P(( Rq * )); /* lock the queue */
- int (*rq_unlock) LDAP_P(( Rq * )); /* unlock the queue */
- int (*rq_needtrim) LDAP_P(( Rq * )); /* see if queue needs trimming */
- int (*rq_write) LDAP_P(( Rq *, FILE * )); /*write Rq contents to file*/
- int (*rq_getcount) LDAP_P(( Rq *, int )); /* return queue counts */
- void (*rq_dump) LDAP_P(( Rq * )); /* debugging - print contents */
-};
-
-
-/*
- * An Stel (status element) contains information about one replica.
- * Stel structs are associated with the St (status) struct, defined
- * below.
- */
-typedef struct stel {
- char *hostname; /* host name of replica */
- int port; /* port number of replica */
- time_t last; /* timestamp of last successful repl */
- int seq; /* Sequence number of last repl */
-} Stel;
-
-
-/*
- * An St struct in an in-core structure which contains the current
- * slurpd state. Most importantly, it contains an array of Stel
- * structs which contain the timestamp and sequence number of the last
- * successful replication for each replica. The st_write() member
- * function is called periodically to flush status information to
- * disk. At startup time, slurpd checks for the status file, and
- * if present, uses the timestamps to avoid "replaying" replications
- * which have already been sent to a given replica.
- */
-typedef struct st St;
-struct st {
- /* Private data */
- ldap_pvt_thread_mutex_t
- st_mutex; /* mutex to serialize access */
- Stel **st_data; /* array of pointers to Stel structs */
- int st_nreplicas; /* number of repl hosts */
- int st_err_logged; /* 1 if fopen err logged */
- FILE *st_fp; /* st file kept open */
- FILE *st_lfp; /* lockfile fp */
-
- /* Public member functions */
- int (*st_update) LDAP_P(( St *, Stel*, Re* ));/*update entry for a host*/
- Stel*(*st_add) LDAP_P(( St *, Ri * )); /*add a new repl host*/
- int (*st_write) LDAP_P(( St * )); /* write status to disk */
- int (*st_read) LDAP_P(( St * )); /* read status info from disk */
- int (*st_lock) LDAP_P(( St * )); /* read status info from disk */
- int (*st_unlock) LDAP_P(( St * )); /* read status info from disk */
-};
-
-#if defined( HAVE_LWP )
-typedef struct tl {
- thread_t tl_tid; /* thread being managed */
- time_t tl_wake; /* time thread should be resumed */
- struct tl *tl_next; /* next node in list */
-} tl_t;
-
-typedef struct tsl {
- tl_t *tsl_list;
- mon_t tsl_mon;
-} tsl_t;
-#endif /* HAVE_LWP */
-
-/*
- * Public functions used to instantiate and initialize queue objects.
- */
-extern int Ri_init LDAP_P(( Ri **ri ));
-extern int Rq_init LDAP_P(( Rq **rq ));
-extern int Re_init LDAP_P(( Re **re ));
-
-#include "proto-slurp.h"
-
-LDAP_END_DECL
-
-#endif /* _SLURPD_H_ */
+++ /dev/null
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by the University of Michigan
- * (as part of U-MICH LDAP).
- */
-
-
-/*
- * st.c - routines for managing the status structure, and for reading and
- * writing status information to disk.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-#include <ac/string.h>
-#include <ac/unistd.h>
-
-#include "slurp.h"
-#include "globals.h"
-#include "lutil.h"
-
-/*
- * Add information about replica host specified by Ri to list
- * of hosts.
- */
-static Stel *
-St_add(
- St *st,
- Ri *ri
-)
-{
- int ind;
-
- if ( st == NULL || ri == NULL ) {
- return NULL;
- }
-
- /* Serialize access to the St struct */
- ldap_pvt_thread_mutex_lock( &(st->st_mutex ));
-
- st->st_nreplicas++;
- ind = st->st_nreplicas - 1;
- st->st_data = ( Stel ** ) ch_realloc( st->st_data,
- ( st->st_nreplicas * sizeof( Stel * )));
- if ( st->st_data == NULL ) {
- ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
- return NULL;
- }
- st->st_data[ ind ] = ( Stel * ) ch_malloc( sizeof( Stel ) );
- if ( st->st_data[ ind ] == NULL ) {
- ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
- return NULL;
- }
-
- st->st_data[ ind ]->hostname = strdup( ri->ri_hostname );
- st->st_data[ ind ]->port = ri->ri_port;
- st->st_data[ ind ]->last = 0;
- st->st_data[ ind ]->seq = 0;
-
- ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
- return st->st_data[ ind ];
-}
-
-
-
-/*
- * Write the contents of an St to disk.
- */
-static int
-St_write (
- St *st
-)
-{
- int rc;
- Stel *stel;
- int i;
-
- if ( st == NULL ) {
- return -1;
- }
- ldap_pvt_thread_mutex_lock( &(st->st_mutex ));
- if ( st->st_fp == NULL ) {
- /* Open file */
- if (( rc = acquire_lock( sglob->slurpd_status_file, &(st->st_fp),
- &(st->st_lfp))) < 0 ) {
- if ( !st->st_err_logged ) {
- Debug( LDAP_DEBUG_ANY,
- "Error: cannot open status file \"%s\": %s\n",
- sglob->slurpd_status_file, sys_errlist[ errno ], 0 );
- st->st_err_logged = 1;
- ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
- return -1;
- }
- } else {
- st->st_err_logged = 0;
- }
- }
-
- /* Write data to the file */
- truncate( sglob->slurpd_status_file, 0L );
- fseek( st->st_fp, 0L, 0 );
- for ( i = 0; i < st->st_nreplicas; i++ ) {
- stel = st->st_data[ i ];
- fprintf( st->st_fp, "%s:%d:%ld:%d\n",
- stel->hostname, stel->port,
- (long) stel->last, stel->seq );
- }
- fflush( st->st_fp );
-
- ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
-
- return 0;
-}
-
-
-
-
-/*
- * Update the entry for a given host.
- */
-static int
-St_update(
- St *st,
- Stel *stel,
- Re *re
-)
-{
- if ( stel == NULL || re == NULL ) {
- return -1;
- }
-
- ldap_pvt_thread_mutex_lock( &(st->st_mutex ));
- stel->last = re->re_timestamp;
- stel->seq = re->re_seq;
- ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
- return 0;
-}
-
-
-
-
-/*
- * Read status information from disk file.
- */
-static int
-St_read(
- St *st
-)
-{
- FILE *fp;
- FILE *lfp;
- char buf[ 255 ];
- int i;
- int rc;
- char *hostname, *port, *timestamp, *seq, *p, *t;
- int found;
-
- if ( st == NULL ) {
- return -1;
- }
- ldap_pvt_thread_mutex_lock( &(st->st_mutex ));
- if ( access( sglob->slurpd_status_file, F_OK ) < 0 ) {
- /*
- * File doesn't exist, so create it and return.
- */
- if (( fp = fopen( sglob->slurpd_status_file, "w" )) == NULL ) {
- Debug( LDAP_DEBUG_ANY, "Error: cannot create status file \"%s\"\n",
- sglob->slurpd_status_file, 0, 0 );
- ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
- return -1;
- }
- (void) fclose( fp );
- ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
- Debug( LDAP_DEBUG_ARGS, "No status file found, defaulting values\n",
- 0, 0, 0 );
- return 0;
- }
- if (( rc = acquire_lock( sglob->slurpd_status_file, &fp, &lfp)) < 0 ) {
- ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
- return 0;
- }
- while ( fgets( buf, sizeof( buf ), fp ) != NULL ) {
- p = buf;
- hostname = p;
- if (( t = strchr( p, ':' )) == NULL ) {
- goto bad;
- }
- *t++ = '\0';
- p = t;
- port = p;
- if (( t = strchr( p, ':' )) == NULL ) {
- goto bad;
- }
- *t++ = '\0';
- p = t;
- timestamp = p;
- if (( t = strchr( p, ':' )) == NULL ) {
- goto bad;
- }
- *t++ = '\0';
- seq = t;
- if (( t = strchr( seq, '\n' )) != NULL ) {
- *t = '\0';
- }
-
- found = 0;
- for ( i = 0; i < sglob->st->st_nreplicas; i++ ) {
- int p;
- if ( !strcmp( hostname, sglob->st->st_data[ i ]->hostname ) &&
- lutil_atoi( &p, port ) == 0 && p == sglob->st->st_data[ i ]->port )
- {
- found = 1;
- if ( lutil_atol( &sglob->st->st_data[ i ]->last, timestamp ) != 0
- || lutil_atoi( &sglob->st->st_data[ i ]->seq, seq ) != 0 )
- {
- found = 0;
- }
- break;
- }
- }
- if ( found ) {
- char tbuf[ 255 ];
- sprintf( tbuf, "%s.%s", timestamp, seq );
- Debug( LDAP_DEBUG_ARGS,
- "Retrieved state information for %s:%s (timestamp %s)\n",
- hostname, port, tbuf );
- } else {
- Debug( LDAP_DEBUG_ANY,
- "Warning: saved state for %s:%s, not a known replica\n",
- hostname, port, 0 );
- }
- }
- (void) relinquish_lock( sglob->slurpd_status_file, fp, lfp);
- ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
- return 0;
-
-bad:
- (void) relinquish_lock( sglob->slurpd_status_file, fp, lfp);
- ldap_pvt_thread_mutex_unlock( &(st->st_mutex ));
- return -1;
-}
-
-
-
-
-/*
- * Lock an St struct.
- */
-static int
-St_lock(
- St *st
-)
-{
- return( ldap_pvt_thread_mutex_lock( &st->st_mutex ));
-}
-
-
-
-
-/*
- * Lock an St struct.
- */
-static int
-St_unlock(
- St *st
-)
-{
- return( ldap_pvt_thread_mutex_unlock( &st->st_mutex ));
-}
-
-
-
-
-/*
- * Allocate and initialize an St struct.
- */
-int
-St_init(
- St **st
-)
-{
- if ( st == NULL ) {
- return -1;
- }
-
- (*st) = (St *) malloc( sizeof( St ));
- if ( *st == NULL ) {
- return -1;
- }
-
- ldap_pvt_thread_mutex_init( &((*st)->st_mutex) );
- (*st)->st_data = NULL;
- (*st)->st_fp = NULL;
- (*st)->st_lfp = NULL;
- (*st)->st_nreplicas = 0;
- (*st)->st_err_logged = 0;
- (*st)->st_update = St_update;
- (*st)->st_add = St_add;
- (*st)->st_write = St_write;
- (*st)->st_read = St_read;
- (*st)->st_lock = St_lock;
- (*st)->st_unlock = St_unlock;
- return 0;
-}
-