]> git.sur5r.net Git - openldap/blob - servers/slurpd/slurp.h
syncinfo_free must be able to free multiple syncinfos
[openldap] / servers / slurpd / slurp.h
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2007 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
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>.
14  */
15 /* Portions Copyright (c) 1996 Regents of the University of Michigan.
16  * All rights reserved.
17  *
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.
24  */
25 /* ACKNOWLEDGEMENTS:
26  * This work was originally developed by the University of Michigan
27  * (as part of U-MICH LDAP).
28  */
29
30 /* slurp.h - Standalone Ldap Update Replication Daemon (slurpd) */
31
32 #ifndef _SLURPD_H_
33 #define _SLURPD_H_
34
35 #if !defined(HAVE_WINSOCK) && !defined(LDAP_SYSLOG)
36 #define LDAP_SYSLOG 1
37 #endif
38
39 #include <ac/errno.h>
40 #include <ac/param.h>
41 #include <ac/signal.h>
42 #include <ac/syslog.h>
43 #include <ac/time.h>
44
45 #include <sys/types.h>
46
47 #include <ldap.h>
48
49 #undef  ldap_debug
50 #define ldap_debug slurp_debug
51 #include "ldap_log.h"
52
53 #include "ldap_pvt_thread.h"
54 #include "ldap_defaults.h"
55 #include "ldif.h"
56
57 #ifdef HAVE_WINSOCK
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)
62 #define S_IRGRP 0
63 #define S_IWGRP 0
64 #ifndef F_OK
65 #define F_OK 0
66 #endif
67 #ifndef W_OK
68 #define W_OK 2
69 #endif
70 #ifndef R_OK
71 #define R_OK 4
72 #endif
73 #ifndef S_IRUSR
74 #define S_IRUSR S_IREAD
75 #endif
76 #ifndef S_IWUSR
77 #define S_IWUSR S_IWRITE
78 #endif
79 #endif
80
81 #undef SERVICE_NAME
82 #define SERVICE_NAME    OPENLDAP_PACKAGE "-slurpd"
83
84 /* Default directory for slurpd's private copy of replication logs */
85 #define DEFAULT_SLURPD_REPLICA_DIR      LDAP_RUNDIR LDAP_DIRSEP "openldap-slurp"
86
87 /* Default name for slurpd's private copy of the replication log */
88 #define DEFAULT_SLURPD_REPLOGFILE       "slurpd.replog"
89
90 /* Name of file which stores saved slurpd state info, for restarting */
91 #define DEFAULT_SLURPD_STATUS_FILE      "slurpd.status"
92
93 /* slurpd dump file - contents of rq struct are written here (debugging) */
94 #define SLURPD_DUMPFILE                 LDAP_TMPDIR LDAP_DIRSEP "slurpd.dump"
95
96 /* Amount of time to sleep if no more work to do */
97 #define DEFAULT_NO_WORK_INTERVAL        3
98
99 /* The time we wait between checks to see if the replog file needs trimming */
100 #define TRIMCHECK_INTERVAL              ( 60 * 5 )
101
102 /* Only try to trim slurpd replica files larger than this size */
103 #define MIN_TRIM_FILESIZE               ( 10L * 1024L )
104
105 /* Maximum line length we can read from replication log */
106 #define REPLBUFLEN                      256
107
108 /* TLS flags */
109 #define TLS_OFF                 0
110 #define TLS_ON                  1
111 #define TLS_CRITICAL    2
112
113 /* Rejection records are prefaced with this string */
114 #define ERROR_STR       "ERROR"
115
116 /* Strings found in replication entries */
117 #define T_CHANGETYPESTR         "changetype"
118 #define T_CHANGETYPE            1
119 #define T_TIMESTR               "time"
120 #define T_TIME                  2
121 #define T_DNSTR                 "dn"
122 #define T_DN                    3
123
124 #define T_ADDCTSTR              "add"
125 #define T_ADDCT                 4
126 #define T_MODIFYCTSTR           "modify"
127 #define T_MODIFYCT              5
128 #define T_DELETECTSTR           "delete"
129 #define T_DELETECT              6
130 #define T_MODRDNCTSTR           "modrdn"
131 #define T_MODDNCTSTR            "moddn"
132 #define T_RENAMECTSTR           "rename"
133 #define T_MODRDNCT              7
134
135 #define T_MODOPADDSTR           "add"
136 #define T_MODOPADD              8
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             "-"
144 #define T_MODSEP                12
145
146 #define T_NEWRDNSTR             "newrdn"
147 #define T_DELOLDRDNSTR  "deleteoldrdn"
148 #define T_NEWSUPSTR             "newsuperior"
149
150 #define T_ERR                   -1
151
152 /* Config file keywords */
153 #define HOSTSTR                 "host"
154 #define URISTR                  "uri"
155 #define ATTRSTR                 "attr"
156 #define SUFFIXSTR               "suffix"
157 #define BINDDNSTR               "binddn"
158 #define BINDMETHSTR             "bindmethod"
159 #define SIMPLESTR               "simple"
160 #define SASLSTR                 "sasl"
161 #define CREDSTR                 "credentials"
162 #define OLDAUTHCSTR             "bindprincipal"
163 #define AUTHCSTR                "authcID"
164 #define AUTHZSTR                "authzID"
165 #define SASLMECHSTR             "saslmech"
166 #define REALMSTR                "realm"
167 #define SECPROPSSTR             "secprops"
168 #define STARTTLSSTR             "starttls"
169 #define TLSSTR                  "tls"
170 #define CRITICALSTR             "critical"
171
172 #define REPLICA_SLEEP_TIME      ( 10 )
173
174 /* Enumeration of various types of bind failures */
175 #define BIND_OK                                         0
176 #define BIND_ERR_BADLDP                         1
177 #define BIND_ERR_OPEN                           2
178 #define BIND_ERR_BAD_ATYPE                      3
179 #define BIND_ERR_SIMPLE_FAILED          4
180 #define BIND_ERR_BADRI                          6
181 #define BIND_ERR_VERSION                        7
182 #define BIND_ERR_REFERRALS                      8
183 #define BIND_ERR_MANAGEDSAIT            9
184 #define BIND_ERR_SASL_FAILED            10
185 #define BIND_ERR_TLS_FAILED                     11
186
187 /* Return codes for do_ldap() */
188 #define DO_LDAP_OK                      0
189 #define DO_LDAP_ERR_RETRYABLE           1
190 #define DO_LDAP_ERR_FATAL               2
191
192 /*
193  * Types of counts one can request from the Rq rq_getcount()
194  * member function
195  */
196 /* all elements */
197 #define RQ_COUNT_ALL                    1
198 /* all elements with nonzero refcnt */
199 #define RQ_COUNT_NZRC                   2
200
201 /* Amount of time, in seconds, for a thread to sleep when it encounters
202  * a retryable error in do_ldap().
203  */
204 #define RETRY_SLEEP_TIME                60
205
206
207 LDAP_BEGIN_DECL
208
209 /*
210  * ****************************************************************************
211  * Data types for replication queue and queue elements.
212  * ****************************************************************************
213  */
214
215
216 /*
217  * Replica host information.  An Ri struct will contain an array of these,
218  * with one entry for each replica.  The end of the array is signaled
219  * by a NULL value in the rh_hostname field.
220  */
221 typedef struct rh {
222     char        *rh_hostname;           /* replica hostname  */
223     int         rh_port;                /* replica port */
224 } Rh;
225
226
227 /*
228  * Per-replica information.
229  *
230  * Notes:
231  *  - Private data should not be manipulated expect by Ri member functions.
232  */
233 typedef struct ri Ri;
234 struct ri {
235     /* Private data */
236     char        *ri_hostname;           /* canonical hostname of replica */
237     int         ri_port;                /* port where slave slapd running */
238     char        *ri_uri;                /* e.g. "ldaps://ldap-1.example.com:636" */
239     LDAP        *ri_ldp;                /* LDAP struct for this replica */
240     int         ri_tls;                 /* TLS: 0=no, 1=yes, 2=critical */
241     int         ri_bind_method;         /* AUTH_SIMPLE or AUTH_SASL */
242     char        *ri_bind_dn;            /* DN to bind as when replicating */
243     char        *ri_password;           /* Password for any method */
244     char        *ri_secprops;           /* SASL security properties */
245     char        *ri_realm;                      /* realm for any mechanism */
246     char        *ri_authcId;            /* authentication ID for any mechanism */
247     char        *ri_authzId;            /* authorization ID for any mechanism */
248     char        *ri_saslmech;           /* SASL mechanism to use */
249     struct re   *ri_curr;               /* current repl entry being processed */
250     struct stel *ri_stel;               /* pointer to Stel for this replica */
251     unsigned long
252                 ri_seq;                 /* seq number of last repl */
253     ldap_pvt_thread_t   ri_tid;                 /* ID of thread for this replica */
254
255     /* Member functions */
256     int (*ri_process) LDAP_P(( Ri * )); /* process the next repl entry */
257     void (*ri_wake)   LDAP_P(( Ri * )); /* wake up a sleeping thread */
258 };
259
260
261
262 /*
263  * Information about one particular modification to make.  This data should
264  * be considered private to routines in re.c, and to routines in ri.c.
265  */
266 typedef struct mi {
267     /* Private data */
268     char        *mi_type;               /* attr or type */
269     char        *mi_val;                /* value */
270     int         mi_len;                 /* length of mi_val */
271 } Mi;
272
273
274
275 /* 
276  * Information about one particular replication entry.  Only routines in
277  * re.c  and rq.c should touch the private data.  Other routines should
278  * only use member functions.
279  */
280 typedef struct re Re;
281 struct re {
282     /* Private data */
283     ldap_pvt_thread_mutex_t
284                 re_mutex;               /* mutex for this Re */
285     int         re_refcnt;              /* ref count, 0 = done */
286     time_t      re_timestamp;           /* timestamp of this re */
287     int         re_seq;                 /* sequence number */
288     Rh          *re_replicas;           /* array of replica info */
289     char        *re_dn;                 /* dn of entry being modified */
290     int         re_changetype;          /* type of modification */
291     Mi          *re_mods;               /* array of modifications to make */
292     struct re   *re_next;               /* pointer to next element */
293
294     /* Public functions */
295     int (*re_free)    LDAP_P(( Re * )); /* free an re struct */
296     Re *(*re_getnext) LDAP_P(( Re * )); /* return next Re in linked list */
297     int (*re_parse) LDAP_P(( Re *, char * )); /* parse replication log entry */
298     int (*re_write) LDAP_P(( Ri *, Re *, FILE * )); /* write repl. log entry */
299     void (*re_dump)  LDAP_P(( Re *, FILE * )); /* debugging - print contents */
300     int (*re_lock)   LDAP_P(( Re * ));    /* lock this re */
301     int (*re_unlock) LDAP_P(( Re * ));    /* unlock this re */
302     int (*re_decrefcnt) LDAP_P(( Re * )); /* decrement the refcnt */
303     int (*re_getrefcnt) LDAP_P(( Re * )); /* get the refcnt */
304 };
305
306
307
308
309 /* 
310  * Definition for the queue of replica information.  Private data is
311  * private to rq.c.  Other routines should only touch public data or
312  * use member functions.  Note that although we have a member function
313  * for locking the queue's mutex, we need to expose the rq_mutex
314  * variable so routines in ri.c can use it as a mutex for the
315  * rq_more condition variable.
316  */
317 typedef struct rq Rq;
318 struct rq {
319
320     /* Private data */
321     Re          *rq_head;               /* pointer to head */
322     Re          *rq_tail;               /* pointer to tail */
323     int         rq_nre;                 /* total number of Re's in queue */
324     int         rq_ndel;                /* number of deleted Re's in queue */
325     time_t      rq_lasttrim;            /* Last time we trimmed file */
326     
327     /* Public data */
328     ldap_pvt_thread_mutex_t
329                 rq_mutex;               /* mutex for whole queue */
330     ldap_pvt_thread_cond_t
331                 rq_more;                /* condition var - more work added */
332
333     /* Member functions */
334     Re * (*rq_gethead)  LDAP_P(( Rq * )); /* get the element at head */
335     Re * (*rq_getnext)  LDAP_P(( Re * )); /* get the next element */
336     int  (*rq_delhead)  LDAP_P(( Rq * )); /* delete the element at head */
337     int  (*rq_add)      LDAP_P(( Rq *, char * )); /* add at tail */
338     void (*rq_gc)       LDAP_P(( Rq * )); /* garbage-collect queue */
339     int  (*rq_lock)     LDAP_P(( Rq * )); /* lock the queue */
340     int  (*rq_unlock)   LDAP_P(( Rq * )); /* unlock the queue */
341     int  (*rq_needtrim) LDAP_P(( Rq * )); /* see if queue needs trimming */
342     int  (*rq_write)    LDAP_P(( Rq *, FILE * )); /*write Rq contents to file*/
343     int  (*rq_getcount) LDAP_P(( Rq *, int )); /* return queue counts */
344     void (*rq_dump)     LDAP_P(( Rq * )); /* debugging - print contents */
345 };
346
347
348 /*
349  * An Stel (status element) contains information about one replica.
350  * Stel structs are associated with the St (status) struct, defined 
351  * below.
352  */
353 typedef struct stel {
354     char        *hostname;              /* host name of replica */
355     int         port;                   /* port number of replica */
356     time_t      last;                   /* timestamp of last successful repl */
357     int         seq;                    /* Sequence number of last repl */
358 } Stel;
359
360
361 /*
362  * An St struct in an in-core structure which contains the current
363  * slurpd state.  Most importantly, it contains an array of Stel
364  * structs which contain the timestamp and sequence number of the last
365  * successful replication for each replica.  The st_write() member
366  * function is called periodically to flush status information to
367  * disk.  At startup time, slurpd checks for the status file, and
368  * if present, uses the timestamps to avoid "replaying" replications
369  * which have already been sent to a given replica.
370  */
371 typedef struct st St;
372 struct st {
373     /* Private data */
374     ldap_pvt_thread_mutex_t
375                 st_mutex;               /* mutex to serialize access */
376     Stel        **st_data;              /* array of pointers to Stel structs */
377     int         st_nreplicas;           /* number of repl hosts */
378     int         st_err_logged;          /* 1 if fopen err logged */
379     FILE        *st_fp;                 /* st file kept open */
380     FILE        *st_lfp;                /* lockfile fp */
381
382     /* Public member functions */
383     int  (*st_update) LDAP_P(( St *, Stel*, Re* ));/*update entry for a host*/
384     Stel*(*st_add)    LDAP_P(( St *, Ri * ));      /*add a new repl host*/
385     int  (*st_write)  LDAP_P(( St * )); /* write status to disk */
386     int  (*st_read)   LDAP_P(( St * )); /* read status info from disk */
387     int  (*st_lock)   LDAP_P(( St * )); /* read status info from disk */
388     int  (*st_unlock) LDAP_P(( St * )); /* read status info from disk */
389 };
390
391 #if defined( HAVE_LWP )
392 typedef struct tl {
393     thread_t    tl_tid;         /* thread being managed */
394     time_t      tl_wake;        /* time thread should be resumed */
395     struct tl   *tl_next;       /* next node in list */
396 } tl_t;
397
398 typedef struct tsl {
399     tl_t        *tsl_list;
400     mon_t       tsl_mon;
401 } tsl_t;
402 #endif /* HAVE_LWP */
403
404 /* 
405  * Public functions used to instantiate and initialize queue objects.
406  */
407 extern int Ri_init LDAP_P(( Ri **ri ));
408 extern int Rq_init LDAP_P(( Rq **rq ));
409 extern int Re_init LDAP_P(( Re **re ));
410
411 #include "proto-slurp.h"
412
413 LDAP_END_DECL
414
415 #endif /* _SLURPD_H_ */