From: Howard Chu Date: Thu, 5 Apr 2007 23:20:04 +0000 (+0000) Subject: slurpd is strongly deprecated X-Git-Tag: OPENLDAP_REL_ENG_2_4_MP~547 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=3d1fe19accae03a356e6809a084ee72140379215;p=openldap slurpd is strongly deprecated --- diff --git a/servers/Makefile.in b/servers/Makefile.in index 4fc47ae36a..010cca46ca 100644 --- a/servers/Makefile.in +++ b/servers/Makefile.in @@ -13,5 +13,5 @@ ## top-level directory of the distribution or, alternatively, at ## . -SUBDIRS= slapd slurpd +SUBDIRS= slapd diff --git a/servers/slurpd/DESIGN b/servers/slurpd/DESIGN deleted file mode 100644 index dc5994e8b9..0000000000 --- a/servers/slurpd/DESIGN +++ /dev/null @@ -1,51 +0,0 @@ -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 diff --git a/servers/slurpd/Makefile.in b/servers/slurpd/Makefile.in deleted file mode 100644 index 9ce402c03a..0000000000 --- a/servers/slurpd/Makefile.in +++ /dev/null @@ -1,67 +0,0 @@ -# Makefile.in for slurpd -# $OpenLDAP$ -## This work is part of OpenLDAP Software . -## -## 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 -## . - -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 \ - ) - diff --git a/servers/slurpd/NOTES b/servers/slurpd/NOTES deleted file mode 100644 index c8b1ae9163..0000000000 --- a/servers/slurpd/NOTES +++ /dev/null @@ -1,67 +0,0 @@ -Written by Ganesan Rajagopal 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!). diff --git a/servers/slurpd/admin.c b/servers/slurpd/admin.c deleted file mode 100644 index fa4e8f8a35..0000000000 --- a/servers/slurpd/admin.c +++ /dev/null @@ -1,61 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 -#include - -#include - -#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 ); -} diff --git a/servers/slurpd/args.c b/servers/slurpd/args.c deleted file mode 100644 index c5685817ef..0000000000 --- a/servers/slurpd/args.c +++ /dev/null @@ -1,181 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include -#include -#include - -#include -#include - -#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; -} diff --git a/servers/slurpd/ch_malloc.c b/servers/slurpd/ch_malloc.c deleted file mode 100644 index 7532fbe4dc..0000000000 --- a/servers/slurpd/ch_malloc.c +++ /dev/null @@ -1,158 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include - -#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 diff --git a/servers/slurpd/config.c b/servers/slurpd/config.c deleted file mode 100644 index 949e3084e0..0000000000 --- a/servers/slurpd/config.c +++ /dev/null @@ -1,675 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include -#include -#include - -#include -#include - -#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, "\" 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 \" 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 \" 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 \" 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 \" 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 \" 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= binddn= - * bindmethod="simple" credentials= - * - * where: - * describes the host name and port number where the - * replica is running, - * - * is the DN to bind to the replica slapd as, - * - * bindmethod is "simple", and - * - * are the credentials (e.g. password) for binddn. 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; -} - diff --git a/servers/slurpd/fm.c b/servers/slurpd/fm.c deleted file mode 100644 index 23d08bfba0..0000000000 --- a/servers/slurpd/fm.c +++ /dev/null @@ -1,274 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include -#include -#include -#include - -#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 ); -} diff --git a/servers/slurpd/globals.c b/servers/slurpd/globals.c deleted file mode 100644 index 80e2238f72..0000000000 --- a/servers/slurpd/globals.c +++ /dev/null @@ -1,100 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include - -#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; -} diff --git a/servers/slurpd/globals.h b/servers/slurpd/globals.h deleted file mode 100644 index 28a960b9f9..0000000000 --- a/servers/slurpd/globals.h +++ /dev/null @@ -1,89 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 */ diff --git a/servers/slurpd/ldap_op.c b/servers/slurpd/ldap_op.c deleted file mode 100644 index dc06b2d310..0000000000 --- a/servers/slurpd/ldap_op.c +++ /dev/null @@ -1,918 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include - -#include -#include -#include -#include -#include - -#define LDAP_DEPRECATED 1 -#include -#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 diff --git a/servers/slurpd/lock.c b/servers/slurpd/lock.c deleted file mode 100644 index 7b459abc31..0000000000 --- a/servers/slurpd/lock.c +++ /dev/null @@ -1,144 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_FILE_H -#include -#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 ); -} diff --git a/servers/slurpd/main.c b/servers/slurpd/main.c deleted file mode 100644 index 4284c87361..0000000000 --- a/servers/slurpd/main.c +++ /dev/null @@ -1,355 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 -#include -#include -#include - -#include "slurp.h" -#include "globals.h" -#include "lutil.h" - -#include - -#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 */ -} diff --git a/servers/slurpd/nt_svc.c b/servers/slurpd/nt_svc.c deleted file mode 100644 index e2b0f88918..0000000000 --- a/servers/slurpd/nt_svc.c +++ /dev/null @@ -1,110 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ - -#include "portable.h" -#include -#include -#include -#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 diff --git a/servers/slurpd/proto-slurp.h b/servers/slurpd/proto-slurp.h deleted file mode 100644 index b21386737c..0000000000 --- a/servers/slurpd/proto-slurp.h +++ /dev/null @@ -1,113 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -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 */ diff --git a/servers/slurpd/re.c b/servers/slurpd/re.c deleted file mode 100644 index e0d4ddd8f1..0000000000 --- a/servers/slurpd/re.c +++ /dev/null @@ -1,793 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include -#include -#include -#include - -#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; - } -} diff --git a/servers/slurpd/reject.c b/servers/slurpd/reject.c deleted file mode 100644 index 9eeac4f315..0000000000 --- a/servers/slurpd/reject.c +++ /dev/null @@ -1,155 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include -#include -#include - -#include -#include - -#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/:.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; -} - diff --git a/servers/slurpd/replica.c b/servers/slurpd/replica.c deleted file mode 100644 index 4702d105c7..0000000000 --- a/servers/slurpd/replica.c +++ /dev/null @@ -1,83 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 -#include - -#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; -} diff --git a/servers/slurpd/replog.c b/servers/slurpd/replog.c deleted file mode 100644 index e4bf325747..0000000000 --- a/servers/slurpd/replog.c +++ /dev/null @@ -1,169 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#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 ); - } -} diff --git a/servers/slurpd/ri.c b/servers/slurpd/ri.c deleted file mode 100644 index 62062cceb8..0000000000 --- a/servers/slurpd/ri.c +++ /dev/null @@ -1,285 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include -#include - -#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; -} diff --git a/servers/slurpd/rq.c b/servers/slurpd/rq.c deleted file mode 100644 index 46010e6757..0000000000 --- a/servers/slurpd/rq.c +++ /dev/null @@ -1,444 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 -#include - -#include -#include -#include /* get ftruncate() */ - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#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; -} diff --git a/servers/slurpd/sanity.c b/servers/slurpd/sanity.c deleted file mode 100644 index 56d1ed3d67..0000000000 --- a/servers/slurpd/sanity.c +++ /dev/null @@ -1,225 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include -#include - -#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; -} diff --git a/servers/slurpd/slurp.h b/servers/slurpd/slurp.h deleted file mode 100644 index 9a125c63f7..0000000000 --- a/servers/slurpd/slurp.h +++ /dev/null @@ -1,415 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 -#include -#include -#include -#include - -#include - -#include - -#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_ */ diff --git a/servers/slurpd/st.c b/servers/slurpd/st.c deleted file mode 100644 index 609766e204..0000000000 --- a/servers/slurpd/st.c +++ /dev/null @@ -1,331 +0,0 @@ -/* $OpenLDAP$ */ -/* This work is part of OpenLDAP Software . - * - * 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 - * . - */ -/* 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 - -#include -#include -#include - -#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; -} -