3 * Copyright (c) 1996 Regents of the University of Michigan.
6 * Redistribution and use in source and binary forms are permitted
7 * provided that this notice is preserved and that due credit is given
8 * to the University of Michigan at Ann Arbor. The name of the University
9 * may not be used to endorse or promote products derived from this
10 * software without specific prior written permission. This software
11 * is provided ``as is'' without express or implied warranty.
14 /* slurp.h - Standalone Ldap Update Replication Daemon (slurpd) */
24 #include <ac/signal.h>
25 #include <ac/syslog.h>
28 #ifdef HAVE_SYS_PARAM_H
29 #include <sys/param.h>
31 #include <sys/types.h>
36 #define ldap_debug slurp_debug
39 #include "ldap_pvt_thread.h"
40 #include "ldap_defaults.h"
44 /* Default directory for slurpd's private copy of replication logs */
45 #define DEFAULT_SLURPD_REPLICA_DIR "/usr/tmp"
47 /* Default name for slurpd's private copy of the replication log */
48 #define DEFAULT_SLURPD_REPLOGFILE "slurpd.replog"
50 /* Name of file which stores saved slurpd state info, for restarting */
51 #define DEFAULT_SLURPD_STATUS_FILE "slurpd.status"
53 /* slurpd dump file - contents of rq struct are written here (debugging) */
54 #define SLURPD_DUMPFILE "/tmp/slurpd.dump"
56 /* default srvtab file. Can be overridden */
57 #define SRVTAB "/etc/srvtab"
59 /* Amount of time to sleep if no more work to do */
60 #define DEFAULT_NO_WORK_INTERVAL 3
62 /* The time we wait between checks to see if the replog file needs trimming */
63 #define TRIMCHECK_INTERVAL ( 60 * 5 )
65 /* Only try to trim slurpd replica files larger than this size */
66 #define MIN_TRIM_FILESIZE ( 10L * 1024L )
68 /* Maximum line length we can read from replication log */
69 #define REPLBUFLEN 256
71 /* We support simple (plaintext password) and kerberos authentication */
73 #define AUTH_KERBEROS 2
75 /* Rejection records are prefaced with this string */
76 #define ERROR_STR "ERROR"
78 /* Strings found in replication entries */
79 #define T_CHANGETYPESTR "changetype"
80 #define T_CHANGETYPE 1
81 #define T_TIMESTR "time"
86 #define T_ADDCTSTR "add"
88 #define T_MODIFYCTSTR "modify"
90 #define T_DELETECTSTR "delete"
92 #define T_MODRDNCTSTR "modrdn"
93 #define T_MODDNCTSTR "moddn"
94 #define T_RENAMECTSTR "rename"
97 #define T_MODOPADDSTR "add"
99 #define T_MODOPREPLACESTR "replace"
100 #define T_MODOPREPLACE 9
101 #define T_MODOPDELETESTR "delete"
102 #define T_MODOPDELETE 10
103 #define T_MODSEPSTR "-"
106 #define T_NEWRDNSTR "newrdn"
107 #define T_DELOLDRDNSTR "deleteoldrdn"
108 #define T_NEWSUPSTR "newsuperior"
112 /* Config file keywords */
113 #define HOSTSTR "host"
114 #define BINDDNSTR "binddn"
115 #define BINDMETHSTR "bindmethod"
116 #define KERBEROSSTR "kerberos"
117 #define SIMPLESTR "simple"
118 #define CREDSTR "credentials"
119 #define BINDPSTR "bindprincipal"
120 #define SRVTABSTR "srvtab"
122 #define REPLICA_SLEEP_TIME ( 10 )
124 /* Enumeration of various types of bind failures */
126 #define BIND_ERR_BADLDP 1
127 #define BIND_ERR_OPEN 2
128 #define BIND_ERR_BAD_ATYPE 3
129 #define BIND_ERR_SIMPLE_FAILED 4
130 #define BIND_ERR_KERBEROS_FAILED 5
131 #define BIND_ERR_BADRI 6
133 /* Return codes for do_ldap() */
135 #define DO_LDAP_ERR_RETRYABLE 1
136 #define DO_LDAP_ERR_FATAL 2
139 * Types of counts one can request from the Rq rq_getcount()
143 #define RQ_COUNT_ALL 1
144 /* all elements with nonzero refcnt */
145 #define RQ_COUNT_NZRC 2
147 /* Amount of time, in seconds, for a thread to sleep when it encounters
148 * a retryable error in do_ldap().
150 #define RETRY_SLEEP_TIME 60
156 * ****************************************************************************
157 * Data types for replication queue and queue elements.
158 * ****************************************************************************
163 * Replica host information. An Ri struct will contain an array of these,
164 * with one entry for each replica. The end of the array is signaled
165 * by a NULL value in the rh_hostname field.
168 char *rh_hostname; /* replica hostname */
169 int rh_port; /* replica port */
174 * Per-replica information.
177 * - Private data should not be manipulated expect by Ri member functions.
179 typedef struct ri Ri;
183 char *ri_hostname; /* canonical hostname of replica */
184 int ri_port; /* port where slave slapd running */
185 LDAP *ri_ldp; /* LDAP struct for this replica */
186 int ri_bind_method; /* AUTH_SIMPLE or AUTH_KERBEROS */
187 char *ri_bind_dn; /* DN to bind as when replicating */
188 char *ri_password; /* Password for AUTH_SIMPLE */
189 char *ri_principal; /* principal for kerberos bind */
190 char *ri_srvtab; /* srvtab file for kerberos bind */
191 struct re *ri_curr; /* current repl entry being processed */
192 struct stel *ri_stel; /* pointer to Stel for this replica */
194 ri_seq; /* seq number of last repl */
195 ldap_pvt_thread_t ri_tid; /* ID of thread for this replica */
197 /* Member functions */
198 int (*ri_process) LDAP_P(( Ri * )); /* process the next repl entry */
199 void (*ri_wake) LDAP_P(( Ri * )); /* wake up a sleeping thread */
206 * Information about one particular modification to make. This data should
207 * be considered private to routines in re.c, and to routines in ri.c.
212 char *mi_type; /* attr or type */
213 char *mi_val; /* value */
214 int mi_len; /* length of mi_val */
221 * Information about one particular replication entry. Only routines in
222 * re.c and rq.c should touch the private data. Other routines should
223 * only use member functions.
225 typedef struct re Re;
229 ldap_pvt_thread_mutex_t
230 re_mutex; /* mutex for this Re */
231 int re_refcnt; /* ref count, 0 = done */
232 char *re_timestamp; /* timestamp of this re */
233 int re_seq; /* sequence number */
234 Rh *re_replicas; /* array of replica info */
235 char *re_dn; /* dn of entry being modified */
236 int re_changetype; /* type of modification */
237 Mi *re_mods; /* array of modifications to make */
238 struct re *re_next; /* pointer to next element */
240 /* Public functions */
241 int (*re_free) LDAP_P(( Re * )); /* free an re struct */
242 Re *(*re_getnext) LDAP_P(( Re * )); /* return next Re in linked list */
243 int (*re_parse) LDAP_P(( Re *, char * )); /* parse replication log entry */
244 int (*re_write) LDAP_P(( Ri *, Re *, FILE * )); /* write repl. log entry */
245 void (*re_dump) LDAP_P(( Re *, FILE * )); /* debugging - print contents */
246 int (*re_lock) LDAP_P(( Re * )); /* lock this re */
247 int (*re_unlock) LDAP_P(( Re * )); /* unlock this re */
248 int (*re_decrefcnt) LDAP_P(( Re * )); /* decrement the refcnt */
249 int (*re_getrefcnt) LDAP_P(( Re * )); /* get the refcnt */
256 * Definition for the queue of replica information. Private data is
257 * private to rq.c. Other routines should only touch public data or
258 * use member functions. Note that although we have a member function
259 * for locking the queue's mutex, we need to expose the rq_mutex
260 * variable so routines in ri.c can use it as a mutex for the
261 * rq_more condition variable.
263 typedef struct rq Rq;
267 Re *rq_head; /* pointer to head */
268 Re *rq_tail; /* pointer to tail */
269 int rq_nre; /* total number of Re's in queue */
270 int rq_ndel; /* number of deleted Re's in queue */
271 time_t rq_lasttrim; /* Last time we trimmed file */
274 ldap_pvt_thread_mutex_t
275 rq_mutex; /* mutex for whole queue */
276 ldap_pvt_thread_cond_t
277 rq_more; /* condition var - more work added */
279 /* Member functions */
280 Re * (*rq_gethead) LDAP_P(( Rq * )); /* get the element at head */
281 Re * (*rq_getnext) LDAP_P(( Re * )); /* get the next element */
282 int (*rq_delhead) LDAP_P(( Rq * )); /* delete the element at head */
283 int (*rq_add) LDAP_P(( Rq *, char * )); /* add at tail */
284 void (*rq_gc) LDAP_P(( Rq * )); /* garbage-collect queue */
285 int (*rq_lock) LDAP_P(( Rq * )); /* lock the queue */
286 int (*rq_unlock) LDAP_P(( Rq * )); /* unlock the queue */
287 int (*rq_needtrim) LDAP_P(( Rq * )); /* see if queue needs trimming */
288 int (*rq_write) LDAP_P(( Rq *, FILE * )); /*write Rq contents to file*/
289 int (*rq_getcount) LDAP_P(( Rq *, int )); /* return queue counts */
290 void (*rq_dump) LDAP_P(( Rq * )); /* debugging - print contents */
295 * An Stel (status element) contains information about one replica.
296 * Stel structs are associated with the St (status) struct, defined
299 typedef struct stel {
300 char *hostname; /* host name of replica */
301 int port; /* port number of replica */
302 char last[ 64 ]; /* timestamp of last successful repl */
303 int seq; /* Sequence number of last repl */
308 * An St struct in an in-core structure which contains the current
309 * slurpd state. Most importantly, it contains an array of Stel
310 * structs which contain the timestamp and sequence number of the last
311 * successful replication for each replica. The st_write() member
312 * function is called periodically to flush status information to
313 * disk. At startup time, slurpd checks for the status file, and
314 * if present, uses the timestamps to avoid "replaying" replications
315 * which have already been sent to a given replica.
317 typedef struct st St;
320 ldap_pvt_thread_mutex_t
321 st_mutex; /* mutex to serialize access */
322 Stel **st_data; /* array of pointers to Stel structs */
323 int st_nreplicas; /* number of repl hosts */
324 int st_err_logged; /* 1 if fopen err logged */
325 FILE *st_fp; /* st file kept open */
326 FILE *st_lfp; /* lockfile fp */
328 /* Public member functions */
329 int (*st_update) LDAP_P(( St *, Stel*, Re* ));/*update entry for a host*/
330 Stel*(*st_add) LDAP_P(( St *, Ri * )); /*add a new repl host*/
331 int (*st_write) LDAP_P(( St * )); /* write status to disk */
332 int (*st_read) LDAP_P(( St * )); /* read status info from disk */
333 int (*st_lock) LDAP_P(( St * )); /* read status info from disk */
334 int (*st_unlock) LDAP_P(( St * )); /* read status info from disk */
337 #if defined( HAVE_LWP )
339 thread_t tl_tid; /* thread being managed */
340 time_t tl_wake; /* time thread should be resumed */
341 struct tl *tl_next; /* next node in list */
348 #endif /* HAVE_LWP */
351 * Public functions used to instantiate and initialize queue objects.
353 extern int Ri_init LDAP_P(( Ri **ri ));
354 extern int Rq_init LDAP_P(( Rq **rq ));
355 extern int Re_init LDAP_P(( Re **re ));
357 #include "proto-slurp.h"
361 #endif /* _SLURPD_H_ */