mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-20 22:59:34 -05:00
lloadd ahoy
This commit is contained in:
parent
a87ae275e1
commit
46ddb4039c
25 changed files with 6537 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -96,6 +96,7 @@ servers/slapd/slapmodify
|
|||
servers/slapd/slappasswd
|
||||
servers/slapd/slapschema
|
||||
servers/slapd/slaptest
|
||||
servers/lloadd/lloadd
|
||||
tests/progs/ldif-filter
|
||||
tests/progs/slapd-addel
|
||||
tests/progs/slapd-bind
|
||||
|
|
|
|||
|
|
@ -164,6 +164,8 @@ LTHREAD_LIBS = @LTHREAD_LIBS@
|
|||
SLAPD_NDB_LIBS = @SLAPD_NDB_LIBS@
|
||||
WT_LIBS = @WT_LIBS@
|
||||
|
||||
LEVENT_LIBS = @LEVENT_LIBS@
|
||||
|
||||
LDAP_LIBLBER_LA = $(LDAP_LIBDIR)/liblber/liblber.la
|
||||
LDAP_LIBLDAP_LA = $(LDAP_LIBDIR)/libldap/libldap.la
|
||||
|
||||
|
|
@ -175,6 +177,8 @@ LDAP_L = $(LDAP_LIBLUTIL_A) \
|
|||
$(LDAP_LIBLDAP_LA) $(LDAP_LIBLBER_LA)
|
||||
SLAPD_L = $(LDAP_LIBLUNICODE_A) $(LDAP_LIBREWRITE_A) \
|
||||
$(LDAP_LIBLUTIL_A) $(LDAP_LIBLDAP_LA) $(LDAP_LIBLBER_LA)
|
||||
LLOADD_L = $(LDAP_LIBLUTIL_A) $(LDAP_LIBLDAP_LA) \
|
||||
$(LDAP_LIBLBER_LA)
|
||||
|
||||
WRAP_LIBS = @WRAP_LIBS@
|
||||
# AutoConfig generated
|
||||
|
|
@ -202,6 +206,7 @@ SLAPD_SQL_INCLUDES = @SLAPD_SQL_INCLUDES@
|
|||
SLAPD_SQL_LIBS = @SLAPD_SQL_LIBS@
|
||||
|
||||
SLAPD_LIBS = @SLAPD_LIBS@ @SLAPD_PERL_LDFLAGS@ @SLAPD_SQL_LDFLAGS@ @SLAPD_SQL_LIBS@ @SLAPD_SLP_LIBS@ @SLAPD_GMP_LIBS@
|
||||
LLOADD_LIBS = @BALANCER_LIBS@ $(LEVENT_LIBS)
|
||||
|
||||
# Our Defaults
|
||||
CC = $(AC_CC)
|
||||
|
|
|
|||
44
configure.ac
44
configure.ac
|
|
@ -410,6 +410,12 @@ OL_ARG_ENABLE(unique, [AS_HELP_STRING([--enable-unique], [Attribute Uniqueness o
|
|||
OL_ARG_ENABLE(valsort, [AS_HELP_STRING([--enable-valsort], [Value Sorting overlay])],
|
||||
no, [no yes mod], ol_enable_overlays)
|
||||
|
||||
dnl ----------------------------------------------------------------
|
||||
dnl BALANCER OPTIONS
|
||||
AC_ARG_ENABLE(balanceroptions,[
|
||||
LLOADD (Load Balancer Daemon) Options:])
|
||||
OL_ARG_ENABLE(balancer,[ --enable-balancer enable building load balancer], auto)dnl
|
||||
|
||||
dnl ----------------------------------------------------------------
|
||||
AC_ARG_ENABLE(xxliboptions,[
|
||||
Library Generation & Linking Options])
|
||||
|
|
@ -481,6 +487,13 @@ if test $ol_enable_modules = yes ; then
|
|||
ol_enable_dynamic=yes
|
||||
fi
|
||||
|
||||
if test $ol_enable_balancer = yes ; then
|
||||
dnl Load Balancer was specifically enabled
|
||||
if test $ol_with_threads = no ; then
|
||||
AC_MSG_ERROR([Load balancer requires threads])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $ol_enable_spasswd = yes ; then
|
||||
if test $ol_with_cyrus_sasl = no ; then
|
||||
AC_MSG_ERROR([--enable-spasswd requires --with-cyrus-sasl])
|
||||
|
|
@ -504,13 +517,16 @@ LDAP_LIBS=
|
|||
SLAPD_NDB_LIBS=
|
||||
SLAPD_NDB_INCS=
|
||||
LTHREAD_LIBS=
|
||||
LEVENT_LIBS=
|
||||
LUTIL_LIBS=
|
||||
|
||||
CLIENT_LIBS=
|
||||
|
||||
SLAPD_LIBS=
|
||||
BALANCER_LIBS=
|
||||
|
||||
BUILD_SLAPD=no
|
||||
BUILD_BALANCER=no
|
||||
|
||||
BUILD_THREAD=no
|
||||
|
||||
|
|
@ -2128,6 +2144,24 @@ if test $ol_enable_slp != no ; then
|
|||
fi
|
||||
fi
|
||||
|
||||
dnl ----------------------------------------------------------------
|
||||
dnl Libevent
|
||||
if test $ol_enable_balancer != no ; then
|
||||
AC_CHECK_LIB(event_core, evconnlistener_set_error_cb,
|
||||
[have_libevent=yes
|
||||
LEVENT_LIBS="$LEVENT_LIBS -levent_core"],
|
||||
[AC_CHECK_LIB(event, evconnlistener_set_error_cb,
|
||||
[have_libevent=yes
|
||||
LEVENT_LIBS="$LEVENT_LIBS -levent"],
|
||||
[have_libevent=no])])
|
||||
|
||||
if test $have_libevent = yes ; then
|
||||
AC_DEFINE(HAVE_LIBEVENT, 1, [define if you have -levent])
|
||||
elif test $ol_enable_balancer = yes ; then
|
||||
AC_MSG_ERROR([You need libevent 2.0 or later to build the load balancer])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl ----------------------------------------------------------------
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
|
||||
|
|
@ -2930,6 +2964,12 @@ if test "$ol_enable_valsort" != no ; then
|
|||
AC_DEFINE_UNQUOTED(SLAPD_OVER_VALSORT,$MFLAG,[define for Value Sorting overlay])
|
||||
fi
|
||||
|
||||
if test "$ol_enable_balancer" != no \
|
||||
-a "$ol_with_threads" != no \
|
||||
-a "$have_libevent" = yes ; then
|
||||
BUILD_BALANCER=yes
|
||||
fi
|
||||
|
||||
if test "$ol_enable_slapi" != no ; then
|
||||
AC_DEFINE(ENABLE_SLAPI,1,[define to enable slapi library])
|
||||
BUILD_SLAPI=yes
|
||||
|
|
@ -3002,14 +3042,17 @@ dnl overlays
|
|||
AC_SUBST(BUILD_TRANSLUCENT)
|
||||
AC_SUBST(BUILD_UNIQUE)
|
||||
AC_SUBST(BUILD_VALSORT)
|
||||
AC_SUBST(BUILD_BALANCER)
|
||||
|
||||
AC_SUBST(LDAP_LIBS)
|
||||
AC_SUBST(CLIENT_LIBS)
|
||||
AC_SUBST(SLAPD_LIBS)
|
||||
AC_SUBST(BALANCER_LIBS)
|
||||
AC_SUBST(SLAPD_NDB_LIBS)
|
||||
AC_SUBST(SLAPD_NDB_INCS)
|
||||
AC_SUBST(LTHREAD_LIBS)
|
||||
AC_SUBST(LUTIL_LIBS)
|
||||
AC_SUBST(LEVENT_LIBS)
|
||||
AC_SUBST(WRAP_LIBS)
|
||||
|
||||
AC_SUBST(SLAPD_MODULES_CPPFLAGS)
|
||||
|
|
@ -3091,6 +3134,7 @@ AC_CONFIG_FILES([Makefile:build/top.mk:Makefile.in:build/dir.mk]
|
|||
[servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk]
|
||||
[servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk]
|
||||
[servers/slapd/overlays/Makefile:build/top.mk:servers/slapd/overlays/Makefile.in:build/lib.mk]
|
||||
[servers/lloadd/Makefile:build/top.mk:servers/lloadd/Makefile.in:build/srv.mk]
|
||||
[tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk]
|
||||
[tests/run]
|
||||
[tests/progs/Makefile:build/top.mk:tests/progs/Makefile.in:build/rules.mk])
|
||||
|
|
|
|||
282
doc/devel/lloadd/design.md
Normal file
282
doc/devel/lloadd/design.md
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
TODO:
|
||||
- [ ] keep a global op in-flight counter? (might need locking)
|
||||
- [-] scheduling (who does what, more than one select thread? How does the proxy
|
||||
work get distributed between threads?)
|
||||
- [ ] managing timeouts?
|
||||
- [X] outline locking policy: seems like there might be a lock inversion in the
|
||||
design looming: when working with op, might need a lock on both client and
|
||||
upstream but depending on where we started, we might want to start with
|
||||
locking one, then other
|
||||
- [ ] how to deal with the balancer running out of fds? Especially when we hit
|
||||
the limit, then lose an upstream connection and accept() a client, we
|
||||
wouldn't be able to initiate a new one. A bit of a DoS... But probably not
|
||||
a concern for Ericsson
|
||||
- [ ] non-Linux? No idea how anything other than poll works (moot if building a
|
||||
libevent/libuv-based load balancer since they take care of that, except
|
||||
edge-triggered I/O?)
|
||||
- [-] rootDSE? Controls and exops might have different semantics and need
|
||||
binding to the same upstream connection.
|
||||
- [ ] Just piggybacking on OpenLDAP as a module? Would still need some updates
|
||||
in the core and the module/subsystem would be a very invasive one. On the
|
||||
other hand, allows to expose live configuration and monitoring over LDAP
|
||||
over the current slapd listeners without re-inventing the wheel.
|
||||
|
||||
|
||||
Expecting to handle only LDAPv3
|
||||
|
||||
terms:
|
||||
server - configured target
|
||||
upstream - a single connection to a server
|
||||
client - an incoming connection
|
||||
|
||||
To maintain fairness `G( requested => ( F( progressed | failed ) ) )`, use
|
||||
queues and put timeouts in
|
||||
|
||||
Runtime organisation
|
||||
------
|
||||
- main thread with its own event base handling signals
|
||||
- one thread (later possibly more) listening on the rendezvous sockets, handing
|
||||
the new sockets to worker threads
|
||||
- n worker threads dealing with client and server I/O (dispatching actual work
|
||||
to the thread pool most likely)
|
||||
- a thread pool to handle actual work
|
||||
|
||||
Operational behaviour
|
||||
------
|
||||
|
||||
- client read -> upstream write:
|
||||
- client read:
|
||||
- if TLS_SETUP, keep processing, set state back when finished and note that
|
||||
we're under TLS
|
||||
- ber_get_next(), if we don't have a tag, finished (unless we have true
|
||||
edge-triggered I/O, also put the fd back into the ones we're waiting for)
|
||||
- peek at op tag:
|
||||
- unbind:
|
||||
- with a single lock, mark all pending ops in upstreams abandoned, clear
|
||||
client link (would it be fast enough if we remove them from upstream
|
||||
map instead?)
|
||||
- locked per op:
|
||||
- remove op from upstream map
|
||||
- check upstream is not write-suspended, if it is ...
|
||||
- try to write the abandon op to upstream, suspend upstream if not
|
||||
fully sent
|
||||
- remove op from client map (how if we're in avl_apply?, another pass?)
|
||||
- would be nice if we could wipe the complete client map then, otherwise
|
||||
we need to queue it to have it freed when all abandons get passed onto
|
||||
the upstream (just dropping them might put extra strain on upstreams,
|
||||
will probably have a queue on each client/upstream anyway, not just a
|
||||
single Ber)
|
||||
- bind:
|
||||
- check mechanism is not EXTERNAL (or implement it)
|
||||
- abandon existing ops (see unbind)
|
||||
- set state to BINDING, put DN into authzid
|
||||
- pick upstream, create PDU and sent
|
||||
- abandon:
|
||||
- find op, mark for abandon, send to appropriate upstream
|
||||
- Exop:
|
||||
- check not BINDING (unless it's a cancel?)
|
||||
- check OID:
|
||||
- STARTTLS:
|
||||
- check we don't have TLS yet
|
||||
- abandon all
|
||||
- set state to TLS_SETUP
|
||||
- send the hello
|
||||
- VC(?):
|
||||
- similar to bind except for the abandons/state change
|
||||
- other:
|
||||
- check not BINDING
|
||||
- pick an upstream
|
||||
- create a PDU, send (marking upstream suspended if not written in full)
|
||||
- check if should read again (keep a counter of number of times to read
|
||||
off a connection in a single pass so that we maintain fairness)
|
||||
- if read enough requests and can still read, re-queue ourselves (if we
|
||||
don't have true edge-triggered I/O, we can just register the fd again)
|
||||
- upstream write (only when suspended):
|
||||
- flush the current BER
|
||||
- there shouldn't be anything else?
|
||||
- upstream read -> client write:
|
||||
- upstream read:
|
||||
- ber_get_next(), if we don't have a tag, finished (unless we have true
|
||||
edge-triggered I/O, also put the fd back into the ones we're waiting for)
|
||||
- when we get it, peek at msgid, resolve client connection, lock, check:
|
||||
- if unsolicited, handle as close (and mark connection closing)
|
||||
- if op is abandoned or does not exist, drop PDU and op, update counters
|
||||
- if client backlogged, suspend upstream, register callback to unsuspend
|
||||
(on progress when writing to client or abandon from client (connection
|
||||
death, abandon proper, ...))
|
||||
- reconstruct final PDU, write BER to client, if did not write fully,
|
||||
suspend client
|
||||
- if a final response, decrement operation counts on upstream and client
|
||||
- check if should read again (keep a counter of number of responses to read
|
||||
off a connection in a single pass so that we don't starve any?)
|
||||
- client write ready (only checked for when suspended):
|
||||
- write the rest of pending BER if any
|
||||
- on successful write, pick all pending ops that need failure response, push
|
||||
to client (are there any controls that need to be present in response even
|
||||
in the case of failure?, what to do with them?)
|
||||
- on successfully flushing them, walk through suspended upstreams, picking
|
||||
the pending PDU (unsuspending the upstream) and writing, if PDU flushed
|
||||
successfully, pick next upstream
|
||||
- if we successfully flushed all suspended upstreams, unsuspend client
|
||||
(and disable the write callback)
|
||||
- upstream close/error:
|
||||
- look up pending ops, try to write to clients, mark clients suspended that
|
||||
have ops that need responses (another queue associated with client to speed
|
||||
up?)
|
||||
- schedule a new connection open
|
||||
- client close/error:
|
||||
- same as unbind
|
||||
- client inactive (no pending ops and nothing happened in x seconds)
|
||||
- might just send notice of disconnection and close
|
||||
- op timeout handling:
|
||||
- mark for abandon
|
||||
- send abandon
|
||||
- send timeLimitExceeded/adminLimitExceeded to client
|
||||
|
||||
Picking an upstream:
|
||||
- while there is a level available:
|
||||
- pick a random ordering of upstreams based on weights
|
||||
- while there is an upstream in the level:
|
||||
- check number of ops in-flight (this is where we lock the upstream map)
|
||||
- find the least busy connection (and check if a new connection should be
|
||||
opened)
|
||||
- try to lock for socket write, if available (no BER queued) we have our
|
||||
upstream
|
||||
|
||||
PDU processing:
|
||||
- request (have an upstream selected):
|
||||
- get new msgid from upstream
|
||||
- create an Op structure (actually, with the need for freelist lock, we can
|
||||
make it a cache for freed operation structures, avoiding some malloc
|
||||
traffic, to reset, we need slap_sl_mem_create( ,,, 1 ))
|
||||
- check proxyauthz is not present? or just let upstream reject it if there are
|
||||
two?
|
||||
- add own controls at the end:
|
||||
- construct proxyauthz from authzid
|
||||
- construct session tracking from remote IP, own name, authzid
|
||||
- send over
|
||||
- insert Op into client and upstream maps
|
||||
- response/intermediate/entry:
|
||||
- look up Op in upstream's map
|
||||
- write old msgid, rest of the response can go unchanged
|
||||
- if a response, remove Op from all maps (client and upstream)
|
||||
|
||||
Managing upstreams:
|
||||
- async connect up to min_connections (is there a point in having a connection
|
||||
count range if we can't use it when needed since all of the below is async?)
|
||||
- when connected, set up TLS (if requested)
|
||||
- when done, send a bind
|
||||
- go for the bind interaction
|
||||
- when done, add it to the upstream's connection list
|
||||
- (if a connection is suspended or connections are over 75 % op limit, schedule
|
||||
creating a new connection setup unless connection limit has been hit)
|
||||
|
||||
Managing timeouts:
|
||||
- two options:
|
||||
- maintain a separate locked priority queue to give a perfect ordering to when
|
||||
each operation is to time out, would need to maintain yet another place
|
||||
where operations can be found.
|
||||
- the locking protocol for disposing of the operation would need to be
|
||||
adjusted and might become even more complicated, might do the alternative
|
||||
initially and then attempt this if it helps performance
|
||||
- just do a sweep over all clients (that mutex is less contended) every so
|
||||
often. With many in-flight operations might be a lot of wasted work.
|
||||
- we still need to sweep over all clients to check if they should be killed
|
||||
anyway
|
||||
|
||||
Dispatcher thread (2^n of them, fd x is handled by thread no x % (2^n)):
|
||||
- poll on all registered fds
|
||||
- remove each fd that's ready from the registered list and schedule the work
|
||||
- work threads can put their fd back in if they deem necessary (=not suspended)
|
||||
- this works as a poor man's edge-triggered polling, with enough workers, should
|
||||
we do proper edge triggered I/O? What about non-Linux?
|
||||
|
||||
Listener thread:
|
||||
- slapd has just one, which then reassigns the sockets to separate I/O
|
||||
threads
|
||||
|
||||
Threading:
|
||||
- if using slap_sl_malloc, how much perf do we gain? To allocate a context per
|
||||
op, we should have a dedicated parent context so that when we free it, we can
|
||||
use that exclusively. The parent context's parent would be the main thread's
|
||||
context. This implies a lot of slap_sl_mem_setctx/slap_sl_mem_create( ,,, 0 )
|
||||
and making sure an op does not allocate/free things from two threads at the
|
||||
same time (might need an Op mutex after all? Not such a huge cost if we
|
||||
routinely reuse Op structures)
|
||||
|
||||
Locking policy:
|
||||
- read mutexes are unnecessary, we only have one thread receiving data from the
|
||||
connection - the one started from the dispatcher
|
||||
- two reference counters of operation structures (an op is accessible from
|
||||
client and upstream map, each counter is consistent when thread has a lock on
|
||||
corresponding map), when decreasing the counter to zero, start freeing
|
||||
procedure
|
||||
- place to mark disposal finished for each side, consistency enforced by holding
|
||||
the freelist lock when reading/manipulating
|
||||
- when op is created, we already have a write lock on upstream socket and map,
|
||||
start writing, insert to upstream map with upstream refcount 1, unlock, lock
|
||||
client, insert (client refcount 0), unlock, lock upstream, decrement refcount
|
||||
(triggers a test if we need to drop it now), unlock upstream, done
|
||||
- when upstream processes a PDU, locks its map, increments counter, (potentially
|
||||
removes if it's a response), unlocks, locks client's map, write mutex (this
|
||||
order?) and full client mutex (if a bind response)
|
||||
- when client side wants to work with a PDU (abandon, (un)bind), locks its map,
|
||||
increase refcount, unlocks, locks upstream map, write mutex, sends or queues
|
||||
abandon, unlocks write mutex, initiates freeing procedure from upstream side
|
||||
(or if having to remember we've already increased client-side refcount, mark
|
||||
for deletion, lose upstream lock, lock client, decref, either triggering
|
||||
deletion from client or mark for it)
|
||||
- if we have operation lock, we can simplify a bit (no need for three-stage
|
||||
locking above)
|
||||
|
||||
Shutdown:
|
||||
- stop accept() thread(s) - potentially add a channel to hand these listening
|
||||
sockets over for zero-downtime restart
|
||||
- if very gentle, mark connections as closing, start timeout and:
|
||||
- when a new non-abandon PDU comes in from client - return LDAP_UNAVAILABLE
|
||||
- when receiving a PDU from upstream, send over to client, if no ops pending,
|
||||
send unsolicited response and close (RFC4511 suggests unsolicited response
|
||||
is the last PDU coming from the upstream and libldap agrees, so we can't
|
||||
send it for a socket we want to shut down more gracefully)
|
||||
- gentle (or very gentle timed out):
|
||||
- set timeout
|
||||
- mark all ops as abandoned
|
||||
- send unbind to all upstreams
|
||||
- send unsolicited to all clients
|
||||
- imminent (or gentle timed out):
|
||||
- async close all connections?
|
||||
- exit()
|
||||
|
||||
RootDSE:
|
||||
- default option is not to care and if a control/exop has special restrictions,
|
||||
it is the admin's job to flag it as such in the load-balancer's config
|
||||
- another is not to care about the search request but check each search entry
|
||||
being passed back, check DN and if it's a rootDSE, filter the list of
|
||||
controls/exops/sasl mechs (external!) that are supported
|
||||
- last one is to check all search requests for the DN/scope and synthesise the
|
||||
response locally - probably not (would need to configure the complete list of
|
||||
controls, exops, sasl mechs, naming contexts in the balancer)
|
||||
|
||||
Potential red flags:
|
||||
- we suspend upstreams, if we ever suspend clients we need to be sure we can't
|
||||
create dependency cycles
|
||||
- is this an issue when only suspending the read side of each? Because even if
|
||||
we stop reading from everything, we should eventually flush data to those we
|
||||
can still talk to, as upstreams are flushed, we can start sending new
|
||||
requests from live clients (those that are suspended are due to their own
|
||||
inability to accept data)
|
||||
- we might need to suspend a client if there is a reason to choose a
|
||||
particular upstream (multi-request operation - bind, VC, PR, TXN, ...)
|
||||
- a SASL bind, but that means there are no outstanding ops to receive
|
||||
it holds that !suspended(client) \or !suspended(upstream), so they
|
||||
cannot participate in a cycle
|
||||
- VC - multiple binds at the same time - !!! more analysis needed
|
||||
- PR - should only be able to have one per connection (that's a problem
|
||||
for later, maybe even needs a dedicated upstream connection)
|
||||
- TXN - ??? probably same situation as PR
|
||||
- or if we have a queue for pending Bers on the server, we not need to suspend
|
||||
clients, upstream is only chosen if the queue is free or there is a reason
|
||||
to send it to that particular upstream (multi-stage bind/VC, PR, ...), but
|
||||
that still makes it possible for a client to exhaust all our memory by
|
||||
sending requests (VC or other ones bound to a slow upstream or by not
|
||||
reading the responses at all)
|
||||
|
|
@ -63,4 +63,9 @@
|
|||
/* dn of the default "monitor" subentry */
|
||||
#define SLAPD_MONITOR_DN "cn=Monitor"
|
||||
|
||||
/*
|
||||
* LLOADD DEFINITIONS
|
||||
*/
|
||||
#define LLOADD_DEFAULT_CONFIGFILE LDAP_SYSCONFDIR LDAP_DIRSEP "lloadd.conf"
|
||||
|
||||
#endif /* _LDAP_CONFIG_H */
|
||||
|
|
|
|||
|
|
@ -13,5 +13,5 @@
|
|||
## top-level directory of the distribution or, alternatively, at
|
||||
## <http://www.OpenLDAP.org/license.html>.
|
||||
|
||||
SUBDIRS= slapd
|
||||
SUBDIRS= slapd lloadd
|
||||
|
||||
|
|
|
|||
74
servers/lloadd/Makefile.in
Normal file
74
servers/lloadd/Makefile.in
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Makefile.in for Load Balancer
|
||||
# $OpenLDAP$
|
||||
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
##
|
||||
## Copyright 1998-2020 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>.
|
||||
|
||||
PROGRAMS = lloadd
|
||||
XPROGRAMS = slloadd
|
||||
|
||||
XSRCS = version.c
|
||||
|
||||
NT_SRCS = nt_svc.c
|
||||
NT_OBJS = nt_svc.o ../../libraries/liblutil/slapdmsg.res
|
||||
|
||||
SRCS = main.c globals.c config.c connection.c client.c daemon.c \
|
||||
ch_malloc.c init.c user.c sl_malloc.c value.c \
|
||||
libevent_support.c \
|
||||
$(@PLAT@_SRCS)
|
||||
|
||||
OBJS = $(patsubst %.c,%.o,$(SRCS)) $(@PLAT@_OBJS)
|
||||
|
||||
LDAP_INCDIR= ../../include -I$(srcdir)
|
||||
LDAP_LIBDIR= ../../libraries
|
||||
|
||||
BUILD_OPT = "--enable-balancer"
|
||||
BUILD_SRV = @BUILD_BALANCER@
|
||||
|
||||
all-local-srv: $(PROGRAMS)
|
||||
|
||||
# $(LTHREAD_LIBS) must be last!
|
||||
XLIBS = $(LLOADD_L)
|
||||
XXLIBS = $(LLOADD_LIBS) $(SECURITY_LIBS) $(LUTIL_LIBS)
|
||||
XXXLIBS = $(LTHREAD_LIBS)
|
||||
|
||||
NT_DEPENDS = slapd.exp
|
||||
NT_OBJECTS = slapd.exp symdummy.o $(LLOADD_OBJS) version.o
|
||||
|
||||
UNIX_DEPENDS = version.o $(LLOADD_L)
|
||||
UNIX_OBJECTS = $(OBJS) version.o
|
||||
|
||||
LLOADD_DEPENDS = $(@PLAT@_DEPENDS)
|
||||
LLOADD_OBJECTS = $(@PLAT@_OBJECTS)
|
||||
|
||||
lloadd: $(LLOADD_DEPENDS) version.o
|
||||
$(LTLINK) -o $@ $(OBJS) version.o $(LIBS)
|
||||
|
||||
slloadd: version.o
|
||||
$(LTLINK) -static -o $@ $(OBJS) version.o $(LIBS)
|
||||
|
||||
version.c: Makefile
|
||||
@-$(RM) $@
|
||||
$(MKVERSION) -s -n Versionstr lloadd > $@
|
||||
|
||||
version.o: version.c $(OBJS) $(LLOADD_L)
|
||||
|
||||
install-local-srv: FORCE
|
||||
-$(MKDIR) $(DESTDIR)$(libexecdir)
|
||||
@-$(INSTALL) -m 700 -d $(DESTDIR)$(localstatedir)/openldap-lloadd
|
||||
@( \
|
||||
for prg in $(PROGRAMS); do \
|
||||
$(LTINSTALL) $(INSTALLFLAGS) $(STRIP) -m 755 $$prg$(EXEEXT) \
|
||||
$(DESTDIR)$(libexecdir); \
|
||||
done \
|
||||
)
|
||||
|
||||
1
servers/lloadd/ch_malloc.c
Symbolic link
1
servers/lloadd/ch_malloc.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../slapd/ch_malloc.c
|
||||
103
servers/lloadd/client.c
Normal file
103
servers/lloadd/client.c
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 1998-2020 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>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <ac/socket.h>
|
||||
#include <ac/errno.h>
|
||||
#include <ac/string.h>
|
||||
#include <ac/time.h>
|
||||
#include <ac/unistd.h>
|
||||
|
||||
#include "lutil.h"
|
||||
#include "slap.h"
|
||||
|
||||
static void client_destroy( Connection *c );
|
||||
|
||||
static void
|
||||
client_read_cb( evutil_socket_t s, short what, void *arg )
|
||||
{
|
||||
Connection *c = arg;
|
||||
Debug( LDAP_DEBUG_CONNS, "client_read_cb: "
|
||||
"connection %lu ready to read\n",
|
||||
c->c_connid );
|
||||
evutil_closesocket( s );
|
||||
client_destroy( c );
|
||||
}
|
||||
|
||||
static void
|
||||
client_write_cb( evutil_socket_t s, short what, void *arg )
|
||||
{
|
||||
Connection *c = arg;
|
||||
}
|
||||
|
||||
Connection *
|
||||
client_init(
|
||||
ber_socket_t s,
|
||||
Listener *listener,
|
||||
const char *peername,
|
||||
struct event_base *base,
|
||||
int flags )
|
||||
{
|
||||
Connection *c;
|
||||
struct event *event;
|
||||
|
||||
assert( listener != NULL );
|
||||
|
||||
c = connection_init( s, peername, flags );
|
||||
|
||||
event = event_new( base, s, EV_READ|EV_PERSIST, client_read_cb, c );
|
||||
if ( !event ) {
|
||||
Debug( LDAP_DEBUG_ANY, "Read event could not be allocated\n" );
|
||||
goto fail;
|
||||
}
|
||||
event_add( event, NULL );
|
||||
c->c_read_event = event;
|
||||
|
||||
event = event_new( base, s, EV_WRITE, client_write_cb, c );
|
||||
if ( !event ) {
|
||||
Debug( LDAP_DEBUG_ANY, "Write event could not be allocated\n" );
|
||||
goto fail;
|
||||
}
|
||||
/* We only register the write event when we have data pending */
|
||||
c->c_write_event = event;
|
||||
|
||||
c->c_private = listener;
|
||||
|
||||
return c;
|
||||
fail:
|
||||
if ( c->c_write_event ) {
|
||||
event_del( c->c_write_event );
|
||||
event_free( c->c_write_event );
|
||||
}
|
||||
if ( c->c_read_event ) {
|
||||
event_del( c->c_read_event );
|
||||
event_free( c->c_read_event );
|
||||
}
|
||||
connection_destroy( c );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
client_destroy( Connection *c )
|
||||
{
|
||||
event_del( c->c_read_event );
|
||||
event_free( c->c_read_event );
|
||||
|
||||
event_del( c->c_write_event );
|
||||
event_free( c->c_write_event );
|
||||
|
||||
connection_destroy( c );
|
||||
}
|
||||
2374
servers/lloadd/config.c
Normal file
2374
servers/lloadd/config.c
Normal file
File diff suppressed because it is too large
Load diff
147
servers/lloadd/config.h
Normal file
147
servers/lloadd/config.h
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/* config.h - configuration abstraction structure */
|
||||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 1998-2020 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>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <ac/string.h>
|
||||
|
||||
LDAP_BEGIN_DECL
|
||||
|
||||
typedef struct ConfigTable {
|
||||
const char *name;
|
||||
const char *what;
|
||||
int min_args;
|
||||
int max_args;
|
||||
int length;
|
||||
unsigned int arg_type;
|
||||
void *arg_item;
|
||||
} ConfigTable;
|
||||
|
||||
/* search entries are returned according to this order */
|
||||
typedef enum {
|
||||
Cft_Abstract = 0,
|
||||
Cft_Global,
|
||||
Cft_Module,
|
||||
Cft_Schema,
|
||||
Cft_Backend,
|
||||
Cft_Database,
|
||||
Cft_Overlay,
|
||||
Cft_Misc /* backend/overlay defined */
|
||||
} ConfigType;
|
||||
|
||||
#define ARGS_USERLAND 0x00000fff
|
||||
|
||||
/* types are enumerated, not a bitmask */
|
||||
#define ARGS_TYPES 0x0000f000
|
||||
#define ARG_INT 0x00001000
|
||||
#define ARG_LONG 0x00002000
|
||||
#define ARG_BER_LEN_T 0x00003000
|
||||
#define ARG_ON_OFF 0x00004000
|
||||
#define ARG_STRING 0x00005000
|
||||
#define ARG_BERVAL 0x00006000
|
||||
#define ARG_UINT 0x00008000
|
||||
#define ARG_ULONG 0x0000a000
|
||||
#define ARG_BINARY 0x0000b000
|
||||
|
||||
#define ARGS_SYNTAX 0xffff0000
|
||||
#define ARG_IGNORED 0x00080000
|
||||
#define ARG_PAREN 0x01000000
|
||||
#define ARG_NONZERO 0x02000000
|
||||
#define ARG_NO_INSERT 0x04000000 /* no arbitrary inserting */
|
||||
#define ARG_NO_DELETE 0x08000000 /* no runtime deletes */
|
||||
#define ARG_UNIQUE 0x10000000
|
||||
#define ARG_QUOTE 0x20000000 /* wrap with quotes before parsing */
|
||||
#define ARG_OFFSET 0x40000000
|
||||
#define ARG_MAGIC 0x80000000
|
||||
|
||||
#define ARG_BAD_CONF 0xdead0000 /* overload return values */
|
||||
|
||||
struct config_args_s;
|
||||
|
||||
typedef int (ConfigDriver)( struct config_args_s *c );
|
||||
|
||||
struct config_reply_s {
|
||||
int err;
|
||||
char msg[SLAP_TEXT_BUFLEN];
|
||||
};
|
||||
|
||||
typedef struct config_args_s {
|
||||
int argc;
|
||||
char **argv;
|
||||
int argv_size;
|
||||
char *line;
|
||||
char *tline;
|
||||
const char *fname;
|
||||
int lineno;
|
||||
int linelen;
|
||||
char log[MAXPATHLEN + STRLENOF(": line ") +
|
||||
LDAP_PVT_INTTYPE_CHARS(unsigned long)];
|
||||
#define cr_msg reply.msg
|
||||
ConfigReply reply;
|
||||
int depth;
|
||||
int valx; /* multi-valued value index */
|
||||
/* parsed first val for simple cases */
|
||||
union {
|
||||
int v_int;
|
||||
unsigned v_uint;
|
||||
long v_long;
|
||||
size_t v_ulong;
|
||||
ber_len_t v_ber_t;
|
||||
char *v_string;
|
||||
struct berval v_bv;
|
||||
} values;
|
||||
/* return values for emit mode */
|
||||
BerVarray rvalue_vals;
|
||||
BerVarray rvalue_nvals;
|
||||
#define SLAP_CONFIG_EMIT 0x2000 /* emit instead of set */
|
||||
#define SLAP_CONFIG_ADD 0x4000 /* config file add vs LDAP add */
|
||||
int op;
|
||||
int type; /* ConfigTable.arg_type & ARGS_USERLAND */
|
||||
void *ca_private; /* anything */
|
||||
#ifndef SLAP_CONFIG_CLEANUP_MAX
|
||||
#define SLAP_CONFIG_CLEANUP_MAX 16
|
||||
#endif
|
||||
ConfigDriver *cleanups[SLAP_CONFIG_CLEANUP_MAX];
|
||||
ConfigType table; /* which config table did we come from */
|
||||
int num_cleanups;
|
||||
} ConfigArgs;
|
||||
|
||||
#define value_int values.v_int
|
||||
#define value_uint values.v_uint
|
||||
#define value_long values.v_long
|
||||
#define value_ulong values.v_ulong
|
||||
#define value_ber_t values.v_ber_t
|
||||
#define value_string values.v_string
|
||||
#define value_bv values.v_bv
|
||||
|
||||
int config_fp_parse_line( ConfigArgs *c );
|
||||
|
||||
int config_set_vals( ConfigTable *ct, ConfigArgs *c );
|
||||
int config_add_vals( ConfigTable *ct, ConfigArgs *c );
|
||||
|
||||
int config_push_cleanup( ConfigArgs *c, ConfigDriver *cleanup );
|
||||
|
||||
void init_config_argv( ConfigArgs *c );
|
||||
int read_config_file( const char *fname, int depth, ConfigArgs *cf, ConfigTable *cft );
|
||||
|
||||
ConfigTable *config_find_keyword( ConfigTable *ct, ConfigArgs *c );
|
||||
|
||||
Listener *config_check_my_url( const char *url, LDAPURLDesc *lud );
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
148
servers/lloadd/connection.c
Normal file
148
servers/lloadd/connection.c
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 1998-2020 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.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include <ac/socket.h>
|
||||
#include <ac/errno.h>
|
||||
#include <ac/string.h>
|
||||
#include <ac/time.h>
|
||||
#include <ac/unistd.h>
|
||||
|
||||
#include "lutil.h"
|
||||
#include "slap.h"
|
||||
|
||||
static ldap_pvt_thread_mutex_t conn_nextid_mutex;
|
||||
static unsigned long conn_nextid = 0;
|
||||
|
||||
static void
|
||||
connection_assign_nextid( Connection *conn )
|
||||
{
|
||||
ldap_pvt_thread_mutex_lock( &conn_nextid_mutex );
|
||||
conn->c_connid = conn_nextid++;
|
||||
ldap_pvt_thread_mutex_unlock( &conn_nextid_mutex );
|
||||
}
|
||||
|
||||
void
|
||||
connection_destroy( Connection *c )
|
||||
{
|
||||
assert( c );
|
||||
|
||||
ldap_pvt_thread_mutex_destroy( &c->c_io_mutex );
|
||||
ldap_pvt_thread_mutex_destroy( &c->c_mutex );
|
||||
|
||||
ber_sockbuf_free( c->c_sb );
|
||||
ch_free( c );
|
||||
}
|
||||
|
||||
Connection *
|
||||
connection_init( ber_socket_t s, const char *peername, int flags )
|
||||
{
|
||||
Connection *c;
|
||||
|
||||
assert( peername != NULL );
|
||||
|
||||
#ifndef HAVE_TLS
|
||||
assert( !(flags & CONN_IS_TLS) );
|
||||
#endif
|
||||
|
||||
if ( s == AC_SOCKET_INVALID ) {
|
||||
Debug( LDAP_DEBUG_ANY, "connection_init: "
|
||||
"init of socket fd=%ld invalid.\n",
|
||||
(long)s );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert( s >= 0 );
|
||||
|
||||
c = ch_calloc( 1, sizeof(Connection) );
|
||||
|
||||
c->c_sb = ber_sockbuf_alloc();
|
||||
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_FD, &s );
|
||||
|
||||
{
|
||||
ber_len_t max = sockbuf_max_incoming;
|
||||
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
|
||||
}
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
if ( flags & CONN_IS_IPC ) {
|
||||
#ifdef LDAP_DEBUG
|
||||
ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug,
|
||||
LBER_SBIOD_LEVEL_PROVIDER, (void *)"ipc_" );
|
||||
#endif
|
||||
ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_fd,
|
||||
LBER_SBIOD_LEVEL_PROVIDER, (void *)&s );
|
||||
#ifdef LDAP_PF_LOCAL_SENDMSG
|
||||
if ( !BER_BVISEMPTY( peerbv ) )
|
||||
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_UNGET_BUF, peerbv );
|
||||
#endif
|
||||
} else
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
{
|
||||
#ifdef LDAP_DEBUG
|
||||
ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug,
|
||||
LBER_SBIOD_LEVEL_PROVIDER, (void *)"tcp_" );
|
||||
#endif
|
||||
ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_tcp,
|
||||
LBER_SBIOD_LEVEL_PROVIDER, (void *)&s );
|
||||
}
|
||||
|
||||
#ifdef LDAP_DEBUG
|
||||
ber_sockbuf_add_io(
|
||||
c->c_sb, &ber_sockbuf_io_debug, INT_MAX, (void *)"lload_" );
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
if ( flags & CONN_IS_TLS ) {
|
||||
/* TODO: will need an asynchronous TLS implementation in libldap */
|
||||
assert(0);
|
||||
c->c_is_tls = 1;
|
||||
c->c_needs_tls_accept = 1;
|
||||
} else {
|
||||
c->c_is_tls = 0;
|
||||
c->c_needs_tls_accept = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
ldap_pvt_thread_mutex_init( &c->c_mutex );
|
||||
ldap_pvt_thread_mutex_init( &c->c_io_mutex );
|
||||
|
||||
connection_assign_nextid( c );
|
||||
|
||||
Debug( LDAP_DEBUG_CONNS, "connection_init: "
|
||||
"connection connid=%lu allocated for socket fd=%d\n",
|
||||
c->c_connid, s );
|
||||
|
||||
return c;
|
||||
fail:
|
||||
connection_destroy( c );
|
||||
return NULL;
|
||||
}
|
||||
1400
servers/lloadd/daemon.c
Normal file
1400
servers/lloadd/daemon.c
Normal file
File diff suppressed because it is too large
Load diff
1
servers/lloadd/design.md
Symbolic link
1
servers/lloadd/design.md
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../doc/devel/lloadd/design.md
|
||||
1
servers/lloadd/globals.c
Symbolic link
1
servers/lloadd/globals.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../slapd/globals.c
|
||||
144
servers/lloadd/init.c
Normal file
144
servers/lloadd/init.c
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/* init.c - initialize various things */
|
||||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 1998-2020 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.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/socket.h>
|
||||
#include <ac/string.h>
|
||||
#include <ac/time.h>
|
||||
|
||||
#include "slap.h"
|
||||
#include "lber_pvt.h"
|
||||
|
||||
#include "ldap_rq.h"
|
||||
|
||||
/*
|
||||
* read-only global variables or variables only written by the listener
|
||||
* thread (after they are initialized) - no need to protect them with a mutex.
|
||||
*/
|
||||
int slap_debug = 0;
|
||||
|
||||
#ifdef LDAP_DEBUG
|
||||
int ldap_syslog = LDAP_DEBUG_STATS;
|
||||
#else
|
||||
int ldap_syslog;
|
||||
#endif
|
||||
|
||||
#ifdef LOG_DEBUG
|
||||
int ldap_syslog_level = LOG_DEBUG;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* global variables that need mutex protection
|
||||
*/
|
||||
ldap_pvt_thread_pool_t connection_pool;
|
||||
int connection_pool_max = SLAP_MAX_WORKER_THREADS;
|
||||
int connection_pool_queues = 1;
|
||||
int slap_tool_thread_max = 1;
|
||||
|
||||
static const char *slap_name = NULL;
|
||||
int slapMode = SLAP_UNDEFINED_MODE;
|
||||
|
||||
int
|
||||
slap_init( int mode, const char *name )
|
||||
{
|
||||
int rc = LDAP_SUCCESS;
|
||||
|
||||
assert( mode );
|
||||
|
||||
if ( slapMode != SLAP_UNDEFINED_MODE ) {
|
||||
/* Make sure we write something to stderr */
|
||||
slap_debug |= LDAP_DEBUG_NONE;
|
||||
Debug( LDAP_DEBUG_ANY, "%s init: "
|
||||
"init called twice (old=%d, new=%d)\n",
|
||||
name, slapMode, mode );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
slapMode = mode;
|
||||
|
||||
switch ( slapMode & SLAP_MODE ) {
|
||||
case SLAP_SERVER_MODE:
|
||||
Debug( LDAP_DEBUG_TRACE, "%s init: "
|
||||
"initiated server.\n",
|
||||
name );
|
||||
|
||||
slap_name = name;
|
||||
|
||||
ldap_pvt_thread_pool_init_q( &connection_pool, connection_pool_max,
|
||||
0, connection_pool_queues );
|
||||
|
||||
ldap_pvt_thread_mutex_init( &slapd_rq.rq_mutex );
|
||||
LDAP_STAILQ_INIT( &slapd_rq.task_list );
|
||||
LDAP_STAILQ_INIT( &slapd_rq.run_list );
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
slap_debug |= LDAP_DEBUG_NONE;
|
||||
Debug( LDAP_DEBUG_ANY, "%s init: "
|
||||
"undefined mode (%d).\n",
|
||||
name, mode );
|
||||
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
slap_destroy( void )
|
||||
{
|
||||
int rc = LDAP_SUCCESS;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "%s destroy: "
|
||||
"freeing system resources.\n",
|
||||
slap_name );
|
||||
|
||||
ldap_pvt_thread_pool_free( &connection_pool );
|
||||
|
||||
switch ( slapMode & SLAP_MODE ) {
|
||||
case SLAP_SERVER_MODE:
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY, "slap_destroy(): "
|
||||
"undefined mode (%d).\n",
|
||||
slapMode );
|
||||
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_destroy();
|
||||
|
||||
/* should destroy the above mutex */
|
||||
return rc;
|
||||
}
|
||||
161
servers/lloadd/libevent_support.c
Normal file
161
servers/lloadd/libevent_support.c
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/* libevent_support.c - routines to bridge libldap and libevent */
|
||||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 2017-2020 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>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <ac/time.h>
|
||||
|
||||
#include <event2/event.h>
|
||||
#include <event2/thread.h>
|
||||
|
||||
#include "slap.h"
|
||||
#include "ldap_pvt_thread.h"
|
||||
|
||||
static void *
|
||||
lload_libevent_mutex_init( unsigned locktype )
|
||||
{
|
||||
int rc;
|
||||
ldap_pvt_thread_mutex_t *mutex =
|
||||
ch_malloc( sizeof(ldap_pvt_thread_mutex_t) );
|
||||
|
||||
if ( locktype & EVTHREAD_LOCKTYPE_RECURSIVE ) {
|
||||
rc = ldap_pvt_thread_mutex_recursive_init( mutex );
|
||||
} else {
|
||||
rc = ldap_pvt_thread_mutex_init( mutex );
|
||||
}
|
||||
if ( rc ) {
|
||||
ch_free( mutex );
|
||||
mutex = NULL;
|
||||
}
|
||||
return mutex;
|
||||
}
|
||||
|
||||
static void
|
||||
lload_libevent_mutex_destroy( void *lock, unsigned locktype )
|
||||
{
|
||||
int rc;
|
||||
ldap_pvt_thread_mutex_t *mutex = lock;
|
||||
|
||||
rc = ldap_pvt_thread_mutex_destroy( mutex );
|
||||
assert( rc == 0 );
|
||||
ch_free( mutex );
|
||||
}
|
||||
|
||||
static int
|
||||
lload_libevent_mutex_lock( unsigned mode, void *lock )
|
||||
{
|
||||
ldap_pvt_thread_mutex_t *mutex = lock;
|
||||
|
||||
if ( mode & EVTHREAD_TRY ) {
|
||||
return ldap_pvt_thread_mutex_trylock( mutex );
|
||||
} else {
|
||||
return ldap_pvt_thread_mutex_lock( mutex );
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
lload_libevent_mutex_unlock( unsigned mode, void *lock )
|
||||
{
|
||||
ldap_pvt_thread_mutex_t *mutex = lock;
|
||||
|
||||
return ldap_pvt_thread_mutex_unlock( mutex );
|
||||
}
|
||||
|
||||
static void *
|
||||
lload_libevent_cond_init( unsigned condtype )
|
||||
{
|
||||
int rc;
|
||||
ldap_pvt_thread_cond_t *cond =
|
||||
ch_malloc( sizeof(ldap_pvt_thread_cond_t) );
|
||||
|
||||
assert( condtype == 0 );
|
||||
rc = ldap_pvt_thread_cond_init( cond );
|
||||
if ( rc ) {
|
||||
ch_free( cond );
|
||||
cond = NULL;
|
||||
}
|
||||
return cond;
|
||||
}
|
||||
|
||||
static void
|
||||
lload_libevent_cond_destroy( void *c )
|
||||
{
|
||||
int rc;
|
||||
ldap_pvt_thread_cond_t *cond = c;
|
||||
|
||||
rc = ldap_pvt_thread_cond_destroy( cond );
|
||||
assert( rc == 0 );
|
||||
ch_free( c );
|
||||
}
|
||||
|
||||
static int
|
||||
lload_libevent_cond_signal( void *c, int broadcast )
|
||||
{
|
||||
ldap_pvt_thread_cond_t *cond = c;
|
||||
|
||||
if ( broadcast ) {
|
||||
return ldap_pvt_thread_cond_broadcast( cond );
|
||||
} else {
|
||||
return ldap_pvt_thread_cond_signal( cond );
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
lload_libevent_cond_timedwait(
|
||||
void *c,
|
||||
void *lock,
|
||||
const struct timeval *timeout )
|
||||
{
|
||||
ldap_pvt_thread_cond_t *cond = c;
|
||||
ldap_pvt_thread_mutex_t *mutex = lock;
|
||||
|
||||
/*
|
||||
* libevent does not seem to request a timeout, this is true as of 2.1.8
|
||||
* that has just been marked the first stable release of the 2.1 series
|
||||
*/
|
||||
assert( timeout == NULL );
|
||||
|
||||
return ldap_pvt_thread_cond_wait( cond, mutex );
|
||||
}
|
||||
|
||||
int
|
||||
lload_libevent_init( void )
|
||||
{
|
||||
struct evthread_lock_callbacks cbs = {
|
||||
EVTHREAD_LOCK_API_VERSION,
|
||||
EVTHREAD_LOCKTYPE_RECURSIVE,
|
||||
lload_libevent_mutex_init,
|
||||
lload_libevent_mutex_destroy,
|
||||
lload_libevent_mutex_lock,
|
||||
lload_libevent_mutex_unlock
|
||||
};
|
||||
struct evthread_condition_callbacks cond_cbs = {
|
||||
EVTHREAD_CONDITION_API_VERSION,
|
||||
lload_libevent_cond_init,
|
||||
lload_libevent_cond_destroy,
|
||||
lload_libevent_cond_signal,
|
||||
lload_libevent_cond_timedwait
|
||||
};
|
||||
|
||||
if ( ldap_pvt_thread_initialize() ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
evthread_set_lock_callbacks( &cbs );
|
||||
evthread_set_condition_callbacks( &cond_cbs );
|
||||
evthread_set_id_callback( ldap_pvt_thread_self );
|
||||
return 0;
|
||||
}
|
||||
974
servers/lloadd/main.c
Normal file
974
servers/lloadd/main.c
Normal file
|
|
@ -0,0 +1,974 @@
|
|||
/* $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.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/ctype.h>
|
||||
#include <ac/socket.h>
|
||||
#include <ac/string.h>
|
||||
#include <ac/time.h>
|
||||
#include <ac/unistd.h>
|
||||
#include <ac/wait.h>
|
||||
#include <ac/errno.h>
|
||||
|
||||
#include <event2/event.h>
|
||||
|
||||
#include "slap.h"
|
||||
#include "lutil.h"
|
||||
#include "ldif.h"
|
||||
|
||||
#ifdef LDAP_SIGCHLD
|
||||
static void wait4child( evutil_socket_t sig, short what, void *arg );
|
||||
#endif
|
||||
|
||||
#ifdef SIGPIPE
|
||||
static void sigpipe( evutil_socket_t sig, short what, void *arg );
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NT_SERVICE_MANAGER
|
||||
#define MAIN_RETURN(x) return
|
||||
static struct sockaddr_in bind_addr;
|
||||
|
||||
#define SERVICE_EXIT( e, n ) \
|
||||
do { \
|
||||
if ( is_NT_Service ) { \
|
||||
lutil_ServiceStatus.dwWin32ExitCode = (e); \
|
||||
lutil_ServiceStatus.dwServiceSpecificExitCode = (n); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define SERVICE_EXIT( e, n )
|
||||
#define MAIN_RETURN(x) return (x)
|
||||
#endif
|
||||
|
||||
struct signal_handler {
|
||||
int signal;
|
||||
event_callback_fn handler;
|
||||
struct event *event;
|
||||
} signal_handlers[] = {
|
||||
{ LDAP_SIGUSR2, slap_sig_shutdown },
|
||||
|
||||
#ifdef SIGPIPE
|
||||
{ SIGPIPE, sigpipe },
|
||||
#endif
|
||||
#ifdef SIGHUP
|
||||
{ SIGHUP, slap_sig_shutdown },
|
||||
#endif
|
||||
{ SIGINT, slap_sig_shutdown },
|
||||
{ SIGTERM, slap_sig_shutdown },
|
||||
#ifdef SIGTRAP
|
||||
{ SIGTRAP, slap_sig_shutdown },
|
||||
#endif
|
||||
#ifdef LDAP_SIGCHLD
|
||||
{ LDAP_SIGCHLD, wait4child },
|
||||
#endif
|
||||
#ifdef SIGBREAK
|
||||
/* SIGBREAK is generated when Ctrl-Break is pressed. */
|
||||
{ SIGBREAK, slap_sig_shutdown },
|
||||
#endif
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
* when more than one lloadd is running on one machine, each one might have
|
||||
* it's own LOCAL for syslogging and must have its own pid/args files
|
||||
*/
|
||||
|
||||
#ifndef HAVE_MKVERSION
|
||||
const char Versionstr[] = OPENLDAP_PACKAGE
|
||||
" " OPENLDAP_VERSION " LDAP Load Balancer Server (lloadd)";
|
||||
#endif
|
||||
|
||||
#define CHECK_NONE 0x00
|
||||
#define CHECK_CONFIG 0x01
|
||||
#define CHECK_LOGLEVEL 0x02
|
||||
static int check = CHECK_NONE;
|
||||
static int version = 0;
|
||||
|
||||
void *slap_tls_ctx;
|
||||
LDAP *slap_tls_ld;
|
||||
|
||||
static int
|
||||
slapd_opt_slp( const char *val, void *arg )
|
||||
{
|
||||
#ifdef HAVE_SLP
|
||||
/* NULL is default */
|
||||
if ( val == NULL || *val == '(' || strcasecmp( val, "on" ) == 0 ) {
|
||||
slapd_register_slp = 1;
|
||||
slapd_slp_attrs = ( val != NULL && *val == '(' ) ? val : NULL;
|
||||
|
||||
} else if ( strcasecmp( val, "off" ) == 0 ) {
|
||||
slapd_register_slp = 0;
|
||||
|
||||
/* NOTE: add support for URL specification? */
|
||||
|
||||
} else {
|
||||
fprintf( stderr, "unrecognized value \"%s\" for SLP option\n", val );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#else
|
||||
fputs( "lloadd: SLP support is not available\n", stderr );
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Option helper structure:
|
||||
*
|
||||
* oh_nam is left-hand part of <option>[=<value>]
|
||||
* oh_fnc is handler function
|
||||
* oh_arg is an optional arg to oh_fnc
|
||||
* oh_usage is the one-line usage string related to the option,
|
||||
* which is assumed to start with <option>[=<value>]
|
||||
*
|
||||
* please leave valid options in the structure, and optionally #ifdef
|
||||
* their processing inside the helper, so that reasonable and helpful
|
||||
* error messages can be generated if a disabled option is requested.
|
||||
*/
|
||||
struct option_helper {
|
||||
struct berval oh_name;
|
||||
int (*oh_fnc)( const char *val, void *arg );
|
||||
void *oh_arg;
|
||||
const char *oh_usage;
|
||||
} option_helpers[] = {
|
||||
{ BER_BVC("slp"), slapd_opt_slp, NULL,
|
||||
"slp[={on|off|(attrs)}] enable/disable SLP using (attrs)" },
|
||||
{ BER_BVNULL, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
#if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG)
|
||||
#ifdef LOG_LOCAL4
|
||||
int
|
||||
parse_syslog_user( const char *arg, int *syslogUser )
|
||||
{
|
||||
static slap_verbmasks syslogUsers[] = {
|
||||
{ BER_BVC("LOCAL0"), LOG_LOCAL0 },
|
||||
{ BER_BVC("LOCAL1"), LOG_LOCAL1 },
|
||||
{ BER_BVC("LOCAL2"), LOG_LOCAL2 },
|
||||
{ BER_BVC("LOCAL3"), LOG_LOCAL3 },
|
||||
{ BER_BVC("LOCAL4"), LOG_LOCAL4 },
|
||||
{ BER_BVC("LOCAL5"), LOG_LOCAL5 },
|
||||
{ BER_BVC("LOCAL6"), LOG_LOCAL6 },
|
||||
{ BER_BVC("LOCAL7"), LOG_LOCAL7 },
|
||||
#ifdef LOG_USER
|
||||
{ BER_BVC("USER"), LOG_USER },
|
||||
#endif /* LOG_USER */
|
||||
#ifdef LOG_DAEMON
|
||||
{ BER_BVC("DAEMON"), LOG_DAEMON },
|
||||
#endif /* LOG_DAEMON */
|
||||
{ BER_BVNULL, 0 }
|
||||
};
|
||||
int i = verb_to_mask( arg, syslogUsers );
|
||||
|
||||
if ( BER_BVISNULL( &syslogUsers[i].word ) ) {
|
||||
Debug( LDAP_DEBUG_ANY, "unrecognized syslog user \"%s\".\n", arg );
|
||||
return 1;
|
||||
}
|
||||
|
||||
*syslogUser = syslogUsers[i].mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* LOG_LOCAL4 */
|
||||
|
||||
int
|
||||
parse_syslog_level( const char *arg, int *levelp )
|
||||
{
|
||||
static slap_verbmasks str2syslog_level[] = {
|
||||
{ BER_BVC("EMERG"), LOG_EMERG },
|
||||
{ BER_BVC("ALERT"), LOG_ALERT },
|
||||
{ BER_BVC("CRIT"), LOG_CRIT },
|
||||
{ BER_BVC("ERR"), LOG_ERR },
|
||||
{ BER_BVC("WARNING"), LOG_WARNING },
|
||||
{ BER_BVC("NOTICE"), LOG_NOTICE },
|
||||
{ BER_BVC("INFO"), LOG_INFO },
|
||||
{ BER_BVC("DEBUG"), LOG_DEBUG },
|
||||
{ BER_BVNULL, 0 }
|
||||
};
|
||||
int i = verb_to_mask( arg, str2syslog_level );
|
||||
if ( BER_BVISNULL( &str2syslog_level[i].word ) ) {
|
||||
Debug( LDAP_DEBUG_ANY, "unknown syslog level \"%s\".\n", arg );
|
||||
return 1;
|
||||
}
|
||||
|
||||
*levelp = str2syslog_level[i].mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* LDAP_DEBUG && LDAP_SYSLOG */
|
||||
|
||||
int
|
||||
parse_debug_unknowns( char **unknowns, int *levelp )
|
||||
{
|
||||
int i, level, rc = 0;
|
||||
|
||||
for ( i = 0; unknowns[i] != NULL; i++ ) {
|
||||
level = 0;
|
||||
if ( str2loglevel( unknowns[i], &level ) ) {
|
||||
fprintf( stderr, "unrecognized log level \"%s\"\n", unknowns[i] );
|
||||
rc = 1;
|
||||
} else {
|
||||
*levelp |= level;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
parse_debug_level( const char *arg, int *levelp, char ***unknowns )
|
||||
{
|
||||
int level;
|
||||
|
||||
if ( arg && arg[0] != '-' && !isdigit( (unsigned char)arg[0] ) ) {
|
||||
int i;
|
||||
char **levels;
|
||||
|
||||
levels = ldap_str2charray( arg, "," );
|
||||
|
||||
for ( i = 0; levels[i] != NULL; i++ ) {
|
||||
level = 0;
|
||||
|
||||
if ( str2loglevel( levels[i], &level ) ) {
|
||||
/* remember this for later */
|
||||
ldap_charray_add( unknowns, levels[i] );
|
||||
fprintf( stderr, "unrecognized log level \"%s\" (deferred)\n",
|
||||
levels[i] );
|
||||
} else {
|
||||
*levelp |= level;
|
||||
}
|
||||
}
|
||||
|
||||
ldap_charray_free( levels );
|
||||
|
||||
} else {
|
||||
int rc;
|
||||
|
||||
if ( arg[0] == '-' ) {
|
||||
rc = lutil_atoix( &level, arg, 0 );
|
||||
} else {
|
||||
unsigned ulevel;
|
||||
|
||||
rc = lutil_atoux( &ulevel, arg, 0 );
|
||||
level = (int)ulevel;
|
||||
}
|
||||
|
||||
if ( rc ) {
|
||||
fprintf( stderr,
|
||||
"unrecognized log level "
|
||||
"\"%s\"\n",
|
||||
arg );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( level == 0 ) {
|
||||
*levelp = 0;
|
||||
|
||||
} else {
|
||||
*levelp |= level;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
usage( char *name )
|
||||
{
|
||||
fprintf( stderr, "usage: %s options\n", name );
|
||||
fprintf( stderr,
|
||||
"\t-4\t\tIPv4 only\n"
|
||||
"\t-6\t\tIPv6 only\n"
|
||||
"\t-d level\tDebug level"
|
||||
"\n"
|
||||
"\t-f filename\tConfiguration file\n"
|
||||
#if defined(HAVE_SETUID) && defined(HAVE_SETGID)
|
||||
"\t-g group\tGroup (id or name) to run as\n"
|
||||
#endif
|
||||
"\t-h URLs\t\tList of URLs to serve\n"
|
||||
#ifdef SLAP_DEFAULT_SYSLOG_USER
|
||||
"\t-l facility\tSyslog facility (default: LOCAL4)\n"
|
||||
#endif
|
||||
"\t-n serverName\tService name\n"
|
||||
"\t-o <opt>[=val] generic means to specify options" );
|
||||
if ( !BER_BVISNULL( &option_helpers[0].oh_name ) ) {
|
||||
int i;
|
||||
|
||||
fprintf( stderr, "; supported options:\n" );
|
||||
for ( i = 0; !BER_BVISNULL( &option_helpers[i].oh_name ); i++ ) {
|
||||
fprintf( stderr, "\t\t%s\n", option_helpers[i].oh_usage );
|
||||
}
|
||||
} else {
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
fprintf( stderr,
|
||||
#ifdef HAVE_CHROOT
|
||||
"\t-r directory\tSandbox directory to chroot to\n"
|
||||
#endif
|
||||
"\t-s level\tSyslog level\n"
|
||||
"\t-t\t\tCheck configuration file\n"
|
||||
#if defined(HAVE_SETUID) && defined(HAVE_SETGID)
|
||||
"\t-u user\t\tUser (id or name) to run as\n"
|
||||
#endif
|
||||
"\t-V\t\tprint version info (-VV exit afterwards)\n" );
|
||||
}
|
||||
|
||||
#ifdef HAVE_NT_SERVICE_MANAGER
|
||||
void WINAPI
|
||||
ServiceMain( DWORD argc, LPTSTR *argv )
|
||||
#else
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
#endif
|
||||
{
|
||||
int i, no_detach = 0;
|
||||
int rc = 1;
|
||||
char *urls = NULL;
|
||||
#if defined(HAVE_SETUID) && defined(HAVE_SETGID)
|
||||
char *username = NULL;
|
||||
char *groupname = NULL;
|
||||
#endif
|
||||
#if defined(HAVE_CHROOT)
|
||||
char *sandbox = NULL;
|
||||
#endif
|
||||
#ifdef SLAP_DEFAULT_SYSLOG_USER
|
||||
int syslogUser = SLAP_DEFAULT_SYSLOG_USER;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WINSOCK
|
||||
int pid, waitfds[2];
|
||||
#endif
|
||||
int g_argc = argc;
|
||||
char **g_argv = argv;
|
||||
|
||||
char *configfile = NULL;
|
||||
char *configdir = NULL;
|
||||
char *serverName;
|
||||
int serverMode = SLAP_SERVER_MODE;
|
||||
|
||||
char **debug_unknowns = NULL;
|
||||
char **syslog_unknowns = NULL;
|
||||
|
||||
int slapd_pid_file_unlink = 0, slapd_args_file_unlink = 0;
|
||||
int firstopt = 1;
|
||||
|
||||
struct event_base *daemon_base = NULL;
|
||||
|
||||
slap_sl_mem_init();
|
||||
|
||||
(void)lload_libevent_init();
|
||||
|
||||
serverName = lutil_progname( "lloadd", argc, argv );
|
||||
|
||||
#ifdef HAVE_NT_SERVICE_MANAGER
|
||||
{
|
||||
int *ip;
|
||||
char *newConfigFile;
|
||||
char *newConfigDir;
|
||||
char *newUrls;
|
||||
char *regService = NULL;
|
||||
|
||||
if ( is_NT_Service ) {
|
||||
lutil_CommenceStartupProcessing( serverName, slap_sig_shutdown );
|
||||
if ( strcmp( serverName, SERVICE_NAME ) ) regService = serverName;
|
||||
}
|
||||
|
||||
ip = (int *)lutil_getRegParam( regService, "DebugLevel" );
|
||||
if ( ip != NULL ) {
|
||||
slap_debug = *ip;
|
||||
Debug( LDAP_DEBUG_ANY, "new debug level from registry is: %d\n",
|
||||
slap_debug );
|
||||
}
|
||||
|
||||
newUrls = (char *)lutil_getRegParam( regService, "Urls" );
|
||||
if ( newUrls ) {
|
||||
if ( urls ) ch_free( urls );
|
||||
|
||||
urls = ch_strdup( newUrls );
|
||||
Debug( LDAP_DEBUG_ANY, "new urls from registry: %s\n", urls );
|
||||
}
|
||||
|
||||
newConfigFile = (char *)lutil_getRegParam( regService, "ConfigFile" );
|
||||
if ( newConfigFile != NULL ) {
|
||||
configfile = ch_strdup( newConfigFile );
|
||||
Debug( LDAP_DEBUG_ANY, "new config file from registry is: %s\n",
|
||||
configfile );
|
||||
}
|
||||
|
||||
newConfigDir = (char *)lutil_getRegParam( regService, "ConfigDir" );
|
||||
if ( newConfigDir != NULL ) {
|
||||
configdir = ch_strdup( newConfigDir );
|
||||
Debug( LDAP_DEBUG_ANY, "new config dir from registry is: %s\n",
|
||||
configdir );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while ( (i = getopt( argc, argv,
|
||||
"c:d:f:F:h:n:o:s:tV"
|
||||
#ifdef LDAP_PF_INET6
|
||||
"46"
|
||||
#endif
|
||||
#ifdef HAVE_CHROOT
|
||||
"r:"
|
||||
#endif
|
||||
#if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG)
|
||||
"S:"
|
||||
#ifdef LOG_LOCAL4
|
||||
"l:"
|
||||
#endif
|
||||
#endif
|
||||
#if defined(HAVE_SETUID) && defined(HAVE_SETGID)
|
||||
"u:g:"
|
||||
#endif
|
||||
)) != EOF ) {
|
||||
switch ( i ) {
|
||||
#ifdef LDAP_PF_INET6
|
||||
case '4':
|
||||
slap_inet4or6 = AF_INET;
|
||||
break;
|
||||
case '6':
|
||||
slap_inet4or6 = AF_INET6;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'h': /* listen URLs */
|
||||
if ( urls != NULL ) free( urls );
|
||||
urls = ch_strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'd': { /* set debug level and 'do not detach' flag */
|
||||
int level = 0;
|
||||
|
||||
if ( strcmp( optarg, "?" ) == 0 ) {
|
||||
check |= CHECK_LOGLEVEL;
|
||||
break;
|
||||
}
|
||||
|
||||
no_detach = 1;
|
||||
if ( parse_debug_level( optarg, &level, &debug_unknowns ) ) {
|
||||
goto destroy;
|
||||
}
|
||||
#ifdef LDAP_DEBUG
|
||||
slap_debug |= level;
|
||||
#else
|
||||
if ( level != 0 )
|
||||
fputs( "must compile with LDAP_DEBUG for debugging\n",
|
||||
stderr );
|
||||
#endif
|
||||
} break;
|
||||
|
||||
case 'f': /* read config file */
|
||||
configfile = ch_strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'o': {
|
||||
char *val = strchr( optarg, '=' );
|
||||
struct berval opt;
|
||||
|
||||
opt.bv_val = optarg;
|
||||
|
||||
if ( val ) {
|
||||
opt.bv_len = ( val - optarg );
|
||||
val++;
|
||||
|
||||
} else {
|
||||
opt.bv_len = strlen( optarg );
|
||||
}
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &option_helpers[i].oh_name );
|
||||
i++ ) {
|
||||
if ( ber_bvstrcasecmp( &option_helpers[i].oh_name, &opt ) ==
|
||||
0 ) {
|
||||
assert( option_helpers[i].oh_fnc != NULL );
|
||||
if ( (*option_helpers[i].oh_fnc)(
|
||||
val, option_helpers[i].oh_arg ) == -1 ) {
|
||||
/* we assume the option parsing helper
|
||||
* issues appropriate and self-explanatory
|
||||
* error messages... */
|
||||
goto stop;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( BER_BVISNULL( &option_helpers[i].oh_name ) ) {
|
||||
goto unhandled_option;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 's': /* set syslog level */
|
||||
if ( strcmp( optarg, "?" ) == 0 ) {
|
||||
check |= CHECK_LOGLEVEL;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( parse_debug_level(
|
||||
optarg, &ldap_syslog, &syslog_unknowns ) ) {
|
||||
goto destroy;
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG)
|
||||
case 'S':
|
||||
if ( parse_syslog_level( optarg, &ldap_syslog_level ) ) {
|
||||
goto destroy;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef LOG_LOCAL4
|
||||
case 'l': /* set syslog local user */
|
||||
if ( parse_syslog_user( optarg, &syslogUser ) ) {
|
||||
goto destroy;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif /* LDAP_DEBUG && LDAP_SYSLOG */
|
||||
|
||||
#ifdef HAVE_CHROOT
|
||||
case 'r':
|
||||
if ( sandbox ) free( sandbox );
|
||||
sandbox = ch_strdup( optarg );
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SETUID) && defined(HAVE_SETGID)
|
||||
case 'u': /* user name */
|
||||
if ( username ) free( username );
|
||||
username = ch_strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'g': /* group name */
|
||||
if ( groupname ) free( groupname );
|
||||
groupname = ch_strdup( optarg );
|
||||
break;
|
||||
#endif /* SETUID && GETUID */
|
||||
|
||||
case 'n': /* NT service name */
|
||||
serverName = ch_strdup( optarg );
|
||||
break;
|
||||
|
||||
case 't':
|
||||
check |= CHECK_CONFIG;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
version++;
|
||||
break;
|
||||
|
||||
default:
|
||||
unhandled_option:;
|
||||
usage( argv[0] );
|
||||
rc = 1;
|
||||
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 15 );
|
||||
goto stop;
|
||||
}
|
||||
|
||||
if ( firstopt ) {
|
||||
firstopt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( optind != argc ) goto unhandled_option;
|
||||
|
||||
ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug );
|
||||
ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug );
|
||||
ldif_debug = slap_debug;
|
||||
|
||||
if ( version ) {
|
||||
fprintf( stderr, "%s\n", Versionstr );
|
||||
|
||||
if ( version > 1 ) goto stop;
|
||||
}
|
||||
|
||||
#if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG)
|
||||
{
|
||||
char *logName;
|
||||
#ifdef HAVE_EBCDIC
|
||||
logName = ch_strdup( serverName );
|
||||
__atoe( logName );
|
||||
#else
|
||||
logName = serverName;
|
||||
#endif
|
||||
|
||||
#ifdef LOG_LOCAL4
|
||||
openlog( logName, OPENLOG_OPTIONS, syslogUser );
|
||||
#elif defined LOG_DEBUG
|
||||
openlog( logName, OPENLOG_OPTIONS );
|
||||
#endif
|
||||
#ifdef HAVE_EBCDIC
|
||||
free( logName );
|
||||
#endif
|
||||
}
|
||||
#endif /* LDAP_DEBUG && LDAP_SYSLOG */
|
||||
|
||||
Debug( LDAP_DEBUG_ANY, "%s", Versionstr );
|
||||
|
||||
global_host = ldap_pvt_get_fqdn( NULL );
|
||||
|
||||
if ( check == CHECK_NONE && slapd_daemon_init( urls ) != 0 ) {
|
||||
rc = 1;
|
||||
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 16 );
|
||||
goto stop;
|
||||
}
|
||||
|
||||
#if defined(HAVE_CHROOT)
|
||||
if ( sandbox ) {
|
||||
if ( chdir( sandbox ) ) {
|
||||
perror( "chdir" );
|
||||
rc = 1;
|
||||
goto stop;
|
||||
}
|
||||
if ( chroot( sandbox ) ) {
|
||||
perror( "chroot" );
|
||||
rc = 1;
|
||||
goto stop;
|
||||
}
|
||||
if ( chdir( "/" ) ) {
|
||||
perror( "chdir" );
|
||||
rc = 1;
|
||||
goto stop;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SETUID) && defined(HAVE_SETGID)
|
||||
if ( username != NULL || groupname != NULL ) {
|
||||
slap_init_user( username, groupname );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
rc = ldap_create( &slap_tls_ld );
|
||||
if ( rc ) {
|
||||
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 );
|
||||
goto destroy;
|
||||
}
|
||||
/* Library defaults to full certificate checking. This is correct when
|
||||
* a client is verifying a server because all servers should have a
|
||||
* valid cert. But few clients have valid certs, so we want our default
|
||||
* to be no checking. The config file can override this as usual.
|
||||
*/
|
||||
rc = LDAP_OPT_X_TLS_NEVER;
|
||||
(void)ldap_pvt_tls_set_option(
|
||||
slap_tls_ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &rc );
|
||||
#endif
|
||||
|
||||
rc = slap_init( serverMode, serverName );
|
||||
if ( rc ) {
|
||||
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 18 );
|
||||
goto destroy;
|
||||
}
|
||||
|
||||
if ( read_config( configfile, configdir ) != 0 ) {
|
||||
rc = 1;
|
||||
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 );
|
||||
|
||||
if ( check & CHECK_CONFIG ) {
|
||||
fprintf( stderr, "config check failed\n" );
|
||||
}
|
||||
|
||||
goto destroy;
|
||||
}
|
||||
|
||||
if ( debug_unknowns ) {
|
||||
rc = parse_debug_unknowns( debug_unknowns, &slap_debug );
|
||||
ldap_charray_free( debug_unknowns );
|
||||
debug_unknowns = NULL;
|
||||
if ( rc ) goto destroy;
|
||||
}
|
||||
if ( syslog_unknowns ) {
|
||||
rc = parse_debug_unknowns( syslog_unknowns, &ldap_syslog );
|
||||
ldap_charray_free( syslog_unknowns );
|
||||
syslog_unknowns = NULL;
|
||||
if ( rc ) goto destroy;
|
||||
}
|
||||
|
||||
if ( check & CHECK_LOGLEVEL ) {
|
||||
rc = 0;
|
||||
goto destroy;
|
||||
}
|
||||
|
||||
if ( check & CHECK_CONFIG ) {
|
||||
fprintf( stderr, "config check succeeded\n" );
|
||||
|
||||
check &= ~CHECK_CONFIG;
|
||||
if ( check == CHECK_NONE ) {
|
||||
rc = 0;
|
||||
goto destroy;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
rc = ldap_pvt_tls_init();
|
||||
if ( rc != 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "main: "
|
||||
"TLS init failed: %d\n",
|
||||
rc );
|
||||
rc = 1;
|
||||
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 );
|
||||
goto destroy;
|
||||
}
|
||||
|
||||
{
|
||||
int opt = 1;
|
||||
|
||||
/* Force new ctx to be created */
|
||||
rc = ldap_pvt_tls_set_option(
|
||||
slap_tls_ld, LDAP_OPT_X_TLS_NEWCTX, &opt );
|
||||
if ( rc == 0 ) {
|
||||
/* The ctx's refcount is bumped up here */
|
||||
ldap_pvt_tls_get_option(
|
||||
slap_tls_ld, LDAP_OPT_X_TLS_CTX, &slap_tls_ctx );
|
||||
} else if ( rc != LDAP_NOT_SUPPORTED ) {
|
||||
Debug( LDAP_DEBUG_ANY, "main: "
|
||||
"TLS init def ctx failed: %d\n",
|
||||
rc );
|
||||
rc = 1;
|
||||
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 );
|
||||
goto destroy;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
daemon_base = event_base_new();
|
||||
if ( !daemon_base ) {
|
||||
Debug( LDAP_DEBUG_ANY, "main: "
|
||||
"main event base allocation failed\n" );
|
||||
rc = 1;
|
||||
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 21 );
|
||||
goto destroy;
|
||||
}
|
||||
|
||||
for ( i = 0; signal_handlers[i].signal; i++ ) {
|
||||
struct event *event;
|
||||
event = evsignal_new( daemon_base, signal_handlers[i].signal,
|
||||
signal_handlers[i].handler, daemon_base );
|
||||
if ( !event || event_add( event, NULL ) ) {
|
||||
Debug( LDAP_DEBUG_ANY, "main: "
|
||||
"failed to register a handler for signal %d\n",
|
||||
signal_handlers[i].signal );
|
||||
rc = 1;
|
||||
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 21 );
|
||||
goto destroy;
|
||||
}
|
||||
signal_handlers[i].event = event;
|
||||
}
|
||||
|
||||
#ifndef HAVE_WINSOCK
|
||||
if ( !no_detach ) {
|
||||
if ( lutil_pair( waitfds ) < 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "main: "
|
||||
"lutil_pair failed\n" );
|
||||
rc = 1;
|
||||
goto destroy;
|
||||
}
|
||||
pid = lutil_detach( no_detach, 0 );
|
||||
if ( pid ) {
|
||||
char buf[4];
|
||||
rc = EXIT_SUCCESS;
|
||||
close( waitfds[1] );
|
||||
if ( read( waitfds[0], buf, 1 ) != 1 ) rc = EXIT_FAILURE;
|
||||
_exit( rc );
|
||||
} else {
|
||||
close( waitfds[0] );
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_WINSOCK */
|
||||
|
||||
if ( slapd_pid_file != NULL ) {
|
||||
FILE *fp = fopen( slapd_pid_file, "w" );
|
||||
|
||||
if ( fp == NULL ) {
|
||||
char ebuf[128];
|
||||
int save_errno = errno;
|
||||
|
||||
Debug( LDAP_DEBUG_ANY, "unable to open pid file "
|
||||
"\"%s\": %d (%s)\n",
|
||||
slapd_pid_file, save_errno,
|
||||
AC_STRERROR_R( save_errno, ebuf, sizeof(ebuf) ) );
|
||||
|
||||
free( slapd_pid_file );
|
||||
slapd_pid_file = NULL;
|
||||
|
||||
rc = 1;
|
||||
goto destroy;
|
||||
}
|
||||
fprintf( fp, "%d\n", (int)getpid() );
|
||||
fclose( fp );
|
||||
slapd_pid_file_unlink = 1;
|
||||
}
|
||||
|
||||
if ( slapd_args_file != NULL ) {
|
||||
FILE *fp = fopen( slapd_args_file, "w" );
|
||||
|
||||
if ( fp == NULL ) {
|
||||
char ebuf[128];
|
||||
int save_errno = errno;
|
||||
|
||||
Debug( LDAP_DEBUG_ANY, "unable to open args file "
|
||||
"\"%s\": %d (%s)\n",
|
||||
slapd_args_file, save_errno,
|
||||
AC_STRERROR_R( save_errno, ebuf, sizeof(ebuf) ) );
|
||||
|
||||
free( slapd_args_file );
|
||||
slapd_args_file = NULL;
|
||||
|
||||
rc = 1;
|
||||
goto destroy;
|
||||
}
|
||||
|
||||
for ( i = 0; i < g_argc; i++ ) {
|
||||
fprintf( fp, "%s ", g_argv[i] );
|
||||
}
|
||||
fprintf( fp, "\n" );
|
||||
fclose( fp );
|
||||
slapd_args_file_unlink = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: moved here from slapd_daemon_task()
|
||||
* because back-monitor db_open() needs it
|
||||
*/
|
||||
time( &starttime );
|
||||
|
||||
Debug( LDAP_DEBUG_ANY, "lloadd starting\n" );
|
||||
|
||||
#ifndef HAVE_WINSOCK
|
||||
if ( !no_detach ) {
|
||||
write( waitfds[1], "1", 1 );
|
||||
close( waitfds[1] );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NT_EVENT_LOG
|
||||
if ( is_NT_Service )
|
||||
lutil_LogStartedEvent( serverName, slap_debug,
|
||||
configfile ? configfile : LLOADD_DEFAULT_CONFIGFILE, urls );
|
||||
#endif
|
||||
|
||||
rc = slapd_daemon( daemon_base );
|
||||
|
||||
#ifdef HAVE_NT_SERVICE_MANAGER
|
||||
/* Throw away the event that we used during the startup process. */
|
||||
if ( is_NT_Service ) ldap_pvt_thread_cond_destroy( &started_event );
|
||||
#endif
|
||||
|
||||
destroy:
|
||||
if ( check & CHECK_LOGLEVEL ) {
|
||||
(void)loglevel_print( stdout );
|
||||
}
|
||||
/* remember an error during destroy */
|
||||
rc |= slap_destroy();
|
||||
|
||||
stop:
|
||||
#ifdef HAVE_NT_EVENT_LOG
|
||||
if ( is_NT_Service ) lutil_LogStoppedEvent( serverName );
|
||||
#endif
|
||||
|
||||
Debug( LDAP_DEBUG_ANY, "lloadd stopped.\n" );
|
||||
|
||||
#ifdef HAVE_NT_SERVICE_MANAGER
|
||||
lutil_ReportShutdownComplete();
|
||||
#endif
|
||||
|
||||
#ifdef LOG_DEBUG
|
||||
closelog();
|
||||
#endif
|
||||
slapd_daemon_destroy();
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
if ( slap_tls_ld ) {
|
||||
ldap_pvt_tls_ctx_free( slap_tls_ctx );
|
||||
ldap_unbind_ext( slap_tls_ld, NULL, NULL );
|
||||
}
|
||||
ldap_pvt_tls_destroy();
|
||||
#endif
|
||||
|
||||
if ( slapd_pid_file_unlink ) {
|
||||
unlink( slapd_pid_file );
|
||||
}
|
||||
if ( slapd_args_file_unlink ) {
|
||||
unlink( slapd_args_file );
|
||||
}
|
||||
|
||||
config_destroy();
|
||||
|
||||
if ( configfile ) ch_free( configfile );
|
||||
if ( configdir ) ch_free( configdir );
|
||||
if ( urls ) ch_free( urls );
|
||||
if ( global_host ) ch_free( global_host );
|
||||
|
||||
/* kludge, get symbols referenced */
|
||||
tavl_free( NULL, NULL );
|
||||
|
||||
MAIN_RETURN(rc);
|
||||
}
|
||||
|
||||
#ifdef SIGPIPE
|
||||
|
||||
/*
|
||||
* Catch and discard terminated child processes, to avoid zombies.
|
||||
*/
|
||||
|
||||
static void
|
||||
sigpipe( evutil_socket_t sig, short what, void *arg )
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* SIGPIPE */
|
||||
|
||||
#ifdef LDAP_SIGCHLD
|
||||
|
||||
/*
|
||||
* Catch and discard terminated child processes, to avoid zombies.
|
||||
*/
|
||||
|
||||
static void
|
||||
wait4child( evutil_socket_t sig, short what, void *arg )
|
||||
{
|
||||
int save_errno = errno;
|
||||
|
||||
#ifdef WNOHANG
|
||||
do
|
||||
errno = 0;
|
||||
#ifdef HAVE_WAITPID
|
||||
while ( waitpid( (pid_t)-1, NULL, WNOHANG ) > 0 || errno == EINTR );
|
||||
#else
|
||||
while ( wait3( NULL, WNOHANG, NULL ) > 0 || errno == EINTR );
|
||||
#endif
|
||||
#else
|
||||
(void)wait( NULL );
|
||||
#endif
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
#endif /* LDAP_SIGCHLD */
|
||||
1
servers/lloadd/nt_svc.c
Symbolic link
1
servers/lloadd/nt_svc.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../slapd/nt_svc.c
|
||||
268
servers/lloadd/proto-slap.h
Normal file
268
servers/lloadd/proto-slap.h
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
/* $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 PROTO_SLAP_H
|
||||
#define PROTO_SLAP_H
|
||||
|
||||
#include <ldap_cdefs.h>
|
||||
#include "ldap_pvt.h"
|
||||
|
||||
#include <event2/event.h>
|
||||
|
||||
LDAP_BEGIN_DECL
|
||||
|
||||
struct config_args_s; /* config.h */
|
||||
struct config_reply_s; /* config.h */
|
||||
|
||||
/*
|
||||
* ch_malloc.c
|
||||
*/
|
||||
LDAP_SLAPD_V (BerMemoryFunctions) ch_mfuncs;
|
||||
LDAP_SLAPD_F (void *) ch_malloc( ber_len_t size );
|
||||
LDAP_SLAPD_F (void *) ch_realloc( void *block, ber_len_t size );
|
||||
LDAP_SLAPD_F (void *) ch_calloc( ber_len_t nelem, ber_len_t size );
|
||||
LDAP_SLAPD_F (char *) ch_strdup( const char *string );
|
||||
LDAP_SLAPD_F (void) ch_free( void * );
|
||||
|
||||
#ifndef CH_FREE
|
||||
#undef free
|
||||
#define free ch_free
|
||||
#endif
|
||||
|
||||
/*
|
||||
* config.c
|
||||
*/
|
||||
LDAP_SLAPD_F (int) read_config( const char *fname, const char *dir );
|
||||
LDAP_SLAPD_F (void) config_destroy( void );
|
||||
LDAP_SLAPD_F (int) verb_to_mask( const char *word, slap_verbmasks *v );
|
||||
LDAP_SLAPD_F (int) str2loglevel( const char *s, int *l );
|
||||
LDAP_SLAPD_F (void) bindconf_free( slap_bindconf *bc );
|
||||
|
||||
/*
|
||||
* connection.c
|
||||
*/
|
||||
LDAP_SLAPD_F (Connection *) connection_init( ber_socket_t s, const char *peername, int use_tls );
|
||||
LDAP_SLAPD_F (Connection *) client_init( ber_socket_t s, Listener *url, const char *peername, struct event_base *base, int use_tls );
|
||||
LDAP_SLAPD_F (void) connection_destroy( Connection *c );
|
||||
|
||||
/*
|
||||
* daemon.c
|
||||
*/
|
||||
LDAP_SLAPD_F (int) slapd_daemon_init( const char *urls );
|
||||
LDAP_SLAPD_F (int) slapd_daemon_destroy( void );
|
||||
LDAP_SLAPD_F (int) slapd_daemon( struct event_base *daemon_base );
|
||||
LDAP_SLAPD_F (Listener **) slapd_get_listeners( void );
|
||||
|
||||
LDAP_SLAPD_F (void) slap_sig_shutdown( evutil_socket_t sig, short what, void *arg );
|
||||
|
||||
LDAP_SLAPD_V (volatile sig_atomic_t) slapd_shutdown;
|
||||
LDAP_SLAPD_V (int) lloadd_inited;
|
||||
LDAP_SLAPD_V (struct runqueue_s) slapd_rq;
|
||||
LDAP_SLAPD_V (int) slapd_daemon_threads;
|
||||
LDAP_SLAPD_V (int) slapd_daemon_mask;
|
||||
#ifdef LDAP_TCP_BUFFER
|
||||
LDAP_SLAPD_V (int) slapd_tcp_rmem;
|
||||
LDAP_SLAPD_V (int) slapd_tcp_wmem;
|
||||
#endif /* LDAP_TCP_BUFFER */
|
||||
|
||||
#define bvmatch( bv1, bv2 ) \
|
||||
( ( (bv1)->bv_len == (bv2)->bv_len ) && \
|
||||
( memcmp( (bv1)->bv_val, (bv2)->bv_val, (bv1)->bv_len ) == 0 ) )
|
||||
|
||||
/*
|
||||
* globals.c
|
||||
*/
|
||||
LDAP_SLAPD_V (const struct berval) slap_empty_bv;
|
||||
LDAP_SLAPD_V (const struct berval) slap_unknown_bv;
|
||||
LDAP_SLAPD_V (const struct berval) slap_true_bv;
|
||||
LDAP_SLAPD_V (const struct berval) slap_false_bv;
|
||||
LDAP_SLAPD_V (struct slap_sync_cookie_s) slap_sync_cookie;
|
||||
LDAP_SLAPD_V (void *) slap_tls_ctx;
|
||||
LDAP_SLAPD_V (LDAP *) slap_tls_ld;
|
||||
|
||||
/*
|
||||
* init.c
|
||||
*/
|
||||
LDAP_SLAPD_F (int) slap_init( int mode, const char *name );
|
||||
LDAP_SLAPD_F (int) slap_destroy( void );
|
||||
|
||||
/*
|
||||
* libevent_support.c
|
||||
*/
|
||||
LDAP_SLAPD_F (int) lload_libevent_init( void );
|
||||
|
||||
/*
|
||||
* main.c
|
||||
*/
|
||||
LDAP_SLAPD_V (int) slapd_register_slp;
|
||||
LDAP_SLAPD_V (const char *) slapd_slp_attrs;
|
||||
|
||||
/*
|
||||
* sl_malloc.c
|
||||
*/
|
||||
LDAP_SLAPD_F (void *) slap_sl_malloc( ber_len_t size, void *ctx );
|
||||
LDAP_SLAPD_F (void *) slap_sl_realloc( void *block, ber_len_t size, void *ctx );
|
||||
LDAP_SLAPD_F (void *) slap_sl_calloc( ber_len_t nelem, ber_len_t size, void *ctx );
|
||||
LDAP_SLAPD_F (void) slap_sl_free( void *, void *ctx );
|
||||
|
||||
LDAP_SLAPD_V (BerMemoryFunctions) slap_sl_mfuncs;
|
||||
|
||||
LDAP_SLAPD_F (void) slap_sl_mem_init( void );
|
||||
LDAP_SLAPD_F (void *) slap_sl_mem_create( ber_len_t size, int stack, void *ctx, int flag );
|
||||
LDAP_SLAPD_F (void) slap_sl_mem_setctx( void *ctx, void *memctx );
|
||||
LDAP_SLAPD_F (void) slap_sl_mem_destroy( void *key, void *data );
|
||||
LDAP_SLAPD_F (void *) slap_sl_context( void *ptr );
|
||||
|
||||
/* assumes (x) > (y) returns 1 if true, 0 otherwise */
|
||||
#define SLAP_PTRCMP(x, y) ( (x) < (y) ? -1 : (x) > (y) )
|
||||
|
||||
/*
|
||||
* user.c
|
||||
*/
|
||||
#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
|
||||
LDAP_SLAPD_F (void) slap_init_user( char *username, char *groupname );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* value.c
|
||||
*/
|
||||
LDAP_SLAPD_F (int) value_add_one( BerVarray *vals, struct berval *addval );
|
||||
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
/*
|
||||
* zn_malloc.c
|
||||
*/
|
||||
LDAP_SLAPD_F (void *) slap_zn_malloc( ber_len_t, void * );
|
||||
LDAP_SLAPD_F (void *) slap_zn_realloc( void *, ber_len_t, void * );
|
||||
LDAP_SLAPD_F (void *) slap_zn_calloc( ber_len_t, ber_len_t, void * );
|
||||
LDAP_SLAPD_F (void) slap_zn_free( void *, void * );
|
||||
|
||||
LDAP_SLAPD_F (void *) slap_zn_mem_create( ber_len_t, ber_len_t, ber_len_t, ber_len_t );
|
||||
LDAP_SLAPD_F (void) slap_zn_mem_destroy( void * );
|
||||
LDAP_SLAPD_F (int) slap_zn_validate( void *, void *, int );
|
||||
LDAP_SLAPD_F (int) slap_zn_invalidate( void *, void * );
|
||||
LDAP_SLAPD_F (int) slap_zh_rlock( void * );
|
||||
LDAP_SLAPD_F (int) slap_zh_runlock( void * );
|
||||
LDAP_SLAPD_F (int) slap_zh_wlock( void * );
|
||||
LDAP_SLAPD_F (int) slap_zh_wunlock( void * );
|
||||
LDAP_SLAPD_F (int) slap_zn_rlock( void *, void * );
|
||||
LDAP_SLAPD_F (int) slap_zn_runlock( void *, void * );
|
||||
LDAP_SLAPD_F (int) slap_zn_wlock( void *, void * );
|
||||
LDAP_SLAPD_F (int) slap_zn_wunlock( void *, void * );
|
||||
#endif
|
||||
|
||||
LDAP_SLAPD_V (ber_len_t) sockbuf_max_incoming;
|
||||
LDAP_SLAPD_V (ber_len_t) sockbuf_max_incoming_auth;
|
||||
|
||||
LDAP_SLAPD_V (slap_mask_t) global_allows;
|
||||
LDAP_SLAPD_V (slap_mask_t) global_disallows;
|
||||
|
||||
LDAP_SLAPD_V (const char) Versionstr[];
|
||||
|
||||
LDAP_SLAPD_V (int) global_gentlehup;
|
||||
LDAP_SLAPD_V (int) global_idletimeout;
|
||||
LDAP_SLAPD_V (char *) global_host;
|
||||
LDAP_SLAPD_V (int) lber_debug;
|
||||
LDAP_SLAPD_V (int) ldap_syslog;
|
||||
|
||||
LDAP_SLAPD_V (char *) slapd_pid_file;
|
||||
LDAP_SLAPD_V (char *) slapd_args_file;
|
||||
LDAP_SLAPD_V (time_t) starttime;
|
||||
|
||||
/* use time(3) -- no mutex */
|
||||
#define slap_get_time() time( NULL )
|
||||
|
||||
LDAP_SLAPD_V (ldap_pvt_thread_pool_t) connection_pool;
|
||||
LDAP_SLAPD_V (int) connection_pool_max;
|
||||
LDAP_SLAPD_V (int) connection_pool_queues;
|
||||
LDAP_SLAPD_V (int) slap_tool_thread_max;
|
||||
|
||||
#ifdef USE_MP_BIGNUM
|
||||
#define UI2BVX( bv, ui, ctx ) \
|
||||
do { \
|
||||
char *val; \
|
||||
ber_len_t len; \
|
||||
val = BN_bn2dec( ui ); \
|
||||
if (val) { \
|
||||
len = strlen( val ); \
|
||||
if ( len > (bv)->bv_len ) { \
|
||||
(bv)->bv_val = ber_memrealloc_x( (bv)->bv_val, len + 1, (ctx) ); \
|
||||
} \
|
||||
AC_MEMCPY( (bv)->bv_val, val, len + 1 ); \
|
||||
(bv)->bv_len = len; \
|
||||
OPENSSL_free( val ); \
|
||||
} else { \
|
||||
ber_memfree_x( (bv)->bv_val, (ctx) ); \
|
||||
BER_BVZERO( (bv) ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#elif defined(USE_MP_GMP)
|
||||
/* NOTE: according to the documentation, the result
|
||||
* of mpz_sizeinbase() can exceed the length of the
|
||||
* string representation of the number by 1
|
||||
*/
|
||||
#define UI2BVX( bv, ui, ctx ) \
|
||||
do { \
|
||||
ber_len_t len = mpz_sizeinbase( (ui), 10 ); \
|
||||
if ( len > (bv)->bv_len ) { \
|
||||
(bv)->bv_val = ber_memrealloc_x( (bv)->bv_val, len + 1, (ctx) ); \
|
||||
} \
|
||||
(void)mpz_get_str( (bv)->bv_val, 10, (ui) ); \
|
||||
if ( (bv)->bv_val[len - 1] == '\0' ) { \
|
||||
len--; \
|
||||
} \
|
||||
(bv)->bv_len = len; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#ifdef USE_MP_LONG_LONG
|
||||
#define UI2BV_FORMAT "%llu"
|
||||
#elif defined USE_MP_LONG
|
||||
#define UI2BV_FORMAT "%lu"
|
||||
#elif defined HAVE_LONG_LONG
|
||||
#define UI2BV_FORMAT "%llu"
|
||||
#else
|
||||
#define UI2BV_FORMAT "%lu"
|
||||
#endif
|
||||
|
||||
#define UI2BVX( bv, ui, ctx ) \
|
||||
do { \
|
||||
char buf[LDAP_PVT_INTTYPE_CHARS(long)]; \
|
||||
ber_len_t len; \
|
||||
len = snprintf( buf, sizeof( buf ), UI2BV_FORMAT, (ui) ); \
|
||||
if ( len > (bv)->bv_len ) { \
|
||||
(bv)->bv_val = ber_memrealloc_x( (bv)->bv_val, len + 1, (ctx) ); \
|
||||
} \
|
||||
(bv)->bv_len = len; \
|
||||
AC_MEMCPY( (bv)->bv_val, buf, len + 1 ); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define UI2BV( bv, ui ) UI2BVX( bv, ui, NULL )
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
#endif /* PROTO_SLAP_H */
|
||||
1
servers/lloadd/sl_malloc.c
Symbolic link
1
servers/lloadd/sl_malloc.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../slapd/sl_malloc.c
|
||||
332
servers/lloadd/slap.h
Normal file
332
servers/lloadd/slap.h
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
/* 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 )
|
||||
|
||||
#define SLAP_TEXT_BUFLEN ( 256 )
|
||||
|
||||
/* unknown config file directive */
|
||||
#define SLAP_CONF_UNKNOWN ( -1026 )
|
||||
|
||||
LDAP_SLAPD_V (int) slap_debug;
|
||||
|
||||
typedef unsigned long slap_mask_t;
|
||||
|
||||
typedef struct Connection Connection;
|
||||
/* 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
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* represents a connection from an ldap client
|
||||
*/
|
||||
/* structure state (protected by connections_mutex) */
|
||||
enum sc_struct_state {
|
||||
SLAP_C_UNINITIALIZED = 0, /* MUST BE ZERO (0) */
|
||||
SLAP_C_UNUSED,
|
||||
SLAP_C_USED,
|
||||
SLAP_C_PENDING
|
||||
};
|
||||
|
||||
/* connection state (protected by c_mutex) */
|
||||
enum sc_conn_state {
|
||||
SLAP_C_INVALID = 0, /* MUST BE ZERO (0) */
|
||||
SLAP_C_INACTIVE, /* zero threads */
|
||||
SLAP_C_CLOSING, /* closing */
|
||||
SLAP_C_ACTIVE, /* one or more threads */
|
||||
SLAP_C_BINDING, /* binding */
|
||||
SLAP_C_CLIENT /* outbound client conn */
|
||||
};
|
||||
struct Connection {
|
||||
enum sc_struct_state c_struct_state; /* structure management state */
|
||||
enum sc_conn_state c_conn_state; /* connection state */
|
||||
ber_socket_t c_sd;
|
||||
|
||||
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 */
|
||||
|
||||
time_t c_activitytime; /* when the connection was last used */
|
||||
|
||||
struct event *c_read_event, *c_write_event;
|
||||
|
||||
/* can only be changed by binding thread */
|
||||
struct berval c_sasl_bind_mech; /* mech in progress */
|
||||
|
||||
ldap_pvt_thread_mutex_t c_io_mutex; /* only one pdu written at a time */
|
||||
|
||||
BerElement *c_currentber; /* ber we're attempting to read */
|
||||
struct berval c_pendingber; /* ber we're attempting to write */
|
||||
|
||||
#define CONN_IS_TLS 1
|
||||
#define CONN_IS_CLIENT 4
|
||||
#define CONN_IS_IPC 8
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
char c_is_tls; /* true if this LDAP over raw TLS */
|
||||
char c_needs_tls_accept; /* true if SSL_accept should be called */
|
||||
#endif
|
||||
|
||||
long c_n_ops_executing; /* num of ops currently executing */
|
||||
long c_n_ops_completed; /* num of ops completed */
|
||||
|
||||
void *c_private;
|
||||
};
|
||||
|
||||
#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_ */
|
||||
1
servers/lloadd/user.c
Symbolic link
1
servers/lloadd/user.c
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../slapd/user.c
|
||||
67
servers/lloadd/value.c
Normal file
67
servers/lloadd/value.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* value.c - routines for dealing with values */
|
||||
/* $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>.
|
||||
*/
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "slap.h"
|
||||
|
||||
int
|
||||
value_add_one( BerVarray *vals, struct berval *addval )
|
||||
{
|
||||
int n;
|
||||
BerVarray v2;
|
||||
|
||||
if ( *vals == NULL ) {
|
||||
*vals = (BerVarray)SLAP_MALLOC( 2 * sizeof(struct berval) );
|
||||
if ( *vals == NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "value_add_one: "
|
||||
"SLAP_MALLOC failed.\n" );
|
||||
return LBER_ERROR_MEMORY;
|
||||
}
|
||||
n = 0;
|
||||
|
||||
} else {
|
||||
for ( n = 0; !BER_BVISNULL( &(*vals)[n] ); n++ ) {
|
||||
; /* Empty */
|
||||
}
|
||||
*vals = (BerVarray)SLAP_REALLOC(
|
||||
(char *)*vals, ( n + 2 ) * sizeof(struct berval) );
|
||||
if ( *vals == NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "value_add_one: "
|
||||
"SLAP_MALLOC failed.\n" );
|
||||
return LBER_ERROR_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
v2 = &(*vals)[n];
|
||||
ber_dupbv( v2, addval );
|
||||
|
||||
v2++;
|
||||
BER_BVZERO( v2 );
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
|
@ -257,6 +257,7 @@ static OidRec OidMacros[] = {
|
|||
* OLcfg{Bk|Db}{Oc|At}:10 -> back-shell
|
||||
* OLcfg{Bk|Db}{Oc|At}:11 -> back-perl
|
||||
* OLcfg{Bk|Db}{Oc|At}:12 -> back-mdb
|
||||
* OLcfg{Bk|Db}{Oc|At}:13 -> lloadd
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue