]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/main.c
ITS#4780 plug leak
[openldap] / servers / slapd / main.c
index 79a83434dbd7fcf38d585daca08b7489771b3159..877c04250311b9e4eca49a25040bb5ee9e360e23 100644 (file)
@@ -98,25 +98,23 @@ const char Versionstr[] =
        OPENLDAP_PACKAGE " " OPENLDAP_VERSION " Standalone LDAP Server (slapd)";
 #endif
 
-#define CHECK_NONE     0x00
-#define CHECK_CONFIG   0x01
+#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;
 
-#ifdef LOG_LOCAL4
-#define DEFAULT_SYSLOG_USER    LOG_LOCAL4
-#endif /* LOG_LOCAL4 */
-
 static int
 slapd_opt_slp( const char *val, void *arg )
 {
 #ifdef HAVE_SLP
        /* NULL is default */
-       if ( val == NULL || strcasecmp( val, "on" ) == 0 ) {
+       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;
@@ -155,12 +153,13 @@ struct option_helper {
        void            *oh_arg;
        const char      *oh_usage;
 } option_helpers[] = {
-       { BER_BVC("slp"),       slapd_opt_slp,  NULL, "slp[={on|off}] enable/disable SLP" },
+       { 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
-static int
+int
 parse_syslog_user( const char *arg, int *syslogUser )
 {
        static slap_verbmasks syslogUsers[] = {
@@ -180,12 +179,12 @@ parse_syslog_user( const char *arg, int *syslogUser )
 #endif /* LOG_DAEMON */
                { BER_BVNULL, 0 }
        };
-       int i = verb_to_mask( optarg, syslogUsers );
+       int i = verb_to_mask( arg, syslogUsers );
 
        if ( BER_BVISNULL( &syslogUsers[ i ].word ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "unrecognized syslog user \"%s\".\n",
-                       optarg, 0, 0 );
+                       arg, 0, 0 );
                return 1;
        }
 
@@ -195,7 +194,7 @@ parse_syslog_user( const char *arg, int *syslogUser )
 }
 #endif /* LOG_LOCAL4 */
 
-static int
+int
 parse_syslog_level( const char *arg, int *levelp )
 {
        static slap_verbmasks   str2syslog_level[] = {
@@ -221,6 +220,7 @@ parse_syslog_level( const char *arg, int *levelp )
 
        return 0;
 }
+#endif /* LDAP_DEBUG && LDAP_SYSLOG */
 
 int
 parse_debug_unknowns( char **unknowns, int *levelp )
@@ -349,7 +349,7 @@ int main( int argc, char **argv )
        char *sandbox = NULL;
 #endif
 #ifdef LOG_LOCAL4
-       int syslogUser = DEFAULT_SYSLOG_USER;
+       int syslogUser = SLAP_DEFAULT_SYSLOG_USER;
 #endif
        
        int g_argc = argc;
@@ -370,6 +370,7 @@ int main( int argc, char **argv )
        size_t  l;
 
        int slapd_pid_file_unlink = 0, slapd_args_file_unlink = 0;
+       int firstopt = 1;
 
 #ifdef CSRIMALLOC
        FILE *leakfile;
@@ -446,12 +447,12 @@ int main( int argc, char **argv )
 #ifdef HAVE_CHROOT
                                "r:"
 #endif
-#ifdef LDAP_SYSLOG
+#if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG)
                                "S:"
-#endif
 #ifdef LOG_LOCAL4
                                "l:"
 #endif
+#endif
 #if defined(HAVE_SETUID) && defined(HAVE_SETGID)
                                "u:g:"
 #endif
@@ -502,6 +503,11 @@ int main( int argc, char **argv )
                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;
@@ -558,6 +564,11 @@ int main( int argc, char **argv )
                }
 
                case 's':       /* set syslog level */
+                       if ( strcmp( optarg, "?" ) == 0 ) {
+                               check |= CHECK_LOGLEVEL;
+                               break;
+                       }
+
                        if ( parse_debug_level( optarg, &ldap_syslog, &syslog_unknowns ) ) {
                                goto destroy;
                        }
@@ -569,7 +580,6 @@ int main( int argc, char **argv )
                                goto destroy;
                        }
                        break;
-#endif /* LDAP_DEBUG && LDAP_SYSLOG */
 
 #ifdef LOG_LOCAL4
                case 'l':       /* set syslog local user */
@@ -578,6 +588,7 @@ int main( int argc, char **argv )
                        }
                        break;
 #endif
+#endif /* LDAP_DEBUG && LDAP_SYSLOG */
 
 #ifdef HAVE_CHROOT
                case 'r':
@@ -614,6 +625,12 @@ int main( int argc, char **argv )
                        break;
 
                case 'T':
+                       if ( firstopt == 0 ) {
+                               fprintf( stderr, "warning: \"-T %s\" "
+                                       "should be the first option.\n",
+                                       optarg );
+                       }
+
                        /* try full option string first */
                        for ( i = 0; tools[i].name; i++ ) {
                                if ( strcmp( optarg, &tools[i].name[4] ) == 0 ) {
@@ -644,6 +661,10 @@ unhandled_option:;
                        SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 15 );
                        goto stop;
                }
+
+               if ( firstopt ) {
+                       firstopt = 0;
+               }
        }
 
        ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug);
@@ -745,6 +766,11 @@ unhandled_option:;
                syslog_unknowns = NULL;
                if ( rc )
                        goto destroy;
+       }       
+
+       if ( check & CHECK_LOGLEVEL ) {
+               rc = 0;
+               goto destroy;
        }
 
        if ( check & CHECK_CONFIG ) {
@@ -915,6 +941,9 @@ shutdown:
        rc |= slap_shutdown( NULL );
 
 destroy:
+       if ( check & CHECK_LOGLEVEL ) {
+               (void)loglevel_print( stdout );
+       }
        /* remember an error during destroy */
        rc |= slap_destroy();
 
@@ -960,14 +989,15 @@ stop:
        lutil_passwd_destroy();
 
 #ifdef HAVE_TLS
-       /* Setting it to itself decreases refcount, allowing it to be freed
-        * when the LD is freed.
-        */
-       ldap_pvt_tls_set_option( slap_tls_ld, LDAP_OPT_X_TLS_CTX, slap_tls_ctx );
-       ldap_ld_free( slap_tls_ld, 0, NULL, NULL );
+       if ( slap_tls_ld ) {
+               SSL_CTX_free( slap_tls_ctx );
+               ldap_unbind_ext( slap_tls_ld, NULL, NULL );
+       }
        ldap_pvt_tls_destroy();
 #endif
 
+       slap_sasl_regexp_destroy();
+
        if ( slapd_pid_file_unlink ) {
                unlink( slapd_pid_file );
        }
@@ -984,6 +1014,9 @@ stop:
        if ( urls )
                ch_free( urls );
 
+       /* kludge, get symbols referenced */
+       tavl_free( NULL, NULL );
+
 #ifdef CSRIMALLOC
        mal_dumpleaktrace( leakfile );
 #endif