]> git.sur5r.net Git - openldap/blob - servers/slurpd/slurp.h
5dcce03befc8b784d61daffb2437a716378d8172
[openldap] / servers / slurpd / slurp.h
1 /*
2  * Copyright (c) 1996 Regents of the University of Michigan.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that this notice is preserved and that due credit is given
7  * to the University of Michigan at Ann Arbor. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  */
12
13 /* slurp.h - Standalone Ldap Update Replication Daemon (slurpd) */
14
15 #ifndef _SLURPD_H_
16 #define _SLURPD_H_
17
18 #ifndef LDAP_SYSLOG
19 #define LDAP_SYSLOG 1
20 #endif
21
22 #include <ac/errno.h>
23 #include <ac/signal.h>
24 #include <ac/syslog.h>
25 #include <ac/time.h>
26
27 #ifdef HAVE_SYS_PARAM_H
28 #include <sys/param.h>
29 #endif
30 #include <sys/types.h>
31
32 #include "lber.h"
33 #include "ldap.h"
34
35 #define ldap_debug slurp_debug
36 #include "ldap_log.h"
37
38 #include "ldap_pvt_thread.h"
39 #include "ldap_defaults.h"
40 #include "ldif.h"
41
42
43 /* Default directory for slurpd's private copy of replication logs */
44 #define DEFAULT_SLURPD_REPLICA_DIR      "/usr/tmp"
45
46 /* Default name for slurpd's private copy of the replication log */
47 #define DEFAULT_SLURPD_REPLOGFILE       "slurpd.replog"
48
49 /* Name of file which stores saved slurpd state info, for restarting */
50 #define DEFAULT_SLURPD_STATUS_FILE      "slurpd.status"
51
52 /* slurpd dump file - contents of rq struct are written here (debugging) */
53 #define SLURPD_DUMPFILE                 "/tmp/slurpd.dump"
54
55 /* default srvtab file.  Can be overridden */
56 #define SRVTAB                          "/etc/srvtab"
57
58 /* Amount of time to sleep if no more work to do */
59 #define DEFAULT_NO_WORK_INTERVAL        3
60
61 /* The time we wait between checks to see if the replog file needs trimming */
62 #define TRIMCHECK_INTERVAL              ( 60 * 5 )
63
64 /* Only try to trim slurpd replica files larger than this size */
65 #define MIN_TRIM_FILESIZE               ( 10L * 1024L )
66
67 /* Maximum line length we can read from replication log */
68 #define REPLBUFLEN                      256
69
70 /* We support simple (plaintext password) and kerberos authentication */
71 #define AUTH_SIMPLE     1
72 #define AUTH_KERBEROS   2
73
74 /* Rejection records are prefaced with this string */
75 #define ERROR_STR       "ERROR"
76
77 /* Strings found in replication entries */
78 #define T_CHANGETYPESTR         "changetype"
79 #define T_CHANGETYPE            1
80 #define T_TIMESTR               "time"
81 #define T_TIME                  2
82 #define T_DNSTR                 "dn"
83 #define T_DN                    3
84
85 #define T_ADDCTSTR              "add"
86 #define T_ADDCT                 4
87 #define T_MODIFYCTSTR           "modify"
88 #define T_MODIFYCT              5
89 #define T_DELETECTSTR           "delete"
90 #define T_DELETECT              6
91 #define T_MODRDNCTSTR           "modrdn"
92 #define T_MODDNCTSTR            "moddn"
93 #define T_RENAMECTSTR           "rename"
94 #define T_MODRDNCT              7
95
96 #define T_MODOPADDSTR           "add"
97 #define T_MODOPADD              8
98 #define T_MODOPREPLACESTR       "replace"
99 #define T_MODOPREPLACE          9
100 #define T_MODOPDELETESTR        "delete"
101 #define T_MODOPDELETE           10
102 #define T_MODSEPSTR             "-"
103 #define T_MODSEP                11
104
105 #define T_NEWRDNSTR             "newrdn"
106 #define T_DELOLDRDNSTR  "deleteoldrdn"
107 #define T_NEWSUPSTR             "newsuperior"
108
109 #define T_ERR                   -1
110
111 /* Config file keywords */
112 #define HOSTSTR                 "host"
113 #define BINDDNSTR               "binddn"
114 #define BINDMETHSTR             "bindmethod"
115 #define KERBEROSSTR             "kerberos"
116 #define SIMPLESTR               "simple"
117 #define CREDSTR                 "credentials"
118 #define BINDPSTR                "bindprincipal"
119 #define SRVTABSTR               "srvtab"
120
121 #define REPLICA_SLEEP_TIME      ( 10 )
122
123 /* Enumeration of various types of bind failures */
124 #define BIND_OK                         0
125 #define BIND_ERR_BADLDP                 1
126 #define BIND_ERR_OPEN                   2
127 #define BIND_ERR_BAD_ATYPE              3
128 #define BIND_ERR_SIMPLE_FAILED          4
129 #define BIND_ERR_KERBEROS_FAILED        5
130 #define BIND_ERR_BADRI                  6
131
132 /* Return codes for do_ldap() */
133 #define DO_LDAP_OK                      0
134 #define DO_LDAP_ERR_RETRYABLE           1
135 #define DO_LDAP_ERR_FATAL               2
136
137 /*
138  * Types of counts one can request from the Rq rq_getcount()
139  * member function
140  */
141 /* all elements */
142 #define RQ_COUNT_ALL                    1
143 /* all elements with nonzero refcnt */
144 #define RQ_COUNT_NZRC                   2
145
146 /* Amount of time, in seconds, for a thread to sleep when it encounters
147  * a retryable error in do_ldap().
148  */
149 #define RETRY_SLEEP_TIME                60
150
151
152 LDAP_BEGIN_DECL
153
154 /*
155  * ****************************************************************************
156  * Data types for replication queue and queue elements.
157  * ****************************************************************************
158  */
159
160
161 /*
162  * Replica host information.  An Ri struct will contain an array of these,
163  * with one entry for each replica.  The end of the array is signaled
164  * by a NULL value in the rh_hostname field.
165  */
166 typedef struct rh {
167     char        *rh_hostname;           /* replica hostname  */
168     int         rh_port;                /* replica port */
169 } Rh;
170
171
172 /*
173  * Per-replica information.
174  *
175  * Notes:
176  *  - Private data should not be manipulated expect by Ri member functions.
177  */
178 typedef struct ri Ri;
179 struct ri {
180
181     /* Private data */
182     char        *ri_hostname;           /* canonical hostname of replica */
183     int         ri_port;                /* port where slave slapd running */
184     LDAP        *ri_ldp;                /* LDAP struct for this replica */
185     int         ri_bind_method;         /* AUTH_SIMPLE or AUTH_KERBEROS */
186     char        *ri_bind_dn;            /* DN to bind as when replicating */
187     char        *ri_password;           /* Password for AUTH_SIMPLE */
188     char        *ri_principal;          /* principal for kerberos bind */
189     char        *ri_srvtab;             /* srvtab file for kerberos bind */
190     struct re   *ri_curr;               /* current repl entry being processed */
191     struct stel *ri_stel;               /* pointer to Stel for this replica */
192     unsigned long
193                 ri_seq;                 /* seq number of last repl */
194     ldap_pvt_thread_t   ri_tid;                 /* ID of thread for this replica */
195
196     /* Member functions */
197     int (*ri_process) LDAP_P(( Ri * )); /* process the next repl entry */
198     void (*ri_wake)   LDAP_P(( Ri * )); /* wake up a sleeping thread */
199 };
200     
201
202
203
204 /*
205  * Information about one particular modification to make.  This data should
206  * be considered private to routines in re.c, and to routines in ri.c.
207  */
208 typedef struct mi {
209     
210     /* Private data */
211     char        *mi_type;               /* attr or type */
212     char        *mi_val;                /* value */
213     int         mi_len;                 /* length of mi_val */
214
215 } Mi;
216
217
218
219 /* 
220  * Information about one particular replication entry.  Only routines in
221  * re.c  and rq.c should touch the private data.  Other routines should
222  * only use member functions.
223  */
224 typedef struct re Re;
225 struct re {
226
227     /* Private data */
228     ldap_pvt_thread_mutex_t
229                 re_mutex;               /* mutex for this Re */
230     int         re_refcnt;              /* ref count, 0 = done */
231     char        *re_timestamp;          /* timestamp of this re */
232     int         re_seq;                 /* sequence number */
233     Rh          *re_replicas;           /* array of replica info */
234     char        *re_dn;                 /* dn of entry being modified */
235     int         re_changetype;          /* type of modification */
236     Mi          *re_mods;               /* array of modifications to make */
237     struct re   *re_next;               /* pointer to next element */
238
239     /* Public functions */
240     int (*re_free)    LDAP_P(( Re * )); /* free an re struct */
241     Re *(*re_getnext) LDAP_P(( Re * )); /* return next Re in linked list */
242     int (*re_parse) LDAP_P(( Re *, char * )); /* parse replication log entry */
243     int (*re_write) LDAP_P(( Ri *, Re *, FILE * )); /* write repl. log entry */
244     void (*re_dump)  LDAP_P(( Re *, FILE * )); /* debugging - print contents */
245     int (*re_lock)   LDAP_P(( Re * ));    /* lock this re */
246     int (*re_unlock) LDAP_P(( Re * ));    /* unlock this re */
247     int (*re_decrefcnt) LDAP_P(( Re * )); /* decrement the refcnt */
248     int (*re_getrefcnt) LDAP_P(( Re * )); /* get the refcnt */
249 };
250
251
252
253
254 /* 
255  * Definition for the queue of replica information.  Private data is
256  * private to rq.c.  Other routines should only touch public data or
257  * use member functions.  Note that although we have a member function
258  * for locking the queue's mutex, we need to expose the rq_mutex
259  * variable so routines in ri.c can use it as a mutex for the
260  * rq_more condition variable.
261  */
262 typedef struct rq Rq;
263 struct rq {
264
265     /* Private data */
266     Re          *rq_head;               /* pointer to head */
267     Re          *rq_tail;               /* pointer to tail */
268     int         rq_nre;                 /* total number of Re's in queue */
269     int         rq_ndel;                /* number of deleted Re's in queue */
270     time_t      rq_lasttrim;            /* Last time we trimmed file */
271     
272     /* Public data */
273     ldap_pvt_thread_mutex_t
274                 rq_mutex;               /* mutex for whole queue */
275     ldap_pvt_thread_cond_t
276                 rq_more;                /* condition var - more work added */
277
278     /* Member functions */
279     Re * (*rq_gethead)  LDAP_P(( Rq * )); /* get the element at head */
280     Re * (*rq_getnext)  LDAP_P(( Re * )); /* get the next element */
281     int  (*rq_delhead)  LDAP_P(( Rq * )); /* delete the element at head */
282     int  (*rq_add)      LDAP_P(( Rq *, char * )); /* add at tail */
283     void (*rq_gc)       LDAP_P(( Rq * )); /* garbage-collect queue */
284     int  (*rq_lock)     LDAP_P(( Rq * )); /* lock the queue */
285     int  (*rq_unlock)   LDAP_P(( Rq * )); /* unlock the queue */
286     int  (*rq_needtrim) LDAP_P(( Rq * )); /* see if queue needs trimming */
287     int  (*rq_write)    LDAP_P(( Rq *, FILE * )); /*write Rq contents to file*/
288     int  (*rq_getcount) LDAP_P(( Rq *, int )); /* return queue counts */
289     void (*rq_dump)     LDAP_P(( Rq * )); /* debugging - print contents */
290 };
291
292
293 /*
294  * An Stel (status element) contains information about one replica.
295  * Stel structs are associated with the St (status) struct, defined 
296  * below.
297  */
298 typedef struct stel {
299     char        *hostname;              /* host name of replica */
300     int         port;                   /* port number of replica */
301     char        last[ 64 ];             /* timestamp of last successful repl */
302     int         seq;                    /* Sequence number of last repl */
303 } Stel;
304
305
306 /*
307  * An St struct in an in-core structure which contains the current
308  * slurpd state.  Most importantly, it contains an array of Stel
309  * structs which contain the timestamp and sequence number of the last
310  * successful replication for each replica.  The st_write() member
311  * function is called periodically to flush status information to
312  * disk.  At startup time, slurpd checks for the status file, and
313  * if present, uses the timestamps to avoid "replaying" replications
314  * which have already been sent to a given replica.
315  */
316 typedef struct st St;
317 struct st {
318     /* Private data */
319     ldap_pvt_thread_mutex_t
320                 st_mutex;               /* mutex to serialize access */
321     Stel        **st_data;              /* array of pointers to Stel structs */
322     int         st_nreplicas;           /* number of repl hosts */
323     int         st_err_logged;          /* 1 if fopen err logged */
324     FILE        *st_fp;                 /* st file kept open */
325     FILE        *st_lfp;                /* lockfile fp */
326
327     /* Public member functions */
328     int  (*st_update) LDAP_P(( St *, Stel*, Re* ));/*update entry for a host*/
329     Stel*(*st_add)    LDAP_P(( St *, Ri * ));      /*add a new repl host*/
330     int  (*st_write)  LDAP_P(( St * )); /* write status to disk */
331     int  (*st_read)   LDAP_P(( St * )); /* read status info from disk */
332     int  (*st_lock)   LDAP_P(( St * )); /* read status info from disk */
333     int  (*st_unlock) LDAP_P(( St * )); /* read status info from disk */
334 };
335
336 #if defined( HAVE_LWP )
337 typedef struct tl {
338     thread_t    tl_tid;         /* thread being managed */
339     time_t      tl_wake;        /* time thread should be resumed */
340     struct tl   *tl_next;       /* next node in list */
341 } tl_t;
342
343 typedef struct tsl {
344     tl_t        *tsl_list;
345     mon_t       tsl_mon;
346 } tsl_t;
347 #endif /* HAVE_LWP */
348
349 /* 
350  * Public functions used to instantiate and initialize queue objects.
351  */
352 extern int Ri_init LDAP_P(( Ri **ri ));
353 extern int Rq_init LDAP_P(( Rq **rq ));
354 extern int Re_init LDAP_P(( Re **re ));
355
356 #include "proto-slurp.h"
357
358 LDAP_END_DECL
359
360 #endif /* _SLURPD_H_ */