Hi,

in ldapd and ldapctl the "-r directory" command line argument does not
work:

ldapd fork/execs itself but the directory command line argument is not
given to the execvp call which then uses the default data directory.

ldapctl has a thinko/typo which causes the data_db to be always opened
in the default directory for indexing.

The patch below removes the command line argument and corresponding
global variable and instead uses a configuration file directive
"datadir".  Incidentally removes the global 'datadir' variable used
before.

Best regards
Robert


-----------------------------------------------
commit 6a71c90c19b5dc5850305c15696af3f14d26c168 (master)
from: Robert Klein <rokl...@roklein.de>
date: Mon Mar  2 18:50:12 2020 UTC
 
 fix ldapd/ldapctl data directory handling
 
 -r directive didn't work as intended in both
 ldapd and ldapctl.
 
 this patch replaces command line argument '-r directory'
 with a configuration file directive 'datadir'.
 
diff f62b80b397c780e8273b5cc67d544b951c4c9d1f 
35bb29194b2067dab925ec4566dfb82f9bf34d65
blob - 48cff01b435bca0deebf28f55e6f71675c5752f2
blob + 231af2ddbbee2da446d2f03c9c48e679e216e993
--- usr.sbin/ldapctl/ldapctl.8
+++ usr.sbin/ldapctl/ldapctl.8
@@ -24,7 +24,6 @@
 .Nm ldapctl
 .Op Fl v
 .Op Fl f Ar file
-.Op Fl r Ar directory
 .Op Fl s Ar socket
 .Ar command
 .Op Ar argument ...
@@ -42,11 +41,6 @@ Use
 .Ar file
 as the configuration file, instead of the default
 .Pa /etc/ldapd.conf .
-.It Fl r Ar directory
-Store and read database files in
-.Ar directory ,
-instead of the default
-.Pa /var/db/ldap .
 .It Fl s Ar socket
 Use
 .Ar socket
blob - c8564c5543f518a720e049c559556f87edda6b8a
blob + 6830a603d153794390faafbc9aadc8ef0bd985c0
--- usr.sbin/ldapctl/ldapctl.c
+++ usr.sbin/ldapctl/ldapctl.c
@@ -58,10 +58,10 @@ void                 show_stats(struct imsg *imsg);
 void            show_dbstats(const char *prefix, struct btree_stat *st);
 void            show_nsstats(struct imsg *imsg);
 int             compact_db(const char *path);
-int             compact_namespace(struct namespace *ns, const char *datadir);
-int             compact_namespaces(const char *datadir);
-int             index_namespace(struct namespace *ns, const char *datadir);
-int             index_namespaces(const char *datadir);
+int             compact_namespace(struct namespace *ns);
+int             compact_namespaces(void);
+int             index_namespace(struct namespace *ns);
+int             index_namespaces(void);
 int             ssl_load_certfile(struct ldapd_config *, const char *, 
u_int8_t);
 
 __dead void
@@ -70,7 +70,7 @@ usage(void)
        extern char *__progname;
 
        fprintf(stderr,
-           "usage: %s [-v] [-f file] [-r directory] [-s socket] "
+           "usage: %s [-v] [-f file] [-s socket] "
            "command [argument ...]\n",
            __progname);
        exit(1);
@@ -97,11 +97,11 @@ compact_db(const char *path)
 }
 
 int
-compact_namespace(struct namespace *ns, const char *datadir)
+compact_namespace(struct namespace *ns)
 {
        char            *path;
 
-       if (asprintf(&path, "%s/%s_data.db", datadir, ns->suffix) == -1)
+       if (asprintf(&path, "%s/%s_data.db", conf->datadir, ns->suffix) == -1)
                return -1;
        if (compact_db(path) != 0) {
                log_warn("%s", path);
@@ -110,7 +110,7 @@ compact_namespace(struct namespace *ns, const char *da
        }
        free(path);
 
-       if (asprintf(&path, "%s/%s_indx.db", datadir, ns->suffix) == -1)
+       if (asprintf(&path, "%s/%s_indx.db", conf->datadir, ns->suffix) == -1)
                return -1;
        if (compact_db(path) != 0) {
                log_warn("%s", path);
@@ -123,14 +123,14 @@ compact_namespace(struct namespace *ns, const char *da
 }
 
 int
-compact_namespaces(const char *datadir)
+compact_namespaces()
 {
        struct namespace        *ns;
 
        TAILQ_FOREACH(ns, &conf->namespaces, next) {
                if (SLIST_EMPTY(&ns->referrals))
                    continue;
-               if (compact_namespace(ns, datadir) != 0)
+               if (compact_namespace(ns) != 0)
                        return -1;
        }
 
@@ -138,7 +138,7 @@ compact_namespaces(const char *datadir)
 }
 
 int
-index_namespace(struct namespace *ns, const char *datadir)
+index_namespace(struct namespace *ns)
 {
        struct btval             key, val;
        struct btree            *data_db, *indx_db;
@@ -150,14 +150,14 @@ index_namespace(struct namespace *ns, const char *data
 
        log_info("indexing namespace %s", ns->suffix);
 
-       if (asprintf(&path, "%s/%s_data.db", DATADIR, ns->suffix) == -1)
+       if (asprintf(&path, "%s/%s_data.db", conf->datadir, ns->suffix) == -1)
                return -1;
        data_db = btree_open(path, BT_NOSYNC | BT_REVERSEKEY, 0644);
        free(path);
        if (data_db == NULL)
                return -1;
 
-       if (asprintf(&path, "%s/%s_indx.db", datadir, ns->suffix) == -1)
+       if (asprintf(&path, "%s/%s_indx.db", conf->datadir, ns->suffix) == -1)
                return -1;
        indx_db = btree_open(path, BT_NOSYNC, 0644);
        free(path);
@@ -219,14 +219,14 @@ index_namespace(struct namespace *ns, const char *data
 }
 
 int
-index_namespaces(const char *datadir)
+index_namespaces()
 {
        struct namespace        *ns;
 
        TAILQ_FOREACH(ns, &conf->namespaces, next) {
                if (SLIST_EMPTY(&ns->referrals))
                        continue;
-               if (index_namespace(ns, datadir) != 0)
+               if (index_namespace(ns) != 0)
                        return -1;
        }
 
@@ -247,7 +247,6 @@ main(int argc, char *argv[])
        ssize_t                  n;
        int                      ch;
        enum action              action = NONE;
-       const char              *datadir = DATADIR;
        struct stat              sb;
        const char              *sock = LDAPD_SOCKET;
        char                    *conffile = CONFFILE;
@@ -262,9 +261,6 @@ main(int argc, char *argv[])
                case 'f':
                        conffile = optarg;
                        break;
-               case 'r':
-                       datadir = optarg;
-                       break;
                case 's':
                        sock = optarg;
                        break;
@@ -282,11 +278,6 @@ main(int argc, char *argv[])
        if (argc == 0)
                usage();
 
-       if (stat(datadir, &sb) == -1)
-               err(1, "%s", datadir);
-       if (!S_ISDIR(sb.st_mode))
-               errx(1, "%s is not a directory", datadir);
-
        ldap_loginit(NULL, 1, verbose);
 
        if (strcmp(argv[0], "stats") == 0)
@@ -311,13 +302,22 @@ main(int argc, char *argv[])
                if (parse_config(conffile) != 0)
                        exit(2);
 
+               if (conf->datadir == NULL) {
+                       if (asprintf(&conf->datadir, "%s", LDAPD_DATADIR) == -1)
+                               errx(1, "malloc failed");
+               }
+               if (stat(conf->datadir, &sb) == -1)
+                       err(1, "%s", conf->datadir);
+               if (!S_ISDIR(sb.st_mode))
+                       errx(1, "%s is not a directory", conf->datadir);
+
                if (pledge("stdio rpath wpath cpath flock", NULL) == -1)
                        err(1, "pledge");
 
                if (action == COMPACT_DB)
-                       return compact_namespaces(datadir);
+                       return compact_namespaces();
                else
-                       return index_namespaces(datadir);
+                       return index_namespaces();
        }
 
        /* connect to ldapd control socket */
blob - db5a0be5ad93c11c0dd773d342ea131328dcaa82
blob + 8588bbe3dc5ffd81b91967cf809681b1998cbd69
--- usr.sbin/ldapd/ldapd.8
+++ usr.sbin/ldapd/ldapd.8
@@ -27,7 +27,6 @@
 .Fl D Ar macro Ns = Ns Ar value
 .Oc
 .Op Fl f Ar file
-.Op Fl r Ar directory
 .Op Fl s Ar file
 .Sh DESCRIPTION
 .Nm
@@ -61,11 +60,6 @@ as the configuration file, instead of the default
 .It Fl n
 Configtest mode.
 Only check the configuration file for validity.
-.It Fl r Ar directory
-Store and read database files in
-.Ar directory ,
-instead of the default
-.Pa /var/db/ldap .
 .It Fl s Ar file
 Specify an alternative location for the socket file.
 .It Fl v
blob - 797a36f89f33233c2d9655a307ec5e727b9fbaa1
blob + 69ae065ae99ba9ab326afd1fe0db5eeb820ea629
--- usr.sbin/ldapd/ldapd.c
+++ usr.sbin/ldapd/ldapd.c
@@ -55,7 +55,6 @@ static pid_t   start_child(enum ldapd_process, char *, 
 
 struct ldapd_stats      stats;
 pid_t                   ldape_pid;
-const char             *datadir = DATADIR;
 
 void
 usage(void)
@@ -63,7 +62,7 @@ usage(void)
        extern char     *__progname;
 
        fprintf(stderr, "usage: %s [-dnv] [-D macro=value] "
-           "[-f file] [-r directory] [-s file]\n", __progname);
+           "[-f file] [-s file]\n", __progname);
        exit(1);
 }
 
@@ -151,9 +150,6 @@ main(int argc, char *argv[])
                case 'n':
                        configtest = 1;
                        break;
-               case 'r':
-                       datadir = optarg;
-                       break;
                case 's':
                        csockpath = optarg;
                        break;
@@ -193,15 +189,20 @@ main(int argc, char *argv[])
                exit(0);
        }
 
+       if (conf->datadir == NULL) {
+               if (asprintf(&conf->datadir, "%s", LDAPD_DATADIR) == -1)
+                       errx(1, "malloc failed");
+       }
+
        log_init(debug, LOG_DAEMON);
 
        if (eflag)
                ldape(debug, verbose, csockpath);
 
-       if (stat(datadir, &sb) == -1)
-               err(1, "%s", datadir);
+       if (stat(conf->datadir, &sb) == -1)
+               err(1, "%s", conf->datadir);
        if (!S_ISDIR(sb.st_mode))
-               errx(1, "%s is not a directory", datadir);
+               errx(1, "%s is not a directory", conf->datadir);
 
        if (!debug) {
                if (daemon(1, 0) == -1)
@@ -213,7 +214,7 @@ main(int argc, char *argv[])
        if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
            PF_UNSPEC, pipe_parent2ldap) != 0)
                fatal("socketpair");
-       
+
        ldape_pid = start_child(PROC_LDAP_SERVER, saved_argv0,
            pipe_parent2ldap[1], debug, verbose, csockpath, conffile);
 
@@ -392,7 +393,7 @@ ldapd_open_request(struct imsgev *iev, struct imsg *im
        /* make sure path is null-terminated */
        oreq->path[PATH_MAX] = '\0';
 
-       if (strncmp(oreq->path, datadir, strlen(datadir)) != 0) {
+       if (strncmp(oreq->path, conf->datadir, strlen(conf->datadir)) != 0) {
                log_warnx("refusing to open file %s", oreq->path);
                fatal("ldape sent invalid open request");
        }
@@ -459,7 +460,7 @@ start_child(enum ldapd_process p, char *argv0, int fd,
                argv[argc++] = "-f";
                argv[argc++] = conffile;
        }
-       
+
        argv[argc++] = NULL;
 
        execvp(argv0, argv);
blob - 3da0137e137e8b3bc64f6351579fcd6a9344b1f8
blob + 31c894c3e39ab70f3324415ecac5efc1301e0a54
--- usr.sbin/ldapd/ldapd.conf.5
+++ usr.sbin/ldapd/ldapd.conf.5
@@ -130,6 +130,11 @@ The URL has the following format:
 ldap://ldap.example.com
 ldaps://ldap.example.com:3890
 .Ed
+.It datadir Ar directory
+Store and read database files in
+.Ar directory ,
+instead of the default
+.Pa /var/db/ldap .
 .It rootdn Ar dn
 Specify the distinguished name of the root user for all namespaces.
 The root user is always allowed to read and write entries in all
blob - 3f995d184b442f094a95f089e3bb4a727eabf559
blob + 2736d366bf5f92e3579f915f4ceb2a3610d27d54
--- usr.sbin/ldapd/ldapd.h
+++ usr.sbin/ldapd/ldapd.h
@@ -41,7 +41,7 @@
 #define CONFFILE                "/etc/ldapd.conf"
 #define LDAPD_USER              "_ldapd"
 #define LDAPD_SOCKET            "/var/run/ldapd.sock"
-#define DATADIR                         "/var/db/ldap"
+#define LDAPD_DATADIR           "/var/db/ldap"
 #define LDAP_PORT               389
 #define LDAPS_PORT              636
 #define LDAPD_SESSION_TIMEOUT   30
@@ -252,6 +252,7 @@ struct ldapd_config
        struct schema                   *schema;
        char                            *rootdn;
        char                            *rootpw;
+       char                            *datadir;
 };
 
 struct ldapd_stats
blob - 2259f57bde3c2918a8b200747c194e5768ae40f1
blob + 2e39abf6cc94ac6f301876df996a6229a032a7b7
--- usr.sbin/ldapd/namespace.c
+++ usr.sbin/ldapd/namespace.c
@@ -29,8 +29,6 @@
 #include "ldapd.h"
 #include "log.h"
 
-extern const char      *datadir;
-
 /* Maximum number of requests to queue per namespace during compaction.
  * After this many requests, we return LDAP_BUSY.
  */
@@ -118,7 +116,8 @@ namespace_open(struct namespace *ns)
        if (ns->sync == 0)
                db_flags |= BT_NOSYNC;
 
-       if (asprintf(&ns->data_path, "%s/%s_data.db", datadir, ns->suffix) == 
-1)
+       if (asprintf(&ns->data_path, "%s/%s_data.db", conf->datadir,
+           ns->suffix) == -1)
                return -1;
        log_info("opening namespace %s", ns->suffix);
        ns->data_db = btree_open(ns->data_path, db_flags | BT_REVERSEKEY, 0644);
@@ -127,7 +126,8 @@ namespace_open(struct namespace *ns)
 
        btree_set_cache_size(ns->data_db, ns->cache_size);
 
-       if (asprintf(&ns->indx_path, "%s/%s_indx.db", datadir, ns->suffix) == 
-1)
+       if (asprintf(&ns->indx_path, "%s/%s_indx.db", conf->datadir,
+           ns->suffix) == -1)
                return -1;
        ns->indx_db = btree_open(ns->indx_path, db_flags, 0644);
        if (ns->indx_db == NULL)
blob - bad9bc630403e5280e3b0db41d8ec1247db70352
blob + b72e4d89324b332498f8e5e0d1d8db822d4588f9
--- usr.sbin/ldapd/parse.y
+++ usr.sbin/ldapd/parse.y
@@ -117,7 +117,7 @@ static struct namespace *current_ns = NULL;
 %}
 
 %token ERROR LISTEN ON TLS LDAPS PORT NAMESPACE ROOTDN ROOTPW INDEX
-%token SECURE RELAX STRICT SCHEMA USE COMPRESSION LEVEL
+%token SECURE RELAX STRICT SCHEMA USE COMPRESSION LEVEL DATADIR
 %token INCLUDE CERTIFICATE FSYNC CACHE_SIZE INDEX_CACHE_SIZE
 %token DENY ALLOW READ WRITE BIND ACCESS TO ROOT REFERRAL
 %token ANY CHILDREN OF ATTRIBUTE IN SUBTREE BY SELF
@@ -225,6 +225,7 @@ conf_main   : LISTEN ON STRING port ssl certname    {
                        normalize_dn(conf->rootdn);
                }
                | ROOTPW STRING                 { conf->rootpw = $2; }
+               | DATADIR STRING                { conf->datadir = $2; }
                ;
 
 namespace      : NAMESPACE STRING '{' '\n'             {
@@ -441,6 +442,7 @@ lookup(char *s)
                { "certificate",        CERTIFICATE },
                { "children",           CHILDREN },
                { "compression",        COMPRESSION },
+               { "datadir",            DATADIR },
                { "deny",               DENY },
                { "fsync",              FSYNC },
                { "in",                 IN },

Reply via email to