]> git.sur5r.net Git - openldap/blob - servers/slapd/main.c
f7b446939072e727445bbd64dc8de1ab8cce477b
[openldap] / servers / slapd / main.c
1 #include "portable.h"
2
3 #include <stdio.h>
4
5 #include <ac/signal.h>
6 #include <ac/socket.h>
7 #include <ac/string.h>
8 #include <ac/time.h>
9 #include <ac/unistd.h>
10
11 #include "ldapconfig.h"
12 #include "slap.h"
13 #include "lutil.h"                      /* Get lutil_detach() */
14
15 /*
16  * when more than one slapd is running on one machine, each one might have
17  * it's own LOCAL for syslogging and must have its own pid/args files
18  */
19
20 #ifdef LOG_LOCAL4
21
22 #define DEFAULT_SYSLOG_USER  LOG_LOCAL4
23
24 typedef struct _str2intDispatch {
25         char    *stringVal;
26         int      abbr;
27         int      intVal;
28 } STRDISP, *STRDISP_P;
29
30
31 /* table to compute syslog-options to integer */
32 static STRDISP  syslog_types[] = {
33     { "LOCAL0",         6, LOG_LOCAL0 },
34     { "LOCAL1",         6, LOG_LOCAL1 },
35     { "LOCAL2",         6, LOG_LOCAL2 },
36     { "LOCAL3",         6, LOG_LOCAL3 },
37     { "LOCAL4",         6, LOG_LOCAL4 },
38     { "LOCAL5",         6, LOG_LOCAL5 },
39     { "LOCAL6",         6, LOG_LOCAL6 },
40     { "LOCAL7",         6, LOG_LOCAL7 },
41     { NULL }
42 };
43
44 static int   cnvt_str2int( char *, STRDISP_P, int );
45
46 #endif  /* LOG_LOCAL4 */
47
48
49 static void
50 usage( char *name )
51 {
52         fprintf( stderr, "usage: %s [-d ?|debuglevel] [-f configfile] [-p portnumber] [-s sysloglevel]", name );
53 #ifdef LOG_LOCAL4
54     fprintf( stderr, " [-l sysloguser]" );
55 #endif
56     fprintf( stderr, "\n" );
57 }
58
59 int
60 main( int argc, char **argv )
61 {
62         int             i;
63         int             inetd = 0;
64         int             rc = 0;
65         struct sockaddr_in      bind_addr;
66         int             udp;
67 #ifdef LOG_LOCAL4
68     int     syslogUser = DEFAULT_SYSLOG_USER;
69 #endif
70         char            *configfile;
71         char        *serverName;
72         int         serverMode = SLAP_SERVER_MODE;
73
74         configfile = SLAPD_DEFAULT_CONFIGFILE;
75
76         (void) memset( (void*) &bind_addr, '\0', sizeof(bind_addr));
77         bind_addr.sin_family = AF_INET;
78         bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
79         bind_addr.sin_port = htons(LDAP_PORT);
80
81         g_argc = argc;
82         g_argv = argv;
83
84 #ifdef SLAPD_BDB2
85         while ( (i = getopt( argc, argv, "d:f:ia:p:s:ut" )) != EOF ) {
86 #else
87         while ( (i = getopt( argc, argv, "d:f:ia:p:s:u" )) != EOF ) {
88 #endif
89                 switch ( i ) {
90                 case 'a':       /* bind address */
91                         if(!inet_aton(optarg, &bind_addr.sin_addr)) {
92                                 fprintf(stderr, "invalid address (%s) for -a option", optarg);
93                         }
94             break;
95
96 #ifdef LDAP_DEBUG
97                 case 'd':       /* turn on debugging */
98                         if ( optarg[0] == '?' ) {
99                                 printf( "Debug levels:\n" );
100                                 printf( "\tLDAP_DEBUG_TRACE\t%d\n",
101                                     LDAP_DEBUG_TRACE );
102                                 printf( "\tLDAP_DEBUG_PACKETS\t%d\n",
103                                     LDAP_DEBUG_PACKETS );
104                                 printf( "\tLDAP_DEBUG_ARGS\t\t%d\n",
105                                     LDAP_DEBUG_ARGS );
106                                 printf( "\tLDAP_DEBUG_CONNS\t%d\n",
107                                     LDAP_DEBUG_CONNS );
108                                 printf( "\tLDAP_DEBUG_BER\t\t%d\n",
109                                     LDAP_DEBUG_BER );
110                                 printf( "\tLDAP_DEBUG_FILTER\t%d\n",
111                                     LDAP_DEBUG_FILTER );
112                                 printf( "\tLDAP_DEBUG_CONFIG\t%d\n",
113                                     LDAP_DEBUG_CONFIG );
114                                 printf( "\tLDAP_DEBUG_ACL\t\t%d\n",
115                                     LDAP_DEBUG_ACL );
116                                 printf( "\tLDAP_DEBUG_STATS\t%d\n",
117                                     LDAP_DEBUG_STATS );
118                                 printf( "\tLDAP_DEBUG_STATS2\t%d\n",
119                                     LDAP_DEBUG_STATS2 );
120                                 printf( "\tLDAP_DEBUG_SHELL\t%d\n",
121                                     LDAP_DEBUG_SHELL );
122                                 printf( "\tLDAP_DEBUG_PARSE\t%d\n",
123                                     LDAP_DEBUG_PARSE );
124                                 printf( "\tLDAP_DEBUG_ANY\t\t%d\n",
125                                     LDAP_DEBUG_ANY );
126                                 exit( 0 );
127                         } else {
128                                 slap_debug |= atoi( optarg );
129                         }
130                         break;
131 #else
132                 case 'd':       /* turn on debugging */
133                         fprintf( stderr,
134                             "must compile with LDAP_DEBUG for debugging\n" );
135                         break;
136 #endif
137
138                 case 'f':       /* read config file */
139                         configfile = ch_strdup( optarg );
140                         break;
141
142                 case 'i':       /* run from inetd */
143                         inetd = 1;
144                         break;
145
146                 case 'p': {     /* port on which to listen */
147                                 int port = atoi( optarg );
148                                 if(! port ) {
149                                         fprintf(stderr, "-p %s must be numeric\n", optarg);
150                                 } else {
151                                         bind_addr.sin_port = htons(port);
152                                 }
153                         } break;
154
155                 case 's':       /* set syslog level */
156                         ldap_syslog = atoi( optarg );
157                         break;
158
159 #ifdef LOG_LOCAL4
160                 case 'l':       /* set syslog local user */
161                         syslogUser = cnvt_str2int( optarg, syslog_types,
162                                            DEFAULT_SYSLOG_USER );
163                         break;
164 #endif
165
166                 case 'u':       /* do udp */
167                         udp = 1;
168                         break;
169
170 #ifdef SLAPD_BDB2
171                 case 't':  /* timed server */
172                         serverMode = SLAP_TIMEDSERVER_MODE;
173                         break;
174 #endif
175
176                 default:
177                         usage( argv[0] );
178                         exit( 1 );
179                 }
180         }
181
182         lber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug);
183         ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug);
184         ldif_debug = slap_debug;
185
186         Debug( LDAP_DEBUG_TRACE, "%s", Versionstr, 0, 0 );
187
188         if ( (serverName = strrchr( argv[0], '/' )) == NULL ) {
189                 serverName = ch_strdup( argv[0] );
190         } else {
191                 serverName = ch_strdup( serverName + 1 );
192         }
193
194 #ifdef LOG_LOCAL4
195         openlog( serverName, OPENLOG_OPTIONS, syslogUser );
196 #else
197         openlog( serverName, OPENLOG_OPTIONS );
198 #endif
199
200         if ( slap_init( serverMode, serverName ) != 0 ) {
201                 rc = 1;
202                 goto destroy;
203         }
204
205         if ( read_config( configfile ) != 0 ) {
206                 rc = 1;
207                 goto destroy;
208         }
209
210         if ( slap_startup(-1)  != 0 ) {
211                 rc = 1;
212                 goto shutdown;
213         }
214
215         if ( ! inetd ) {
216                 int             status;
217
218                 (void) SIGNAL( LDAP_SIGUSR1, slap_do_nothing );
219                 (void) SIGNAL( LDAP_SIGUSR2, slap_set_shutdown );
220 #ifdef SIGPIPE
221                 (void) SIGNAL( SIGPIPE, SIG_IGN );
222 #endif
223 #ifdef SIGHUP
224                 (void) SIGNAL( SIGHUP, slap_set_shutdown );
225 #endif
226                 (void) SIGNAL( SIGINT, slap_set_shutdown );
227                 (void) SIGNAL( SIGTERM, slap_set_shutdown );
228
229 #ifdef LDAP_DEBUG
230                 lutil_detach( ldap_debug, 0 );
231 #else
232                 lutil_detach( 0, 0 );
233 #endif
234
235                 time( &starttime );
236
237                 status = ldap_pvt_thread_create( &listener_tid, 0,
238                                                  slapd_daemon, &bind_addr );
239                 if ( status != 0 )
240                 {
241                         Debug( LDAP_DEBUG_ANY,
242                             "listener ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );
243
244                         rc = 1;
245
246                 } else {
247                         /* wait for the listener thread to complete */
248                         ldap_pvt_thread_join( listener_tid, (void *) NULL );
249                 }
250
251         } else {
252                 Connection              c;
253                 BerElement              ber;
254                 unsigned long           len, tag;
255                 long                    msgid;
256                 int                     flen;
257                 struct sockaddr_in      from;
258                 struct hostent          *hp;
259
260                 c.c_dn = NULL;
261                 c.c_cdn = NULL;
262                 c.c_ops = NULL;
263            
264                 lber_pvt_sb_init( &c.c_sb );
265                 lber_pvt_sb_set_desc( &c.c_sb, 0 );
266                 lber_pvt_sb_set_io( &c.c_sb, 
267                         (udp) ? &lber_pvt_sb_io_udp : &lber_pvt_sb_io_tcp, 
268                         NULL );
269                 /* FIXME: handle udp here */
270
271                 ldap_pvt_thread_mutex_init( &c.c_dnmutex );
272                 ldap_pvt_thread_mutex_init( &c.c_opsmutex );
273                 ldap_pvt_thread_mutex_init( &c.c_pdumutex );
274 #ifdef notdefcldap
275                 c.c_sb.sb_addrs = (void **) saddrlist;
276                 c.c_sb.sb_fromaddr = &faddr;
277                 c.c_sb.sb_useaddr = saddrlist[ 0 ] = &saddr;
278 #endif
279                 flen = sizeof(from);
280                 if ( getpeername( 0, (struct sockaddr *) &from, &flen ) == 0 ) {
281 #ifdef SLAPD_RLOOKUPS
282                         hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
283                             sizeof(from.sin_addr.s_addr), AF_INET );
284 #else
285                         hp = NULL;
286 #endif
287
288                         Debug( LDAP_DEBUG_ARGS, "connection from %s (%s)\n",
289                             hp == NULL ? "unknown" : hp->h_name,
290                             inet_ntoa( from.sin_addr ), 0 );
291
292                         c.c_addr = inet_ntoa( from.sin_addr );
293                         c.c_domain = ch_strdup( hp == NULL ? "" : hp->h_name );
294                 } else {
295                         Debug( LDAP_DEBUG_ARGS, "connection from unknown\n",
296                             0, 0, 0 );
297                 }
298
299                 c.c_state = SLAP_C_ACTIVE;
300
301                 ber_init_w_nullc( &ber, 0 );
302
303                 while ( (tag = ber_get_next( &c.c_sb, &len, &ber ))
304                     == LDAP_TAG_MESSAGE ) {
305                         ldap_pvt_thread_mutex_lock( &currenttime_mutex );
306                         time( &currenttime );
307                         ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
308
309                         if ( (tag = ber_get_int( &ber, &msgid ))
310                             != LDAP_TAG_MSGID ) {
311                                 /* log and send error */
312                                 Debug( LDAP_DEBUG_ANY,
313                                    "ber_get_int returns 0x%lx\n", tag, 0, 0 );
314                                 ber_free( &ber, 1 );
315                                 return 1;
316                         }
317
318                         if ( (tag = ber_peek_tag( &ber, &len ))
319                             == LBER_ERROR ) {
320                                 /* log, close and send error */
321                                 Debug( LDAP_DEBUG_ANY,
322                                    "ber_peek_tag returns 0x%lx\n", tag, 0, 0 );
323                                 ber_free( &ber, 1 );
324                                 lber_pvt_sb_close( &c.c_sb );
325                                 lber_pvt_sb_destroy( &c.c_sb );
326                                 return 1;
327                         }
328
329                         connection_activity( &c );
330
331                         ber_free( &ber, 1 );
332                 }
333         }
334
335 shutdown:
336         /* remember an error during shutdown */
337         rc |= slap_shutdown(-1);
338 destroy:
339         /* remember an error during destroy */
340         rc |= slap_destroy();
341
342         Debug( LDAP_DEBUG_ANY, "slapd stopped.\n", 0, 0, 0 );
343
344         return rc;
345 }
346
347
348 #ifdef LOG_LOCAL4
349
350 /*
351  *  Convert a string to an integer by means of a dispatcher table
352  *  if the string is not in the table return the default
353  */
354
355 static int
356 cnvt_str2int( char *stringVal, STRDISP_P dispatcher, int defaultVal )
357 {
358     int        retVal = defaultVal;
359     STRDISP_P  disp;
360
361     for (disp = dispatcher; disp->stringVal; disp++) {
362
363         if (!strncasecmp (stringVal, disp->stringVal, disp->abbr)) {
364
365             retVal = disp->intVal;
366             break;
367
368         }
369     }
370
371     return (retVal);
372
373 } /* cnvt_str2int */
374
375 #endif  /* LOG_LOCAL4 */
376