2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2006 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
15 /* Portions Copyright (c) 1996 Regents of the University of Michigan.
16 * All rights reserved.
18 * Redistribution and use in source and binary forms are permitted
19 * provided that this notice is preserved and that due credit is given
20 * to the University of Michigan at Ann Arbor. The name of the University
21 * may not be used to endorse or promote products derived from this
22 * software without specific prior written permission. This software
23 * is provided ``as is'' without express or implied warranty.
26 * This work was originally developed by the University of Michigan
27 * (as part of U-MICH LDAP).
30 /* slurp.h - Standalone Ldap Update Replication Daemon (slurpd) */
35 #if !defined(HAVE_WINSOCK) && !defined(LDAP_SYSLOG)
41 #include <ac/signal.h>
42 #include <ac/syslog.h>
45 #include <sys/types.h>
50 #define ldap_debug slurp_debug
53 #include "ldap_pvt_thread.h"
54 #include "ldap_defaults.h"
58 /* should be moved to portable.h.nt */
59 #define ftruncate(a,b) _chsize(a,b)
60 #define truncate(a,b) _lclose( _lcreat(a, 0))
61 #define mkdir(a,b) mkdir(a)
74 #define S_IRUSR S_IREAD
77 #define S_IWUSR S_IWRITE
82 #define SERVICE_NAME OPENLDAP_PACKAGE "-slurpd"
84 /* Default directory for slurpd's private copy of replication logs */
85 #define DEFAULT_SLURPD_REPLICA_DIR LDAP_RUNDIR LDAP_DIRSEP "openldap-slurp"
87 /* Default name for slurpd's private copy of the replication log */
88 #define DEFAULT_SLURPD_REPLOGFILE "slurpd.replog"
90 /* Name of file which stores saved slurpd state info, for restarting */
91 #define DEFAULT_SLURPD_STATUS_FILE "slurpd.status"
93 /* slurpd dump file - contents of rq struct are written here (debugging) */
94 #define SLURPD_DUMPFILE LDAP_TMPDIR LDAP_DIRSEP "slurpd.dump"
96 /* Amount of time to sleep if no more work to do */
97 #define DEFAULT_NO_WORK_INTERVAL 3
99 /* The time we wait between checks to see if the replog file needs trimming */
100 #define TRIMCHECK_INTERVAL ( 60 * 5 )
102 /* Only try to trim slurpd replica files larger than this size */
103 #define MIN_TRIM_FILESIZE ( 10L * 1024L )
105 /* Maximum line length we can read from replication log */
106 #define REPLBUFLEN 256
111 #define TLS_CRITICAL 2
113 /* Rejection records are prefaced with this string */
114 #define ERROR_STR "ERROR"
116 /* Strings found in replication entries */
117 #define T_CHANGETYPESTR "changetype"
118 #define T_CHANGETYPE 1
119 #define T_TIMESTR "time"
124 #define T_ADDCTSTR "add"
126 #define T_MODIFYCTSTR "modify"
128 #define T_DELETECTSTR "delete"
130 #define T_MODRDNCTSTR "modrdn"
131 #define T_MODDNCTSTR "moddn"
132 #define T_RENAMECTSTR "rename"
135 #define T_MODOPADDSTR "add"
137 #define T_MODOPREPLACESTR "replace"
138 #define T_MODOPREPLACE 9
139 #define T_MODOPDELETESTR "delete"
140 #define T_MODOPDELETE 10
141 #define T_MODOPINCREMENTSTR "increment"
142 #define T_MODOPINCREMENT 11
143 #define T_MODSEPSTR "-"
146 #define T_NEWRDNSTR "newrdn"
147 #define T_DELOLDRDNSTR "deleteoldrdn"
148 #define T_NEWSUPSTR "newsuperior"
152 /* Config file keywords */
153 #define HOSTSTR "host"
155 #define ATTRSTR "attr"
156 #define SUFFIXSTR "suffix"
157 #define BINDDNSTR "binddn"
158 #define BINDMETHSTR "bindmethod"
159 #define KERBEROSSTR "kerberos"
160 #define SIMPLESTR "simple"
161 #define SASLSTR "sasl"
162 #define CREDSTR "credentials"
163 #define OLDAUTHCSTR "bindprincipal"
164 #define AUTHCSTR "authcID"
165 #define AUTHZSTR "authzID"
166 #define SRVTABSTR "srvtab"
167 #define SASLMECHSTR "saslmech"
168 #define REALMSTR "realm"
169 #define SECPROPSSTR "secprops"
170 #define STARTTLSSTR "starttls"
172 #define CRITICALSTR "critical"
174 #define REPLICA_SLEEP_TIME ( 10 )
176 /* Enumeration of various types of bind failures */
178 #define BIND_ERR_BADLDP 1
179 #define BIND_ERR_OPEN 2
180 #define BIND_ERR_BAD_ATYPE 3
181 #define BIND_ERR_SIMPLE_FAILED 4
182 #define BIND_ERR_KERBEROS_FAILED 5
183 #define BIND_ERR_BADRI 6
184 #define BIND_ERR_VERSION 7
185 #define BIND_ERR_REFERRALS 8
186 #define BIND_ERR_MANAGEDSAIT 9
187 #define BIND_ERR_SASL_FAILED 10
188 #define BIND_ERR_TLS_FAILED 11
190 /* Return codes for do_ldap() */
192 #define DO_LDAP_ERR_RETRYABLE 1
193 #define DO_LDAP_ERR_FATAL 2
196 * Types of counts one can request from the Rq rq_getcount()
200 #define RQ_COUNT_ALL 1
201 /* all elements with nonzero refcnt */
202 #define RQ_COUNT_NZRC 2
204 /* Amount of time, in seconds, for a thread to sleep when it encounters
205 * a retryable error in do_ldap().
207 #define RETRY_SLEEP_TIME 60
213 * ****************************************************************************
214 * Data types for replication queue and queue elements.
215 * ****************************************************************************
220 * Replica host information. An Ri struct will contain an array of these,
221 * with one entry for each replica. The end of the array is signaled
222 * by a NULL value in the rh_hostname field.
225 char *rh_hostname; /* replica hostname */
226 int rh_port; /* replica port */
231 * Per-replica information.
234 * - Private data should not be manipulated expect by Ri member functions.
236 typedef struct ri Ri;
239 char *ri_hostname; /* canonical hostname of replica */
240 int ri_port; /* port where slave slapd running */
241 char *ri_uri; /* e.g. "ldaps://ldap-1.example.com:636" */
242 LDAP *ri_ldp; /* LDAP struct for this replica */
243 int ri_tls; /* TLS: 0=no, 1=yes, 2=critical */
244 int ri_bind_method; /* AUTH_SIMPLE or AUTH_KERBEROS */
245 char *ri_bind_dn; /* DN to bind as when replicating */
246 char *ri_password; /* Password for any method */
247 char *ri_secprops; /* SASL security properties */
248 char *ri_realm; /* realm for any mechanism */
249 char *ri_authcId; /* authentication ID for any mechanism */
250 char *ri_authzId; /* authorization ID for any mechanism */
251 char *ri_srvtab; /* srvtab file for kerberos bind */
252 char *ri_saslmech; /* SASL mechanism to use */
253 struct re *ri_curr; /* current repl entry being processed */
254 struct stel *ri_stel; /* pointer to Stel for this replica */
256 ri_seq; /* seq number of last repl */
257 ldap_pvt_thread_t ri_tid; /* ID of thread for this replica */
259 /* Member functions */
260 int (*ri_process) LDAP_P(( Ri * )); /* process the next repl entry */
261 void (*ri_wake) LDAP_P(( Ri * )); /* wake up a sleeping thread */
267 * Information about one particular modification to make. This data should
268 * be considered private to routines in re.c, and to routines in ri.c.
272 char *mi_type; /* attr or type */
273 char *mi_val; /* value */
274 int mi_len; /* length of mi_val */
280 * Information about one particular replication entry. Only routines in
281 * re.c and rq.c should touch the private data. Other routines should
282 * only use member functions.
284 typedef struct re Re;
287 ldap_pvt_thread_mutex_t
288 re_mutex; /* mutex for this Re */
289 int re_refcnt; /* ref count, 0 = done */
290 time_t re_timestamp; /* timestamp of this re */
291 int re_seq; /* sequence number */
292 Rh *re_replicas; /* array of replica info */
293 char *re_dn; /* dn of entry being modified */
294 int re_changetype; /* type of modification */
295 Mi *re_mods; /* array of modifications to make */
296 struct re *re_next; /* pointer to next element */
298 /* Public functions */
299 int (*re_free) LDAP_P(( Re * )); /* free an re struct */
300 Re *(*re_getnext) LDAP_P(( Re * )); /* return next Re in linked list */
301 int (*re_parse) LDAP_P(( Re *, char * )); /* parse replication log entry */
302 int (*re_write) LDAP_P(( Ri *, Re *, FILE * )); /* write repl. log entry */
303 void (*re_dump) LDAP_P(( Re *, FILE * )); /* debugging - print contents */
304 int (*re_lock) LDAP_P(( Re * )); /* lock this re */
305 int (*re_unlock) LDAP_P(( Re * )); /* unlock this re */
306 int (*re_decrefcnt) LDAP_P(( Re * )); /* decrement the refcnt */
307 int (*re_getrefcnt) LDAP_P(( Re * )); /* get the refcnt */
314 * Definition for the queue of replica information. Private data is
315 * private to rq.c. Other routines should only touch public data or
316 * use member functions. Note that although we have a member function
317 * for locking the queue's mutex, we need to expose the rq_mutex
318 * variable so routines in ri.c can use it as a mutex for the
319 * rq_more condition variable.
321 typedef struct rq Rq;
325 Re *rq_head; /* pointer to head */
326 Re *rq_tail; /* pointer to tail */
327 int rq_nre; /* total number of Re's in queue */
328 int rq_ndel; /* number of deleted Re's in queue */
329 time_t rq_lasttrim; /* Last time we trimmed file */
332 ldap_pvt_thread_mutex_t
333 rq_mutex; /* mutex for whole queue */
334 ldap_pvt_thread_cond_t
335 rq_more; /* condition var - more work added */
337 /* Member functions */
338 Re * (*rq_gethead) LDAP_P(( Rq * )); /* get the element at head */
339 Re * (*rq_getnext) LDAP_P(( Re * )); /* get the next element */
340 int (*rq_delhead) LDAP_P(( Rq * )); /* delete the element at head */
341 int (*rq_add) LDAP_P(( Rq *, char * )); /* add at tail */
342 void (*rq_gc) LDAP_P(( Rq * )); /* garbage-collect queue */
343 int (*rq_lock) LDAP_P(( Rq * )); /* lock the queue */
344 int (*rq_unlock) LDAP_P(( Rq * )); /* unlock the queue */
345 int (*rq_needtrim) LDAP_P(( Rq * )); /* see if queue needs trimming */
346 int (*rq_write) LDAP_P(( Rq *, FILE * )); /*write Rq contents to file*/
347 int (*rq_getcount) LDAP_P(( Rq *, int )); /* return queue counts */
348 void (*rq_dump) LDAP_P(( Rq * )); /* debugging - print contents */
353 * An Stel (status element) contains information about one replica.
354 * Stel structs are associated with the St (status) struct, defined
357 typedef struct stel {
358 char *hostname; /* host name of replica */
359 int port; /* port number of replica */
360 time_t last; /* timestamp of last successful repl */
361 int seq; /* Sequence number of last repl */
366 * An St struct in an in-core structure which contains the current
367 * slurpd state. Most importantly, it contains an array of Stel
368 * structs which contain the timestamp and sequence number of the last
369 * successful replication for each replica. The st_write() member
370 * function is called periodically to flush status information to
371 * disk. At startup time, slurpd checks for the status file, and
372 * if present, uses the timestamps to avoid "replaying" replications
373 * which have already been sent to a given replica.
375 typedef struct st St;
378 ldap_pvt_thread_mutex_t
379 st_mutex; /* mutex to serialize access */
380 Stel **st_data; /* array of pointers to Stel structs */
381 int st_nreplicas; /* number of repl hosts */
382 int st_err_logged; /* 1 if fopen err logged */
383 FILE *st_fp; /* st file kept open */
384 FILE *st_lfp; /* lockfile fp */
386 /* Public member functions */
387 int (*st_update) LDAP_P(( St *, Stel*, Re* ));/*update entry for a host*/
388 Stel*(*st_add) LDAP_P(( St *, Ri * )); /*add a new repl host*/
389 int (*st_write) LDAP_P(( St * )); /* write status to disk */
390 int (*st_read) LDAP_P(( St * )); /* read status info from disk */
391 int (*st_lock) LDAP_P(( St * )); /* read status info from disk */
392 int (*st_unlock) LDAP_P(( St * )); /* read status info from disk */
395 #if defined( HAVE_LWP )
397 thread_t tl_tid; /* thread being managed */
398 time_t tl_wake; /* time thread should be resumed */
399 struct tl *tl_next; /* next node in list */
406 #endif /* HAVE_LWP */
409 * Public functions used to instantiate and initialize queue objects.
411 extern int Ri_init LDAP_P(( Ri **ri ));
412 extern int Rq_init LDAP_P(( Rq **rq ));
413 extern int Re_init LDAP_P(( Re **re ));
415 #include "proto-slurp.h"
419 #endif /* _SLURPD_H_ */