slap.h 10.8 KB
Newer Older
Ondřej Kuzník's avatar
Ondřej Kuzník committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/* slap.h - stand alone ldap server include file */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 *
 * Copyright 1998-2015 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
 * <http://www.OpenLDAP.org/license.html>.
 */
/* Portions Copyright (c) 1995 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.
 */

#ifndef _SLAP_H_
#define _SLAP_H_

#include "ldap_defaults.h"

#include <stdio.h>
#include <ac/stdlib.h>

#include <sys/types.h>
#include <ac/syslog.h>
#include <ac/regex.h>
#include <ac/signal.h>
#include <ac/socket.h>
#include <ac/time.h>
#include <ac/param.h>

#include "avl.h"

#ifndef ldap_debug
#define ldap_debug slap_debug
#endif

#include "ldap_log.h"

#include <ldap.h>
#include <ldap_schema.h>

#include "lber_pvt.h"
#include "ldap_pvt.h"
#include "ldap_pvt_thread.h"
#include "ldap_queue.h"

#include <event2/event.h>

LDAP_BEGIN_DECL

/*
 * SLAPD Memory allocation macros
 *
 * Unlike ch_*() routines, these routines do not assert() upon
 * allocation error.  They are intended to be used instead of
 * ch_*() routines where the caller has implemented proper
 * checking for and handling of allocation errors.
 *
 * Patches to convert ch_*() calls to SLAP_*() calls welcomed.
 */
#define SLAP_MALLOC(s) ber_memalloc( ( s ) )
#define SLAP_CALLOC(n, s) ber_memcalloc( ( n ), ( s ) )
#define SLAP_REALLOC(p, s) ber_memrealloc( ( p ), ( s ) )
#define SLAP_FREE(p) ber_memfree( ( p ) )
#define SLAP_VFREE(v) ber_memvfree( (void **)( v ) )
#define SLAP_STRDUP(s) ber_strdup( ( s ) )
#define SLAP_STRNDUP(s, l) ber_strndup( ( s ), ( l ) )

#define SERVICE_NAME OPENLDAP_PACKAGE "-slapd"
#define SLAPD_ANONYMOUS ""
#define SLAP_STRING_UNKNOWN "unknown"

#define SLAP_MAX_WORKER_THREADS ( 16 )

#define SLAP_SB_MAX_INCOMING_DEFAULT ( ( 1 << 18 ) - 1 )
#define SLAP_SB_MAX_INCOMING_AUTH ( ( 1 << 24 ) - 1 )

Ondřej Kuzník's avatar
Ondřej Kuzník committed
90
91
#define SLAP_CONN_MAX_PDUS_PER_CYCLE_DEFAULT 10

Ondřej Kuzník's avatar
Ondřej Kuzník committed
92
93
94
95
96
#define SLAP_TEXT_BUFLEN ( 256 )

/* unknown config file directive */
#define SLAP_CONF_UNKNOWN ( -1026 )

97
98
#define BER_BV_OPTIONAL( bv ) ( BER_BVISNULL( bv ) ? NULL : ( bv ) )

Ondřej Kuzník's avatar
Ondřej Kuzník committed
99
100
101
102
LDAP_SLAPD_V (int) slap_debug;

typedef unsigned long slap_mask_t;

Ondřej Kuzník's avatar
Ondřej Kuzník committed
103
typedef struct Backend Backend;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
104
typedef struct Connection Connection;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
105
typedef struct Operation Operation;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* end of forward declarations */

typedef union Sockaddr {
    struct sockaddr sa_addr;
    struct sockaddr_in sa_in_addr;
#ifdef LDAP_PF_INET6
    struct sockaddr_storage sa_storage;
    struct sockaddr_in6 sa_in6_addr;
#endif
#ifdef LDAP_PF_LOCAL
    struct sockaddr_un sa_un_addr;
#endif
} Sockaddr;

#ifdef LDAP_PF_INET6
extern int slap_inet4or6;
#endif

Ondřej Kuzník's avatar
Ondřej Kuzník committed
124
125
126
127
typedef LDAP_STAILQ_HEAD(BeSt, Backend) slap_b_head;

LDAP_SLAPD_V (slap_b_head) backend;

Ondřej Kuzník's avatar
Ondřej Kuzník committed
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
LDAP_SLAPD_V (int) slapMode;
#define SLAP_UNDEFINED_MODE 0x0000
#define SLAP_SERVER_MODE 0x0001
#define SLAP_TOOL_MODE 0x0002
#define SLAP_MODE 0x0003

#define SLAP_SERVER_RUNNING 0x8000

#define SB_TLS_DEFAULT ( -1 )
#define SB_TLS_OFF 0
#define SB_TLS_ON 1
#define SB_TLS_CRITICAL 2

typedef struct slap_keepalive {
    int sk_idle;
    int sk_probes;
    int sk_interval;
} slap_keepalive;

typedef struct slap_bindconf {
    struct berval sb_uri;
    int sb_version;
    int sb_tls;
    int sb_method;
    int sb_timeout_api;
    int sb_timeout_net;
    struct berval sb_binddn;
    struct berval sb_cred;
    struct berval sb_saslmech;
    char *sb_secprops;
    struct berval sb_realm;
    struct berval sb_authcId;
    struct berval sb_authzId;
    slap_keepalive sb_keepalive;
#ifdef HAVE_TLS
    void *sb_tls_ctx;
    char *sb_tls_cert;
    char *sb_tls_key;
    char *sb_tls_cacert;
    char *sb_tls_cacertdir;
    char *sb_tls_reqcert;
    char *sb_tls_reqsan;
    char *sb_tls_cipher_suite;
    char *sb_tls_protocol_min;
    char *sb_tls_ecname;
#ifdef HAVE_OPENSSL
    char *sb_tls_crlcheck;
#endif
    int sb_tls_int_reqcert;
    int sb_tls_int_reqsan;
    int sb_tls_do_init;
#endif
} slap_bindconf;

typedef struct slap_verbmasks {
    struct berval word;
    const slap_mask_t mask;
} slap_verbmasks;

typedef struct slap_cf_aux_table {
    struct berval key;
    int off;
    char type;
    char quote;
    void *aux;
} slap_cf_aux_table;

typedef int slap_cf_aux_table_parse_x( struct berval *val,
        void *bc,
        slap_cf_aux_table *tab0,
        const char *tabmsg,
        int unparse );

#define SLAP_RESTRICT_OP_ADD 0x0001U
#define SLAP_RESTRICT_OP_BIND 0x0002U
#define SLAP_RESTRICT_OP_COMPARE 0x0004U
#define SLAP_RESTRICT_OP_DELETE 0x0008U
#define SLAP_RESTRICT_OP_EXTENDED 0x0010U
#define SLAP_RESTRICT_OP_MODIFY 0x0020U
#define SLAP_RESTRICT_OP_RENAME 0x0040U
#define SLAP_RESTRICT_OP_SEARCH 0x0080U
#define SLAP_RESTRICT_OP_MASK 0x00FFU

#define SLAP_RESTRICT_READONLY 0x80000000U

#define SLAP_RESTRICT_EXOP_START_TLS 0x0100U
#define SLAP_RESTRICT_EXOP_MODIFY_PASSWD 0x0200U
#define SLAP_RESTRICT_EXOP_WHOAMI 0x0400U
#define SLAP_RESTRICT_EXOP_CANCEL 0x0800U
#define SLAP_RESTRICT_EXOP_MASK 0xFF00U

#define SLAP_RESTRICT_OP_READS \
    ( SLAP_RESTRICT_OP_COMPARE | SLAP_RESTRICT_OP_SEARCH )
#define SLAP_RESTRICT_OP_WRITES \
    ( SLAP_RESTRICT_OP_ADD | SLAP_RESTRICT_OP_DELETE | SLAP_RESTRICT_OP_MODIFY | SLAP_RESTRICT_OP_RENAME )
#define SLAP_RESTRICT_OP_ALL \
    ( SLAP_RESTRICT_OP_READS | SLAP_RESTRICT_OP_WRITES | SLAP_RESTRICT_OP_BIND | SLAP_RESTRICT_OP_EXTENDED )

typedef struct config_reply_s ConfigReply; /* config.h */

typedef struct Listener Listener;

Ondřej Kuzník's avatar
Ondřej Kuzník committed
230
231
232
233
234
typedef enum {
    LLOAD_FEATURE_VC = 1 << 0,
    LLOAD_FEATURE_PROXYAUTHZ = 1 << 1,
} lload_features_t;

Ondřej Kuzník's avatar
Ondřej Kuzník committed
235
236
237
238
239
240
enum lload_tls_type {
    LLOAD_CLEARTEXT = 0,
    LLOAD_LDAPS,
    LLOAD_STARTTLS,
};

Ondřej Kuzník's avatar
Ondřej Kuzník committed
241
/* Can hold mutex when locking a linked connection */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
242
243
struct Backend {
    struct slap_bindconf b_bindconf;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
244
    ldap_pvt_thread_mutex_t b_mutex;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
245
246
247
248
249

    int b_proto, b_port;
    enum lload_tls_type b_tls;
    char *b_host;

250
251
252
253
    int b_retry_timeout, b_failed;
    struct event *b_retry_event;
    struct timeval b_retry_tv;

Ondřej Kuzník's avatar
Ondřej Kuzník committed
254
    int b_numconns, b_numbindconns;
255
256
    int b_bindavail, b_active, b_opening;
    LDAP_LIST_HEAD(ConnSt, Connection) b_conns, b_bindconns;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
257
258
259
260

    LDAP_STAILQ_ENTRY(Backend) b_next;
};

Ondřej Kuzník's avatar
Ondřej Kuzník committed
261
262
typedef int (*OperationHandler)( Operation *op, BerElement *ber );

Ondřej Kuzník's avatar
Ondřej Kuzník committed
263
/* connection state (protected by c_mutex) */
264
enum sc_state {
Ondřej Kuzník's avatar
Ondřej Kuzník committed
265
    SLAP_C_INVALID = 0, /* MUST BE ZERO (0) */
266
    SLAP_C_READY,       /* ready */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
267
    SLAP_C_CLOSING,     /* closing */
268
    SLAP_C_ACTIVE,      /* exclusive operation (tls setup, ...) in progress */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
269
270
    SLAP_C_BINDING,     /* binding */
};
271
272
273
274
enum sc_type {
    SLAP_C_OPEN = 0, /* regular connection */
    SLAP_C_BIND, /* connection used to handle bind client requests if VC not enabled */
};
275
276
277
/*
 * represents a connection from an ldap client/to ldap server
 */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
278
struct Connection {
279
    enum sc_state c_state; /* connection state */
280
    enum sc_type c_type;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
281
    ber_socket_t c_fd;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
282
283
284
285
286
287
288
289
290

    ldap_pvt_thread_mutex_t c_mutex; /* protect the connection */
    Sockbuf *c_sb;                   /* ber connection stuff */

    /* set by connection_init */
    unsigned long c_connid;    /* unique id of this connection */
    struct berval c_peer_name; /* peer name (trans=addr:port) */
    time_t c_starttime;        /* when the connection was opened */

Ondřej Kuzník's avatar
Ondřej Kuzník committed
291
292
    time_t c_activitytime;  /* when the connection was last used */
    ber_int_t c_next_msgid; /* msgid of the next message */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
293
294
295
296
297

    struct event *c_read_event, *c_write_event;

    /* can only be changed by binding thread */
    struct berval c_sasl_bind_mech; /* mech in progress */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
298
299
    struct berval c_auth;           /* authcDN (possibly in progress) */

Ondřej Kuzník's avatar
Ondřej Kuzník committed
300
#ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS
Ondřej Kuzník's avatar
Ondřej Kuzník committed
301
    struct berval c_vc_cookie;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
302
#endif /* LDAP_API_FEATURE_VERIFY_CREDENTIALS */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
303

Ondřej Kuzník's avatar
Ondřej Kuzník committed
304
305
    /* Can be held while acquiring c_mutex to inject things into c_ops or
     * destroy the connection */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
306
307
    ldap_pvt_thread_mutex_t c_io_mutex; /* only one pdu written at a time */

Ondřej Kuzník's avatar
Ondřej Kuzník committed
308
309
    BerElement *c_currentber; /* ber we're attempting to read */
    BerElement *c_pendingber; /* ber we're attempting to write */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
310

Ondřej Kuzník's avatar
Ondřej Kuzník committed
311
312
    TAvlnode *c_ops; /* Operations pending on the connection */

Ondřej Kuzník's avatar
Ondřej Kuzník committed
313
#define CONN_IS_TLS 1
314
#define CONN_IS_BIND 4
Ondřej Kuzník's avatar
Ondřej Kuzník committed
315
316
317
#define CONN_IS_IPC 8

#ifdef HAVE_TLS
Ondřej Kuzník's avatar
Ondřej Kuzník committed
318
319
    enum lload_tls_type c_is_tls; /* true if this LDAP over raw TLS */
    char c_needs_tls_accept;      /* true if SSL_accept should be called */
Ondřej Kuzník's avatar
Ondřej Kuzník committed
320
321
322
323
324
#endif

    long c_n_ops_executing; /* num of ops currently executing */
    long c_n_ops_completed; /* num of ops completed */

325
326
327
    /* Upstream: Protected by its backend's mutex */
    LDAP_LIST_ENTRY( Connection ) c_next;

Ondřej Kuzník's avatar
Ondřej Kuzník committed
328
329
330
    void *c_private;
};

Ondřej Kuzník's avatar
Ondřej Kuzník committed
331
332
struct Operation {
    Connection *o_client, *o_upstream;
333
    unsigned long o_client_connid, o_upstream_connid;
Ondřej Kuzník's avatar
Ondřej Kuzník committed
334
335
336
337
338
339
340
341

    ber_int_t o_client_msgid, o_upstream_msgid;
    ber_tag_t o_tag;

    BerElement *o_ber;
    BerValue o_request, o_ctrls;
};

Ondřej Kuzník's avatar
Ondřej Kuzník committed
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
#ifdef LDAP_DEBUG
#ifdef LDAP_SYSLOG
#ifdef LOG_LOCAL4
#define SLAP_DEFAULT_SYSLOG_USER LOG_LOCAL4
#endif /* LOG_LOCAL4 */

#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) \
    Log( (level), ldap_syslog_level, (fmt), (connid), (opid), \
            ( arg1 ), ( arg2 ), ( arg3 ) )
#define StatslogTest( level ) ( ( ldap_debug | ldap_syslog ) & ( level ) )
#else /* !LDAP_SYSLOG */
#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) \
    do { \
        if ( ldap_debug & (level) ) \
            lutil_debug( ldap_debug, (level), (fmt), (connid), (opid), \
                    ( arg1 ), ( arg2 ), ( arg3 ) ); \
    } while (0)
#define StatslogTest( level ) ( ldap_debug & ( level ) )
#endif /* !LDAP_SYSLOG */
#else /* !LDAP_DEBUG */
#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) ( (void)0 )
#define StatslogTest( level ) ( 0 )
#endif /* !LDAP_DEBUG */

/*
 * listener; need to access it from monitor backend
 */
struct Listener {
    struct berval sl_url;
    struct berval sl_name;
    mode_t sl_perms;
#ifdef HAVE_TLS
    int sl_is_tls;
#endif
    struct event_base *base;
    struct evconnlistener *listener;
    int sl_mute; /* Listener is temporarily disabled due to emfile */
    int sl_busy; /* Listener is busy (accept thread activated) */
    ber_socket_t sl_sd;
    Sockaddr sl_sa;
#define sl_addr sl_sa.sa_in_addr
#define LDAP_TCP_BUFFER
#ifdef LDAP_TCP_BUFFER
    int sl_tcp_rmem; /* custom TCP read buffer size */
    int sl_tcp_wmem; /* custom TCP write buffer size */
#endif
};

LDAP_END_DECL

#include "proto-slap.h"

#endif /* _SLAP_H_ */