]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/config.c
Fix compiler error and warnings.
[openldap] / servers / slapd / config.c
index 53b493ee856870e7fd5fd0849a6a3ef229dbb0be..4d60f6ef08cefca0756225a16acc79f86cdbe93b 100644 (file)
@@ -60,8 +60,6 @@ char  *global_host = NULL;
 char   *global_realm = NULL;
 char           *ldap_srvtab = "";
 char           **default_passwd_hash = NULL;
-char   *passwd_salt;
-char   *logfileName;
 struct berval default_search_base = BER_BVNULL;
 struct berval default_search_nbase = BER_BVNULL;
 
@@ -84,6 +82,9 @@ int use_reverse_lookup = 0;
 static char *replica_pidFile, *replica_argsFile;
 static int replicationInterval;
 
+static char    *passwd_salt;
+static char    *logfileName;
+
 #ifdef LDAP_SLAPI
 int slapi_plugins_used = 0;
 #endif
@@ -99,6 +100,7 @@ int read_config_file(const char *fname, int depth, ConfigArgs *cf);
 
 static int add_syncrepl LDAP_P(( Backend *, char **, int ));
 static int parse_syncrepl_line LDAP_P(( char **, int, syncinfo_t *));
+static void syncrepl_unparse LDAP_P (( syncinfo_t *, struct berval *));
 
 /* All of these table entries and handlers really belong
  * in back-config, only the parser/table engine belongs here.
@@ -226,13 +228,13 @@ static ConfigTable SystemConfiguration[] = {
                &config_generic, "( OLcfgAt:5 NAME 'olcAttributeOptions' "
                        "EQUALITY caseIgnoreMatch "
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
-       { "auth-rewrite", NULL, 2, 2, 14,
+       { "authid-rewrite", NULL, 2, 0, 0,
 #ifdef SLAP_AUTH_REWRITE
                ARG_MAGIC|CFG_REWRITE, &config_generic,
 #else
                ARG_IGNORED, NULL,
 #endif
-                "( OLcfgAt:6 NAME 'olcAuthRewrite' "
+                "( OLcfgAt:6 NAME 'olcAuthIDRewrite' "
                        "EQUALITY caseIgnoreMatch "
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
        { "authz-policy", "policy", 2, 2, 0, ARG_STRING|ARG_MAGIC|CFG_AZPOLICY,
@@ -428,7 +430,7 @@ static ConfigTable SystemConfiguration[] = {
 #endif
                "( OLcfgAt:54 NAME 'olcSaslRealm' "
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
-       { "sasl-regexp", NULL, 2, 2, 0, ARG_MAGIC|CFG_AZREGEXP,
+       { "sasl-regexp", NULL, 3, 3, 0, ARG_MAGIC|CFG_AZREGEXP,
                &config_generic, NULL, NULL, NULL },
        { "sasl-secprops", "properties", 2, 2, 0,
 #ifdef HAVE_CYRUS_SASL
@@ -438,7 +440,7 @@ static ConfigTable SystemConfiguration[] = {
 #endif
                "( OLcfgAt:56 NAME 'olcSaslSecProps' "
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
-       { "saslRegexp", NULL, 2, 2, 0, ARG_MAGIC|CFG_AZREGEXP,
+       { "saslRegexp", NULL, 3, 3, 0, ARG_MAGIC|CFG_AZREGEXP,
                &config_generic, NULL, NULL, NULL },
        { "schemacheck", "on|off", 2, 2, 0, ARG_ON_OFF|ARG_MAGIC|CFG_CHECK,
                &config_generic, "( OLcfgAt:57 NAME 'olcSchemaCheck' "
@@ -480,7 +482,7 @@ static ConfigTable SystemConfiguration[] = {
                        "SYNTAX OMsInteger )", NULL, NULL },
        { "TLSCACertificateFile", NULL, 0, 0, 0,
 #ifdef HAVE_TLS
-               CFG_TLS_CA_FILE|ARG_MAGIC, &config_tls_option,
+               CFG_TLS_CA_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
 #else
                ARG_IGNORED, NULL,
 #endif
@@ -488,7 +490,7 @@ static ConfigTable SystemConfiguration[] = {
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
        { "TLSCACertificatePath", NULL, 0, 0, 0,
 #ifdef HAVE_TLS
-               CFG_TLS_CA_PATH|ARG_MAGIC, &config_tls_option,
+               CFG_TLS_CA_PATH|ARG_STRING|ARG_MAGIC, &config_tls_option,
 #else
                ARG_IGNORED, NULL,
 #endif
@@ -496,7 +498,7 @@ static ConfigTable SystemConfiguration[] = {
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
        { "TLSCertificateFile", NULL, 0, 0, 0,
 #ifdef HAVE_TLS
-               CFG_TLS_CERT_FILE|ARG_MAGIC, &config_tls_option,
+               CFG_TLS_CERT_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
 #else
                ARG_IGNORED, NULL,
 #endif
@@ -504,7 +506,7 @@ static ConfigTable SystemConfiguration[] = {
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
        { "TLSCertificateKeyFile", NULL, 0, 0, 0,
 #ifdef HAVE_TLS
-               CFG_TLS_CERT_KEY|ARG_MAGIC, &config_tls_option,
+               CFG_TLS_CERT_KEY|ARG_STRING|ARG_MAGIC, &config_tls_option,
 #else
                ARG_IGNORED, NULL,
 #endif
@@ -512,7 +514,7 @@ static ConfigTable SystemConfiguration[] = {
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
        { "TLSCipherSuite",     NULL, 0, 0, 0,
 #ifdef HAVE_TLS
-               CFG_TLS_CIPHER|ARG_MAGIC, &config_tls_option,
+               CFG_TLS_CIPHER|ARG_STRING|ARG_MAGIC, &config_tls_option,
 #else
                ARG_IGNORED, NULL,
 #endif
@@ -520,7 +522,7 @@ static ConfigTable SystemConfiguration[] = {
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
        { "TLSCRLCheck", NULL, 0, 0, 0,
 #ifdef HAVE_TLS
-               CFG_TLS_CRLCHECK|ARG_MAGIC, &config_tls_config,
+               CFG_TLS_CRLCHECK|ARG_STRING|ARG_MAGIC, &config_tls_config,
 #else
                ARG_IGNORED, NULL,
 #endif
@@ -528,7 +530,7 @@ static ConfigTable SystemConfiguration[] = {
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
        { "TLSRandFile", NULL, 0, 0, 0,
 #ifdef HAVE_TLS
-               CFG_TLS_RAND|ARG_MAGIC, &config_tls_option,
+               CFG_TLS_RAND|ARG_STRING|ARG_MAGIC, &config_tls_option,
 #else
                ARG_IGNORED, NULL,
 #endif
@@ -536,7 +538,7 @@ static ConfigTable SystemConfiguration[] = {
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
        { "TLSVerifyClient", NULL, 0, 0, 0,
 #ifdef HAVE_TLS
-               CFG_TLS_VERIFY|ARG_MAGIC, &config_tls_config,
+               CFG_TLS_VERIFY|ARG_STRING|ARG_MAGIC, &config_tls_config,
 #else
                ARG_IGNORED, NULL,
 #endif
@@ -752,7 +754,7 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c)
                if (( cf->arg_type & ARGS_POINTER ) == ARG_STRING )
                        ber_bvarray_add(&c->rvalue_vals, &bv);
                else
-                       value_add(&c->rvalue_vals, &bv);
+                       value_add_one(&c->rvalue_vals, &bv);
        }
        return rc;
 }
@@ -979,7 +981,7 @@ config_generic(ConfigArgs *c) {
                        else
                                rc = 1;
                        break;
-               case CFG_LIMITS:
+               case CFG_LIMITS:        /* FIXME */
                        rc = 1;
                        break;
                case CFG_RO:
@@ -992,14 +994,14 @@ config_generic(ConfigArgs *c) {
                        rc = 1;
                        break;
 #ifdef HAVE_CYRUS_SASL
-               case CFG_SASLSECP:
+               case CFG_SASLSECP:      /* FIXME */
                        rc = 1;
                        break;
 #endif
                case CFG_DEPTH:
                        c->value_int = c->be->be_max_deref_depth;
                        break;
-               case CFG_OID:
+               case CFG_OID:   /* FIXME */
                        rc = 1;
                        break;
                case CFG_CHECK:
@@ -1059,18 +1061,18 @@ config_generic(ConfigArgs *c) {
                        c->value_int = index_substr_if_minlen;
                        break;
 #ifdef SLAPD_MODULES
-               case CFG_MODLOAD:
+               case CFG_MODLOAD:       /* FIXME */
                case CFG_MODPATH:
                        rc = 1;
                        break;
 #endif
 #ifdef LDAP_SLAPI
-               case CFG_PLUGIN:
+               case CFG_PLUGIN:        /* FIXME */
                        rc = 1;
                        break;
 #endif
 #ifdef SLAP_AUTH_REWRITE
-               case CFG_REWRITE:
+               case CFG_REWRITE:       /* FIXME */
                        rc = 1;
                        break;
 #endif
@@ -1224,12 +1226,12 @@ config_generic(ConfigArgs *c) {
                        break;
 
                case CFG_LOGFILE: {
-                       if ( logfileName ) ch_free( logfileName );
-                       logfileName = c->value_string;
-                       FILE *logfile = fopen(logfileName, "w");
-                       if(logfile) lutil_debug_file(logfile);
-                       break;
-                       }
+                               FILE *logfile;
+                               if ( logfileName ) ch_free( logfileName );
+                               logfileName = c->value_string;
+                               logfile = fopen(logfileName, "w");
+                               if(logfile) lutil_debug_file(logfile);
+                       } break;
 
                case CFG_LASTMOD:
                        if(SLAP_NOLASTMODCMD(c->be)) {
@@ -1419,7 +1421,7 @@ config_sizelimit(ConfigArgs *c) {
        int i, rc = 0;
        char *next;
        struct slap_limits_set *lim = &c->be->be_def_limit;
-       if (c->emit) {
+       if (c->emit) {  /* FIXME */
                return 1;
        }
        for(i = 1; i < c->argc; i++) {
@@ -1459,7 +1461,7 @@ config_timelimit(ConfigArgs *c) {
        char *next;
        struct slap_limits_set *lim = &c->be->be_def_limit;
        if (c->emit) {
-               return 1;
+               return 1;       /* FIXME */
        }
        for(i = 1; i < c->argc; i++) {
                if(!strncasecmp(c->argv[i], "time", 4)) {
@@ -1611,6 +1613,7 @@ verbs_to_mask(ConfigArgs *c, struct verb_mask_list *v, slap_mask_t *m) {
        for(i = 1; i < c->argc; i++) {
                j = verb_to_mask(c, v, i);
                if(!v[j].word) return(1);
+               while (!v[j].mask) j--;
                *m |= v[j].mask;
        }
        return(0);
@@ -1623,8 +1626,8 @@ mask_to_verbs(ConfigArgs *c, struct verb_mask_list *v, slap_mask_t m) {
 
        if (!m) return 1;
        for (i=0; v[i].word; i++) {
-               if ( v[i].mask == -1 && m != v[i].mask ) continue;
-               if ( m & v[i].mask ) {
+               if (!v[i].mask) continue;
+               if (( m & v[i].mask ) == v[i].mask ) {
                        ber_str2bv( v[i].word, 0, 0, &bv );
                        value_add_one( &c->rvalue_vals, &bv );
                }
@@ -1640,8 +1643,8 @@ config_restrict(ConfigArgs *c) {
                { "bind",               SLAP_RESTRICT_OP_BIND },
                { "add",                SLAP_RESTRICT_OP_ADD },
                { "modify",             SLAP_RESTRICT_OP_MODIFY },
-               { "modrdn",             SLAP_RESTRICT_OP_RENAME },
                { "rename",             SLAP_RESTRICT_OP_RENAME },
+               { "modrdn",             0 },
                { "delete",             SLAP_RESTRICT_OP_DELETE },
                { "search",             SLAP_RESTRICT_OP_SEARCH },
                { "compare",    SLAP_RESTRICT_OP_COMPARE },
@@ -1808,6 +1811,12 @@ config_loglevel(ConfigArgs *c) {
 static int
 config_syncrepl(ConfigArgs *c) {
        if (c->emit) {
+               if ( c->be->be_syncinfo ) {
+                       struct berval bv;
+                       syncrepl_unparse( c->be->be_syncinfo, &bv ); 
+                       ber_bvarray_add( &c->rvalue_vals, &bv );
+                       return 0;
+               }
                return 1;
        }
        if(SLAP_SHADOW(c->be)) {
@@ -1846,45 +1855,59 @@ config_referral(ConfigArgs *c) {
        return(0);
 }
 
+static struct {
+       struct berval key;
+       int off;
+} sec_keys[] = {
+       { BER_BVC("ssf="), offsetof(slap_ssf_set_t, sss_ssf) },
+       { BER_BVC("transport="), offsetof(slap_ssf_set_t, sss_transport) },
+       { BER_BVC("tls="), offsetof(slap_ssf_set_t, sss_tls) },
+       { BER_BVC("sasl="), offsetof(slap_ssf_set_t, sss_sasl) },
+       { BER_BVC("update_ssf="), offsetof(slap_ssf_set_t, sss_update_ssf) },
+       { BER_BVC("update_transport="), offsetof(slap_ssf_set_t, sss_update_transport) },
+       { BER_BVC("update_tls="), offsetof(slap_ssf_set_t, sss_update_tls) },
+       { BER_BVC("update_sasl="), offsetof(slap_ssf_set_t, sss_update_sasl) },
+       { BER_BVC("simple_bind="), offsetof(slap_ssf_set_t, sss_simple_bind) },
+       { BER_BVNULL, 0 }
+};
+
 static int
 config_security(ConfigArgs *c) {
        slap_ssf_set_t *set = &c->be->be_ssf_set;
        char *next;
-       int i;
+       int i, j;
        if (c->emit) {
-               return 1;
+               char numbuf[32];
+               struct berval bv;
+               slap_ssf_t *tgt;
+               int rc = 1;
+
+               for (i=0; !BER_BVISNULL( &sec_keys[i].key ); i++) {
+                       tgt = (slap_ssf_t *)((char *)set + sec_keys[i].off);
+                       if ( *tgt ) {
+                               rc = 0;
+                               bv.bv_len = sprintf( numbuf, "%u", *tgt );
+                               bv.bv_len += sec_keys[i].key.bv_len;
+                               bv.bv_val = ch_malloc( bv.bv_len + 1);
+                               next = lutil_strcopy( bv.bv_val, sec_keys[i].key.bv_val );
+                               strcpy( next, numbuf );
+                               ber_bvarray_add( &c->rvalue_vals, &bv );
+                       }
+               }
+               return rc;
        }
        for(i = 1; i < c->argc; i++) {
-               slap_ssf_t *tgt;
+               slap_ssf_t *tgt = NULL;
                char *src;
-               if(!strncasecmp(c->argv[i], "ssf=", 4)) {
-                       tgt = &set->sss_ssf;
-                       src = &c->argv[i][4];
-               } else if(!strncasecmp(c->argv[i], "transport=", 10)) {
-                       tgt = &set->sss_transport;
-                       src = &c->argv[i][10];
-               } else if(!strncasecmp(c->argv[i], "tls=", 4)) {
-                       tgt = &set->sss_tls;
-                       src = &c->argv[i][4];
-               } else if(!strncasecmp(c->argv[i], "sasl=", 5)) {
-                       tgt = &set->sss_sasl;
-                       src = &c->argv[i][5];
-               } else if(!strncasecmp(c->argv[i], "update_ssf=", 11)) {
-                       tgt = &set->sss_update_ssf;
-                       src = &c->argv[i][11];
-               } else if(!strncasecmp(c->argv[i], "update_transport=", 17)) {
-                       tgt = &set->sss_update_transport;
-                       src = &c->argv[i][17];
-               } else if(!strncasecmp(c->argv[i], "update_tls=", 11)) {
-                       tgt = &set->sss_update_tls;
-                       src = &c->argv[i][11];
-               } else if(!strncasecmp(c->argv[i], "update_sasl=", 12)) {
-                       tgt = &set->sss_update_sasl;
-                       src = &c->argv[i][12];
-               } else if(!strncasecmp(c->argv[i], "simple_bind=", 12)) {
-                       tgt = &set->sss_simple_bind;
-                       src = &c->argv[i][12];
-               } else {
+               for ( j=0; !BER_BVISNULL( &sec_keys[j].key ); j++ ) {
+                       if(!strncasecmp(c->argv[i], sec_keys[j].key.bv_val,
+                               sec_keys[j].key.bv_len)) {
+                               src = c->argv[i] + sec_keys[j].key.bv_len;
+                               tgt = (slap_ssf_t *)((char *)set + sec_keys[j].off);
+                               break;
+                       }
+               }
+               if ( !tgt ) {
                        Debug(LDAP_DEBUG_ANY, "%s: "
                                "unknown factor %s in \"security <factors>\" line\n",
                                c->log, c->argv[i], 0);
@@ -1902,13 +1925,207 @@ config_security(ConfigArgs *c) {
        return(0);
 }
 
+static struct verb_mask_list tlskey[] = {
+       { "no",         SB_TLS_OFF },
+       { "yes",                SB_TLS_ON },
+       { "critical",   SB_TLS_CRITICAL }
+};
+
+static struct verb_mask_list methkey[] = {
+       { "simple",     LDAP_AUTH_SIMPLE },
+#ifdef HAVE_CYRUS_SASL
+       { "sasl",       LDAP_AUTH_SASL },
+#endif
+       { NULL, 0 }
+};
+
+typedef struct cf_aux_table {
+       struct berval key;
+       int off;
+       int quote;
+       struct verb_mask_list *aux;
+} cf_aux_table;
+
+static cf_aux_table bindkey[] = {
+       { BER_BVC("starttls="), offsetof(slap_bindconf, sb_tls), 0, tlskey },
+       { BER_BVC("bindmethod="), offsetof(slap_bindconf, sb_method), 0, methkey },
+       { BER_BVC("binddn="), offsetof(slap_bindconf, sb_binddn), 1, NULL },
+       { BER_BVC("credentials="), offsetof(slap_bindconf, sb_cred), 1, NULL },
+       { BER_BVC("saslmech="), offsetof(slap_bindconf, sb_saslmech), 0, NULL },
+       { BER_BVC("secprops="), offsetof(slap_bindconf, sb_secprops), 0, NULL },
+       { BER_BVC("realm="), offsetof(slap_bindconf, sb_realm), 0, NULL },
+       { BER_BVC("authcID="), offsetof(slap_bindconf, sb_authcId), 0, NULL },
+       { BER_BVC("authzID="), offsetof(slap_bindconf, sb_authzId), 1, NULL },
+       { BER_BVNULL, 0, 0, NULL }
+};
+
+int bindconf_parse( char *word, slap_bindconf *bc ) {
+       int i, rc = 0;
+       char **cptr;
+       cf_aux_table *tab;
+
+       for (tab = bindkey; !BER_BVISNULL(&tab->key); tab++) {
+               if ( !strncasecmp( word, tab->key.bv_val, tab->key.bv_len )) {
+                       cptr = (char **)((char *)bc + tab->off);
+                       if ( tab->aux ) {
+                               int j;
+                               rc = 1;
+                               for (j=0; tab->aux[j].word; j++) {
+                                       if (!strcasecmp(word+tab->key.bv_len, tab->aux[j].word)) {
+                                               int *ptr = (int *)cptr;
+                                               *ptr = tab->aux[j].mask;
+                                               rc = 0;
+                                       }
+                               }
+                               if (rc ) {
+                                       Debug(LDAP_DEBUG_ANY, "invalid bind config value %s\n",
+                                               word, 0, 0 );
+                               }
+                               return rc;
+                       }
+                       *cptr = ch_strdup(word+tab->key.bv_len);
+                       return 0;
+               }
+       }
+       return rc;
+}
+
+int bindconf_unparse( slap_bindconf *bc, struct berval *bv ) {
+       char buf[BUFSIZ], *ptr;
+       cf_aux_table *tab;
+       char **cptr;
+       struct berval tmp;
+
+       ptr = buf;
+       for (tab = bindkey; !BER_BVISNULL(&tab->key); tab++) {
+               cptr = (char **)((char *)bc + tab->off);
+               if ( tab->aux ) {
+                       int *ip = (int *)cptr, i;
+                       for ( i=0; tab->aux[i].word; i++ ) {
+                               if ( *ip == tab->aux[i].mask ) {
+                                       *ptr++ = ' ';
+                                       ptr = lutil_strcopy( ptr, tab->key.bv_val );
+                                       ptr = lutil_strcopy( ptr, tab->aux[i].word );
+                                       break;
+                               }
+                       }
+               } else if ( *cptr ) {
+                       *ptr++ = ' ';
+                       ptr = lutil_strcopy( ptr, tab->key.bv_val );
+                       if ( tab->quote ) *ptr++ = '"';
+                       ptr = lutil_strcopy( ptr, *cptr );
+                       if ( tab->quote ) *ptr++ = '"';
+               }
+       }
+       tmp.bv_val = buf;
+       tmp.bv_len = ptr - buf;
+       ber_dupbv( bv, &tmp );
+       return 0;
+}
+
+void bindconf_free( slap_bindconf *bc ) {
+       if ( bc->sb_binddn ) {
+               ch_free( bc->sb_binddn );
+       }
+       if ( bc->sb_cred ) {
+               ch_free( bc->sb_cred );
+       }
+       if ( bc->sb_saslmech ) {
+               ch_free( bc->sb_saslmech );
+       }
+       if ( bc->sb_secprops ) {
+               ch_free( bc->sb_secprops );
+       }
+       if ( bc->sb_realm ) {
+               ch_free( bc->sb_realm );
+       }
+       if ( bc->sb_authcId ) {
+               ch_free( bc->sb_authcId );
+       }
+       if ( bc->sb_authzId ) {
+               ch_free( bc->sb_authzId );
+       }
+}
+
+static char *
+anlist_unparse( AttributeName *an, char *ptr ) {
+       int comma = 0;
+
+       for (; !BER_BVISNULL( &an->an_name ); an++) {
+               if ( comma ) *ptr++ = ',';
+               ptr = lutil_strcopy( ptr, an->an_name.bv_val );
+               comma = 1;
+       }
+       return ptr;
+}
+
+static void
+replica_unparse( struct slap_replica_info *ri, int i, struct berval *bv )
+{
+       int len;
+       char *ptr;
+       struct berval bc = {0};
+       char numbuf[32];
+
+       len = sprintf(numbuf, "{%d}", i );
+
+       len += strlen( ri->ri_uri ) + STRLENOF("uri=");
+       if ( ri->ri_nsuffix ) {
+               for (i=0; !BER_BVISNULL( &ri->ri_nsuffix[i] ); i++) {
+                       len += ri->ri_nsuffix[i].bv_len + STRLENOF(" suffix=\"\"");
+               }
+       }
+       if ( ri->ri_attrs ) {
+               len += STRLENOF("attr");
+               if ( ri->ri_exclude ) len++;
+               for (i=0; !BER_BVISNULL( &ri->ri_attrs[i].an_name ); i++) {
+                       len += 1 + ri->ri_attrs[i].an_name.bv_len;
+               }
+       }
+       bindconf_unparse( &ri->ri_bindconf, &bc );
+       len += bc.bv_len;
+
+       bv->bv_val = ch_malloc(len + 1);
+       bv->bv_len = len;
+
+       ptr = lutil_strcopy( bv->bv_val, numbuf );
+       ptr = lutil_strcopy( ptr, "uri=" );
+       ptr = lutil_strcopy( ptr, ri->ri_uri );
+
+       if ( ri->ri_nsuffix ) {
+               for (i=0; !BER_BVISNULL( &ri->ri_nsuffix[i] ); i++) {
+                       ptr = lutil_strcopy( ptr, " suffix=\"" );
+                       ptr = lutil_strcopy( ptr, ri->ri_nsuffix[i].bv_val );
+                       *ptr++ = '"';
+               }
+       }
+       if ( ri->ri_attrs ) {
+               ptr = lutil_strcopy( ptr, "attr" );
+               if ( ri->ri_exclude ) *ptr++ = '!';
+               *ptr++ = '=';
+               ptr = anlist_unparse( ri->ri_attrs, ptr );
+       }
+       if ( bc.bv_val ) {
+               strcpy( ptr, bc.bv_val );
+               ch_free( bc.bv_val );
+       }
+}
+
 static int
 config_replica(ConfigArgs *c) {
-       int i, nr = -1;
-       char *replicahost, *replicalog = NULL;
+       int i, nr = -1, len;
+       char *replicahost, *replicauri;
        LDAPURLDesc *ludp;
 
        if (c->emit) {
+               if (c->be->be_replica) {
+                       struct berval bv;
+                       for (i=0;c->be->be_replica[i]; i++) {
+                               replica_unparse( c->be->be_replica[i], i, &bv );
+                               ber_bvarray_add( &c->rvalue_vals, &bv );
+                       }
+                       return 0;
+               }
                return 1;
        }
        if(SLAP_MONITOR(c->be)) {
@@ -1920,8 +2137,12 @@ config_replica(ConfigArgs *c) {
 
        for(i = 1; i < c->argc; i++) {
                if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) {
-                       replicalog = c->argv[i] + STRLENOF("host=");
-                       nr = add_replica_info(c->be, c->argv[i] + STRLENOF("host="));
+                       replicahost = c->argv[i] + STRLENOF("host=");
+                       len = strlen( replicahost );
+                       replicauri = ch_malloc( len + STRLENOF("ldap://") + 1 );
+                       sprintf( replicauri, "ldap://%s", replicahost );
+                       replicahost = replicauri + STRLENOF( "ldap://");
+                       nr = add_replica_info(c->be, replicauri, replicahost);
                        break;
                } else if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
                        if(ldap_url_parse(c->argv[i] + STRLENOF("uri="), &ludp) != LDAP_SUCCESS) {
@@ -1937,18 +2158,12 @@ config_replica(ConfigArgs *c) {
                                        c->log, 0, 0);
                                return(1);
                        }
-                       replicahost = ch_malloc(strlen(c->argv[i]));
-                       if(!replicahost) {
-                               Debug(LDAP_DEBUG_ANY,
-                                       "out of memory in read_config\n", 0, 0, 0);
-                               ldap_free_urldesc(ludp);
-                               exit(EXIT_FAILURE);
-                       }
-                       sprintf(replicahost, "%s:%d", ludp->lud_host, ludp->lud_port);
-                       replicalog = c->argv[i] + STRLENOF("uri=");
-                       nr = add_replica_info(c->be, replicahost);
                        ldap_free_urldesc(ludp);
-                       ch_free(replicahost);
+                       replicauri = c->argv[i] + STRLENOF("uri=");
+                       replicauri = ch_strdup( replicauri );
+                       replicahost = strchr( replicauri, '/' );
+                       replicahost += 2;
+                       nr = add_replica_info(c->be, replicauri, replicahost);
                        break;
                }
        }
@@ -1960,7 +2175,7 @@ config_replica(ConfigArgs *c) {
        } else if(nr == -1) {
                Debug(LDAP_DEBUG_ANY, "%s: "
                        "unable to add replica \"%s\"\n",
-                       c->log, replicalog, 0);
+                       c->log, replicauri, 0);
                return(1);
        } else {
                for(i = 1; i < c->argc; i++) {
@@ -1994,6 +2209,9 @@ config_replica(ConfigArgs *c) {
                                                c->log, arg + 1, 0);
                                        return(1);
                                }
+                       } else if ( bindconf_parse( c->argv[i],
+                                       &c->be->be_replica[nr]->ri_bindconf ) ) {
+                               return(1);
                        }
                }
        }
@@ -2047,7 +2265,7 @@ config_updateref(ConfigArgs *c) {
        }
        if(!SLAP_SHADOW(c->be)) {
                Debug(LDAP_DEBUG_ANY, "%s: "
-                       "updateref line must after syncrepl or updatedn.\n",
+                       "updateref line must come after syncrepl or updatedn.\n",
                        c->log, 0, 0);
                return(1);
        }
@@ -2064,8 +2282,6 @@ config_updateref(ConfigArgs *c) {
        return(0);
 }
 
-/* XXX meaningless in ldif */
-
 static int
 config_include(ConfigArgs *c) {
        unsigned long savelineno = c->lineno;
@@ -2101,33 +2317,61 @@ config_tls_option(ConfigArgs *c) {
        int flag;
        switch(c->type) {
        case CFG_TLS_RAND:              flag = LDAP_OPT_X_TLS_RANDOM_FILE;      break;
-       case CFG_TLS_CIPHER:            flag = LDAP_OPT_X_TLS_CIPHER_SUITE;     break;
+       case CFG_TLS_CIPHER:    flag = LDAP_OPT_X_TLS_CIPHER_SUITE;     break;
        case CFG_TLS_CERT_FILE: flag = LDAP_OPT_X_TLS_CERTFILE;         break;  
        case CFG_TLS_CERT_KEY:  flag = LDAP_OPT_X_TLS_KEYFILE;          break;
        case CFG_TLS_CA_PATH:   flag = LDAP_OPT_X_TLS_CACERTDIR;        break;
        case CFG_TLS_CA_FILE:   flag = LDAP_OPT_X_TLS_CACERTFILE;       break;
-               default:                Debug(LDAP_DEBUG_ANY, "%s: "
-                                               "unknown tls_option <%x>\n",
-                                               c->log, c->type, 0);
+       default:                Debug(LDAP_DEBUG_ANY, "%s: "
+                                       "unknown tls_option <%x>\n",
+                                       c->log, c->type, 0);
        }
        if (c->emit) {
-               return 1;
+               return ldap_pvt_tls_get_option( NULL, flag, &c->value_string );
        }
+       ch_free(c->value_string);
        return(ldap_pvt_tls_set_option(NULL, flag, c->argv[1]));
 }
 
+/* FIXME: this ought to be provided by libldap */
 static int
 config_tls_config(ConfigArgs *c) {
        int i, flag;
-       if (c->emit) {
-               return 1;
-       }
+       struct verb_mask_list crlkeys[] = {
+               { "none",       LDAP_OPT_X_TLS_CRL_NONE },
+               { "peer",       LDAP_OPT_X_TLS_CRL_PEER },
+               { "all",        LDAP_OPT_X_TLS_CRL_ALL },
+               { NULL, 0 }
+       };
+       struct verb_mask_list vfykeys[] = {
+               { "never",      LDAP_OPT_X_TLS_NEVER },
+               { "demand",     LDAP_OPT_X_TLS_DEMAND },
+               { "try",        LDAP_OPT_X_TLS_TRY },
+               { "hard",       LDAP_OPT_X_TLS_HARD },
+               { NULL, 0 }
+       }, *keys;
        switch(c->type) {
 #ifdef HAVE_OPENSSL_CRL
-       case CFG_TLS_CRLCHECK:  flag = LDAP_OPT_X_TLS_CRLCHECK;         break;
+       case CFG_TLS_CRLCHECK:  flag = LDAP_OPT_X_TLS_CRLCHECK; keys = crlkeys;
+               break;
 #endif
-       case CFG_TLS_VERIFY:    flag = LDAP_OPT_X_TLS_REQUIRE_CERT;     break;
+       case CFG_TLS_VERIFY:    flag = LDAP_OPT_X_TLS_REQUIRE_CERT; keys = vfykeys;
+               break;
+       default:                Debug(LDAP_DEBUG_ANY, "%s: "
+                                       "unknown tls_option <%x>\n",
+                                       c->log, c->type, 0);
+       }
+       if (c->emit) {
+               ldap_pvt_tls_get_option( NULL, flag, &c->value_int );
+               for (i=0; keys[i].word; i++) {
+                       if (keys[i].mask == c->value_int) {
+                               c->value_string = ch_strdup( keys[i].word );
+                               return 0;
+                       }
+               }
+               return 1;
        }
+       ch_free( c->value_string );
        if(isdigit((unsigned char)c->argv[1][0])) {
                i = atoi(c->argv[1]);
                return(ldap_pvt_tls_set_option(NULL, flag, &i));
@@ -2336,8 +2580,8 @@ add_syncrepl(
                return 1;
        }
 
-       si->si_tls = SYNCINFO_TLS_OFF;
-       si->si_bindmethod = LDAP_AUTH_SIMPLE;
+       si->si_bindconf.sb_tls = SB_TLS_OFF;
+       si->si_bindconf.sb_method = LDAP_AUTH_SIMPLE;
        si->si_schemachecking = 0;
        ber_str2bv( "(objectclass=*)", STRLENOF("(objectclass=*)"), 1,
                &si->si_filterstr );
@@ -2396,23 +2640,10 @@ add_syncrepl(
 #define SLIMITSTR              "sizelimit"
 #define TLIMITSTR              "timelimit"
 #define SCHEMASTR              "schemachecking"
-#define BINDMETHSTR            "bindmethod"
-#define SIMPLESTR                      "simple"
-#define SASLSTR                                "sasl"
-#define BINDDNSTR              "binddn"
-#define SASLMECHSTR            "saslmech"
-#define AUTHCSTR               "authcID"
-#define AUTHZSTR               "authzID"
-#define CREDSTR                        "credentials"
-#define REALMSTR               "realm"
-#define SECPROPSSTR            "secprops"
 
 /* FIXME: undocumented */
 #define OLDAUTHCSTR            "bindprincipal"
-#define STARTTLSSTR            "starttls"
-#define CRITICALSTR                    "critical"
 #define EXATTRSSTR             "exattrs"
-#define MANAGEDSAITSTR         "manageDSAit"
 #define RETRYSTR               "retry"
 
 /* FIXME: unused */
@@ -2422,15 +2653,28 @@ add_syncrepl(
 #define LMREQSTR               "req"
 #define SRVTABSTR              "srvtab"
 #define SUFFIXSTR              "suffix"
-#define UPDATEDNSTR            "updatedn"
+#define MANAGEDSAITSTR         "manageDSAit"
 
 /* mandatory */
 #define GOT_ID                 0x0001
 #define GOT_PROVIDER           0x0002
-#define GOT_METHOD             0x0004
 
 /* check */
-#define GOT_ALL                        (GOT_ID|GOT_PROVIDER|GOT_METHOD)
+#define GOT_ALL                        (GOT_ID|GOT_PROVIDER)
+
+static struct {
+       struct berval key;
+       int val;
+} scopes[] = {
+       { BER_BVC("base"), LDAP_SCOPE_BASE },
+       { BER_BVC("one"), LDAP_SCOPE_ONELEVEL },
+#ifdef LDAP_SCOPE_SUBORDINATE
+       { BER_BVC("children"), LDAP_SCOPE_SUBORDINATE },
+       { BER_BVC("subordinate"), 0 },
+#endif
+       { BER_BVC("sub"), LDAP_SCOPE_SUBTREE },
+       { BER_BVNULL, 0 }
+};
 
 static int
 parse_syncrepl_line(
@@ -2464,79 +2708,6 @@ parse_syncrepl_line(
                        val = cargv[ i ] + STRLENOF( PROVIDERSTR "=" );
                        ber_str2bv( val, 0, 1, &si->si_provideruri );
                        gots |= GOT_PROVIDER;
-               } else if ( !strncasecmp( cargv[ i ], STARTTLSSTR "=",
-                                       STRLENOF(STARTTLSSTR "=") ) )
-               {
-                       val = cargv[ i ] + STRLENOF( STARTTLSSTR "=" );
-                       if( !strcasecmp( val, CRITICALSTR ) ) {
-                               si->si_tls = SYNCINFO_TLS_CRITICAL;
-                       } else {
-                               si->si_tls = SYNCINFO_TLS_ON;
-                       }
-               } else if ( !strncasecmp( cargv[ i ], BINDMETHSTR "=",
-                               STRLENOF( BINDMETHSTR "=" ) ) )
-               {
-                       val = cargv[ i ] + STRLENOF( BINDMETHSTR "=" );
-                       if ( !strcasecmp( val, SIMPLESTR )) {
-                               si->si_bindmethod = LDAP_AUTH_SIMPLE;
-                               gots |= GOT_METHOD;
-                       } else if ( !strcasecmp( val, SASLSTR )) {
-#ifdef HAVE_CYRUS_SASL
-                               si->si_bindmethod = LDAP_AUTH_SASL;
-                               gots |= GOT_METHOD;
-#else /* HAVE_CYRUS_SASL */
-                               fprintf( stderr, "Error: parse_syncrepl_line: "
-                                       "not compiled with SASL support\n" );
-                               return -1;
-#endif /* HAVE_CYRUS_SASL */
-                       } else {
-                               si->si_bindmethod = -1;
-                       }
-               } else if ( !strncasecmp( cargv[ i ], BINDDNSTR "=",
-                                       STRLENOF( BINDDNSTR "=" ) ) )
-               {
-                       val = cargv[ i ] + STRLENOF( BINDDNSTR "=" );
-                       si->si_binddn = ch_strdup( val );
-               } else if ( !strncasecmp( cargv[ i ], CREDSTR "=",
-                                       STRLENOF( CREDSTR "=" ) ) )
-               {
-                       val = cargv[ i ] + STRLENOF( CREDSTR "=" );
-                       si->si_passwd = ch_strdup( val );
-               } else if ( !strncasecmp( cargv[ i ], SASLMECHSTR "=",
-                                       STRLENOF( SASLMECHSTR "=" ) ) )
-               {
-                       val = cargv[ i ] + STRLENOF( SASLMECHSTR "=" );
-                       si->si_saslmech = ch_strdup( val );
-               } else if ( !strncasecmp( cargv[ i ], SECPROPSSTR "=",
-                                       STRLENOF( SECPROPSSTR "=" ) ) )
-               {
-                       val = cargv[ i ] + STRLENOF( SECPROPSSTR "=" );
-                       si->si_secprops = ch_strdup( val );
-               } else if ( !strncasecmp( cargv[ i ], REALMSTR "=",
-                                       STRLENOF( REALMSTR "=" ) ) )
-               {
-                       val = cargv[ i ] + STRLENOF( REALMSTR "=" );
-                       si->si_realm = ch_strdup( val );
-               } else if ( !strncasecmp( cargv[ i ], AUTHCSTR "=",
-                                       STRLENOF( AUTHCSTR "=" ) ) )
-               {
-                       val = cargv[ i ] + STRLENOF( AUTHCSTR "=" );
-                       if ( si->si_authcId )
-                               ch_free( si->si_authcId );
-                       si->si_authcId = ch_strdup( val );
-               } else if ( !strncasecmp( cargv[ i ], OLDAUTHCSTR "=",
-                                       STRLENOF( OLDAUTHCSTR "=" ) ) ) 
-               {
-                       /* Old authcID is provided for some backwards compatibility */
-                       val = cargv[ i ] + STRLENOF( OLDAUTHCSTR "=" );
-                       if ( si->si_authcId )
-                               ch_free( si->si_authcId );
-                       si->si_authcId = ch_strdup( val );
-               } else if ( !strncasecmp( cargv[ i ], AUTHZSTR "=",
-                                       STRLENOF( AUTHZSTR "=" ) ) )
-               {
-                       val = cargv[ i ] + STRLENOF( AUTHZSTR "=" );
-                       si->si_authzId = ch_strdup( val );
                } else if ( !strncasecmp( cargv[ i ], SCHEMASTR "=",
                                        STRLENOF( SCHEMASTR "=" ) ) )
                {
@@ -2573,20 +2744,17 @@ parse_syncrepl_line(
                } else if ( !strncasecmp( cargv[ i ], SCOPESTR "=",
                                        STRLENOF( SCOPESTR "=" ) ) )
                {
+                       int j;
                        val = cargv[ i ] + STRLENOF( SCOPESTR "=" );
-                       if ( !strncasecmp( val, "base", STRLENOF( "base" ) )) {
-                               si->si_scope = LDAP_SCOPE_BASE;
-                       } else if ( !strncasecmp( val, "one", STRLENOF( "one" ) )) {
-                               si->si_scope = LDAP_SCOPE_ONELEVEL;
-#ifdef LDAP_SCOPE_SUBORDINATE
-                       } else if ( !strcasecmp( val, "subordinate" ) ||
-                               !strcasecmp( val, "children" ))
-                       {
-                               si->si_scope = LDAP_SCOPE_SUBORDINATE;
-#endif
-                       } else if ( !strncasecmp( val, "sub", STRLENOF( "sub" ) )) {
-                               si->si_scope = LDAP_SCOPE_SUBTREE;
-                       } else {
+                       for ( j=0; !BER_BVISNULL(&scopes[j].key); j++ ) {
+                               if (!strncasecmp( val, scopes[j].key.bv_val,
+                                       scopes[j].key.bv_len )) {
+                                       while (!scopes[j].val) j--;
+                                       si->si_scope = scopes[j].val;
+                                       break;
+                               }
+                       }
+                       if ( BER_BVISNULL(&scopes[j].key) ) {
                                fprintf( stderr, "Error: parse_syncrepl_line: "
                                        "unknown scope \"%s\"\n", val);
                                return -1;
@@ -2607,7 +2775,7 @@ parse_syncrepl_line(
                                        ch_free( attr_fname );
                                        return -1;
                                }
-                               ch_free( attr_fname );
+                               si->si_anfile = attr_fname;
                        } else {
                                char *str, *s, *next;
                                char delimstr[] = " ,\t";
@@ -2784,7 +2952,7 @@ parse_syncrepl_line(
                {
                        val = cargv[ i ] + STRLENOF( TLIMITSTR "=" );
                        si->si_tlimit = atoi( val );
-               } else {
+               } else if ( bindconf_parse( cargv[i], &si->si_bindconf )) {
                        fprintf( stderr, "Error: parse_syncrepl_line: "
                                "unknown keyword \"%s\"\n", cargv[ i ] );
                        return -1;
@@ -2800,6 +2968,119 @@ parse_syncrepl_line(
        return 0;
 }
 
+
+
+static void
+syncrepl_unparse( syncinfo_t *si, struct berval *bv )
+{
+       struct berval bc;
+       char buf[BUFSIZ*2], *ptr;
+       int i, len;
+
+       bindconf_unparse( &si->si_bindconf, &bc );
+       ptr = buf;
+       ptr += sprintf( ptr, IDSTR "=%03d " PROVIDERSTR "=%s",
+               si->si_rid, si->si_provideruri.bv_val );
+       if ( !BER_BVISNULL( &bc )) {
+               ptr = lutil_strcopy( ptr, bc.bv_val );
+               free( bc.bv_val );
+       }
+       if ( !BER_BVISEMPTY( &si->si_filterstr )) {
+               ptr = lutil_strcopy( ptr, " " FILTERSTR "=\"" );
+               ptr = lutil_strcopy( ptr, si->si_filterstr.bv_val );
+               *ptr++ = '"';
+       }
+       if ( !BER_BVISNULL( &si->si_base )) {
+               ptr = lutil_strcopy( ptr, " " SEARCHBASESTR "=\"" );
+               ptr = lutil_strcopy( ptr, si->si_base.bv_val );
+               *ptr++ = '"';
+       }
+       for (i=0; !BER_BVISNULL(&scopes[i].key);i++) {
+               if ( si->si_scope == scopes[i].val ) {
+                       ptr = lutil_strcopy( ptr, " " SCOPESTR "=" );
+                       ptr = lutil_strcopy( ptr, scopes[i].key.bv_val );
+                       break;
+               }
+       }
+       if ( si->si_attrsonly ) {
+               ptr = lutil_strcopy( ptr, " " ATTRSONLYSTR "=yes" );
+       }
+       if ( si->si_anfile ) {
+               ptr = lutil_strcopy( ptr, " " ATTRSSTR "=:include:" );
+               ptr = lutil_strcopy( ptr, si->si_anfile );
+       } else if ( si->si_allattrs || si->si_allopattrs ||
+               ( si->si_anlist && !BER_BVISNULL(&si->si_anlist[0].an_name) )) {
+               char *old;
+               ptr = lutil_strcopy( ptr, " " ATTRSSTR "=\"" );
+               old = ptr;
+               ptr = anlist_unparse( si->si_anlist, ptr );
+               if ( si->si_allattrs ) {
+                       if ( old != ptr ) *ptr++ = ',';
+                       *ptr++ = '*';
+               }
+               if ( si->si_allopattrs ) {
+                       if ( old != ptr ) *ptr++ = ',';
+                       *ptr++ = '+';
+               }
+               *ptr++ = '"';
+       }
+       if ( si->si_exanlist && !BER_BVISNULL(&si->si_exanlist[0].an_name) ) {
+               ptr = lutil_strcopy( ptr, " " EXATTRSSTR "=" );
+               ptr = anlist_unparse( si->si_exanlist, ptr );
+       }
+       ptr = lutil_strcopy( ptr, " " SCHEMASTR "=" );
+       ptr = lutil_strcopy( ptr, si->si_schemachecking ? "on" : "off" );
+       
+       ptr = lutil_strcopy( ptr, " " TYPESTR "=" );
+       ptr = lutil_strcopy( ptr, si->si_type == LDAP_SYNC_REFRESH_AND_PERSIST ?
+               "refreshAndPersist" : "refreshOnly" );
+
+       if ( si->si_type == LDAP_SYNC_REFRESH_ONLY ) {
+               int dd, hh, mm, ss;
+
+               dd = si->si_interval;
+               ss = dd % 60;
+               dd /= 60;
+               mm = dd % 60;
+               dd /= 60;
+               hh = dd % 24;
+               dd /= 24;
+               ptr = lutil_strcopy( ptr, " " INTERVALSTR "=" );
+               ptr += sprintf( ptr, "%02d:%02d:%02d:%02d", dd, hh, mm, ss );
+       } else if ( si->si_retryinterval ) {
+               int space=0;
+               ptr = lutil_strcopy( ptr, " " RETRYSTR "=\"" );
+               for (i=0; si->si_retryinterval[i]; i++) {
+                       if ( space ) *ptr++ = ' ';
+                       space = 1;
+                       ptr += sprintf( ptr, "%d", si->si_retryinterval[i] );
+                       if ( si->si_retrynum_init[i] == -1 )
+                               *ptr++ = '+';
+                       else
+                               ptr += sprintf( ptr, "%d", si->si_retrynum_init );
+               }
+               *ptr++ = '"';
+       }
+
+#if 0 /* FIXME: unused in syncrepl.c, should remove it */
+       ptr = lutil_strcopy( ptr, " " MANAGEDSAITSTR "=" );
+       ptr += sprintf( ptr, "%d", si->si_manageDSAit );
+#endif
+
+       if ( si->si_slimit ) {
+               ptr = lutil_strcopy( ptr, " " SLIMITSTR "=" );
+               ptr += sprintf( ptr, "%d", si->si_slimit );
+       }
+
+       if ( si->si_tlimit ) {
+               ptr = lutil_strcopy( ptr, " " TLIMITSTR "=" );
+               ptr += sprintf( ptr, "%d", si->si_tlimit );
+       }
+       bc.bv_len = ptr - buf;
+       bc.bv_val = buf;
+       ber_dupbv( bv, &bc );
+}
+
 char **
 slap_str2clist( char ***out, char *in, const char *brkstr )
 {