Support for using $u username variable in AFP volume definitions
authorRalph Boehme <rb@sernet.de>
Wed, 19 Feb 2014 15:19:42 +0000 (16:19 +0100)
committerRalph Boehme <rb@sernet.de>
Tue, 20 May 2014 16:33:32 +0000 (18:33 +0200)
* Prepare CNID backend dbd for user variable expansion
* Store a struct vol pointer in the CNID db handles.
* Pass three arguments to the CNID daemon:
  - the afp.conf volume section name
  - the volume path
  - an optional username

* Rename several struct elements by prefixing them with a struct tag,
  helps catching bad or missing assignments.

* Disable uniconv, doesn't use laod_volumes() and thus wont work with
  the new CNID dbd backend.

From FR#90.

Signed-off-by: Ralph Boehme <rb@sernet.de>
40 files changed:
NEWS
bin/Makefile.am
bin/ad/ad_util.c
doc/manpages/man1/dbd.1.xml
doc/manpages/man5/afp.conf.5.xml
etc/afpd/file.c
etc/afpd/volume.c
etc/cnid_dbd/cmd_dbd.c
etc/cnid_dbd/cnid_metad.c
etc/cnid_dbd/main.c
include/atalk/cnid.h
include/atalk/cnid_bdb_private.h
include/atalk/cnid_mysql_private.h
include/atalk/cnid_private.h
include/atalk/util.h
libatalk/cnid/cdb/cnid_cdb_add.c
libatalk/cnid/cdb/cnid_cdb_close.c
libatalk/cnid/cdb/cnid_cdb_delete.c
libatalk/cnid/cdb/cnid_cdb_get.c
libatalk/cnid/cdb/cnid_cdb_lookup.c
libatalk/cnid/cdb/cnid_cdb_open.c
libatalk/cnid/cdb/cnid_cdb_rebuild_add.c
libatalk/cnid/cdb/cnid_cdb_resolve.c
libatalk/cnid/cdb/cnid_cdb_update.c
libatalk/cnid/cnid.c
libatalk/cnid/dbd/cnid_dbd.c
libatalk/cnid/last/cnid_last.c
libatalk/cnid/mysql/cnid_mysql.c
libatalk/cnid/tdb/cnid_tdb_add.c
libatalk/cnid/tdb/cnid_tdb_close.c
libatalk/cnid/tdb/cnid_tdb_delete.c
libatalk/cnid/tdb/cnid_tdb_get.c
libatalk/cnid/tdb/cnid_tdb_lookup.c
libatalk/cnid/tdb/cnid_tdb_open.c
libatalk/cnid/tdb/cnid_tdb_resolve.c
libatalk/cnid/tdb/cnid_tdb_update.c
libatalk/util/netatalk_conf.c
libatalk/util/unix.c
man/man1/dbd.1.in
man/man5/afp.conf.5.in

diff --git a/NEWS b/NEWS
index afbc751af26cb161876c6a750d0765d4834e8240..7e85ab8f2ec11fd496ce28b11c751efe1156a031 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,8 @@ Changes in 3.1.2
 * FIX: put the Solaris share reservation after our locking stuff, bug #560.
 * UPD: Improve Linux quota behaviour
 * FIX: xattrs on *BSD, bug #562
+* NEW: afpd: support for using $u username variable in AFP volume
+       definitions. FR#90.
 
 Changes in 3.1.1
 ================
index f5d1448ae3621d70a8241af4864a925335693e68..9aedd4b694a2989e3c8a792205e297bbb0176c28 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile.am for bin/
 
-SUBDIRS = afppasswd cnid megatron uniconv misc
+SUBDIRS = afppasswd cnid megatron misc
 
 if HAVE_ATFUNCS
 SUBDIRS += ad
index 782bbffa6c7a0042f7f97c6c02e732e67ef32ea9..27f42b052cec9faff446681358ede8d251d8c557 100644 (file)
@@ -124,13 +124,9 @@ int openvol(AFPObj *obj, const char *path, afpvol_t *vol)
     if ((vol->vol->v_flags & AFPVOL_NODEV))
         flags |= CNID_FLAG_NODEV;
 
-    if ((vol->vol->v_cdb = cnid_open(vol->vol->v_path,
-                                     0000,
+    if ((vol->vol->v_cdb = cnid_open(vol->vol,
                                      "dbd",
-                                     flags,
-                                     vol->vol->v_cnidserver,
-                                     vol->vol->v_cnidport,
-                                     NULL, NULL)) == NULL)
+                                     flags)) == NULL)
         ERROR("Cant initialize CNID database connection for %s", vol->vol->v_path);
 
     cnid_getstamp(vol->vol->v_cdb,
index 36b7aba02b2c2e0edd7fa0b25aa8afe5997b335e..467537896e0447490a6335325b49ee99cc54bffb 100644 (file)
@@ -22,7 +22,7 @@
           <primary>dbd</primary>
         </indexterm></command>
 
-      <arg choice="opt">-fsv</arg>
+      <arg choice="opt">-cfFstuvV</arg>
 
       <arg choice="plain"><replaceable>volumepath</replaceable></arg>
     </cmdsynopsis>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term>-u</term>
+
+        <listitem>
+          <para>username for use with AFP volumes using user variable $u</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term>-v</term>
 
index cc46ce99880afd23d7b36b35167d772de81ff224..b6094c4e0769f0e5c89f606f9d0e7c3c6be97dc4 100644 (file)
     <title>VARIABLE SUBSTITUTIONS</title>
 
     <para>You can use variables in volume names. The use of variables in paths
-    is not supported for now.</para>
+     is limited to $u.</para>
 
     <orderedlist>
       <listitem>
index cb8a968af09ddf491721b18b6b691f0fa97b62ce..9c78b1b2f3f4baaf1ade8e468ab65f584a42ece0 100644 (file)
@@ -252,7 +252,7 @@ restart:
                     }
                     LOG(log_error, logtype_afpd, "Reopen volume %s using in memory temporary CNID DB.",
                         vol->v_path);
-                    vol->v_cdb = cnid_open(vol->v_path, vol->v_umask, "tdb", flags, NULL, NULL, NULL, NULL);
+                    vol->v_cdb = cnid_open(vol, "tdb", flags);
                     if (vol->v_cdb) {
                         if (!(vol->v_flags & AFPVOL_TM)) {
                             vol->v_flags |= AFPVOL_RO;
@@ -1662,7 +1662,7 @@ int afp_createid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
         return( AFPERR_PARAM);
     }
 
-    if (vol->v_cdb == NULL || !(vol->v_cdb->flags & CNID_FLAG_PERSISTENT)) {
+    if (vol->v_cdb == NULL || !(vol->v_cdb->cnid_db_flags & CNID_FLAG_PERSISTENT)) {
         return AFPERR_NOOP;
     }
 
@@ -1801,7 +1801,7 @@ int afp_resolveid(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_
         return( AFPERR_PARAM);
     }
 
-    if (vol->v_cdb == NULL || !(vol->v_cdb->flags & CNID_FLAG_PERSISTENT)) {
+    if (vol->v_cdb == NULL || !(vol->v_cdb->cnid_db_flags & CNID_FLAG_PERSISTENT)) {
         return AFPERR_NOOP;
     }
 
@@ -1909,7 +1909,7 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
         return( AFPERR_PARAM);
     }
 
-    if (vol->v_cdb == NULL || !(vol->v_cdb->flags & CNID_FLAG_PERSISTENT)) {
+    if (vol->v_cdb == NULL || !(vol->v_cdb->cnid_db_flags & CNID_FLAG_PERSISTENT)) {
         return AFPERR_NOOP;
     }
 
index a3ee79278763d198029af7c35a0be3260cae17a2..7bdff75dff53ecf87007a9b001a45c87bae944de 100644 (file)
@@ -369,7 +369,7 @@ static int getvolparams(const AFPObj *obj, uint16_t bitmap, struct vol *vol, str
             }
             /* prior 2.1 only VOLPBIT_ATTR_RO is defined */
             if (obj->afp_version > 20) {
-                if (vol->v_cdb != NULL && (vol->v_cdb->flags & CNID_FLAG_PERSISTENT))
+                if (vol->v_cdb != NULL && (vol->v_cdb->cnid_db_flags & CNID_FLAG_PERSISTENT))
                     ashort |= VOLPBIT_ATTR_FILEID;
                 ashort |= VOLPBIT_ATTR_CATSEARCH;
 
@@ -639,16 +639,7 @@ static int volume_openDB(const AFPObj *obj, struct vol *volume)
         flags |= CNID_FLAG_NODEV;
     }
 
-    LOG(log_debug, logtype_afpd, "CNID server: %s:%s", volume->v_cnidserver, volume->v_cnidport);
-
-    volume->v_cdb = cnid_open(volume->v_path,
-                              volume->v_umask,
-                              volume->v_cnidscheme,
-                              flags,
-                              volume->v_cnidserver,
-                              volume->v_cnidport,
-                              (const void *)obj,
-                              volume->v_uuid);
+    volume->v_cdb = cnid_open(volume, volume->v_cnidscheme, flags);
 
     if ( ! volume->v_cdb && ! (flags & CNID_FLAG_MEMORY)) {
         /* The first attempt failed and it wasn't yet an attempt to open in-memory */
@@ -657,7 +648,7 @@ static int volume_openDB(const AFPObj *obj, struct vol *volume)
         LOG(log_error, logtype_afpd, "Reopen volume %s using in memory temporary CNID DB.",
             volume->v_path);
         flags |= CNID_FLAG_MEMORY;
-        volume->v_cdb = cnid_open (volume->v_path, volume->v_umask, "tdb", flags, NULL, NULL, NULL, NULL);
+        volume->v_cdb = cnid_open(volume, "tdb", flags);
 #ifdef SERVERTEXT
         /* kill ourself with SIGUSR2 aka msg pending */
         if (volume->v_cdb) {
@@ -855,7 +846,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
          * fixing the trash at DID 17.
          * FIXME (RL): should it be done inside a CNID backend ? (always returning Trash DID when asked) ?
          */
-        if ((volume->v_cdb->flags & CNID_FLAG_PERSISTENT)) {
+        if ((volume->v_cdb->cnid_db_flags & CNID_FLAG_PERSISTENT)) {
 
             /* FIXME find db time stamp */
             if (cnid_getstamp(volume->v_cdb, volume->v_stamp, sizeof(volume->v_stamp)) < 0) {
index 266b986ba00da9905c56777b4ac5dff6f50b4625..17df52a90f1a76fcd2d5473b0aec010c17b20e94 100644 (file)
@@ -25,6 +25,7 @@
 #include <signal.h>
 #include <string.h>
 #include <errno.h>
+#include <pwd.h>
 
 #include <atalk/logger.h>
 #include <atalk/globals.h>
@@ -103,6 +104,7 @@ static void usage (void)
            "   -F location of the afp.conf config file\n"
            "   -f delete and recreate CNID database\n"
            "   -t show statistics while running\n"
+           "   -u username for use with AFP volumes using user variable $u\n"
            "   -v verbose\n"
            "   -V show version info\n\n"
         );
@@ -136,9 +138,9 @@ int main(int argc, char **argv)
     AFPObj obj = { 0 };
     struct vol *vol = NULL;
     const char *volpath = NULL;
-
+    char *username;
     int c;
-    while ((c = getopt(argc, argv, ":cfF:rstvV")) != -1) {
+    while ((c = getopt(argc, argv, ":cfF:rstu:vV")) != -1) {
         switch(c) {
         case 'c':
             flags |= DBD_FLAGS_V2TOEA;
@@ -159,6 +161,9 @@ int main(int argc, char **argv)
         case 't':
             flags |= DBD_FLAGS_STATS;
             break;
+        case 'u':
+            username = strdup(optarg);
+            break;
         case 'v':
             flags |= DBD_FLAGS_VERBOSE;
             break;
@@ -203,6 +208,7 @@ int main(int argc, char **argv)
         exit(EXIT_FAILURE);
     }
 
+
     /* Initialize CNID subsystem */
     cnid_init();
 
@@ -212,6 +218,18 @@ int main(int argc, char **argv)
     else
         setuplog("default:note", "/dev/tty");
 
+    /* Set username */
+    if (username) {
+        strncpy(obj.username, username, MAXUSERLEN);
+        struct passwd *pwd;
+        pwd = getpwnam(obj.username);
+        if (!pwd) {
+            dbd_log( LOGSTD, "unknown user");
+            exit(EXIT_FAILURE);
+        }
+        obj.uid = pwd->pw_uid;
+    }
+
     if (load_volumes(&obj, lv_all) != 0) {
         dbd_log( LOGSTD, "Couldn't load volumes");
         exit(EXIT_FAILURE);
@@ -232,14 +250,9 @@ int main(int argc, char **argv)
         dbd_log(LOGSTD, "\"%s\" isn't a \"dbd\" CNID volume", vol->v_path);
         exit(EXIT_FAILURE);
     }
-    if ((vol->v_cdb = cnid_open(vol->v_path,
-                                0000,
-                                vol->v_cnidscheme,
-                                vol->v_flags & AFPVOL_NODEV ? CNID_FLAG_NODEV : 0,
-                                vol->v_cnidserver,
-                                vol->v_cnidport,
-                                &obj,
-                                vol->v_uuid)) == NULL) {
+    vol->v_cdb = cnid_open(vol, vol->v_cnidscheme,
+                           vol->v_flags & AFPVOL_NODEV ? CNID_FLAG_NODEV : 0);
+    if (vol->v_cdb == NULL) {
         dbd_log(LOGSTD, "Cant initialize CNID database connection for %s", vol->v_path);
         exit(EXIT_FAILURE);
     }
index 1b991cb8bf39d5f89a86d4f3c849e3d63b4379ce..b05d72db61cf4d1d3cd76711f129ba50079d9358 100644 (file)
@@ -155,8 +155,17 @@ static struct server *test_usockfn(const char *path)
     return NULL;
 }
 
-/* -------------------- */
-static int maybe_start_dbd(const AFPObj *obj, char *dbdpn, const char *volpath)
+/**
+ * Pass connection request to existing cnid_dbd process or start a new one
+ *
+ * @param[in] obj      handle
+ * @param[in] dbdpn    Path to cnid_dbd binary
+ * @param[in] volpath  Path of AFP volume
+ * @param[in] username  Optional username, may be NULL
+ *
+ * @return 0 on success, -1 on error
+ **/
+ int maybe_start_dbd(const AFPObj *obj, char *dbdpn, const char *volpath, const char *username)
 {
     pid_t pid;
     struct server *up;
@@ -266,9 +275,21 @@ static int maybe_start_dbd(const AFPObj *obj, char *dbdpn, const char *volpath)
             LOG(log_warning, logtype_cnid,
                 "Multiple attempts to start CNID db daemon for \"%s\" failed, wiping the slate clean...",
                 up->v_path);
-            ret = execlp(dbdpn, dbdpn, "-F", obj->options.configfile, "-p", volpath, "-t", buf1, "-l", buf2, "-d", NULL);
+            ret = execlp(dbdpn, dbdpn,
+                         "-F", obj->options.configfile,
+                         "-p", volpath,
+                         "-t", buf1,
+                         "-l", buf2,
+                         "-u", username,
+                         NULL);
         } else {
-            ret = execlp(dbdpn, dbdpn, "-F", obj->options.configfile, "-p", volpath, "-t", buf1, "-l", buf2, NULL);
+            ret = execlp(dbdpn, dbdpn,
+                         "-F", obj->options.configfile,
+                         "-p", volpath,
+                         "-t", buf1,
+                         "-l", buf2,
+                         "-u", username,
+                         NULL);
         }
         /* Yikes! We're still here, so exec failed... */
         LOG(log_error, logtype_cnid, "Fatal error in exec: %s", strerror(errno));
@@ -419,11 +440,23 @@ static int setlimits(void)
     return 0;
 }
 
+static uid_t uid_from_name(const char *name)
+{
+    struct passwd *pwd;
+
+    pwd = getpwnam(name);
+    if (pwd == NULL)
+        return 0;
+    return pwd->pw_uid;
+}
+
 /* ------------------ */
 int main(int argc, char *argv[])
 {
-    char  volpath[MAXPATHLEN + 1];
-    int   len, actual_len;
+    char  *volname = NULL;
+    char  *volpath = NULL;
+    char  *username = NULL;
+    int   len[DBD_NUM_OPEN_ARGS], actual_len;
     pid_t pid;
     int   status;
     char  *dbdpn = _PATH_CNID_DBD;
@@ -463,9 +496,6 @@ int main(int argc, char *argv[])
     if (afp_config_parse(&obj, "cnid_metad") != 0)
         daemon_exit(1);
 
-    if (load_volumes(&obj, lv_all) != 0)
-        daemon_exit(1);
-
     (void)setlimits();
 
     host = atalk_iniparser_getstrdup(obj.iniconfig, INISEC_GLOBAL, "cnid listen", "localhost:4700");
@@ -529,7 +559,7 @@ int main(int argc, char *argv[])
         if (rqstfd <= 0)
             continue;
 
-        ret = readt(rqstfd, &len, sizeof(int), 1, 4);
+        ret = readt(rqstfd, &len[0], sizeof(int) * DBD_NUM_OPEN_ARGS, 1, 4);
 
         if (!ret) {
             /* already close */
@@ -539,31 +569,58 @@ int main(int argc, char *argv[])
             LOG(log_severe, logtype_cnid, "error read: %s", strerror(errno));
             goto loop_end;
         }
-        else if (ret != sizeof(int)) {
+        else if (ret != DBD_NUM_OPEN_ARGS * sizeof(int)) {
             LOG(log_error, logtype_cnid, "short read: got %d", ret);
             goto loop_end;
         }
+
         /*
          *  checks for buffer overruns. The client libatalk side does it too
          *  before handing the dir path over but who trusts clients?
          */
-        if (!len || len +DBHOMELEN +2 > MAXPATHLEN) {
-            LOG(log_error, logtype_cnid, "wrong len parameter: %d", len);
+        if (!len[0] || !len[1]) {
+            LOG(log_error, logtype_cnid, "wrong len parameter: len[0]: %d, len[1]: %d", len[0], len[1]);
             goto loop_end;
         }
 
-        actual_len = readt(rqstfd, volpath, len, 1, 5);
-        if (actual_len < 0) {
-            LOG(log_severe, logtype_cnid, "Read(2) error : %s", strerror(errno));
+        volname = malloc(len[0]);
+        volpath = malloc(len[1]);
+        if (len[2]) {
+            username = malloc(len[2]);
+        }
+        if (!volname || !volpath || (len[2] && !username)) {
+            LOG(log_severe, logtype_cnid, "malloc: %s", strerror(errno));
             goto loop_end;
         }
-        if (actual_len != len) {
-            LOG(log_error, logtype_cnid, "error/short read (dir): %s", strerror(errno));
+
+        actual_len = readt(rqstfd, volname, len[0], 1, 5);
+        if (actual_len != len[0]) {
+            LOG(log_severe, logtype_cnid, "readt: %s", strerror(errno));
+            goto loop_end;
+        }
+
+        actual_len = readt(rqstfd, volpath, len[1], 1, 5);
+        if (actual_len != len[1]) {
+            LOG(log_severe, logtype_cnid, "readt: %s", strerror(errno));
             goto loop_end;
         }
-        volpath[len] = '\0';
 
-        LOG(log_debug, logtype_cnid, "main: request for volume: %s", volpath);
+        if (len[2]) {
+            actual_len = readt(rqstfd, username, len[2], 1, 5);
+            if (actual_len != len[2]) {
+                LOG(log_severe, logtype_cnid, "readt: %s", strerror(errno));
+                goto loop_end;
+            }
+            strlcpy(obj.username, username, MAXUSERLEN);
+            obj.uid = uid_from_name(username);
+            if (!obj.uid)
+                goto loop_end;
+        } else {
+            obj.username[0] = 0;
+        }
+
+        LOG(log_debug, logtype_cnid, "user: %s, volume %s, path %s",
+            username ? username : "-", volname, volpath);
 
         if (load_volumes(&obj, lv_all) != 0) {
             LOG(log_severe, logtype_cnid, "main: error reloading config");
@@ -577,12 +634,17 @@ int main(int argc, char *argv[])
 
         LOG(log_maxdebug, logtype_cnid, "main: dbpath: %s", vol->v_dbpath);
 
-        if (set_dbdir(vol->v_dbpath, volpath) < 0) {
+        if (set_dbdir(vol->v_dbpath, vol->v_path) < 0) {
             goto loop_end;
         }
 
-        maybe_start_dbd(&obj, dbdpn, vol->v_path);
+        maybe_start_dbd(&obj, dbdpn, vol->v_path, username);
+
     loop_end:
         close(rqstfd);
+        unload_volumes(&obj);
+        SAFE_FREE(volname);
+        SAFE_FREE(volpath);
+        SAFE_FREE(username);
     }
 }
index 994c8ff698f44776c92b8413e4f344ff38892661..ddcf66743c8812273b16b3ad484466ecfbcfae2b 100644 (file)
@@ -474,6 +474,16 @@ static void set_signal(void)
     }
 }
 
+static uid_t uid_from_name(const char *name)
+{
+    struct passwd *pwd;
+
+    pwd = getpwnam(name);
+    if (pwd == NULL)
+        return 0;
+    return pwd->pw_uid;
+}
+
 /* ------------------------ */
 int main(int argc, char *argv[])
 {
@@ -482,8 +492,9 @@ int main(int argc, char *argv[])
     int ctrlfd = -1, clntfd = -1;
     AFPObj obj = { 0 };
     char *volpath = NULL;
+    char *username = NULL;
 
-    while (( ret = getopt( argc, argv, "dF:l:p:t:vV")) != -1 ) {
+    while (( ret = getopt( argc, argv, ":dF:l:p:t:u:vV")) != -1 ) {
         switch (ret) {
         case 'd':
             /* this is now just ignored, as we do it automatically anyway */
@@ -501,10 +512,15 @@ int main(int argc, char *argv[])
         case 't':
             ctrlfd = atoi(optarg);
             break;
+        case 'u':
+            username = strdup(optarg);
+            break;
         case 'v':
         case 'V':
             printf("cnid_dbd (Netatalk %s)\n", VERSION);
             return -1;
+        case ':':
+            break;
         }
     }
 
@@ -515,6 +531,17 @@ int main(int argc, char *argv[])
 
     EC_ZERO( afp_config_parse(&obj, "cnid_dbd") );
 
+    if (username) {
+        strlcpy(obj.username, username, MAXUSERLEN);
+        obj.uid = uid_from_name(username);
+        if (!obj.uid) {
+            EC_FAIL_LOG("unknown user: '%s'", username);
+        }
+    }
+
+    LOG(log_debug, logtype_cnid, "user: %s, path %s",
+        username ? username : "-", volpath);
+
     EC_ZERO( load_volumes(&obj, lv_all) );
     EC_NULL( vol = getvolbypath(&obj, volpath) );
     EC_ZERO( load_charset(vol) );
index 9c8e0bacd065a69afb363b499ee78024c41f26f3..4fefcd0439a0b902ef6548fdc9f3143629e77429 100644 (file)
 /*
  * This is instance of CNID database object.
  */
-struct _cnid_db {
-    uint32_t flags;             /* Flags describing some CNID backend aspects. */
-    char *volpath;               /* Volume path this particular CNID db refers to. */
-    void *_private;              /* back-end speficic data */
+typedef struct _cnid_db {
+    uint32_t      cnid_db_flags;     /* Flags describing some CNID backend aspects. */
+    struct vol   *cnid_db_vol;
+    void         *cnid_db_private;   /* back-end speficic data */
 
     cnid_t (*cnid_add)         (struct _cnid_db *cdb, const struct stat *st, cnid_t did,
                                 const char *name, size_t, cnid_t hint);
@@ -71,25 +71,15 @@ struct _cnid_db {
     int    (*cnid_find)        (struct _cnid_db *cdb, const char *name, size_t namelen,
                                 void *buffer, size_t buflen);
     int    (*cnid_wipe)        (struct _cnid_db *cdb);
-};
-typedef struct _cnid_db cnid_db;
+} cnid_db;
 
 /*
  * Consolidation of args passedn from main cnid_open to modules cnid_XXX_open, so
  * that it's easier to add aditional args as required.
  */
 struct cnid_open_args {
-    const char *dir;
-    mode_t mask;
-    uint32_t flags;
-
-    /* for dbd */
-    const char *cnidserver;
-    const char *cnidport;
-
-    /* for MySQL */
-    const void *obj;
-    char *voluuid;
+    uint32_t cnid_args_flags;
+    struct vol *cnid_args_vol;
 };
 
 /*
@@ -111,14 +101,7 @@ void cnid_init();
 void cnid_register(struct _cnid_module *module);
 
 /* This function opens a CNID database for selected volume. */
-struct _cnid_db *cnid_open(const char *volpath,
-                           mode_t mask,
-                           char *type,
-                           int flags,
-                           const char *cnidsrv,
-                           const char *cnidport,
-                           const void *obj,
-                           char *uuid);
+struct _cnid_db *cnid_open(struct vol *vol, char *type, int flags);
 cnid_t cnid_add        (struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
                         const char *name, const size_t len, cnid_t hint);
 int    cnid_delete     (struct _cnid_db *cdb, cnid_t id);
index 8aab3e059e8545698dd0bd345fce59fdfa9f1aa3..f87eddd0f2a850d9b77f8783f109da06c528e40c 100644 (file)
@@ -36,6 +36,7 @@
 #define CNID_DBD_RES_SRCH_DONE     0x06
 
 #define DBD_MAX_SRCH_RSLTS 100
+#define DBD_NUM_OPEN_ARGS 3
 
 struct cnid_dbd_rqst {
     int     op;
@@ -57,10 +58,7 @@ struct cnid_dbd_rply {
 };
 
 typedef struct CNID_bdb_private {
-    uint32_t magic;
-    char      db_dir[MAXPATHLEN + 1]; /* Database directory without /.AppleDB appended */
-    char      *cnidserver;
-    char      *cnidport;
+    struct vol *vol;
     int       fd;              /* File descriptor to cnid_dbd */
     char      stamp[ADEDLEN_PRIVSYN]; /* db timestamp */
     char      *client_stamp;
index 6affaf7a15aae1ba9f87f79bee918dbe616fecce..79a54e8a0a3c92bbaf64b329f47a02398e819ea7 100644 (file)
@@ -7,12 +7,9 @@
 #define CNID_MYSQL_FLAG_DEPLETED (1 << 0) /* CNID set overflowed */
 
 typedef struct CNID_mysql_private {
+    struct vol *vol;
     uint32_t      cnid_mysql_flags;
-    uint32_t      cnid_mysql_magic;
-    char         *cnid_mysql_volname;
-    const void   *cnid_mysql_obj;
     MYSQL        *cnid_mysql_con;
-    atalk_uuid_t  cnid_mysql_voluuid;
     char         *cnid_mysql_voluuid_str;
     cnid_t        cnid_mysql_hint;
     MYSQL_STMT   *cnid_lookup_stmt;
index f5f825faa362f806e124cf3e0e32280166756a9c..c030ff99f404b2d99d09ef8d11b0a6d887c6e358 100644 (file)
@@ -5,9 +5,6 @@
 #ifndef _ATALK_CNID_PRIVATE_H
 #define _ATALK_CNID_PRIVATE_H 1
 
-#define CNID_DB_MAGIC   0x434E4944U  /* CNID */
-#define CNID_DATA_MAGIC 0x434E4945U  /* CNIE */
-
 #define CNID_OFS                 0
 #define CNID_LEN                 4
  
index 38e1e7b2dd4f36a115c4ca2a73ba5b0d8b60d326..312160be008947f71dfa066dd90d7f7e2c9fb6a3 100644 (file)
 #define ntoh64(x)       (hton64(x))
 #endif
 
+#ifndef SAFE_FREE
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
+#endif
+
 #ifdef WITH_SENDFILE
 extern ssize_t sys_sendfile (int __out_fd, int __in_fd, off_t *__offset,size_t __count);
 #endif
index a1e69a76ac5446a37afde531b208c9cbdc1a46bf..18f42c3cc0ffc36c89fde8c2ba6310d2871bdba0 100644 (file)
@@ -173,7 +173,7 @@ cnid_t cnid_cdb_add(struct _cnid_db *cdb, const struct stat *st,
     cnid_t id;
     int rc;
 
-    if (!cdb || !(db = cdb->_private) || !st || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !st || !name) {
         errno = CNID_ERR_PARAM;
         return CNID_INVALID;
     }
@@ -192,7 +192,7 @@ cnid_t cnid_cdb_add(struct _cnid_db *cdb, const struct stat *st,
     memset(&key, 0, sizeof(key));
     memset(&data, 0, sizeof(data));
 
-    if ((data.data = make_cnid_data(cdb->flags, st, did, name, len)) == NULL) {
+    if ((data.data = make_cnid_data(cdb->cnid_db_flags, st, did, name, len)) == NULL) {
         LOG(log_error, logtype_default, "cnid_add: Path name is too long");
         errno = CNID_ERR_PATH;
         return CNID_INVALID;
@@ -248,7 +248,7 @@ int cnid_cdb_getstamp(struct _cnid_db *cdb, void *buffer, const size_t len)
     int rc;
     CNID_private *db;
 
-    if (!cdb || !(db = cdb->_private) || !buffer || !len) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !buffer || !len) {
         errno = CNID_ERR_PARAM;
         return -1;
     }
index d34a418b7e3cef4b623912d2008a4f54cec5a04e..c5aeceec21b5ed4c1cde4f3a67fb7f34ffff2ed9 100644 (file)
@@ -16,7 +16,7 @@ void cnid_cdb_close(struct _cnid_db *cdb) {
            return;
     }
 
-    if (!(db = cdb->_private)) {
+    if (!(db = cdb->cnid_db_private)) {
         return;
     }
     db->db_didname->sync(db->db_didname, 0); 
@@ -30,7 +30,6 @@ void cnid_cdb_close(struct _cnid_db *cdb) {
     db->dbenv->close(db->dbenv, 0);
 
     free(db);
-    free(cdb->volpath);
     free(cdb);
 }
 
index ace358aa8b617b79a1f01fa0f4d8274b7c8e9822..deaeca44a816349a123bc9dbd5109c96658c0964 100644 (file)
@@ -21,7 +21,7 @@ int cnid_cdb_delete(struct _cnid_db *cdb, const cnid_t id) {
     DBT key;
     int rc;
 
-    if (!cdb || !(db = cdb->_private) || !id || (db->flags & CNIDFLAG_DB_RO)) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !id || (db->flags & CNIDFLAG_DB_RO)) {
         return -1;
     }
 
index d4e090550eab6f85e3de0aa6671f7aa7d6006453..9c682a8c1d260781ed3d734e994c74f34917995e 100644 (file)
@@ -14,7 +14,7 @@ cnid_t cnid_cdb_get(struct _cnid_db *cdb, cnid_t did, const char *name, size_t l
     cnid_t id;
     int rc;
 
-    if (!cdb || !(db = cdb->_private) || (len > MAXPATHLEN)) {
+    if (!cdb || !(db = cdb->cnid_db_private) || (len > MAXPATHLEN)) {
         return 0;
     }
 
index 7b2f933c5182b4e1c4d4974f5a46c3bd7aa695ac..950709d5d201a6d3081b8c301201f2e324a20cd6 100644 (file)
@@ -26,11 +26,11 @@ cnid_t cnid_cdb_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did,
     cnid_t id_devino, id_didname,id = 0;
     int rc;
 
-    if (!cdb || !(db = cdb->_private) || !st || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !st || !name) {
         return 0;
     }
     
-    if ((buf = make_cnid_data(cdb->flags, st, did, name, len)) == NULL) {
+    if ((buf = make_cnid_data(cdb->cnid_db_flags, st, did, name, len)) == NULL) {
         LOG(log_error, logtype_default, "cnid_lookup: Pathname is too long");
         return 0;
     }
@@ -63,7 +63,7 @@ cnid_t cnid_cdb_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did,
         type_devino = ntohl(type_devino);
     }
 
-    buf = make_cnid_data(cdb->flags, st, did, name, len);
+    buf = make_cnid_data(cdb->cnid_db_flags, st, did, name, len);
     key.data = buf +CNID_DID_OFS;
     key.size = CNID_DID_LEN + len + 1;
     
index 757d1b0da1e2c3c351ef618679e5ab37b2c64b48..0a8cfa39ed8fa4c9811747909e822c7f8d69c2d8 100644 (file)
@@ -38,6 +38,7 @@
 
 #ifdef CNID_BACKEND_CDB
 
+#include <atalk/volume.h>
 #include <atalk/cnid_private.h>
 #include "cnid_cdb_private.h"
 
@@ -109,7 +110,7 @@ static int my_open(DB * p, const char *f, const char *d, DBTYPE t, u_int32_t fla
 }
 
 /* --------------- */
-static struct _cnid_db *cnid_cdb_new(const char *volpath)
+static struct _cnid_db *cnid_cdb_new(struct vol *vol)
 {
     struct _cnid_db *cdb;
     int major, minor, patch;
@@ -127,13 +128,8 @@ static struct _cnid_db *cnid_cdb_new(const char *volpath)
     if ((cdb = (struct _cnid_db *) calloc(1, sizeof(struct _cnid_db))) == NULL)
         return NULL;
 
-    if ((cdb->volpath = strdup(volpath)) == NULL) {
-        free(cdb);
-        return NULL;
-    }
-
-    cdb->flags = CNID_FLAG_PERSISTENT;
-
+    cdb->cnid_db_vol = vol;
+    cdb->cnid_db_flags = CNID_FLAG_PERSISTENT;
     cdb->cnid_add = cnid_cdb_add;
     cdb->cnid_delete = cnid_cdb_delete;
     cdb->cnid_get = cnid_cdb_get;
@@ -188,19 +184,16 @@ struct _cnid_db *cnid_cdb_open(struct cnid_open_args *args)
     int open_flag, len;
     static int first = 0;
     int rc;
-
-    if (!args->dir || *args->dir == 0) {
-        return NULL;
-    }
+    struct vol *vol = args->cnid_args_vol;
 
     /* this checks .AppleDB.
        We need space for dir + '/' + DBHOMELEN + '/' + DBLEN */
-    if ((len = strlen(args->dir)) > (MAXPATHLEN - DBHOMELEN - DBLEN - 2)) {
-        LOG(log_error, logtype_default, "cnid_open: Pathname too large: %s", args->dir);
+    if ((len = strlen(vol->v_path)) > (MAXPATHLEN - DBHOMELEN - DBLEN - 2)) {
+        LOG(log_error, logtype_default, "cnid_open: Pathname too large: %s", vol->v_path);
         return NULL;
     }
 
-    if ((cdb = cnid_cdb_new(args->dir)) == NULL) {
+    if ((cdb = cnid_cdb_new(vol)) == NULL) {
         LOG(log_error, logtype_default, "cnid_open: Unable to allocate memory for database");
         return NULL;
     }
@@ -210,17 +203,16 @@ struct _cnid_db *cnid_cdb_open(struct cnid_open_args *args)
         goto fail_cdb;
     }
 
-    cdb->_private = (void *) db;
-    db->magic = CNID_DB_MAGIC;
+    cdb->cnid_db_private = (void *) db;
 
-    strcpy(path, args->dir);
+    strcpy(path, vol->v_path);
     if (path[len - 1] != '/') {
         strcat(path, "/");
         len++;
     }
 
     strcpy(path + len, DBHOME);
-    if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777 & ~args->mask) < 0)) {
+    if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777 & ~vol->v_umask) < 0)) {
         LOG(log_error, logtype_default, "cnid_open: DBHOME mkdir failed for %s", path);
         goto fail_adouble;
     }
@@ -247,7 +239,7 @@ struct _cnid_db *cnid_cdb_open(struct cnid_open_args *args)
     }
 
     /* Open the database environment. */
-    if ((rc = db->dbenv->open(db->dbenv, path, DBOPTIONS, 0666 & ~args->mask)) != 0) {
+    if ((rc = db->dbenv->open(db->dbenv, path, DBOPTIONS, 0666 & ~vol->v_umask)) != 0) {
        LOG(log_error, logtype_default, "cnid_open: dbenv->open (rw) of %s failed: %s", path, db_strerror(rc));
        /* FIXME: This should probably go. Even if it worked, any use for a read-only DB? Didier? */
         if (rc == DB_RUNRECOVERY) {
@@ -260,10 +252,10 @@ struct _cnid_db *cnid_cdb_open(struct cnid_open_args *args)
         /* We can't get a full transactional environment, so multi-access
          * is out of the question.  Let's assume a read-only environment,
          * and try to at least get a shared memory pool. */
-        if ((rc = db->dbenv->open(db->dbenv, path, DB_INIT_MPOOL, 0666 & ~args->mask)) != 0) {
+        if ((rc = db->dbenv->open(db->dbenv, path, DB_INIT_MPOOL, 0666 & ~vol->v_umask)) != 0) {
             /* Nope, not a MPOOL, either.  Last-ditch effort: we'll try to
              * open the environment with no flags. */
-            if ((rc = db->dbenv->open(db->dbenv, path, 0, 0666 & ~args->mask)) != 0) {
+            if ((rc = db->dbenv->open(db->dbenv, path, 0, 0666 & ~vol->v_umask)) != 0) {
                 LOG(log_error, logtype_default, "cnid_open: dbenv->open of %s failed: %s", path, db_strerror(rc));
                 goto fail_lock;
             }
@@ -282,7 +274,7 @@ struct _cnid_db *cnid_cdb_open(struct cnid_open_args *args)
         goto fail_appinit;
     }
 
-    if ((rc = my_open(db->db_cnid, DBCNID, DBCNID, DB_BTREE, open_flag, 0666 & ~args->mask)) != 0) {
+    if ((rc = my_open(db->db_cnid, DBCNID, DBCNID, DB_BTREE, open_flag, 0666 & ~vol->v_umask)) != 0) {
         LOG(log_error, logtype_default, "cnid_open: Failed to open dev/ino database: %s",
             db_strerror(rc));
         goto fail_appinit;
@@ -297,7 +289,7 @@ struct _cnid_db *cnid_cdb_open(struct cnid_open_args *args)
         goto fail_appinit;
     }
 
-    if ((rc = my_open(db->db_didname, DBCNID, DBDIDNAME, DB_BTREE, open_flag, 0666 & ~args->mask))) {
+    if ((rc = my_open(db->db_didname, DBCNID, DBDIDNAME, DB_BTREE, open_flag, 0666 & ~vol->v_umask))) {
         LOG(log_error, logtype_default, "cnid_open: Failed to open did/name database: %s",
             db_strerror(rc));
         goto fail_appinit;
@@ -312,7 +304,7 @@ struct _cnid_db *cnid_cdb_open(struct cnid_open_args *args)
         goto fail_appinit;
     }
 
-    if ((rc = my_open(db->db_devino, DBCNID, DBDEVINO, DB_BTREE, open_flag, 0666 & ~args->mask)) != 0) {
+    if ((rc = my_open(db->db_devino, DBCNID, DBDEVINO, DB_BTREE, open_flag, 0666 & ~vol->v_umask)) != 0) {
         LOG(log_error, logtype_default, "cnid_open: Failed to open devino database: %s",
             db_strerror(rc));
         goto fail_appinit;
@@ -373,8 +365,6 @@ struct _cnid_db *cnid_cdb_open(struct cnid_open_args *args)
     free(db);
 
   fail_cdb:
-    if (cdb->volpath != NULL)
-        free(cdb->volpath);
     free(cdb);
 
     return NULL;
index 4620782e14057f4ce5cf29d7976ad7e6d3c9b885..951674656c85931f45edd6cdf7a4fa8c99fe8a4b 100644 (file)
@@ -79,7 +79,7 @@ cnid_t cnid_cdb_rebuild_add(struct _cnid_db *cdb, const struct stat *st,
     DBT key, data;
     int rc;
 
-    if (!cdb || !(db = cdb->_private) || !st || !name || hint == CNID_INVALID || hint < CNID_START) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !st || !name || hint == CNID_INVALID || hint < CNID_START) {
         errno = CNID_ERR_PARAM;
         return CNID_INVALID;
     }
@@ -101,7 +101,7 @@ cnid_t cnid_cdb_rebuild_add(struct _cnid_db *cdb, const struct stat *st,
     memset(&key, 0, sizeof(key));
     memset(&data, 0, sizeof(data));
 
-    if ((data.data = make_cnid_data(cdb->flags, st, did, name, len)) == NULL) {
+    if ((data.data = make_cnid_data(cdb->cnid_db_flags, st, did, name, len)) == NULL) {
         LOG(log_error, logtype_default, "cnid_add: Path name is too long");
         errno = CNID_ERR_PATH;
         return CNID_INVALID;
index 63ed9f8a1c14b51c9de5837ef32e91ab2713d558..d3f6dab97a64099f763e9a62a93dc2439b7e329e 100644 (file)
@@ -14,7 +14,7 @@ char *cnid_cdb_resolve(struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t le
     DBT key, data;
     int rc;
 
-    if (!cdb || !(db = cdb->_private) || !id || !(*id)) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !id || !(*id)) {
         return NULL;
     }
 
index f7676c840054516c10be062dae3e874719b7e23e..90c7d93ff54655b82812b1699732fab60b5c3250 100644 (file)
@@ -20,7 +20,7 @@ int cnid_cdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
     int notfound = 0;
     char getbuf[CNID_HEADER_LEN + MAXPATHLEN +1];
 
-    if (!cdb || !(db = cdb->_private) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO)) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO)) {
         return -1;
     }
 
@@ -28,7 +28,7 @@ int cnid_cdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
     memset(&pkey, 0, sizeof(pkey));
     memset(&data, 0, sizeof(data));
 
-    buf = make_cnid_data(cdb->flags, st, did, name, len);
+    buf = make_cnid_data(cdb->cnid_db_flags, st, did, name, len);
 
     key.data = buf +CNID_DEVINO_OFS;
     key.size = CNID_DEVINO_LEN;
@@ -54,7 +54,7 @@ int cnid_cdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
     }
 
     memset(&pkey, 0, sizeof(pkey));
-    buf = make_cnid_data(cdb->flags, st, did, name, len);
+    buf = make_cnid_data(cdb->cnid_db_flags, st, did, name, len);
     key.data = buf + CNID_DID_OFS;
     key.size = CNID_DID_LEN + len + 1;
 
@@ -83,7 +83,7 @@ int cnid_cdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
 
     memset(&data, 0, sizeof(data));
     /* Make a new entry. */
-    buf = make_cnid_data(cdb->flags, st, did, name, len);
+    buf = make_cnid_data(cdb->cnid_db_flags, st, did, name, len);
     data.data = buf;
     memcpy(data.data, &id, sizeof(id));
     data.size = CNID_HEADER_LEN + len + 1;
index 9212caccafa73ad1ef0c7585d4bdfa6a29782ed7..fde4d70f500298b3de09f6189de46e7f2eaffe22 100644 (file)
@@ -30,6 +30,7 @@
 #include <atalk/logger.h>
 #include <atalk/util.h>
 #include <atalk/compat.h>
+#include <atalk/volume.h>
 
 /* List of all registered modules. */
 static struct list_head modules = ATALK_LIST_HEAD_INIT(modules);
@@ -91,8 +92,7 @@ static int cnid_dir(const char *dir, mode_t mask)
 }
 
 /* Opens CNID database using particular back-end */
-struct _cnid_db *cnid_open(const char *volpath, mode_t mask, char *type, int flags,
-                           const char *cnidsrv, const char *cnidport, const void *obj, char *uuid)
+struct _cnid_db *cnid_open(struct vol *vol, char *type, int flags)
 {
     struct _cnid_db *db;
     cnid_module *mod = NULL;
@@ -119,7 +119,7 @@ struct _cnid_db *cnid_open(const char *volpath, mode_t mask, char *type, int fla
             LOG(log_error, logtype_afpd, "seteuid failed %s", strerror(errno));
             return NULL;
         }
-        if (cnid_dir(volpath, mask) < 0) {
+        if (cnid_dir(vol->v_path, vol->v_umask) < 0) {
             if ( setegid(gid) < 0 || seteuid(uid) < 0) {
                 LOG(log_error, logtype_afpd, "can't seteuid back %s", strerror(errno));
                 exit(EXITERR_SYS);
@@ -128,7 +128,11 @@ struct _cnid_db *cnid_open(const char *volpath, mode_t mask, char *type, int fla
         }
     }
 
-    struct cnid_open_args args = {volpath, mask, flags, cnidsrv, cnidport, obj, uuid};
+    struct cnid_open_args args =  {
+        .cnid_args_flags = flags,
+        .cnid_args_vol   = vol
+    };
+
     db = mod->cnid_open(&args);
 
     if ((mod->flags & CNID_FLAG_SETUID) && !(flags & CNID_FLAG_MEMORY)) {
@@ -140,16 +144,15 @@ struct _cnid_db *cnid_open(const char *volpath, mode_t mask, char *type, int fla
     }
 
     if (NULL == db) {
-        LOG(log_error, logtype_afpd, "Cannot open CNID db at [%s].", volpath);
+        LOG(log_error, logtype_afpd, "Cannot open CNID db at [%s].", vol->v_path);
         return NULL;
     }
-    /* FIXME should module know about it ? */
-    if ((flags & CNID_FLAG_NODEV)) {
-        db->flags |= CNID_FLAG_NODEV;
-    }
-    db->flags |= mod->flags;
 
-    if ((db->flags & CNID_FLAG_BLOCK)) {
+    db->cnid_db_flags |= mod->flags;
+    if (flags & CNID_FLAG_NODEV)
+        db->cnid_db_flags |= CNID_FLAG_NODEV;
+
+    if (db->cnid_db_flags & CNID_FLAG_BLOCK) {
         sigemptyset(&sigblockset);
         sigaddset(&sigblockset, SIGTERM);
         sigaddset(&sigblockset, SIGHUP);
@@ -207,7 +210,7 @@ void cnid_close(struct _cnid_db *db)
         return;
     }
     /* cnid_close free db */
-    flags = db->flags;
+    flags = db->cnid_db_flags;
     block_signal(flags);
     db->cnid_close(db);
     unblock_signal(flags);
@@ -222,9 +225,9 @@ cnid_t cnid_add(struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
     if (len == 0)
         return CNID_INVALID;
 
-    block_signal(cdb->flags);
+    block_signal(cdb->cnid_db_flags);
     ret = valide(cdb->cnid_add(cdb, st, did, name, len, hint));
-    unblock_signal(cdb->flags);
+    unblock_signal(cdb->cnid_db_flags);
     return ret;
 }
 
@@ -233,9 +236,9 @@ int cnid_delete(struct _cnid_db *cdb, cnid_t id)
 {
 int ret;
 
-    block_signal(cdb->flags);
+    block_signal(cdb->cnid_db_flags);
     ret = cdb->cnid_delete(cdb, id);
-    unblock_signal(cdb->flags);
+    unblock_signal(cdb->cnid_db_flags);
     return ret;
 }
 
@@ -245,9 +248,9 @@ cnid_t cnid_get(struct _cnid_db *cdb, const cnid_t did, char *name,const size_t
 {
 cnid_t ret;
 
-    block_signal(cdb->flags);
+    block_signal(cdb->cnid_db_flags);
     ret = valide(cdb->cnid_get(cdb, did, name, len));
-    unblock_signal(cdb->flags);
+    unblock_signal(cdb->cnid_db_flags);
     return ret;
 }
 
@@ -266,9 +269,9 @@ time_t t;
        memcpy(buffer, &t, sizeof(time_t));
         return 0;
     }
-    block_signal(cdb->flags);
+    block_signal(cdb->cnid_db_flags);
     ret = cdb->cnid_getstamp(cdb, buffer, len);
-    unblock_signal(cdb->flags);
+    unblock_signal(cdb->cnid_db_flags);
     return ret;
 }
 
@@ -278,9 +281,9 @@ cnid_t cnid_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t did
 {
     cnid_t ret;
 
-    block_signal(cdb->flags);
+    block_signal(cdb->cnid_db_flags);
     ret = valide(cdb->cnid_lookup(cdb, st, did, name, len));
-    unblock_signal(cdb->flags);
+    unblock_signal(cdb->cnid_db_flags);
     return ret;
 }
 
@@ -294,9 +297,9 @@ int cnid_find(struct _cnid_db *cdb, const char *name, size_t namelen, void *buff
         return -1;
     }
 
-    block_signal(cdb->flags);
+    block_signal(cdb->cnid_db_flags);
     ret = cdb->cnid_find(cdb, name, namelen, buffer, buflen);
-    unblock_signal(cdb->flags);
+    unblock_signal(cdb->cnid_db_flags);
     return ret;
 }
 
@@ -305,9 +308,9 @@ char *cnid_resolve(struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t len)
 {
 char *ret;
 
-    block_signal(cdb->flags);
+    block_signal(cdb->cnid_db_flags);
     ret = cdb->cnid_resolve(cdb, id, buffer, len);
-    unblock_signal(cdb->flags);
+    unblock_signal(cdb->cnid_db_flags);
     if (ret && !strcmp(ret, "..")) {
         LOG(log_error, logtype_afpd, "cnid_resolve: name is '..', corrupted db? ");
         ret = NULL;
@@ -321,9 +324,9 @@ int cnid_update   (struct _cnid_db *cdb, const cnid_t id, const struct stat *st,
 {
 int ret;
 
-    block_signal(cdb->flags);
+    block_signal(cdb->cnid_db_flags);
     ret = cdb->cnid_update(cdb, id, st, did, name, len);
-    unblock_signal(cdb->flags);
+    unblock_signal(cdb->cnid_db_flags);
     return ret;
 }
                        
@@ -333,9 +336,9 @@ cnid_t cnid_rebuild_add(struct _cnid_db *cdb, const struct stat *st, const cnid_
 {
 cnid_t ret;
 
-    block_signal(cdb->flags);
+    block_signal(cdb->cnid_db_flags);
     ret = cdb->cnid_rebuild_add(cdb, st, did, name, len, hint);
-    unblock_signal(cdb->flags);
+    unblock_signal(cdb->cnid_db_flags);
     return ret;
 }
 
@@ -344,9 +347,9 @@ int cnid_wipe(struct _cnid_db *cdb)
 {
     int ret = 0;
 
-    block_signal(cdb->flags);
+    block_signal(cdb->cnid_db_flags);
     if (cdb->cnid_wipe)
         ret = cdb->cnid_wipe(cdb);
-    unblock_signal(cdb->flags);
+    unblock_signal(cdb->cnid_db_flags);
     return ret;
 }
index 1b365065cdd79194d2b8329fbef496bfa8ffdcf6..d4606400aa1539e6bd64bf52b24c410bfa1a3b9e 100644 (file)
@@ -33,6 +33,7 @@
 #include <atalk/cnid.h>
 #include <atalk/cnid_bdb_private.h>
 #include <atalk/util.h>
+#include <atalk/volume.h>
 
 #include "cnid_dbd.h"
 
@@ -227,24 +228,46 @@ static int write_vec(int fd, struct iovec *iov, ssize_t towrite, int vecs)
 static int init_tsock(CNID_bdb_private *db)
 {
     int fd;
-    int len;
-    struct iovec iov[2];
+    int len[DBD_NUM_OPEN_ARGS];
+    int iovecs;
+    struct iovec iov[DBD_NUM_OPEN_ARGS + 1] = {{0}};
+    struct vol *vol = db->vol;
+    ssize_t iovlen;
 
-    LOG(log_debug, logtype_cnid, "init_tsock: BEGIN. Opening volume '%s', CNID Server: %s/%s",
-        db->db_dir, db->cnidserver, db->cnidport);
+    LOG(log_debug, logtype_cnid, "connecting to CNID server: %s:%s",
+        vol->v_cnidserver, vol->v_cnidport);
 
-    if ((fd = tsock_getfd(db->cnidserver, db->cnidport)) < 0)
+    if ((fd = tsock_getfd(vol->v_cnidserver, vol->v_cnidport)) < 0)
         return -1;
 
-    len = strlen(db->db_dir);
+    LOG(log_debug, logtype_cnid, "connecting volume '%s', path: %s, user: %s",
+        vol->v_configname, vol->v_path, vol->v_obj->username[0] ? vol->v_obj->username : "-");
+
+    iovecs = 1 + DBD_NUM_OPEN_ARGS - 1;
+
+    len[0] = strlen(vol->v_configname) + 1;
+    len[1] = strlen(vol->v_path) + 1;
+    len[2] = strlen(vol->v_obj->username);
 
-    iov[0].iov_base = &len;
-    iov[0].iov_len  = sizeof(int);
+    iov[0].iov_base = &len[0];
+    iov[0].iov_len  = DBD_NUM_OPEN_ARGS * sizeof(int);
 
-    iov[1].iov_base = db->db_dir;
-    iov[1].iov_len  = len;
+    iov[1].iov_base = vol->v_configname;
+    iov[1].iov_len  = len[0];
 
-    if (write_vec(fd, iov, len + sizeof(int), 2) != len + sizeof(int)) {
+    iov[2].iov_base = vol->v_path;
+    iov[2].iov_len  = len[1];
+
+    if (len[2] > 0) {
+        len[2] += 1;
+        iovecs++;
+        iov[3].iov_base = vol->v_obj->username;
+        iov[3].iov_len  = len[2];
+    }
+
+    iovlen = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len + iov[3].iov_len;
+
+    if (write_vec(fd, iov, iovlen, iovecs) != iovlen) {
         LOG(log_error, logtype_cnid, "init_tsock: Error/short write: %s", strerror(errno));
         close(fd);
         return -1;
@@ -275,8 +298,8 @@ static int send_packet(CNID_bdb_private *db, struct cnid_dbd_rqst *rqst)
     }
 
     if (write_vec(db->fd, iov, towrite, vecs) != towrite) {
-        LOG(log_warning, logtype_cnid, "send_packet: Error writev rqst (db_dir %s): %s",
-            db->db_dir, strerror(errno));
+        LOG(log_warning, logtype_cnid, "send_packet: Error writev rqst (volume %s): %s",
+            db->vol->v_localname, strerror(errno));
         return -1;
     }
 
@@ -327,21 +350,21 @@ static int dbd_rpc(CNID_bdb_private *db, struct cnid_dbd_rqst *rqst, struct cnid
     ret = readt(db->fd, rply, sizeof(struct cnid_dbd_rply), 0, ONE_DELAY);
 
     if (ret != sizeof(struct cnid_dbd_rply)) {
-        LOG(log_debug, logtype_cnid, "dbd_rpc: Error reading header from fd (db_dir %s): %s",
-            db->db_dir, ret == -1 ? strerror(errno) : "closed");
+        LOG(log_debug, logtype_cnid, "dbd_rpc: Error reading header from fd (volume %s): %s",
+            db->vol->v_localname, ret == -1 ? strerror(errno) : "closed");
         rply->name = nametmp;
         return -1;
     }
     rply->name = nametmp;
     if (rply->namelen && rply->namelen > len) {
         LOG(log_error, logtype_cnid,
-            "dbd_rpc: Error reading name (db_dir %s): %s name too long: %d. only wanted %d, garbage?",
-            db->db_dir, rply->name, rply->namelen, len);
+            "dbd_rpc: Error reading name (volume %s): %s name too long: %d. only wanted %d, garbage?",
+            db->vol->v_localname, rply->name, rply->namelen, len);
         return -1;
     }
     if (rply->namelen && (ret = readt(db->fd, rply->name, rply->namelen, 0, ONE_DELAY)) != (ssize_t)rply->namelen) {
-        LOG(log_error, logtype_cnid, "dbd_rpc: Error reading name from fd (db_dir %s): %s",
-            db->db_dir, ret == -1?strerror(errno):"closed");
+        LOG(log_error, logtype_cnid, "dbd_rpc: Error reading name from fd (volume %s): %s",
+            db->vol->v_localname, ret == -1?strerror(errno):"closed");
         return -1;
     }
 
@@ -367,7 +390,7 @@ static int transmit(CNID_bdb_private *db, struct cnid_dbd_rqst *rqst, struct cni
             } else { /* db->notfirst == 0 */
                 db->notfirst = 1;
             }
-            LOG(log_debug, logtype_cnid, "transmit: attached to '%s'", db->db_dir);
+            LOG(log_debug, logtype_cnid, "transmit: attached to '%s'", db->vol->v_localname);
         }
         if (!dbd_rpc(db, rqst, rply)) {
             LOG(log_maxdebug, logtype_cnid, "transmit: {done}");
@@ -381,14 +404,14 @@ static int transmit(CNID_bdb_private *db, struct cnid_dbd_rqst *rqst, struct cni
 
         if (errno == ECONNREFUSED) { /* errno carefully injected in tsock_getfd */
             /* give up */
-            LOG(log_error, logtype_cnid, "transmit: connection refused (db_dir %s)", db->db_dir);
+            LOG(log_error, logtype_cnid, "transmit: connection refused (volume %s)", db->vol->v_localname);
             return -1;
         }
 
         if (!clean) { /* don't sleep if just got disconnected by cnid server */
             time(&t);
             if (t - orig > MAX_DELAY) {
-                LOG(log_error, logtype_cnid, "transmit: Request to dbd daemon (db_dir %s) timed out.", db->db_dir);
+                LOG(log_error, logtype_cnid, "transmit: Request to dbd daemon (volume %s) timed out.", db->vol->v_localname);
                 return -1;
             }
             /* sleep a little before retry */
@@ -402,20 +425,15 @@ static int transmit(CNID_bdb_private *db, struct cnid_dbd_rqst *rqst, struct cni
 }
 
 /* ---------------------- */
-static struct _cnid_db *cnid_dbd_new(const char *volpath)
+static struct _cnid_db *cnid_dbd_new(struct vol *vol)
 {
     struct _cnid_db *cdb;
 
     if ((cdb = (struct _cnid_db *)calloc(1, sizeof(struct _cnid_db))) == NULL)
         return NULL;
 
-    if ((cdb->volpath = strdup(volpath)) == NULL) {
-        free(cdb);
-        return NULL;
-    }
-
-    cdb->flags = CNID_FLAG_PERSISTENT | CNID_FLAG_LAZY_INIT;
-
+    cdb->cnid_db_vol = vol;
+    cdb->cnid_db_flags = CNID_FLAG_PERSISTENT | CNID_FLAG_LAZY_INIT;
     cdb->cnid_add = cnid_dbd_add;
     cdb->cnid_delete = cnid_dbd_delete;
     cdb->cnid_get = cnid_dbd_get;
@@ -437,11 +455,7 @@ struct _cnid_db *cnid_dbd_open(struct cnid_open_args *args)
     CNID_bdb_private *db = NULL;
     struct _cnid_db *cdb = NULL;
 
-    if (!args->dir) {
-        return NULL;
-    }
-
-    if ((cdb = cnid_dbd_new(args->dir)) == NULL) {
+    if ((cdb = cnid_dbd_new(args->cnid_args_vol)) == NULL) {
         LOG(log_error, logtype_cnid, "cnid_open: Unable to allocate memory for database");
         return NULL;
     }
@@ -451,27 +465,19 @@ struct _cnid_db *cnid_dbd_open(struct cnid_open_args *args)
         goto cnid_dbd_open_fail;
     }
 
-    cdb->_private = db;
+    cdb->cnid_db_private = db;
 
-    /* We keep a copy of the directory in the db structure so that we can
-       transparently reconnect later. */
-    strcpy(db->db_dir, args->dir);
-    db->magic = CNID_DB_MAGIC;
     db->fd = -1;
-    db->cnidserver = strdup(args->cnidserver);
-    db->cnidport = strdup(args->cnidport);
+    db->vol = args->cnid_args_vol;
 
-    LOG(log_debug, logtype_cnid, "cnid_dbd_open: Finished initializing cnid dbd module for volume '%s'", db->db_dir);
+    LOG(log_debug, logtype_cnid, "Finished initializing CNID dbd module for volume '%s'",
+        args->cnid_args_vol->v_localname);
 
     return cdb;
 
 cnid_dbd_open_fail:
-    if (cdb != NULL) {
-        if (cdb->volpath != NULL) {
-            free(cdb->volpath);
-        }
+    if (cdb != NULL)
         free(cdb);
-    }
     if (db != NULL)
         free(db);
 
@@ -488,15 +494,14 @@ void cnid_dbd_close(struct _cnid_db *cdb)
         return;
     }
 
-    if ((db = cdb->_private) != NULL) {
-        LOG(log_debug, logtype_cnid, "closing database connection for volume '%s'", db->db_dir);
+    if ((db = cdb->cnid_db_private) != NULL) {
+        LOG(log_debug, logtype_cnid, "closing database connection for volume '%s'", db->vol->v_localname);
 
         if (db->fd >= 0)
             close(db->fd);
         free(db);
     }
 
-    free(cdb->volpath);
     free(cdb);
 
     return;
@@ -537,7 +542,7 @@ cnid_t cnid_dbd_add(struct _cnid_db *cdb, const struct stat *st,
     struct cnid_dbd_rply rply;
     cnid_t id;
 
-    if (!cdb || !(db = cdb->_private) || !st || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !st || !name) {
         LOG(log_error, logtype_cnid, "cnid_add: Parameter error");
         errno = CNID_ERR_PARAM;
         return CNID_INVALID;
@@ -552,7 +557,7 @@ cnid_t cnid_dbd_add(struct _cnid_db *cdb, const struct stat *st,
     RQST_RESET(&rqst);
     rqst.op = CNID_DBD_OP_ADD;
 
-    if (!(cdb->flags & CNID_FLAG_NODEV)) {
+    if (!(cdb->cnid_db_flags & CNID_FLAG_NODEV)) {
         rqst.dev = st->st_dev;
     }
 
@@ -601,7 +606,7 @@ cnid_t cnid_dbd_get(struct _cnid_db *cdb, cnid_t did, const char *name, size_t l
     struct cnid_dbd_rply rply;
     cnid_t id;
 
-    if (!cdb || !(db = cdb->_private) || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !name) {
         LOG(log_error, logtype_cnid, "cnid_dbd_get: Parameter error");
         errno = CNID_ERR_PARAM;
         return CNID_INVALID;
@@ -654,7 +659,7 @@ char *cnid_dbd_resolve(struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t le
     struct cnid_dbd_rply rply;
     char *name;
 
-    if (!cdb || !(db = cdb->_private) || !id || !(*id)) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !id || !(*id)) {
         LOG(log_error, logtype_cnid, "cnid_resolve: Parameter error");
         errno = CNID_ERR_PARAM;
         return NULL;
@@ -710,7 +715,7 @@ int cnid_dbd_getstamp(struct _cnid_db *cdb, void *buffer, const size_t len)
 {
     CNID_bdb_private *db;
 
-    if (!cdb || !(db = cdb->_private) || len != ADEDLEN_PRIVSYN) {
+    if (!cdb || !(db = cdb->cnid_db_private) || len != ADEDLEN_PRIVSYN) {
         LOG(log_error, logtype_cnid, "cnid_getstamp: Parameter error");
         errno = CNID_ERR_PARAM;
         return -1;
@@ -730,7 +735,7 @@ cnid_t cnid_dbd_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did,
     struct cnid_dbd_rply rply;
     cnid_t id;
 
-    if (!cdb || !(db = cdb->_private) || !st || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !st || !name) {
         LOG(log_error, logtype_cnid, "cnid_lookup: Parameter error");
         errno = CNID_ERR_PARAM;
         return CNID_INVALID;
@@ -745,7 +750,7 @@ cnid_t cnid_dbd_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did,
     RQST_RESET(&rqst);
     rqst.op = CNID_DBD_OP_LOOKUP;
 
-    if (!(cdb->flags & CNID_FLAG_NODEV)) {
+    if (!(cdb->cnid_db_flags & CNID_FLAG_NODEV)) {
         rqst.dev = st->st_dev;
     }
 
@@ -791,7 +796,7 @@ int cnid_dbd_find(struct _cnid_db *cdb, const char *name, size_t namelen, void *
     struct cnid_dbd_rply rply;
     int count;
 
-    if (!cdb || !(db = cdb->_private) || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !name) {
         LOG(log_error, logtype_cnid, "cnid_find: Parameter error");
         errno = CNID_ERR_PARAM;
         return CNID_INVALID;
@@ -846,7 +851,7 @@ int cnid_dbd_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
     struct cnid_dbd_rqst rqst;
     struct cnid_dbd_rply rply;
 
-    if (!cdb || !(db = cdb->_private) || !id || !st || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !id || !st || !name) {
         LOG(log_error, logtype_cnid, "cnid_update: Parameter error");
         errno = CNID_ERR_PARAM;
         return -1;
@@ -861,7 +866,7 @@ int cnid_dbd_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
     RQST_RESET(&rqst);
     rqst.op = CNID_DBD_OP_UPDATE;
     rqst.cnid = id;
-    if (!(cdb->flags & CNID_FLAG_NODEV)) {
+    if (!(cdb->cnid_db_flags & CNID_FLAG_NODEV)) {
         rqst.dev = st->st_dev;
     }
     rqst.ino = st->st_ino;
@@ -901,7 +906,7 @@ cnid_t cnid_dbd_rebuild_add(struct _cnid_db *cdb, const struct stat *st,
     struct cnid_dbd_rply rply;
     cnid_t id;
 
-    if (!cdb || !(db = cdb->_private) || !st || !name || hint == CNID_INVALID) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !st || !name || hint == CNID_INVALID) {
         LOG(log_error, logtype_cnid, "cnid_rebuild_add: Parameter error");
         errno = CNID_ERR_PARAM;
         return CNID_INVALID;
@@ -916,7 +921,7 @@ cnid_t cnid_dbd_rebuild_add(struct _cnid_db *cdb, const struct stat *st,
     RQST_RESET(&rqst);
     rqst.op = CNID_DBD_OP_REBUILD_ADD;
 
-    if (!(cdb->flags & CNID_FLAG_NODEV)) {
+    if (!(cdb->cnid_db_flags & CNID_FLAG_NODEV)) {
         rqst.dev = st->st_dev;
     }
 
@@ -962,7 +967,7 @@ int cnid_dbd_delete(struct _cnid_db *cdb, const cnid_t id)
     struct cnid_dbd_rqst rqst;
     struct cnid_dbd_rply rply;
 
-    if (!cdb || !(db = cdb->_private) || !id) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !id) {
         LOG(log_error, logtype_cnid, "cnid_delete: Parameter error");
         errno = CNID_ERR_PARAM;
         return -1;
@@ -999,7 +1004,7 @@ int cnid_dbd_wipe(struct _cnid_db *cdb)
     struct cnid_dbd_rqst rqst;
     struct cnid_dbd_rply rply;
 
-    if (!cdb || !(db = cdb->_private)) {
+    if (!cdb || !(db = cdb->cnid_db_private)) {
         LOG(log_error, logtype_cnid, "cnid_wipe: Parameter error");
         errno = CNID_ERR_PARAM;
         return -1;
index cc2ae1c7d19e79ec3ef8ae13c14936bc491908b7..2314217cd50b1eb4c3109d98f3ccab85bfc1bfe4 100644 (file)
@@ -58,10 +58,10 @@ cnid_t cnid_last_add(struct _cnid_db *cdb, const struct stat *st,
 
     struct _cnid_last_private *priv;
 
-    if (!cdb || !(cdb->_private))
+    if (!cdb || !(cdb->cnid_db_private))
         return CNID_INVALID;
 
-    priv = (struct _cnid_last_private *) (cdb->_private);
+    priv = (struct _cnid_last_private *) (cdb->cnid_db_private);
 
     if (S_ISDIR(st->st_mode))
         return htonl(priv->last_did++);
@@ -73,8 +73,7 @@ cnid_t cnid_last_add(struct _cnid_db *cdb, const struct stat *st,
 
 void cnid_last_close(struct _cnid_db *cdb)
 {
-    free(cdb->volpath);
-    free(cdb->_private);
+    free(cdb->cnid_db_private);
     free(cdb);
 }
 
@@ -105,7 +104,7 @@ cnid_t cnid_last_lookup(struct _cnid_db *cdb _U_, const struct stat *st _U_, cni
 }
 
 
-static struct _cnid_db *cnid_last_new(const char *volpath)
+static struct _cnid_db *cnid_last_new(struct vol *vol)
 {
     struct _cnid_db *cdb;
     struct _cnid_last_private *priv;
@@ -113,23 +112,17 @@ static struct _cnid_db *cnid_last_new(const char *volpath)
     if ((cdb = (struct _cnid_db *) calloc(1, sizeof(struct _cnid_db))) == NULL)
         return NULL;
 
-    if ((cdb->volpath = strdup(volpath)) == NULL) {
-        free(cdb);
-        return NULL;
-    }
-
-    if ((cdb->_private = calloc(1, sizeof(struct _cnid_last_private))) == NULL) {
-        free(cdb->volpath);
+    if ((cdb->cnid_db_private = calloc(1, sizeof(struct _cnid_last_private))) == NULL) {
         free(cdb);
         return NULL;
     }
 
     /* Set up private state */
-    priv = (struct _cnid_last_private *) (cdb->_private);
+    priv = (struct _cnid_last_private *) (cdb->cnid_db_private);
     priv->last_did = 17;
 
     /* Set up standard fields */
-    cdb->flags = 0;
+    cdb->cnid_db_flags = 0;
     cdb->cnid_add = cnid_last_add;
     cdb->cnid_delete = cnid_last_delete;
     cdb->cnid_get = cnid_last_get;
@@ -147,11 +140,7 @@ struct _cnid_db *cnid_last_open(struct cnid_open_args *args)
 {
     struct _cnid_db *cdb;
 
-    if (!args->dir) {
-        return NULL;
-    }
-
-    if ((cdb = cnid_last_new(args->dir)) == NULL) {
+    if ((cdb = cnid_last_new(args->cnid_args_vol)) == NULL) {
         LOG(log_error, logtype_default, "cnid_open: Unable to allocate memory for database");
         return NULL;
     }
index c661f9ac3d5623e43a4ad9be700865125c8ec4fa..aa04bf81f259127585974ac9f2764e3a000a63e0 100644 (file)
@@ -7,6 +7,8 @@
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
 
+#undef _FORTIFY_SOURCE
+
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <sys/uio.h>
@@ -36,6 +38,8 @@
 #include <atalk/cnid_bdb_private.h>
 #include <atalk/errchk.h>
 #include <atalk/globals.h>
+#include <atalk/volume.h>
+
 
 static MYSQL_BIND lookup_param[4], lookup_result[5];
 static MYSQL_BIND add_param[4], put_param[5];
@@ -240,7 +244,7 @@ int cnid_mysql_delete(struct _cnid_db *cdb, const cnid_t id)
     EC_INIT;
     CNID_mysql_private *db;
 
-    if (!cdb || !(db = cdb->_private) || !id) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !id) {
         LOG(log_error, logtype_cnid, "cnid_mysql_delete: Parameter error");
         errno = CNID_ERR_PARAM;
         EC_FAIL;
@@ -268,8 +272,9 @@ void cnid_mysql_close(struct _cnid_db *cdb)
         return;
     }
 
-    if ((db = cdb->_private) != NULL) {
-        LOG(log_debug, logtype_cnid, "closing database connection for volume '%s'", db->cnid_mysql_volname);
+    if ((db = cdb->cnid_db_private) != NULL) {
+        LOG(log_debug, logtype_cnid, "closing database connection for volume '%s'",
+            cdb->cnid_db_vol->v_localname);
 
         free(db->cnid_mysql_voluuid_str);
 
@@ -280,7 +285,6 @@ void cnid_mysql_close(struct _cnid_db *cdb)
         free(db);
     }
 
-    free(cdb->volpath);
     free(cdb);
 
     return;
@@ -297,7 +301,7 @@ int cnid_mysql_update(struct _cnid_db *cdb,
     CNID_mysql_private *db;
     cnid_t update_id;
 
-    if (!cdb || !(db = cdb->_private) || !id || !st || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !id || !st || !name) {
         LOG(log_error, logtype_cnid, "cnid_update: Parameter error");
         errno = CNID_ERR_PARAM;
         EC_FAIL;
@@ -366,7 +370,7 @@ cnid_t cnid_mysql_lookup(struct _cnid_db *cdb,
     cnid_t id = CNID_INVALID;
     bool have_result = false;
 
-    if (!cdb || !(db = cdb->_private) || !st || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !st || !name) {
         LOG(log_error, logtype_cnid, "cnid_mysql_lookup: Parameter error");
         errno = CNID_ERR_PARAM;
         EC_FAIL;
@@ -505,7 +509,7 @@ cnid_t cnid_mysql_add(struct _cnid_db *cdb,
     MYSQL_STMT *stmt;
     my_ulonglong lastid;
 
-    if (!cdb || !(db = cdb->_private) || !st || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !st || !name) {
         LOG(log_error, logtype_cnid, "cnid_mysql_add: Parameter error");
         errno = CNID_ERR_PARAM;
         EC_FAIL;
@@ -609,7 +613,7 @@ cnid_t cnid_mysql_get(struct _cnid_db *cdb, cnid_t did, const char *name, size_t
     MYSQL_RES *result = NULL;
     MYSQL_ROW row;
 
-    if (!cdb || !(db = cdb->_private) || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !name) {
         LOG(log_error, logtype_cnid, "cnid_mysql_get: Parameter error");
         errno = CNID_ERR_PARAM;
         EC_FAIL;
@@ -658,7 +662,7 @@ char *cnid_mysql_resolve(struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t
     MYSQL_RES *result = NULL;
     MYSQL_ROW row;
 
-    if (!cdb || !(db = cdb->_private)) {
+    if (!cdb || !(db = cdb->cnid_db_private)) {
         LOG(log_error, logtype_cnid, "cnid_mysql_get: Parameter error");
         errno = CNID_ERR_PARAM;
         EC_FAIL;
@@ -700,7 +704,7 @@ int cnid_mysql_getstamp(struct _cnid_db *cdb, void *buffer, const size_t len)
     MYSQL_RES *result = NULL;
     MYSQL_ROW row;
 
-    if (!cdb || !(db = cdb->_private)) {
+    if (!cdb || !(db = cdb->cnid_db_private)) {
         LOG(log_error, logtype_cnid, "cnid_find: Parameter error");
         errno = CNID_ERR_PARAM;
         return CNID_INVALID;
@@ -711,7 +715,7 @@ int cnid_mysql_getstamp(struct _cnid_db *cdb, void *buffer, const size_t len)
 
     if (cnid_mysql_execute(db->cnid_mysql_con,
                            "SELECT Stamp FROM volumes WHERE VolPath='%s'",
-                           db->cnid_mysql_volname)) {
+                           cdb->cnid_db_vol->v_path)) {
         if (mysql_errno(db->cnid_mysql_con) != ER_DUP_ENTRY) {
             LOG(log_error, logtype_cnid, "MySQL query error: %s", mysql_error(db->cnid_mysql_con));
             EC_FAIL;
@@ -724,7 +728,7 @@ int cnid_mysql_getstamp(struct _cnid_db *cdb, void *buffer, const size_t len)
         EC_FAIL;
     }
     if (!mysql_num_rows(result)) {
-        LOG(log_error, logtype_cnid, "Can't get DB stamp for volumes \"%s\"", db->cnid_mysql_volname);
+        LOG(log_error, logtype_cnid, "Can't get DB stamp for volumes \"%s\"", cdb->cnid_db_vol->v_path);
         EC_FAIL;
     }
     row = mysql_fetch_row(result);
@@ -758,7 +762,7 @@ int cnid_mysql_wipe(struct _cnid_db *cdb)
     CNID_mysql_private *db;
     MYSQL_RES *result = NULL;
 
-    if (!cdb || !(db = cdb->_private)) {
+    if (!cdb || !(db = cdb->cnid_db_private)) {
         LOG(log_error, logtype_cnid, "cnid_wipe: Parameter error");
         errno = CNID_ERR_PARAM;
         return -1;
@@ -787,19 +791,15 @@ EC_CLEANUP:
     EC_EXIT;
 }
 
-static struct _cnid_db *cnid_mysql_new(const char *volpath)
+static struct _cnid_db *cnid_mysql_new(struct vol *vol)
 {
     struct _cnid_db *cdb;
 
     if ((cdb = (struct _cnid_db *)calloc(1, sizeof(struct _cnid_db))) == NULL)
         return NULL;
 
-    if ((cdb->volpath = strdup(volpath)) == NULL) {
-        free(cdb);
-        return NULL;
-    }
-
-    cdb->flags = CNID_FLAG_PERSISTENT | CNID_FLAG_LAZY_INIT;
+    cdb->cnid_db_vol = vol;
+    cdb->cnid_db_flags = CNID_FLAG_PERSISTENT | CNID_FLAG_LAZY_INIT;
     cdb->cnid_add = cnid_mysql_add;
     cdb->cnid_delete = cnid_mysql_delete;
     cdb->cnid_get = cnid_mysql_get;
@@ -817,7 +817,6 @@ static struct _cnid_db *cnid_mysql_new(const char *volpath)
 
 static const char *printuuid(const unsigned char *uuid) {
     static char uuidstring[64];
-    const char *uuidmask;
     int i = 0;
     unsigned char c;
 
@@ -838,16 +837,13 @@ struct _cnid_db *cnid_mysql_open(struct cnid_open_args *args)
     struct _cnid_db *cdb = NULL;
     MYSQL_RES *result = NULL;
     MYSQL_ROW row;
+    struct vol *vol = args->cnid_args_vol;
 
-    EC_NULL( cdb = cnid_mysql_new(args->dir) );
+    EC_NULL( cdb = cnid_mysql_new(vol) );
     EC_NULL( db = (CNID_mysql_private *)calloc(1, sizeof(CNID_mysql_private)) );
-    cdb->_private = db;
+    cdb->cnid_db_private = db;
 
-    db->cnid_mysql_volname = strdup(args->dir); /* db_dir contains the volume name */
-    db->cnid_mysql_magic = CNID_DB_MAGIC;
-    db->cnid_mysql_obj = args->obj;
-    memcpy(db->cnid_mysql_voluuid, args->voluuid, sizeof(atalk_uuid_t));
-    db->cnid_mysql_voluuid_str = strdup(printuuid(db->cnid_mysql_voluuid));
+    db->cnid_mysql_voluuid_str = strdup(printuuid(vol->v_uuid));
 
     /* Initialize and connect to MySQL server */
     EC_NULL( db->cnid_mysql_con = mysql_init(NULL) );
@@ -856,7 +852,7 @@ struct _cnid_db *cnid_mysql_open(struct cnid_open_args *args)
     int my_timeout = 600;
     EC_ZERO( mysql_options(db->cnid_mysql_con, MYSQL_OPT_CONNECT_TIMEOUT, &my_timeout) );
 
-    const AFPObj *obj = db->cnid_mysql_obj;
+    const AFPObj *obj = vol->v_obj;
 
     EC_NULL( mysql_real_connect(db->cnid_mysql_con,
                                 obj->options.cnid_mysql_host,
@@ -883,7 +879,7 @@ struct _cnid_db *cnid_mysql_open(struct cnid_open_args *args)
                            "INSERT INTO volumes (VolUUID,Volpath,Stamp,Depleted) "
                            "VALUES('%s','%s','%s',0)",
                            db->cnid_mysql_voluuid_str,
-                           db->cnid_mysql_volname,
+                           vol->v_path,
                            blob)) {
         if (mysql_errno(db->cnid_mysql_con) != ER_DUP_ENTRY) {
             LOG(log_error, logtype_cnid, "MySQL query error: %s", mysql_error(db->cnid_mysql_con));
@@ -934,18 +930,14 @@ struct _cnid_db *cnid_mysql_open(struct cnid_open_args *args)
     EC_ZERO( init_prepared_stmt(db) );
 
     LOG(log_debug, logtype_cnid, "Finished initializing MySQL CNID module for volume '%s'",
-        db->cnid_mysql_volname);
+        vol->v_path);
 
 EC_CLEANUP:
     if (result)
         mysql_free_result(result);
     if (ret != 0) {
-        if (cdb) {
-            if (cdb->volpath != NULL) {
-                free(cdb->volpath);
-            }
+        if (cdb)
             free(cdb);
-        }
         cdb = NULL;
         if (db)
             free(db);
index 3203eda94a9f80de30e180f44bd3744755d65b92..b3babcd35f2b87f58d9f08474dbf9bea15099ccd 100644 (file)
@@ -160,7 +160,7 @@ cnid_t cnid_tdb_add(struct _cnid_db *cdb, const struct stat *st,
     TDB_DATA key, data; 
     int rc;      
     
-    if (!cdb || !(priv = cdb->_private) || !st || !name) {
+    if (!cdb || !(priv = cdb->cnid_db_private) || !st || !name) {
         errno = CNID_ERR_PARAM;
         return CNID_INVALID;
     }
@@ -183,7 +183,7 @@ cnid_t cnid_tdb_add(struct _cnid_db *cdb, const struct stat *st,
 
     key.dptr = (unsigned char *)&hint;
     key.dsize = sizeof(cnid_t);
-    if ((data.dptr = make_tdb_data(cdb->flags, lstp, did, name, len)) == NULL) {
+    if ((data.dptr = make_tdb_data(cdb->cnid_db_flags, lstp, did, name, len)) == NULL) {
         LOG(log_error, logtype_default, "tdb_add: Path name is too long");
         errno = CNID_ERR_PATH;
         return CNID_INVALID;
index c500181611549fb49deeddfabe646c30ec6aa6c8..4879e10bba415ef75a4f1bcc201653430df19d1d 100644 (file)
@@ -13,10 +13,9 @@ void cnid_tdb_close(struct _cnid_db *cdb)
 {
     struct _cnid_tdb_private *db;
 
-    free(cdb->volpath);
-    db = (struct _cnid_tdb_private *)cdb->_private;
+    db = (struct _cnid_tdb_private *)cdb->cnid_db_private;
     tdb_close(db->tdb_cnid);
-    free(cdb->_private);
+    free(cdb->cnid_db_private);
     free(cdb);
 }
 
index a16a99519327bcab826589b3995524b44a67b2d0..95441098bf807938476cd60e6ed1c8500e0ec7de 100644 (file)
@@ -19,7 +19,7 @@ int cnid_tdb_delete(struct _cnid_db *cdb, const cnid_t id)
     struct _cnid_tdb_private *db;
     TDB_DATA key, data;
 
-    if (!cdb || !(db = cdb->_private) || !id) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !id) {
         return -1;
     }
     memset(&key, 0, sizeof(key));
index 4e7f638dd18debb62470bc4f19b7bcb58be589e7..5c7536777eca193a7c80da3411e3172a3ceaf91c 100644 (file)
@@ -14,7 +14,7 @@ cnid_t cnid_tdb_get(struct _cnid_db *cdb, cnid_t did, const char *name, size_t l
     TDB_DATA key, data;
     cnid_t id;
 
-    if (!cdb || !(db = cdb->_private) || (len > MAXPATHLEN)) {
+    if (!cdb || !(db = cdb->cnid_db_private) || (len > MAXPATHLEN)) {
         return 0;
     }
 
index c95631afee52574c292cb0534b85b6a407cc6e0f..7c7bdff14c2fdfd3b5dcc9dc01420a5bc2dc1faa 100644 (file)
@@ -21,11 +21,11 @@ cnid_t cnid_tdb_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did,
     int update = 0;
     cnid_t id_devino = 0, id_didname = 0,id = 0;
 
-    if (!cdb || !(db = cdb->_private) || !st || !name) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !st || !name) {
         return 0;
     }
 
-    if ((buf = (char *)make_tdb_data(cdb->flags, st, did, name, len)) == NULL) {
+    if ((buf = (char *)make_tdb_data(cdb->cnid_db_flags, st, did, name, len)) == NULL) {
         LOG(log_error, logtype_default, "tdb_lookup: Pathname is too long");
         return 0;
     }
index 0aee5b4df5469ddbb3282c8d23d67f35f3bb3837..7e2558fe3c34fc13592f24e40df6ccd0a78c31e6 100644 (file)
@@ -12,6 +12,8 @@
 
 #include "cnid_tdb.h"
 #include <atalk/logger.h>
+#include <atalk/volume.h>
+
 #include <stdlib.h>
 #define DBHOME       ".AppleDB"
 #define DBHOMELEN    9                  /* strlen(DBHOME) +1 for / */
 #define DBVERSION2       0x00000002U
 #define DBVERSION        DBVERSION2
 
-static struct _cnid_db *cnid_tdb_new(const char *volpath)
+static struct _cnid_db *cnid_tdb_new(struct vol *vol)
 {
     struct _cnid_db *cdb;
-    struct _cnid_tdb_private *priv;
 
     if ((cdb = (struct _cnid_db *) calloc(1, sizeof(struct _cnid_db))) == NULL)
         return NULL;
 
-    if ((cdb->volpath = strdup(volpath)) == NULL) {
-        free(cdb);
-        return NULL;
-    }
+    cdb->cnid_db_vol = vol;
 
-    if ((cdb->_private = calloc(1, sizeof(struct _cnid_tdb_private))) == NULL) {
-        free(cdb->volpath);
+    if ((cdb->cnid_db_private = calloc(1, sizeof(struct _cnid_tdb_private))) == NULL) {
         free(cdb);
         return NULL;
     }
 
-    /* Set up private state */
-    priv = (struct _cnid_tdb_private *) (cdb->_private);
-
     /* Set up standard fields */
-    cdb->flags = CNID_FLAG_PERSISTENT;
+    cdb->cnid_db_flags = CNID_FLAG_PERSISTENT;
 
     cdb->cnid_add = cnid_tdb_add;
     cdb->cnid_delete = cnid_tdb_delete;
@@ -72,31 +66,27 @@ struct _cnid_db *cnid_tdb_open(struct cnid_open_args *args)
     TDB_DATA                  key, data;
     int                      hash_size = 131071;
     int                       tdb_flags = 0;
+    struct vol               *vol = args->cnid_args_vol;
 
-    if (!args->dir) {
-        /* note: dir and path are not used for in memory db */
+    if ((cdb = cnid_tdb_new(vol)) == NULL) {
+        LOG(log_error, logtype_default, "tdb_open: Unable to allocate memory for tdb");
         return NULL;
     }
 
-    if ((len = strlen(args->dir)) > (MAXPATHLEN - DBLEN - 1)) {
-        LOG(log_error, logtype_default, "tdb_open: Pathname too large: %s", args->dir);
-        return NULL;
-    }
-    
-    if ((cdb = cnid_tdb_new(args->dir)) == NULL) {
-        LOG(log_error, logtype_default, "tdb_open: Unable to allocate memory for tdb");
+    if ((len = strlen(vol->v_path)) > (MAXPATHLEN - DBLEN - 1)) {
+        LOG(log_error, logtype_default, "tdb_open: Pathname too large: %s", vol->v_path);
         return NULL;
     }
     
-    strcpy(path, args->dir);
+    strcpy(path, vol->v_path);
     if (path[len - 1] != '/') {
         strcat(path, "/");
         len++;
     }
  
     strcpy(path + len, DBHOME);
-    if (!(args->flags & CNID_FLAG_MEMORY)) {
-        if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777 & ~args->mask) < 0)) {
+    if (!(args->cnid_args_flags & CNID_FLAG_MEMORY)) {
+        if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777 & ~vol->v_umask) < 0)) {
             LOG(log_error, logtype_default, "tdb_open: DBHOME mkdir failed for %s", path);
             goto fail;
         }
@@ -107,12 +97,12 @@ struct _cnid_db *cnid_tdb_open(struct cnid_open_args *args)
     }
     strcat(path, "/");
  
-    db = (struct _cnid_tdb_private *)cdb->_private;
+    db = (struct _cnid_tdb_private *)cdb->cnid_db_private;
 
     path[len + DBHOMELEN] = '\0';
     strcat(path, DBCNID);
 
-    db->tdb_cnid = tdb_open(path, hash_size, tdb_flags , O_RDWR | O_CREAT, 0666 & ~args->mask);
+    db->tdb_cnid = tdb_open(path, hash_size, tdb_flags , O_RDWR | O_CREAT, 0666 & ~vol->v_umask);
     if (!db->tdb_cnid) {
         LOG(log_error, logtype_default, "tdb_open: unable to open tdb", path);
         goto fail;
@@ -146,8 +136,7 @@ struct _cnid_db *cnid_tdb_open(struct cnid_open_args *args)
     return cdb;
 
 fail:
-    free(cdb->_private);
-    free(cdb->volpath);
+    free(cdb->cnid_db_private);
     free(cdb);
     
     return NULL;
index 851f9e55e7be86811bb4106018411f0cc98b5a30..b999ca3e001d73b6d5271149b52c3a3e814dc773 100644 (file)
@@ -15,7 +15,7 @@ char *cnid_tdb_resolve(struct _cnid_db *cdb, cnid_t * id, void *buffer, size_t l
     struct _cnid_tdb_private *db;
     TDB_DATA key, data;      
 
-    if (!cdb || !(db = cdb->_private) || !id || !(*id)) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !id || !(*id)) {
         return NULL;
     }
     key.dptr  = (unsigned char *)id;
index 6d23b109f528ab71aad7de553339d534fd85431e..9688d866c5c5490a16751de56d89ea144298e9b5 100644 (file)
@@ -13,7 +13,7 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
     struct _cnid_tdb_private *db;
     TDB_DATA key, data, altdata;
 
-    if (!cdb || !(db = cdb->_private) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO)) {
+    if (!cdb || !(db = cdb->cnid_db_private) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO)) {
         return -1;
     }
 
@@ -22,7 +22,7 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
 
 
     /* Get the old info. search by dev/ino */
-    data.dptr = make_tdb_data(cdb->flags, st, did, name, len);
+    data.dptr = make_tdb_data(cdb->cnid_db_flags, st, did, name, len);
     data.dsize = CNID_HEADER_LEN + len + 1;
     key.dptr = data.dptr +CNID_DEVINO_OFS;
     key.dsize = CNID_DEVINO_LEN;
@@ -47,7 +47,7 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
     }
 
     /* search by did/name */
-    data.dptr = make_tdb_data(cdb->flags, st, did, name, len);
+    data.dptr = make_tdb_data(cdb->cnid_db_flags, st, did, name, len);
     data.dsize = CNID_HEADER_LEN + len + 1;
     key.dptr = (unsigned char *)data.dptr +CNID_DID_OFS;
     key.dsize = data.dsize - CNID_DID_OFS;
@@ -71,7 +71,7 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
     
 
     /* Make a new entry. */
-    data.dptr = make_tdb_data(cdb->flags, st, did, name, len);
+    data.dptr = make_tdb_data(cdb->cnid_db_flags, st, did, name, len);
     data.dsize = CNID_HEADER_LEN + len + 1;
     memcpy(data.dptr, &id, sizeof(id));
 
index 2bb6d9f8e6c611cad306c2d6874888601a9eecfb..482aa7776420cd4330a4b8faa59c867a70bcba7b 100644 (file)
@@ -1677,13 +1677,15 @@ struct vol *getvolbypath(AFPObj *obj, const char *path)
         subpath = prw;
 
     strlcat(tmpbuf, user, MAXPATHLEN);
-    if (getpwnam(user) == NULL) {
+    if ((pw = getpwnam(user)) == NULL) {
         /* (5b) */
         char *tuser;
         if ((tuser = getuserbypath(tmpbuf)) != NULL) {
             free(user);
             user = strdup(tuser);
         }
+        if ((pw = getpwnam(user)) == NULL)
+            EC_FAIL_LOG("unknown user: %s", user);
     }
     strlcpy(obj->username, user, MAXUSERLEN);
     strlcat(tmpbuf, "/", MAXPATHLEN);
index 37bfe140fe3d1d0101ab966a55ee90db3f67b9d8..dcef1c821856c1d04a1d38517119ac3412ac8f81 100644 (file)
@@ -436,7 +436,7 @@ char *realpath_safe(const char *path)
 
 #ifdef REALPATH_TAKES_NULL
     if ((resolved_path = realpath(path, NULL)) == NULL) {
-        LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path);
+        LOG(log_debug, logtype_afpd, "realpath() cannot resolve path \"%s\"", path);
         return NULL;
     }
     return resolved_path;
@@ -445,7 +445,7 @@ char *realpath_safe(const char *path)
         return NULL;
     if (realpath(path, resolved_path) == NULL) {
         free(resolved_path);
-        LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path);
+        LOG(log_debug, logtype_afpd, "realpath() cannot resolve path \"%s\"", path);
         return NULL;
     }
     /* Safe some memory */
index ad233a9bd0d7493738f6792852ca363f74247224..fb60ce9a11ff817b57bc0308de69bf64fc6c9a76 100644 (file)
@@ -31,7 +31,7 @@
 dbd \- CNID database maintenance
 .SH "SYNOPSIS"
 .HP \w'\fBdbd\fR\fB\fR\ 'u
-\fBdbd\fR\fB\fR [\-fsv] \fIvolumepath\fR
+\fBdbd\fR\fB\fR [\-cfFstuvV] \fIvolumepath\fR
 .SH "DESCRIPTION"
 .PP
 \fBdbd\fR
@@ -63,6 +63,11 @@ scan volume: treat the volume as read only and don\*(Aqt perform any filesystem
 show statistics while running
 .RE
 .PP
+\-u
+.RS 4
+username for use with AFP volumes using user variable $u
+.RE
+.PP
 \-v
 .RS 4
 verbose
index e90e4014ebd9438d1f78412a265496431bceced8..723cf6898ae452f3b34688ec03d18d7c056b44ca 100644 (file)
@@ -174,7 +174,7 @@ in parentheses indicates that a parameter is specific to the [Global] section\&.
 indicates that a parameter can be specified in a volume specific section\&.
 .SH "VARIABLE SUBSTITUTIONS"
 .PP
-You can use variables in volume names\&. The use of variables in paths is not supported for now\&.
+You can use variables in volume names\&. The use of variables in paths is limited to $u\&.
 .sp
 .RS 4
 .ie n \{\