]> arthur.barton.de Git - netatalk.git/commitdiff
Move volume loading to libatalk
authorFrank Lahm <franklahm@googlemail.com>
Fri, 17 Feb 2012 10:11:41 +0000 (11:11 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Fri, 17 Feb 2012 10:11:41 +0000 (11:11 +0100)
32 files changed:
etc/afpd/acls.c
etc/afpd/acls.h
etc/afpd/afp_config.c
etc/afpd/afp_dsi.c
etc/afpd/afp_options.c
etc/afpd/appl.c
etc/afpd/auth.c
etc/afpd/catsearch.c
etc/afpd/desktop.c
etc/afpd/dircache.h
etc/afpd/directory.c
etc/afpd/directory.h
etc/afpd/enumerate.c
etc/afpd/file.c
etc/afpd/file.h
etc/afpd/filedir.c
etc/afpd/fork.c
etc/afpd/main.c
etc/afpd/quota.c
etc/afpd/status.h
etc/afpd/unix.c
etc/afpd/unix.h
etc/afpd/volume.c
etc/afpd/volume.h
include/atalk/Makefile.am
include/atalk/globals.h
include/atalk/netatalk_conf.h [new file with mode: 0644]
include/atalk/unix.h
include/atalk/volume.h
libatalk/util/Makefile.am
libatalk/util/logger.c
libatalk/util/unix.c

index 40281bcc9b079260922af9db90b38a0c879f5069..8cb44d8a20a9e12f26ae7a63927f40d93a345a12 100644 (file)
@@ -45,6 +45,8 @@
 #include <atalk/acl.h>
 #include <atalk/bstrlib.h>
 #include <atalk/bstradd.h>
+#include <atalk/unix.h>
+#include <atalk/netatalk_conf.h>
 
 #include "directory.h"
 #include "desktop.h"
@@ -397,7 +399,9 @@ EC_CLEANUP:
  *
  * @returns                  0 or -1 on error
  */
-static int posix_acl_rights(const char *path,
+
+static int posix_acl_rights(const AFPObj *obj,
+                            const char *path,
                             const struct stat *sb,
                             uint32_t *result)
 {
@@ -422,7 +426,7 @@ static int posix_acl_rights(const char *path,
 
         switch (tag) {
             case ACL_USER_OBJ:
-                if (sb->st_uid == uuid) {
+                if (sb->st_uid == obj->uid) {
                     LOG(log_maxdebug, logtype_afpd, "ACL_USER_OBJ: %u", sb->st_uid);
                     rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
                 }
@@ -431,7 +435,7 @@ static int posix_acl_rights(const char *path,
             case ACL_USER:
                 EC_NULL_LOG(uid = (uid_t *)acl_get_qualifier(e));
 
-                if (*uid == uuid) {
+                if (*uid == obj->uid) {
                     LOG(log_maxdebug, logtype_afpd, "ACL_USER: %u", *uid);
                     acl_rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
                 }
@@ -440,7 +444,7 @@ static int posix_acl_rights(const char *path,
                 break;
 
             case ACL_GROUP_OBJ:
-                if (!(sb->st_uid == uuid) && gmem(sb->st_gid)) {
+                if (!(sb->st_uid == obj->uid) && gmem(sb->st_gid, obj->ngroups, obj->groups)) {
                     LOG(log_maxdebug, logtype_afpd, "ACL_GROUP_OBJ: %u", sb->st_gid);
                     acl_rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
                 }
@@ -449,7 +453,7 @@ static int posix_acl_rights(const char *path,
             case ACL_GROUP:
                 EC_NULL_LOG(gid = (gid_t *)acl_get_qualifier(e));
 
-                if (gmem(*gid)) {
+                if (gmem(*gid, obj->ngroups, obj->groups)) {
                     LOG(log_maxdebug, logtype_afpd, "ACL_GROUP: %u", *gid);
                     acl_rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
                 }
@@ -463,7 +467,7 @@ static int posix_acl_rights(const char *path,
                 break;
 
             case ACL_OTHER:
-                if (!(sb->st_uid == uuid) && !gmem(sb->st_gid)) {
+                if (!(sb->st_uid == obj->uid) && !gmem(sb->st_gid, obj->ngroups, obj->groups)) {
                     LOG(log_maxdebug, logtype_afpd, "ACL_OTHER");
                     rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
                 }
@@ -541,7 +545,7 @@ static u_char acl_permset_to_uarights(acl_entry_t entry) {
  *
  * @returns                  0 or -1 on error
  */
-static int posix_acls_to_uaperms(const char *path, struct stat *sb, struct maccess *ma) {
+static int posix_acls_to_uaperms(const AFPObj *obj, const char *path, struct stat *sb, struct maccess *ma) {
     EC_INIT;
 
     int entry_id = ACL_FIRST_ENTRY;
@@ -567,7 +571,7 @@ static int posix_acls_to_uaperms(const char *path, struct stat *sb, struct macce
             case ACL_USER:
                 EC_NULL_LOG(uid = (uid_t *)acl_get_qualifier(entry));
 
-                if (*uid == uuid && !(whoami == sb->st_uid)) {
+                if (*uid == obj->uid && !(whoami == sb->st_uid)) {
                     LOG(log_maxdebug, logtype_afpd, "ACL_USER: %u", *uid);
                     acl_rights |= acl_permset_to_uarights(entry);
                 }
@@ -578,14 +582,14 @@ static int posix_acls_to_uaperms(const char *path, struct stat *sb, struct macce
                 group_rights = acl_permset_to_uarights(entry);
                 LOG(log_maxdebug, logtype_afpd, "ACL_GROUP_OBJ: %u", sb->st_gid);
 
-                if (gmem(sb->st_gid) && !(whoami == sb->st_uid))
+                if (gmem(sb->st_gid, obj->ngroups, obj->groups) && !(whoami == sb->st_uid))
                     acl_rights |= group_rights;
                 break;
 
             case ACL_GROUP:
                 EC_NULL_LOG(gid = (gid_t *)acl_get_qualifier(entry));
 
-                if (gmem(*gid) && !(whoami == sb->st_uid)) {
+                if (gmem(*gid, obj->ngroups, obj->groups) && !(whoami == sb->st_uid)) {
                     LOG(log_maxdebug, logtype_afpd, "ACL_GROUP: %u", *gid);
                     acl_rights |= acl_permset_to_uarights(entry);
                 }
@@ -1338,7 +1342,8 @@ EC_CLEANUP:
  *
  * @returns                    AFP result code
 */
-static int check_acl_access(const struct vol *vol,
+static int check_acl_access(const AFPObj *obj,
+                            const struct vol *vol,
                             struct dir *dir,
                             const char *path,
                             const uuidp_t uuid,
@@ -1385,7 +1390,7 @@ static int check_acl_access(const struct vol *vol,
         EC_ZERO_LOG(solaris_acl_rights(path, &st, &allowed_rights));
 #endif
 #ifdef HAVE_POSIX_ACLS
-        EC_ZERO_LOG(posix_acl_rights(path, &st, &allowed_rights));
+        EC_ZERO_LOG(posix_acl_rights(obj, path, &st, &allowed_rights));
 #endif
         /*
          * The DARWIN_ACE_DELETE right might implicitly result from write acces to the parent
@@ -1418,7 +1423,7 @@ static int check_acl_access(const struct vol *vol,
             EC_ZERO_LOG(solaris_acl_rights(cfrombstr(parent), &st, &parent_rights));
 #endif
 #ifdef HAVE_POSIX_ACLS
-            EC_ZERO_LOG(posix_acl_rights(path, &st, &parent_rights));
+            EC_ZERO_LOG(posix_acl_rights(obj, path, &st, &parent_rights));
 #endif
             if (parent_rights & (DARWIN_ACE_WRITE_DATA | DARWIN_ACE_DELETE_CHILD))
                 allowed_rights |= DARWIN_ACE_DELETE; /* man, that was a lot of work! */
@@ -1508,7 +1513,7 @@ int afp_access(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
         return AFPERR_NOOBJ;
     }
 
-    ret = check_acl_access(vol, dir, s_path->u_name, uuid, darwin_ace_rights);
+    ret = check_acl_access(obj, vol, dir, s_path->u_name, uuid, darwin_ace_rights);
 
     return ret;
 }
@@ -1716,12 +1721,12 @@ int afp_setacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
  * This is the magic function that makes ACLs usable by calculating
  * the access granted by ACEs to the logged in user.
  */
-int acltoownermode(const struct vol *vol, char *path, struct stat *st, struct maccess *ma)
+int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct stat *st, struct maccess *ma)
 {
     EC_INIT;
     uint32_t rights = 0;
 
-    if ( ! (AFPobj->options.flags & OPTION_ACL2MACCESS)
+    if ( ! (obj->options.flags & OPTION_ACL2MACCESS)
          || ! (vol->v_flags & AFPVOL_ACLS))
          return 0;
 
@@ -1742,7 +1747,7 @@ int acltoownermode(const struct vol *vol, char *path, struct stat *st, struct ma
 #endif
 
 #ifdef HAVE_POSIX_ACLS
-    EC_ZERO_LOG(posix_acls_to_uaperms(path, st, ma));
+    EC_ZERO_LOG(posix_acls_to_uaperms(obj, path, st, ma));
 #endif
 
     LOG(log_maxdebug, logtype_afpd, "resulting user maccess: 0x%02x group maccess: 0x%02x", ma->ma_user, ma->ma_group);
@@ -1750,39 +1755,3 @@ int acltoownermode(const struct vol *vol, char *path, struct stat *st, struct ma
 EC_CLEANUP:
     EC_EXIT;
 }
-
-/*!
- * Check whether a volume supports ACLs
- *
- * @param vol  (r) volume
- *
- * @returns        0 if not, 1 if yes
- */
-int check_vol_acl_support(const struct vol *vol)
-{
-    int ret = 0;
-
-#ifdef HAVE_SOLARIS_ACLS
-    ace_t *aces = NULL;
-    ret = 1;
-    if (get_nfsv4_acl(vol->v_path, &aces) == -1)
-        ret = 0;
-#endif
-#ifdef HAVE_POSIX_ACLS
-    acl_t acl = NULL;
-    ret = 1;
-    if ((acl = acl_get_file(vol->v_path, ACL_TYPE_ACCESS)) == NULL)
-        ret = 0;
-#endif
-
-#ifdef HAVE_SOLARIS_ACLS
-    if (aces) free(aces);
-#endif
-#ifdef HAVE_POSIX_ACLS
-    if (acl) acl_free(acl);
-#endif /* HAVE_POSIX_ACLS */
-
-    LOG(log_debug, logtype_afpd, "Volume \"%s\" ACL support: %s",
-        vol->v_path, ret ? "yes" : "no");
-    return ret;
-}
index 273a9f13e1cca3cdd31cfc659e1c4cafba6454ed..0913eb2e773a1e276233ee977bbf079d80c5b4cb 100644 (file)
@@ -113,6 +113,5 @@ int afp_setacl (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf,  size_t *rb
 extern int acl_ldap_readconfig(char *name);
 
 /* Misc funcs */
-extern int acltoownermode(const struct vol *vol, char *path, struct stat *st, struct maccess *ma);
-extern int check_vol_acl_support(const struct vol *vol);
+extern int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct stat *st, struct maccess *ma);
 #endif
index d853e0b4ac2eb3893bca7c577e020b9d3a7120b2..27767c10b509378588ba3262783ee57d60361966 100644 (file)
@@ -88,7 +88,7 @@ int configinit(AFPObj *obj)
 
     if (obj->options.listen) {
         EC_NULL( q = p = strdup(obj->options.listen) );
-        EC_NULL( p = strtok(p, ",") );
+        EC_NULL( p = strtok(p, ", ") );
     }
 
     while (1) {
@@ -105,7 +105,7 @@ int configinit(AFPObj *obj)
 
         if (p)
             /* p is NULL if ! obj->options.listen */
-            p = strtok(NULL, ",");
+            p = strtok(NULL, ", ");
         if (!p)
             break;
     }
@@ -124,6 +124,20 @@ int configinit(AFPObj *obj)
         zeroconf_register(obj);
     }
 
+    if ((p = iniparser_getstring(obj->iniconfig, INISEC_AFP, "fcelistener", NULL))) {
+               LOG(log_note, logtype_afpd, "Adding FCE listener: %s", p);
+               fce_add_udp_socket(p);
+    }
+    if ((p = iniparser_getstring(obj->iniconfig, INISEC_AFP, "fcecoalesce", NULL))) {
+               LOG(log_note, logtype_afpd, "Fce coalesce: %s", p);
+               fce_set_coalesce(p);
+    }
+    if ((p = iniparser_getstring(obj->iniconfig, INISEC_AFP, "fceevents", NULL))) {
+               LOG(log_note, logtype_afpd, "Fce events: %s", p);
+               fce_set_events(p);
+    }
+
+
 EC_CLEANUP:
     if (q)
         free(q);
index 2869722e6fbca2e6fb3857fa4042073076d3c2d1..fd38fa853db2523d355d57e64cf35fbdf1261bde 100644 (file)
@@ -37,6 +37,7 @@
 #include <atalk/server_ipc.h>
 #include <atalk/fce_api.h>
 #include <atalk/globals.h>
+#include <atalk/netatalk_conf.h>
 
 #include "switch.h"
 #include "auth.h"
@@ -528,7 +529,7 @@ void afp_over_dsi(AFPObj *obj)
 
         if (reload_request) {
             reload_request = 0;
-            load_volumes(AFPobj);
+            load_volumes(AFPobj, of_closevol);
         }
 
         /* The first SIGINT enables debugging, the next restores the config */
index 34253ee837f5108600735daa4098bede8e5b1d28..3b37538b642c312f212f6e1821dc601d6da34a84 100644 (file)
@@ -93,206 +93,6 @@ void afp_options_free(struct afp_options *opt)
         free(opt->unixcodepage);
 }
 
-#define MAXVAL 1024
-int afp_config_parse(AFPObj *AFPObj)
-{
-    EC_INIT;
-    dictionary *config;
-    struct afp_options *options = &AFPObj->options;
-    int i, c;
-    const char *p, *tmp;
-    char *q, *r;
-    char val[MAXVAL];
-
-    options->configfile  = AFPObj->cmdlineconfigfile ? strdup(AFPObj->cmdlineconfigfile) : strdup(_PATH_CONFDIR "afp.conf");
-    options->sigconffile = strdup(_PATH_CONFDIR "afp_signature.conf");
-    options->uuidconf    = strdup(_PATH_CONFDIR "afp_voluuid.conf");
-    options->flags       = OPTION_ACL2MACCESS | OPTION_UUID | OPTION_SERVERNOTIF | AFPObj->cmdlineflags;
-
-    if ((config = iniparser_load(AFPObj->options.configfile)) == NULL)
-        return -1;
-    AFPObj->iniconfig = config;
-
-    /* [Global] */
-    options->logconfig = iniparser_getstrdup(config, INISEC_GLOBAL, "loglevel", "default:note");
-    options->logfile   = iniparser_getstrdup(config, INISEC_GLOBAL, "logfile",  NULL);
-    set_processname("afpd");
-    setuplog(options->logconfig, options->logfile);
-
-    /* [AFP] "options" options wo values */
-    if (p = iniparser_getstrdup(config, INISEC_AFP, "options", NULL)) {
-        if (p = strtok(q, ", ")) {
-            while (p) {
-                if (strcasecmp(p, "nozeroconf"))
-                    options->flags |= OPTION_NOZEROCONF;
-                if (strcasecmp(p, "icon"))
-                    options->flags |= OPTION_CUSTOMICON;
-                if (strcasecmp(p, "noicon"))
-                    options->flags &= ~OPTION_CUSTOMICON;
-                if (strcasecmp(p, "advertise_ssh"))
-                    options->flags |= OPTION_ANNOUNCESSH;
-                if (strcasecmp(p, "noacl2maccess"))
-                    options->flags &= ~OPTION_ACL2MACCESS;
-                if (strcasecmp(p, "keepsessions"))
-                    options->flags |= OPTION_KEEPSESSIONS;
-                if (strcasecmp(p, "closevol"))
-                    options->flags |= OPTION_CLOSEVOL;
-                if (strcasecmp(p, "client_polling"))
-                    options->flags &= ~OPTION_SERVERNOTIF;
-                if (strcasecmp(p, "nosavepassword"))
-                    options->passwdbits |= PASSWD_NOSAVE;
-                if (strcasecmp(p, "savepassword"))
-                    options->passwdbits &= ~PASSWD_NOSAVE;
-                if (strcasecmp(p, "nosetpassword"))
-                    options->passwdbits &= ~PASSWD_SET;
-                if (strcasecmp(p, "setpassword"))
-                    options->passwdbits |= PASSWD_SET;
-                p = strtok(NULL, ",");
-            }
-        }
-    }
-    /* figure out options w values */
-
-    options->loginmesg      = iniparser_getstrdup(config, INISEC_AFP, "loginmesg",      "");
-    options->guest          = iniparser_getstrdup(config, INISEC_AFP, "guestname",      "nobody");
-    options->passwdfile     = iniparser_getstrdup(config, INISEC_AFP, "passwdfile",     _PATH_AFPDPWFILE);
-    options->uampath        = iniparser_getstrdup(config, INISEC_AFP, "uampath",        _PATH_AFPDUAMPATH);
-    options->uamlist        = iniparser_getstrdup(config, INISEC_AFP, "uamlist",        "uams_dhx.so,uams_dhx2.so");
-    options->port           = iniparser_getstrdup(config, INISEC_AFP, "port",           "548");
-    options->signatureopt   = iniparser_getstrdup(config, INISEC_AFP, "signature",      "auto");
-    options->k5service      = iniparser_getstrdup(config, INISEC_AFP, "k5service",      NULL);
-    options->k5realm        = iniparser_getstrdup(config, INISEC_AFP, "k5realm",        NULL);
-    options->authprintdir   = iniparser_getstrdup(config, INISEC_AFP, "authprintdir",   NULL);
-    options->listen         = iniparser_getstrdup(config, INISEC_AFP, "listen",         NULL);
-    options->ntdomain       = iniparser_getstrdup(config, INISEC_AFP, "ntdomain",       NULL);
-    options->ntseparator    = iniparser_getstrdup(config, INISEC_AFP, "ntseparator",    NULL);
-    options->mimicmodel     = iniparser_getstrdup(config, INISEC_AFP, "mimicmodel",     NULL);
-    options->adminauthuser  = iniparser_getstrdup(config, INISEC_AFP, "adminauthuser",  NULL);
-    options->connections    = iniparser_getint   (config, INISEC_AFP, "maxcon",         200);
-    options->passwdminlen   = iniparser_getint   (config, INISEC_AFP, "passwdminlen",   0);
-    options->tickleval      = iniparser_getint   (config, INISEC_AFP, "tickleval",      30);
-    options->timeout        = iniparser_getint   (config, INISEC_AFP, "timeout",        4);
-    options->dsireadbuf     = iniparser_getint   (config, INISEC_AFP, "dsireadbuf",     12);
-    options->server_quantum = iniparser_getint   (config, INISEC_AFP, "server_quantum", DSI_SERVQUANT_DEF);
-    options->volnamelen     = iniparser_getint   (config, INISEC_AFP, "volnamelen",     80);
-    options->dircachesize   = iniparser_getint   (config, INISEC_AFP, "dircachesize",   DEFAULT_MAX_DIRCACHE_SIZE);
-    options->tcp_sndbuf     = iniparser_getint   (config, INISEC_AFP, "tcpsndbuf",      0);
-    options->tcp_rcvbuf     = iniparser_getint   (config, INISEC_AFP, "tcprcvbuf",      0);
-    options->fce_fmodwait   = iniparser_getint   (config, INISEC_AFP, "fceholdfmod",    60);
-    options->sleep          = iniparser_getint   (config, INISEC_AFP, "sleep",          10) * 60 * 2;
-    options->disconnected   = iniparser_getint   (config, INISEC_AFP, "disconnect",     24) * 60 * 2;
-
-    if ((p = iniparser_getstring(config, INISEC_AFP, "hostname", NULL))) {
-        EC_NULL_LOG( options->hostname = strdup(p) );
-    } else {
-        if (gethostname(val, sizeof(val)) < 0 ) {
-            perror( "gethostname" );
-            EC_FAIL;
-        }
-        if ((q = strchr(val, '.')))
-            *q = '\0';
-        options->hostname = strdup(val);
-    }
-
-    if ((p = iniparser_getstring(config, INISEC_AFP, "k5keytab", NULL))) {
-        EC_NULL_LOG( options->k5keytab = malloc(strlen(p) + 14) );
-        snprintf(options->k5keytab, strlen(p) + 14, "KRB5_KTNAME=%s", p);
-        putenv(options->k5keytab);
-    }
-
-#ifdef ADMIN_GRP
-    if ((p = iniparser_getstring(config, INISEC_AFP, "admingroup",  NULL))) {
-         struct group *gr = getgrnam(p);
-         if (gr != NULL)
-             options->admingid = gr->gr_gid;
-    }
-#endif /* ADMIN_GRP */
-
-    q = iniparser_getstrdup(config, INISEC_AFP, "cnidserver", "localhost:4700");
-    r = strrchr(q, ':');
-    if (r)
-        *r = 0;
-    options->Cnid_srv = strdup(q);
-    if (r)
-        options->Cnid_port = strdup(r + 1);
-    else
-        options->Cnid_port = strdup("4700");
-    LOG(log_debug, logtype_afpd, "CNID Server: %s:%s", options->Cnid_srv, options->Cnid_port);
-    if (q)
-        free(q);
-
-    if ((q = iniparser_getstrdup(config, INISEC_AFP, "fqdn", NULL))) {
-        /* do a little checking for the domain name. */
-        r = strchr(q, ':');
-        if (r)
-            *r = '\0';
-        if (gethostbyname(q)) {
-            if (r)
-                *r = ':';
-            EC_NULL_LOG( options->fqdn = strdup(q) );
-        } else {
-            LOG(log_error, logtype_afpd, "error parsing -fqdn, gethostbyname failed for: %s", c);
-        }
-        free(q);
-    }
-
-    if (!(p = iniparser_getstring(config, INISEC_AFP, "unixcodepage", NULL))) {
-        options->unixcharset = CH_UNIX;
-        options->unixcodepage = strdup("LOCALE");
-    } else {
-        if ((options->unixcharset = add_charset(p)) == (charset_t)-1) {
-            options->unixcharset = CH_UNIX;
-            options->unixcodepage = strdup("LOCALE");
-            LOG(log_warning, logtype_afpd, "Setting Unix codepage to '%s' failed", p);
-        } else {
-            options->unixcodepage = strdup(p);
-        }
-    }
-       
-    if (!(p = iniparser_getstring(config, INISEC_AFP, "maccodepage", NULL))) {
-        options->maccharset = CH_MAC;
-        options->maccodepage = strdup("MAC_ROMAN");
-    } else {
-        if ((options->maccharset = add_charset(p)) == (charset_t)-1) {
-            options->maccharset = CH_MAC;
-            options->maccodepage = strdup("MAC_ROMAN");
-            LOG(log_warning, logtype_afpd, "Setting Unix codepage to '%s' failed", p);
-        } else {
-            options->maccodepage = strdup(p);
-        }
-    }
-
-    if ((p = iniparser_getstring(config, INISEC_AFP, "fcelistener", NULL))) {
-               LOG(log_note, logtype_afpd, "Adding FCE listener: %s", p);
-               fce_add_udp_socket(p);
-    }
-    if ((p = iniparser_getstring(config, INISEC_AFP, "fcecoalesce", NULL))) {
-               LOG(log_note, logtype_afpd, "Fce coalesce: %s", p);
-               fce_set_coalesce(p);
-    }
-    if ((p = iniparser_getstring(config, INISEC_AFP, "fceevents", NULL))) {
-               LOG(log_note, logtype_afpd, "Fce events: %s", p);
-               fce_set_events(p);
-    }
-
-    /* Check for sane values */
-    if (options->tickleval <= 0)
-        options->tickleval = 30;
-    if (options->timeout <= 0)
-        options->timeout = 4;
-    if (options->sleep <= 4)
-        options->disconnected = options->sleep = 4;
-    if (options->dsireadbuf < 6)
-        options->dsireadbuf = 6;
-    if (options->volnamelen < 8)
-        options->volnamelen = 8; /* max mangled volname "???#FFFF" */
-    if (options->volnamelen > 255)
-           options->volnamelen = 255; /* AFP3 spec */
-
-EC_CLEANUP:
-    EC_EXIT;
-}
-
 /*
  * Show version information about afpd.
  * Used by "afp -v".
index 59de70e37a4d2ab04a9719f0b80d0b89ea519106..379fae22efd1344dfee7ebdf6e7f01992c35b6ce 100644 (file)
@@ -23,6 +23,7 @@
 #include <atalk/bstrlib.h>
 #include <atalk/bstradd.h>
 #include <atalk/globals.h>
+#include <atalk/netatalk_conf.h>
 
 #include "volume.h"
 #include "directory.h"
@@ -481,7 +482,7 @@ int afp_getappl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
         return( AFPERR_NOITEM );
     }
     buflen = *rbuflen - sizeof( bitmap ) - sizeof( appltag );
-    if ( getfilparams(vol, bitmap, path, curdir, rbuf + sizeof( bitmap ) +
+    if ( getfilparams(obj, vol, bitmap, path, curdir, rbuf + sizeof( bitmap ) +
                       sizeof( appltag ), &buflen ) != AFP_OK ) {
         *rbuflen = 0;
         return( AFPERR_BITMAP );
index aff77956e69b55bb6cfd2fe63b92d41cf11d31ea..d6054f54b6360a2c232c589c51f28a6c2e25ff78 100644 (file)
@@ -52,22 +52,6 @@ extern void afp_get_cmdline( int *ac, char ***av );
 
 int afp_version = 11;
 static int afp_version_index;
-
-uid_t   uuid;
-
-#if defined( sun ) && !defined( __svr4__ ) || defined( ultrix )
-
-int *groups;
-#define GROUPS_SIZE sizeof(int)
-
-#else /* sun __svr4__ ultrix */
-
-gid_t   *groups;
-#define GROUPS_SIZE sizeof(gid_t)
-#endif /* sun ultrix */
-
-int ngroups;
-
 static struct uam_mod uam_modules = {NULL, NULL, &uam_modules, &uam_modules};
 static struct uam_obj uam_login = {"", "", 0, {{NULL, NULL, NULL, NULL }}, &uam_login,
                                    &uam_login};
@@ -270,17 +254,17 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi
 
     /* Basically if the user is in the admin group, we stay root */
 
-    if (( ngroups = getgroups( 0, NULL )) < 0 ) {
+    if ((obj->ngroups = getgroups( 0, NULL )) < 0 ) {
         LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno) );
         return AFPERR_BADUAM;
     }
 
-    if ( NULL == (groups = calloc(ngroups, GROUPS_SIZE)) ) {
-        LOG(log_error, logtype_afpd, "login: %s calloc: %d", ngroups);
+    if ( NULL == (obj->groups = calloc(obj->ngroups, sizeof(gid_t))) ) {
+        LOG(log_error, logtype_afpd, "login: %s calloc: %d", obj->ngroups);
         return AFPERR_BADUAM;
     }
 
-    if (( ngroups = getgroups( ngroups, groups )) < 0 ) {
+    if (( obj->ngroups = getgroups(obj->ngroups, obj->groups )) < 0 ) {
         LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno) );
         return AFPERR_BADUAM;
     }
@@ -290,8 +274,8 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi
 
     if (obj->options.admingid != 0) {
         int i;
-        for (i = 0; i < ngroups; i++) {
-            if (groups[i] == obj->options.admingid) admin = 1;
+        for (i = 0; i < obj->ngroups; i++) {
+            if (obj->groups[i] == obj->options.admingid) admin = 1;
         }
     }
     if (admin) {
@@ -342,15 +326,15 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi
     }
 #endif /* TRU64 */
 
-    LOG(log_debug, logtype_afpd, "login: supplementary groups: %s", print_groups(ngroups, groups));
+    LOG(log_debug, logtype_afpd, "login: supplementary groups: %s", print_groups(obj->ngroups, obj->groups));
 
     /* There's probably a better way to do this, but for now, we just play root */
 #ifdef ADMIN_GRP
     if (admin)
-        uuid = 0;
+        obj->uid = 0;
     else
 #endif /* ADMIN_GRP */
-        uuid = pwd->pw_uid;
+        obj->uid = geteuid();
 
     set_auth_switch(expired);
     /* save our euid, we need it for preexec_close */
index ad28c6f668d4f36f539d1884c2bd61d3f83f2351..3a6f4cc95757ea20d6ccc34bd656c1c42d83ff5e 100644 (file)
@@ -48,6 +48,7 @@
 #include <atalk/bstradd.h>
 #include <atalk/unicode.h>
 #include <atalk/globals.h>
+#include <atalk/netatalk_conf.h>
 
 #include "desktop.h"
 #include "directory.h"
@@ -423,7 +424,7 @@ crit_check_ret:
 }  
 
 /* ------------------------------ */
-static int rslt_add ( struct vol *vol, struct path *path, char **buf, int ext)
+static int rslt_add (const AFPObj *obj, struct vol *vol, struct path *path, char **buf, int ext)
 {
 
        char            *p = *buf;
@@ -446,11 +447,11 @@ static int rslt_add ( struct vol *vol, struct path *path, char **buf, int ext)
        }
        
        if ( isdir ) {
-        ret = getdirparams(vol, c1.dbitmap, path, path->d_dir, p , &tbuf ); 
+        ret = getdirparams(obj, vol, c1.dbitmap, path, path->d_dir, p , &tbuf ); 
        }
        else {
            /* FIXME slow if we need the file ID, we already know it, done ? */
-               ret = getfilparams ( vol, c1.fbitmap, path, path->d_dir, p, &tbuf);
+               ret = getfilparams (obj, vol, c1.fbitmap, path, path->d_dir, p, &tbuf);
        }
 
        if ( ret != AFP_OK )
@@ -493,7 +494,8 @@ static int rslt_add ( struct vol *vol, struct path *path, char **buf, int ext)
  * @param ext       (r)  extended search flag
  */
 #define NUM_ROUNDS 200
-static int catsearch(struct vol *vol,
+static int catsearch(const AFPObj *obj,
+                     struct vol *vol,
                      struct dir *dir,  
                      int rmatches,
                      uint32_t *pos,
@@ -644,7 +646,7 @@ static int catsearch(struct vol *vol,
 
                        /* bit 0 means that criteria has been met */
                        if ((ccr & 1)) {
-                               r = rslt_add ( vol, &path, &rrbuf, ext);
+                               r = rslt_add (obj, vol, &path, &rrbuf, ext);
                                
                                if (r == 0) {
                                        result = AFPERR_MISC;
@@ -706,7 +708,8 @@ catsearch_end: /* Exiting catsearch: error condition */
  * @param rsize     (w)  length of data written to output buffer
  * @param ext       (r)  extended search flag
  */
-static int catsearch_db(struct vol *vol,
+static int catsearch_db(const AFPObj *obj,
+                        struct vol *vol,
                         struct dir *dir,  
                         const char *uname,
                         int rmatches,
@@ -810,7 +813,7 @@ static int catsearch_db(struct vol *vol,
             LOG(log_debug, logtype_afpd,"catsearch_db: match: %s/%s",
                 getcwdpath(), path.u_name);
             /* bit 1 means that criteria has been met */
-            r = rslt_add(vol, &path, &rrbuf, ext);
+            r = rslt_add(obj, vol, &path, &rrbuf, ext);
             if (r == 0) {
                 result = AFPERR_MISC;
                 goto catsearch_end;
@@ -1050,10 +1053,10 @@ static int catsearch_afp(AFPObj *obj _U_, char *ibuf, size_t ibuflen,
         && (strcmp(vol->v_cnidscheme, "dbd") == 0)
         && (vol->v_flags & AFPVOL_SEARCHDB))
         /* we've got a name and it's a dbd volume, so search CNID database */
-        ret = catsearch_db(vol, vol->v_root, uname, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize, ext);
+        ret = catsearch_db(obj, vol, vol->v_root, uname, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize, ext);
     else
         /* perform a slow filesystem tree search */
-        ret = catsearch(vol, vol->v_root, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize, ext);
+        ret = catsearch(obj, vol, vol->v_root, rmatches, &catpos[0], rbuf+24, &nrecs, &rsize, ext);
 
     memcpy(rbuf, catpos, sizeof(catpos));
     rbuf += sizeof(catpos);
index 258f3e5fc04735307a24dd30a33b40a08d1280fc..afcf41786e1f81937ba4f73413ddee0ea388b375 100644 (file)
@@ -28,6 +28,8 @@
 #include <atalk/util.h>
 #include <atalk/logger.h>
 #include <atalk/globals.h>
+#include <atalk/netatalk_conf.h>
+
 #include "volume.h"
 #include "directory.h"
 #include "fork.h"
@@ -618,7 +620,7 @@ utompath_error:
 }
 
 /* ------------------------- */
-static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf)
+static int ad_addcomment(const AFPObj *obj, struct vol *vol, struct path *path, char *ibuf)
 {
     struct ofork        *of;
     char                *name, *upath;
@@ -630,7 +632,7 @@ static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf)
     clen = min( clen, 199 );
 
     upath = path->u_name;
-    if (check_access(upath, OPENACC_WR ) < 0) {
+    if (check_access(obj, vol, upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
     }
     
@@ -665,7 +667,7 @@ static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf)
 }
 
 /* ----------------------------- */
-int afp_addcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
+int afp_addcomment(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
 {
     struct vol         *vol;
     struct dir         *dir;
@@ -696,7 +698,7 @@ int afp_addcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _
         ibuf++;
     }
 
-    return ad_addcomment(vol, path, ibuf);
+    return ad_addcomment(obj, vol, path, ibuf);
 }
 
 /* -------------------- */
@@ -774,7 +776,7 @@ int afp_getcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf,
 }
 
 /* ----------------------- */
-static int ad_rmvcomment(struct vol *vol, struct path *path)
+static int ad_rmvcomment(const AFPObj *obj, struct vol *vol, struct path *path)
 {
     struct adouble     ad, *adp;
     struct ofork        *of;
@@ -782,7 +784,7 @@ static int ad_rmvcomment(struct vol *vol, struct path *path)
     char               *upath;
 
     upath = path->u_name;
-    if (check_access(upath, OPENACC_WR ) < 0) {
+    if (check_access(obj, vol, upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
     }
 
@@ -840,5 +842,5 @@ int afp_rmvcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _
        return get_afp_errno(AFPERR_NOOBJ);
     }
     
-    return ad_rmvcomment(vol, s_path);
+    return ad_rmvcomment(obj, vol, s_path);
 }
index 42466d2dc67f004ba10c6b35779a6170f28699c2..0b79da01e182f3ad11f2e984c903a28dca0f6c16 100644 (file)
@@ -21,7 +21,6 @@
 #include <atalk/directory.h>
 
 /* Maximum size of the dircache hashtable */
-#define DEFAULT_MAX_DIRCACHE_SIZE 8192
 #define MAX_POSSIBLE_DIRCACHE_SIZE 131072
 #define DIRCACHE_FREE_QUANTUM 256
 
index 905c3bd99deb27f0e8c3f3a8845bbff633104cf1..844d346a1f9d45d6c804d33c7ed06798d051503b 100644 (file)
@@ -32,6 +32,7 @@
 #include <atalk/errchk.h>
 #include <atalk/globals.h>
 #include <atalk/fce_api.h>
+#include <atalk/netatalk_conf.h>
 
 #include "directory.h"
 #include "dircache.h"
@@ -1413,11 +1414,8 @@ int movecwd(const struct vol *vol, struct dir *dir)
  * If we aren't the file's owner we can't change its perms when moving it and smb
  * nfs,... don't even try.
  */
-#define AFP_CHECK_ACCESS
-
-int check_access(char *path, int mode)
+int check_access(const AFPObj *obj, struct vol *vol, char *path, int mode)
 {
-#ifdef AFP_CHECK_ACCESS
     struct maccess ma;
     char *p;
 
@@ -1425,21 +1423,21 @@ int check_access(char *path, int mode)
     if (!p)
         return -1;
 
-    accessmode(current_vol, p, &ma, curdir, NULL);
+    accessmode(obj, vol, p, &ma, curdir, NULL);
     if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE))
         return -1;
     if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD))
         return -1;
-#endif
+
     return 0;
 }
 
 /* --------------------- */
-int file_access(struct path *path, int mode)
+int file_access(const AFPObj *obj, struct vol *vol, struct path *path, int mode)
 {
     struct maccess ma;
 
-    accessmode(current_vol, path->u_name, &ma, curdir, &path->st);
+    accessmode(obj, vol, path->u_name, &ma, curdir, &path->st);
 
     LOG(log_debug, logtype_afpd, "file_access(\"%s\"): mapped user mode: 0x%02x",
         path->u_name, ma.ma_user);
@@ -1478,7 +1476,8 @@ int dirreenumerate(struct dir *dir, struct stat *st)
    (name, dir) with curdir:name == dir, from afp_enumerate
 */
 
-int getdirparams(const struct vol *vol,
+int getdirparams(const AFPObj *obj,
+                 const struct vol *vol,
                  uint16_t bitmap, struct path *s_path,
                  struct dir *dir,
                  char *buf, size_t *buflen )
@@ -1643,7 +1642,7 @@ int getdirparams(const struct vol *vol,
             break;
 
         case DIRPBIT_ACCESS :
-            accessmode(vol, upath, &ma, dir , st);
+            accessmode(obj, vol, upath, &ma, dir , st);
 
             *data++ = ma.ma_user;
             *data++ = ma.ma_world;
@@ -1679,7 +1678,7 @@ int getdirparams(const struct vol *vol,
 
         case DIRPBIT_UNIXPR :
             /* accessmode may change st_mode with ACLs */
-            accessmode(vol, upath, &ma, dir, st);
+            accessmode(obj, vol, upath, &ma, dir, st);
 
             aint = htonl(st->st_uid);
             memcpy( data, &aint, sizeof( aint ));
index 533d30f9fe8ba39dc9b1c8034106131cbdfa14eb..0ef2426ed8d44e7c7a21bbe094c67e16fea0b8a9 100644 (file)
@@ -111,8 +111,7 @@ extern struct path *cname (struct vol *, struct dir *, char **);
 
 extern int         deletecurdir (struct vol *);
 extern mode_t      mtoumode (struct maccess *);
-extern void        utommode (struct stat *, struct maccess *);
-extern int         getdirparams (const struct vol *, uint16_t, struct path *,
+extern int         getdirparams (const AFPObj *obj, const struct vol *, uint16_t, struct path *,
                                  struct dir *, char *, size_t *);
 
 extern int         setdirparams(struct vol *, struct path *, uint16_t, char *);
@@ -122,8 +121,8 @@ extern int         path_error(struct path *, int error);
 extern void        setdiroffcnt(struct dir *dir, struct stat *st,  uint32_t count);
 extern int         dirreenumerate(struct dir *dir, struct stat *st);
 extern int         for_each_dirent(const struct vol *, char *, dir_loop , void *);
-extern int         check_access(char *name , int mode);
-extern int         file_access(struct path *path, int mode);
+extern int         check_access(const AFPObj *obj, struct vol *, char *name , int mode);
+extern int         file_access(const AFPObj *obj, struct vol *vol, struct path *path, int mode);
 extern int         netatalk_unlink (const char *name);
 extern int         caseenumerate (const struct vol *, struct path *, struct dir *);
 
index 1a44aa7f6afb210d11aa98a957920f9b17cf8d63..80759a439cf61bfed6f088b0641bf5e4c48a907a 100644 (file)
@@ -23,6 +23,7 @@
 #include <atalk/bstrlib.h>
 #include <atalk/bstradd.h>
 #include <atalk/globals.h>
+#include <atalk/netatalk_conf.h>
 
 #include "desktop.h"
 #include "directory.h"
@@ -386,7 +387,7 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_,
                     return AFPERR_MISC;
                 }
             }
-            if ((ret = getdirparams(vol, dbitmap, &s_path, dir, data + header , &esz)) != AFP_OK)
+            if ((ret = getdirparams(obj, vol, dbitmap, &s_path, dir, data + header , &esz)) != AFP_OK)
                 return( ret );
 
         } else {
@@ -394,8 +395,8 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_,
                 continue;
             }
             /* files are added to the dircache in getfilparams() -> getmetadata() */
-            if (AFP_OK != ( ret = getfilparams(vol, fbitmap, &s_path, curdir, 
-                                     data + header , &esz )) ) {
+            if (AFP_OK != ( ret = getfilparams(obj, vol, fbitmap, &s_path, curdir, 
+                                               data + header , &esz )) ) {
                 return( ret );
             }
         }
index ce2ab545efd90edb12b869e7c4dfd80a0c3c230c..07813ef4ccb05f51c8cab5fb4e87958a25fdf1fc 100644 (file)
@@ -24,6 +24,7 @@
 #include <atalk/unix.h>
 #include <atalk/globals.h>
 #include <atalk/fce_api.h>
+#include <atalk/netatalk_conf.h>
 
 #include "directory.h"
 #include "dircache.h"
@@ -274,10 +275,11 @@ exit:
 }
              
 /* -------------------------- */
-int getmetadata(struct vol *vol,
-                 uint16_t bitmap,
-                 struct path *path, struct dir *dir, 
-                 char *buf, size_t *buflen, struct adouble *adp)
+int getmetadata(const AFPObj *obj,
+                struct vol *vol,
+                uint16_t bitmap,
+                struct path *path, struct dir *dir, 
+                char *buf, size_t *buflen, struct adouble *adp)
 {
     char               *data, *l_nameoff = NULL, *upath;
     char                *utf_nameoff = NULL;
@@ -536,7 +538,7 @@ int getmetadata(struct vol *vol,
             break;
         case FILPBIT_UNIXPR :
             /* accessmode may change st_mode with ACLs */
-            accessmode(vol, upath, &ma, dir , st);
+            accessmode(obj, vol, upath, &ma, dir , st);
 
             aint = htonl(st->st_uid);
             memcpy( data, &aint, sizeof( aint ));
@@ -589,7 +591,8 @@ int getmetadata(struct vol *vol,
 }
                 
 /* ----------------------- */
-int getfilparams(struct vol *vol,
+int getfilparams(const AFPObj *obj,
+                 struct vol *vol,
                  uint16_t bitmap,
                  struct path *path, struct dir *dir, 
                  char *buf, size_t *buflen )
@@ -627,7 +630,7 @@ int getfilparams(struct vol *vol,
             }
         }
     }
-    rc = getmetadata(vol, bitmap, path, dir, buf, buflen, adp);
+    rc = getmetadata(obj, vol, bitmap, path, dir, buf, buflen, adp);
     ad_close(adp, ADFLAGS_HF | flags);
 
     return( rc );
@@ -784,7 +787,7 @@ int afp_setfilparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
         ibuf++;
     }
 
-    if (AFP_OK == ( rc = setfilparams(vol, s_path, bitmap, ibuf )) ) {
+    if (AFP_OK == ( rc = setfilparams(obj, vol, s_path, bitmap, ibuf )) ) {
         setvoltime(obj, vol );
     }
 
@@ -797,7 +800,7 @@ int afp_setfilparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
 */
 extern struct path Cur_Path;
 
-int setfilparams(struct vol *vol,
+int setfilparams(const AFPObj *obj, struct vol *vol,
                  struct path *path, uint16_t f_bitmap, char *buf )
 {
     struct adouble     ad, *adp;
@@ -828,7 +831,7 @@ int setfilparams(struct vol *vol,
     adp = of_ad(vol, path, &ad);
     upath = path->u_name;
 
-    if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) {
+    if (!vol_unix_priv(vol) && check_access(obj, vol, upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
     }
 
@@ -1768,8 +1771,8 @@ retry:
         return AFPERR_NOID;
     }
     path.id = cnid;
-    if (AFP_OK != (err = getfilparams(vol, bitmap, &path , curdir, 
-                            rbuf + sizeof(bitmap), &buflen))) {
+    if (AFP_OK != (err = getfilparams(obj, vol, bitmap, &path , curdir, 
+                                      rbuf + sizeof(bitmap), &buflen))) {
         return err;
     }
     *rbuflen = buflen + sizeof(bitmap);
@@ -1862,7 +1865,7 @@ delete:
 }
 
 /* ------------------------------ */
-static struct adouble *find_adouble(struct path *path, struct ofork **of, struct adouble *adp)
+static struct adouble *find_adouble(const AFPObj *obj, struct vol *vol, struct path *path, struct ofork **of, struct adouble *adp)
 {
     int             ret;
 
@@ -1884,7 +1887,7 @@ static struct adouble *find_adouble(struct path *path, struct ofork **of, struct
     /* we use file_access both for legacy Mac perm and
      * for unix privilege, rename will take care of folder perms
     */
-    if (file_access(path, OPENACC_WR ) < 0) {
+    if (file_access(obj, vol, path, OPENACC_WR ) < 0) {
         afp_errno = AFPERR_ACCESS;
         return NULL;
     }
@@ -1980,7 +1983,7 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
     }
     
     ad_init(&ads, vol);
-    if (!(adsp = find_adouble( path, &s_of, &ads))) {
+    if (!(adsp = find_adouble(obj, vol, path, &s_of, &ads))) {
         return afp_errno;
     }
 
@@ -2013,7 +2016,7 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
     }
 
     ad_init(&add, vol);
-    if (!(addp = find_adouble( path, &d_of, &add))) {
+    if (!(addp = find_adouble(obj, vol, path, &d_of, &add))) {
         err = afp_errno;
         goto err_exchangefile;
     }
index 76485a3f87f23e2abe89e7979c427f4f6f6d99a7..937395e572baf9c240836c6ac5e86d8d3d16c158 100644 (file)
@@ -108,15 +108,15 @@ extern char *set_name   (const struct vol *, char *, cnid_t, char *, cnid_t, uin
 extern struct extmap   *getextmap (const char *);
 extern struct extmap   *getdefextmap (void);
 
-extern int getfilparams (struct vol *, uint16_t, struct path *,
+extern int getfilparams (const AFPObj *obj, struct vol *, uint16_t, struct path *,
                          struct dir *, char *buf, size_t *);
 
-extern int setfilparams (struct vol *, struct path *, uint16_t, char *);
+extern int setfilparams (const AFPObj *obj, struct vol *, struct path *, uint16_t, char *);
 extern int renamefile   (const struct vol *, int, char *, char *, char *, struct adouble *);
 extern int copyfile     (const struct vol *, const struct vol *, int, char *, char *, char *, struct adouble *);
 extern int deletefile   (const struct vol *, int, char *, int);
 
-extern int getmetadata  (struct vol *vol, uint16_t bitmap, struct path *path, 
+extern int getmetadata  (const AFPObj *obj, struct vol *vol, uint16_t bitmap, struct path *path, 
                          struct dir *dir, char *buf, size_t *buflen, struct adouble *adp);
 
 extern void *get_finderinfo (const struct vol *, const char *, struct adouble *, void *, int);
index d41a439ecb23df0caed1e4bb2fcdaccb64e197c3..e4b88d95afb01334c29d5bbcbf7f3240d2df8d31 100644 (file)
@@ -25,6 +25,7 @@
 #include <atalk/acl.h>
 #include <atalk/globals.h>
 #include <atalk/fce_api.h>
+#include <atalk/netatalk_conf.h>
 
 #include "directory.h"
 #include "dircache.h"
@@ -103,7 +104,7 @@ int afp_getfildirparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *r
             if (!dir)
                 return AFPERR_NOOBJ;
 
-            ret = getdirparams(vol, dbitmap, s_path, dir,
+            ret = getdirparams(obj, vol, dbitmap, s_path, dir,
                                rbuf + 3 * sizeof( uint16_t ), &buflen );
             if (ret != AFP_OK )
                 return( ret );
@@ -111,7 +112,7 @@ int afp_getfildirparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *r
         /* this is a directory */
         *(rbuf + 2 * sizeof( uint16_t )) = (char) FILDIRBIT_ISDIR;
     } else {
-        if (fbitmap && AFP_OK != (ret = getfilparams(vol, fbitmap, s_path, curdir,
+        if (fbitmap && AFP_OK != (ret = getfilparams(obj, vol, fbitmap, s_path, curdir,
                                                      rbuf + 3 * sizeof( uint16_t ), &buflen )) ) {
             return( ret );
         }
@@ -188,7 +189,7 @@ int afp_setfildirparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf
     if (S_ISDIR(st->st_mode)) {
         rc = setdirparams(vol, path, bitmap, ibuf );
     } else {
-        rc = setfilparams(vol, path, bitmap, ibuf );
+        rc = setfilparams(obj, vol, path, bitmap, ibuf );
     }
     if ( rc == AFP_OK ) {
         setvoltime(obj, vol );
index 89f15e18ac23e9a60fae0333354d20b0bc8d7620..3f8018d039e661d4e46221a3ab24833ad013110b 100644 (file)
@@ -24,6 +24,7 @@
 #include <atalk/cnid.h>
 #include <atalk/bstradd.h>
 #include <atalk/globals.h>
+#include <atalk/netatalk_conf.h>
 
 #include "fork.h"
 #include "file.h"
@@ -35,7 +36,7 @@
 struct ofork *writtenfork;
 #endif
 
-static int getforkparams(struct ofork *ofork, uint16_t bitmap, char *buf, size_t *buflen)
+static int getforkparams(const AFPObj *obj, struct ofork *ofork, uint16_t bitmap, char *buf, size_t *buflen)
 {
     struct path         path;
     struct stat     *st;
@@ -84,7 +85,7 @@ static int getforkparams(struct ofork *ofork, uint16_t bitmap, char *buf, size_t
             }
         }
     }
-    return getmetadata(vol, bitmap, &path, dir, buf, buflen, adp );
+    return getmetadata(obj, vol, bitmap, &path, dir, buf, buflen, adp );
 }
 
 static off_t get_off_t(char **ibuf, int is64)
@@ -281,11 +282,11 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
     /* FIXME should we check it first ? */
     upath = s_path->u_name;
     if (!vol_unix_priv(vol)) {
-        if (check_access(upath, access ) < 0) {
+        if (check_access(obj, vol, upath, access ) < 0) {
             return AFPERR_ACCESS;
         }
     } else {
-        if (file_access(s_path, access ) < 0) {
+        if (file_access(obj, vol, s_path, access ) < 0) {
             return AFPERR_ACCESS;
         }
     }
@@ -417,7 +418,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
         }
     }
 
-    if ((ret = getforkparams(ofork, bitmap, rbuf + 2 * sizeof(int16_t), &buflen)) != AFP_OK) {
+    if ((ret = getforkparams(obj, ofork, bitmap, rbuf + 2 * sizeof(int16_t), &buflen)) != AFP_OK) {
         ad_close( ofork->of_ad, adflags | ADFLAGS_SETSHRMD);
         goto openfork_err;
     }
@@ -1281,7 +1282,7 @@ int afp_write_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *r
 }
 
 /* ---------------------------- */
-int afp_getforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
+int afp_getforkparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
 {
     struct ofork    *ofork;
     int             ret;
@@ -1307,7 +1308,7 @@ int afp_getforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbu
         }
     }
 
-    if (AFP_OK != (ret = getforkparams(ofork, bitmap, rbuf + sizeof( u_short ), &buflen ))) {
+    if (AFP_OK != (ret = getforkparams(obj, ofork, bitmap, rbuf + sizeof( u_short ), &buflen ))) {
         return( ret );
     }
 
index f49daf6f140bc65e428d7ed444e3b23f66540723..ca35cc8d1bf92f93fe5552a00e5a5cfd4b721d9d 100644 (file)
@@ -31,6 +31,7 @@
 #include <atalk/server_ipc.h>
 #include <atalk/errchk.h>
 #include <atalk/globals.h>
+#include <atalk/netatalk_conf.h>
 
 #include "afp_config.h"
 #include "status.h"
@@ -238,6 +239,9 @@ int main(int ac, char **av)
     if (afp_config_parse(&obj) != 0)
         exit(EXITERR_CONF);
 
+    set_processname("afpd");
+    setuplog(obj.options.logconfig, obj.options.logfile);
+
     /* Save the user's current umask */
     obj.options.save_mask = umask(obj.options.umask);
 
index 1df5eee51d2f74195bd43d12358f6a986aaa3c9e..5887c6d60da1f853bb1eb0c2cda1e5f01d267992 100644 (file)
@@ -615,7 +615,7 @@ static int getfsquota(struct vol *vol, const int uid, struct dqblk *dq)
 }
 
 
-static int getquota( struct vol *vol, struct dqblk *dq, const uint32_t bsize)
+static int getquota(const AFPObj *obj, struct vol *vol, struct dqblk *dq, const uint32_t bsize)
 {
     char *p;
 
@@ -693,8 +693,8 @@ static int getquota( struct vol *vol, struct dqblk *dq, const uint32_t bsize)
        return getfsquota(vol, uuid, dq);
           
 #else /* TRU64 */
-    return vol->v_nfs ? getnfsquota(vol, uuid, bsize, dq) :
-           getfsquota(vol, uuid, dq);
+    return vol->v_nfs ? getnfsquota(vol, obj->uid, bsize, dq) :
+           getfsquota(vol, obj->uid, dq);
 #endif /* TRU64 */
 }
 
@@ -753,14 +753,14 @@ static int overquota( struct dqblk *dqblk)
 #define tobytes(a, b)  dbtob((VolSpace) (a))
 #endif
 
-int uquota_getvolspace( struct vol *vol, VolSpace *bfree, VolSpace *btotal, const uint32_t bsize)
+int uquota_getvolspace(const AFPObj *obj, struct vol *vol, VolSpace *bfree, VolSpace *btotal, const uint32_t bsize)
 {
        uint64_t this_bsize;
        struct dqblk dqblk;
 
        this_bsize = bsize;
                        
-       if (getquota( vol, &dqblk, bsize) != 0 ) {
+       if (getquota(obj, vol, &dqblk, bsize) != 0 ) {
                return( AFPERR_PARAM );
        }
 
index 3057b7594a14b821aad093bc4ac1e830417e64ee..343774aebb9681df85c00244f875e409f5263822 100644 (file)
 /* AFPSTATUS_MACHLEN is the number of characters for the MachineType. */
 #define AFPSTATUS_MACHLEN     16
 
-
-#define PASSWD_NONE     0
-#define PASSWD_SET     (1 << 0)
-#define PASSWD_NOSAVE  (1 << 1)
-#define PASSWD_ALL     (PASSWD_SET | PASSWD_NOSAVE)
-
 extern void status_versions (char * /*status*/, const DSI *);
 extern void status_uams (char * /*status*/, const char * /*authlist*/);
 extern void status_init (AFPObj *, DSI *dsi);
index 21602ab13b1d8f079ddec03cddb5b8a10e185724..397b99fb3c174319de362de90457c038e60d43c2 100644 (file)
@@ -98,9 +98,9 @@ static int utombits(mode_t bits)
 /* --------------------------------
     cf AFP 3.0 page 63
 */
-void utommode(struct stat *stat, struct maccess *ma)
+static void utommode(const AFPObj *obj, const struct stat *stat, struct maccess *ma)
 {
-mode_t mode;
+    mode_t mode;
 
     mode = stat->st_mode;
     ma->ma_world = utombits( mode );
@@ -114,10 +114,10 @@ mode_t mode;
     /* ma_user is a union of all permissions but we must follow
      * unix perm
     */
-    if ( (uuid == stat->st_uid) || (uuid == 0)) {
+    if ( (obj->uid == stat->st_uid) || (obj->uid == 0)) {
         ma->ma_user = ma->ma_owner | AR_UOWN;
     }
-    else if ( gmem( stat->st_gid )) {
+    else if (gmem(stat->st_gid, obj->ngroups, obj->groups)) {
         ma->ma_user = ma->ma_group;
     }
     else {
@@ -152,7 +152,7 @@ mode_t mode;
  *
  * dir parameter is used by AFS
  */
-void accessmode(const struct vol *vol, char *path, struct maccess *ma, struct dir *dir _U_, struct stat *st)
+void accessmode(const AFPObj *obj, const struct vol *vol, char *path, struct maccess *ma, struct dir *dir _U_, struct stat *st)
 {
     struct stat     sb;
 
@@ -162,24 +162,12 @@ void accessmode(const struct vol *vol, char *path, struct maccess *ma, struct di
             return;
         st = &sb;
     }
-    utommode( st, ma );
+    utommode(obj, st, ma );
 #ifdef HAVE_ACLS
-    acltoownermode(vol, path, st, ma);
+    acltoownermode(obj, vol, path, st, ma);
 #endif
 }
 
-int gmem(const gid_t gid)
-{
-    int                i;
-
-    for ( i = 0; i < ngroups; i++ ) {
-        if ( groups[ i ] == gid ) {
-            return( 1 );
-        }
-    }
-    return( 0 );
-}
-
 static mode_t mtoubits(u_char bits)
 {
     mode_t     mode;
index 417acb172e1561eff6abf9159a311fd9db4475a9..a81391b55d6cd2aab9fc1b433e0baa1df54c79f9 100644 (file)
@@ -207,13 +207,12 @@ extern int getnfsquota (struct vol *, const int, const uint32_t,
                         struct dqblk *);
 
 #endif /* ! HAVE_LIBQUOTA */
-extern int uquota_getvolspace (struct vol *, VolSpace *, VolSpace *,
+extern int uquota_getvolspace (const AFPObj *obj, struct vol *, VolSpace *, VolSpace *,
                                const uint32_t);
 #endif /* NO_QUOTA_SUPPORT */
 
 extern struct afp_options default_options;
 
-extern int gmem            (const gid_t);
 extern int setdeskmode      (const mode_t);
 extern int setdirunixmode   (const struct vol *, const char *, mode_t);
 extern int setdirmode       (const struct vol *, const char *, mode_t);
@@ -221,7 +220,7 @@ extern int setdeskowner     (const uid_t, const gid_t);
 extern int setdirowner      (const struct vol *, const char *, const uid_t, const gid_t);
 extern int setfilunixmode   (const struct vol *, struct path*, const mode_t);
 extern int setfilowner      (const struct vol *, const uid_t, const gid_t, struct path*);
-extern void accessmode      (const struct vol *, char *, struct maccess *, struct dir *, struct stat *);
+extern void accessmode      (const AFPObj *obj, const struct vol *, char *, struct maccess *, struct dir *, struct stat *);
 
 #ifdef AFS     
     #define accessmode afsmode
index 1c6f112aafe06d00d6461a44c4dae2af11f8dc9e..a8b0754dd0cd799eb7c9a8c914ee3f6fa9b381e4 100644 (file)
@@ -39,6 +39,7 @@
 #include <atalk/errchk.h>
 #include <atalk/iniparser.h>
 #include <atalk/unix.h>
+#include <atalk/netatalk_conf.h>
 
 #ifdef CNID_DB
 #include <atalk/cnid.h>
 #include "hash.h"
 #include "acls.h"
 
-extern int afprun(int root, char *cmd, int *outfd);
-
-/* Globals */
-struct vol *current_vol;        /* last volume from getvolbyvid() */
-
-static struct vol *Volumes = NULL;
-static uint16_t    lastvid = 0;
-static char     *Trash = "\02\024Network Trash Folder";
-
-#define VOLOPT_ALLOW      0  /* user allow list */
-#define VOLOPT_DENY       1  /* user deny list */
-#define VOLOPT_RWLIST     2  /* user rw list */
-#define VOLOPT_ROLIST     3  /* user ro list */
-#define VOLOPT_PASSWORD   4  /* volume password */
-#define VOLOPT_CASEFOLD   5  /* character case mangling */
-#define VOLOPT_FLAGS      6  /* various flags */
-#define VOLOPT_DBPATH     7  /* path to database */
-#define VOLOPT_LIMITSIZE  8  /* Limit the size of the volume */
-/* Usable slot: 9 */
-#define VOLOPT_VETO          10  /* list of veto filespec */
-#define VOLOPT_PREEXEC       11  /* preexec command */
-#define VOLOPT_ROOTPREEXEC   12  /* root preexec command */
-#define VOLOPT_POSTEXEC      13  /* postexec command */
-#define VOLOPT_ROOTPOSTEXEC  14  /* root postexec command */
-#define VOLOPT_ENCODING      15  /* mac encoding (pre OSX)*/
-#define VOLOPT_MACCHARSET    16
-#define VOLOPT_CNIDSCHEME    17
-#define VOLOPT_ADOUBLE       18  /* adouble version */
-/* Usable slot: 19/20 */
-#define VOLOPT_UMASK         21
-#define VOLOPT_ALLOWED_HOSTS 22
-#define VOLOPT_DENIED_HOSTS  23
-#define VOLOPT_DPERM         24  /* dperm default directories perms */
-#define VOLOPT_FPERM         25  /* fperm default files perms */
-#define VOLOPT_DFLTPERM      26  /* perm */
-#define VOLOPT_EA_VFS        27  /* Extended Attributes vfs indirection */
-#define VOLOPT_CNIDSERVER    28  /* CNID Server ip address*/
-#define VOLOPT_CNIDPORT      30  /* CNID server tcp port */
-
-#define VOLOPT_MAX           31  /* <== IMPORTANT !!!!!! */
-#define VOLOPT_NUM           (VOLOPT_MAX + 1)
-
 #define VOLPASSLEN  8
 
-struct vol_option {
-    char *c_value;
-    int i_value;
-};
+extern int afprun(int root, char *cmd, int *outfd);
 
 typedef struct _special_folder {
     const char *name;
@@ -110,359 +66,17 @@ typedef struct _special_folder {
 } _special_folder;
 
 static const _special_folder special_folders[] = {
-    {"Network Trash Folder",     1,  0777,  1},
     {".AppleDesktop",            1,  0777,  0},
     {NULL, 0, 0, 0}};
 
 /* Forward declarations */
 static void handle_special_folders (const struct vol *);
-static void deletevol(struct vol *vol);
-static void volume_free(struct vol *vol);
-static void check_ea_support(struct vol *vol);
-static char *get_vol_uuid(const AFPObj *obj, const char *volname);
-
-static void volfree(struct vol_option *options, const struct vol_option *save)
-{
-    int i;
-
-    if (save) {
-        for (i = 0; i < VOLOPT_MAX; i++) {
-            if (options[i].c_value && (options[i].c_value != save[i].c_value))
-                free(options[i].c_value);
-        }
-    } else {
-        for (i = 0; i < VOLOPT_MAX; i++) {
-            if (options[i].c_value)
-                free(options[i].c_value);
-        }
-    }
-}
-
-
-#define is_var(a, b) (strncmp((a), (b), 2) == 0)
-
-/*
- * Handle variable substitutions. here's what we understand:
- * $b   -> basename of path
- * $c   -> client ip/appletalk address
- * $d   -> volume pathname on server
- * $f   -> full name (whatever's in the gecos field)
- * $g   -> group
- * $h   -> hostname
- * $i   -> client ip/appletalk address without port
- * $s   -> server name (hostname if it doesn't exist)
- * $u   -> username (guest is usually nobody)
- * $v   -> volume name or basename if null
- * $$   -> $
- *
- * This get's called from readvolfile with
- * path = NULL, volname = NULL for xlating the volumes path
- * path = path, volname = NULL for xlating the volumes name
- * ... and from volumes options parsing code when xlating eg dbpath with
- * path = path, volname = volname
- *
- * Using this information we can reject xlation of any variable depeninding on a login
- * context which is not given in the afp master, where we must evaluate this whole stuff
- * too for the Zeroconf announcements.
- */
-static char *volxlate(AFPObj *obj,
-                      char *dest,
-                      size_t destlen,
-                      char *src,
-                      struct passwd *pwd,
-                      char *path,
-                      char *volname)
-{
-    char *p, *r;
-    const char *q;
-    int len;
-    char *ret;
-    int afpmaster = 0;
-    int xlatevolname = 0;
-
-    if (parent_or_child == 0)
-        afpmaster = 1;
-
-    if (path && !volname)
-        /* cf above */
-        xlatevolname = 1;
-
-    if (!src) {
-        return NULL;
-    }
-    if (!dest) {
-        dest = calloc(destlen +1, 1);
-    }
-    ret = dest;
-    if (!ret) {
-        return NULL;
-    }
-    strlcpy(dest, src, destlen +1);
-    if ((p = strchr(src, '$')) == NULL) /* nothing to do */
-        return ret;
-
-    /* first part of the path. just forward to the next variable. */
-    len = MIN((size_t)(p - src), destlen);
-    if (len > 0) {
-        destlen -= len;
-        dest += len;
-    }
-
-    while (p && destlen > 0) {
-        /* now figure out what the variable is */
-        q = NULL;
-        if (is_var(p, "$b")) {
-            if (afpmaster && xlatevolname)
-                return NULL;
-            if (path) {
-                if ((q = strrchr(path, '/')) == NULL)
-                    q = path;
-                else if (*(q + 1) != '\0')
-                    q++;
-            }
-        } else if (is_var(p, "$c")) {
-            if (afpmaster && xlatevolname)
-                return NULL;
-            DSI *dsi = obj->dsi;
-            len = sprintf(dest, "%s:%u",
-                          getip_string((struct sockaddr *)&dsi->client),
-                          getip_port((struct sockaddr *)&dsi->client));
-            dest += len;
-            destlen -= len;
-        } else if (is_var(p, "$d")) {
-            if (afpmaster && xlatevolname)
-                return NULL;
-            q = path;
-        } else if (pwd && is_var(p, "$f")) {
-            if (afpmaster && xlatevolname)
-                return NULL;
-            if ((r = strchr(pwd->pw_gecos, ',')))
-                *r = '\0';
-            q = pwd->pw_gecos;
-        } else if (pwd && is_var(p, "$g")) {
-            if (afpmaster && xlatevolname)
-                return NULL;
-            struct group *grp = getgrgid(pwd->pw_gid);
-            if (grp)
-                q = grp->gr_name;
-        } else if (is_var(p, "$h")) {
-            q = obj->options.hostname;
-        } else if (is_var(p, "$i")) {
-            if (afpmaster && xlatevolname)
-                return NULL;
-            DSI *dsi = obj->dsi;
-            q = getip_string((struct sockaddr *)&dsi->client);
-        } else if (is_var(p, "$s")) {
-            q = obj->options.hostname;
-        } else if (obj->username && is_var(p, "$u")) {
-            if (afpmaster && xlatevolname)
-                return NULL;
-            char* sep = NULL;
-            if ( obj->options.ntseparator && (sep = strchr(obj->username, obj->options.ntseparator[0])) != NULL)
-                q = sep+1;
-            else
-                q = obj->username;
-        } else if (is_var(p, "$v")) {
-            if (afpmaster && xlatevolname)
-                return NULL;
-            if (volname) {
-                q = volname;
-            }
-            else if (path) {
-                if ((q = strrchr(path, '/')) == NULL)
-                    q = path;
-                else if (*(q + 1) != '\0')
-                    q++;
-            }
-        } else if (is_var(p, "$$")) {
-            q = "$";
-        } else
-            q = p;
-
-        /* copy the stuff over. if we don't understand something that we
-         * should, just skip it over. */
-        if (q) {
-            len = MIN(p == q ? 2 : strlen(q), destlen);
-            strncpy(dest, q, len);
-            dest += len;
-            destlen -= len;
-        }
-
-        /* stuff up to next $ */
-        src = p + 2;
-        p = strchr(src, '$');
-        len = p ? MIN((size_t)(p - src), destlen) : destlen;
-        if (len > 0) {
-            strncpy(dest, src, len);
-            dest += len;
-            destlen -= len;
-        }
-    }
-    return ret;
-}
-
-/* -------------------- */
-static void setoption(struct vol_option *options, const struct vol_option *save, int opt, const char *val)
-{
-    if (options[opt].c_value && (!save || options[opt].c_value != save[opt].c_value))
-        free(options[opt].c_value);
-    options[opt].c_value = strdup(val);
-}
-
-/* Parse iniconfig and initalize volume options */
-static void volset(const dictionary *conf, const char *vol, struct vol_option *options, const struct vol_option *save)
-{
-    const char *val;
-    char *p, *q;
-
-    if (val = iniparser_getstring(conf, vol, "allow", NULL))
-        setoption(options, save, VOLOPT_ALLOW, val);
-
-    if (val = iniparser_getstring(conf, vol, "deny", NULL))
-        setoption(options, save, VOLOPT_DENY, val);
-
-    if (val = iniparser_getstring(conf, vol, "rwlist", NULL))
-        setoption(options, save, VOLOPT_RWLIST, val);
-
-    if (val = iniparser_getstring(conf, vol, "rolist", NULL))
-        setoption(options, save, VOLOPT_ROLIST, val);
-
-    if (val = iniparser_getstring(conf, vol, "volcharset", NULL))
-        setoption(options, save, VOLOPT_ENCODING, val);
-
-    if (val = iniparser_getstring(conf, vol, "maccharset", NULL))
-        setoption(options, save, VOLOPT_MACCHARSET, val);
-
-    if (val = iniparser_getstring(conf, vol, "veto", NULL))
-        setoption(options, save, VOLOPT_VETO, val);
-
-    if (val = iniparser_getstring(conf, vol, "cnidscheme", NULL))
-        setoption(options, save, VOLOPT_CNIDSCHEME, val);
-
-    if (val = iniparser_getstring(conf, vol, "dbpath", NULL))
-        setoption(options, save, VOLOPT_DBPATH, val);
-
-    if (val = iniparser_getstring(conf, vol, "password", NULL))
-        setoption(options, save, VOLOPT_PASSWORD, val);
-
-    if (val = iniparser_getstring(conf, vol, "root_preexec", NULL))
-        setoption(options, save, VOLOPT_ROOTPREEXEC, val);
-
-    if (val = iniparser_getstring(conf, vol, "preexec", NULL))
-        setoption(options, save, VOLOPT_PREEXEC, val);
-
-    if (val = iniparser_getstring(conf, vol, "root_postexec", NULL))
-        setoption(options, save, VOLOPT_ROOTPOSTEXEC, val);
-
-    if (val = iniparser_getstring(conf, vol, "postexec", NULL))
-        setoption(options, save, VOLOPT_POSTEXEC, val);
-
-    if (val = iniparser_getstring(conf, vol, "allowed_hosts", NULL))
-        setoption(options, save, VOLOPT_ALLOWED_HOSTS, val);
-
-    if (val = iniparser_getstring(conf, vol, "denied_hosts", NULL))
-        setoption(options, save, VOLOPT_DENIED_HOSTS, val);
 
-    if (val = iniparser_getstring(conf, vol, "umask", NULL))
-        options[VOLOPT_UMASK].i_value = (int)strtol(val, NULL, 8);
-
-    if (val = iniparser_getstring(conf, vol, "dperm", NULL))
-        options[VOLOPT_DPERM].i_value = (int)strtol(val, NULL, 8);
-
-    if (val = iniparser_getstring(conf, vol, "fperm", NULL))
-        options[VOLOPT_FPERM].i_value = (int)strtol(val, NULL, 8);
-
-    if (val = iniparser_getstring(conf, vol, "perm", NULL))
-        options[VOLOPT_DFLTPERM].i_value = (int)strtol(val, NULL, 8);
-
-    if (val = iniparser_getstring(conf, vol, "volsizelimit", NULL))
-        options[VOLOPT_LIMITSIZE].i_value = (uint32_t)strtoul(val, NULL, 10);
-
-    if (val = iniparser_getstring(conf, vol, "casefold", NULL)) {
-        if (strcasecmp(val, "tolower") == 0)
-            options[VOLOPT_CASEFOLD].i_value = AFPVOL_UMLOWER;
-        else if (strcasecmp(val, "toupper") == 0)
-            options[VOLOPT_CASEFOLD].i_value = AFPVOL_UMUPPER;
-        else if (strcasecmp(val, "xlatelower") == 0)
-            options[VOLOPT_CASEFOLD].i_value = AFPVOL_UUPPERMLOWER;
-        else if (strcasecmp(val, "xlateupper") == 0)
-            options[VOLOPT_CASEFOLD].i_value = AFPVOL_ULOWERMUPPER;
-    }
-
-    if (val = iniparser_getstring(conf, vol, "adouble", NULL)) {
-        if (strcasecmp(val, "v2") == 0)
-            options[VOLOPT_ADOUBLE].i_value = AD_VERSION2;
-        else if (strcasecmp(val, "ea") == 0)
-            options[VOLOPT_ADOUBLE].i_value = AD_VERSION_EA;
-    }
-
-    if (val = iniparser_getstring(conf, vol, "ea", NULL)) {
-        if (strcasecmp(val, "ad") == 0)
-            options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_AD;
-        else if (strcasecmp(val, "sys") == 0)
-            options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_SYS;
-        else if (strcasecmp(val, "none") == 0)
-            options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_NONE;
-    }
-
-    if (p = iniparser_getstrdup(conf, vol, "cnidserver", NULL)) {
-        if (q = strrchr(val, ':')) {
-            *q = 0;
-            setoption(options, save, VOLOPT_CNIDPORT, q + 1);
-        }
-        setoption(options, save, VOLOPT_CNIDSERVER, p);
-        LOG(log_debug, logtype_afpd, "CNID Server for volume '%s': %s:%s",
-            vol, p, q ? q + 1 : "4700");
-        free(p);
-    }
-
-    if (q = iniparser_getstrdup(conf, vol, "options", NULL)) {
-        if (p = strtok(q, ", ")) {
-            while (p) {
-                if (strcasecmp(p, "ro") == 0)
-                    options[VOLOPT_FLAGS].i_value |= AFPVOL_RO;
-                else if (strcasecmp(p, "nohex") == 0)
-                    options[VOLOPT_FLAGS].i_value |= AFPVOL_NOHEX;
-                else if (strcasecmp(p, "nousedots") == 0)
-                    options[VOLOPT_FLAGS].i_value &= ~AFPVOL_USEDOTS;
-                else if (strcasecmp(p, "invisibledots") == 0)
-                    options[VOLOPT_FLAGS].i_value |= AFPVOL_USEDOTS;
-                else if (strcasecmp(p, "nostat") == 0)
-                    options[VOLOPT_FLAGS].i_value |= AFPVOL_NOSTAT;
-                else if (strcasecmp(p, "preexec_close") == 0)
-                    options[VOLOPT_PREEXEC].i_value = 1;
-                else if (strcasecmp(p, "root_preexec_close") == 0)
-                    options[VOLOPT_ROOTPREEXEC].i_value = 1;
-                else if (strcasecmp(p, "noupriv") == 0)
-                    options[VOLOPT_FLAGS].i_value &= ~AFPVOL_UNIX_PRIV;
-                else if (strcasecmp(p, "nodev") == 0)
-                    options[VOLOPT_FLAGS].i_value |= AFPVOL_NODEV;
-                else if (strcasecmp(p, "caseinsensitive") == 0)
-                    options[VOLOPT_FLAGS].i_value |= AFPVOL_CASEINSEN;
-                else if (strcasecmp(p, "illegalseq") == 0)
-                    options[VOLOPT_FLAGS].i_value |= AFPVOL_EILSEQ;
-                else if (strcasecmp(p, "tm") == 0)
-                    options[VOLOPT_FLAGS].i_value |= AFPVOL_TM;
-                else if (strcasecmp(p, "searchdb") == 0)
-                    options[VOLOPT_FLAGS].i_value |= AFPVOL_SEARCHDB;
-                else if (strcasecmp(p, "nonetids") == 0)
-                    options[VOLOPT_FLAGS].i_value |= AFPVOL_NONETIDS;
-                else if (strcasecmp(p, "noacls") == 0)
-                    options[VOLOPT_FLAGS].i_value &= ~AFPVOL_ACLS;
-                else if (strcasecmp(p, "nov2toeaconv") == 0)
-                    options[VOLOPT_FLAGS].i_value |= AFPVOL_NOV2TOEACONV;
-                p = strtok(NULL, ",");
-            }
-        }
-        free(q);
-    }
-}
-
-/* ----------------- */
 static void showvol(const ucs2_t *name)
 {
-    struct vol  *volume;
-    for ( volume = Volumes; volume; volume = volume->v_next ) {
+    struct vol  *volume = getvolumes();
+
+    for ( ; volume; volume = volume->v_next ) {
         if (volume->v_hide && !strcasecmp_w( volume->v_name, name ) ) {
             volume->v_hide = 0;
             return;
@@ -470,625 +84,37 @@ static void showvol(const ucs2_t *name)
     }
 }
 
-/* ------------------------------- */
-static int creatvol(AFPObj *obj, struct passwd *pwd,
-                    char *path, char *name,
-                    struct vol_option *options)
-{
-    struct vol  *volume;
-    int         suffixlen, vlen, tmpvlen, u8mvlen, macvlen;
-    int         hide = 0;
-    char        tmpname[AFPVOL_U8MNAMELEN+1];
-    ucs2_t      u8mtmpname[(AFPVOL_U8MNAMELEN+1)*2], mactmpname[(AFPVOL_MACNAMELEN+1)*2];
-    char        suffix[6]; /* max is #FFFF */
-    uint16_t   flags;
-
-    LOG(log_debug, logtype_afpd, "createvol: Volume '%s'", name);
-
-    if ( name == NULL || *name == '\0' ) {
-        if ((name = strrchr( path, '/' )) == NULL) {
-            return -1;  /* Obviously not a fully qualified path */
-        }
-
-        /* if you wish to share /, you need to specify a name. */
-        if (*++name == '\0')
-            return -1;
-    }
-
-    /* suffix for mangling use (lastvid + 1)   */
-    /* because v_vid has not been decided yet. */
-    suffixlen = sprintf(suffix, "%c%X", MANGLE_CHAR, lastvid + 1 );
-
-    vlen = strlen( name );
-
-    /* Unicode Volume Name */
-    /* Firstly convert name from unixcharset to UTF8-MAC */
-    flags = CONV_IGNORE;
-    tmpvlen = convert_charset(obj->options.unixcharset, CH_UTF8_MAC, 0, name, vlen, tmpname, AFPVOL_U8MNAMELEN, &flags);
-    if (tmpvlen <= 0) {
-        strcpy(tmpname, "???");
-        tmpvlen = 3;
-    }
-
-    /* Do we have to mangle ? */
-    if ( (flags & CONV_REQMANGLE) || (tmpvlen > obj->options.volnamelen)) {
-        if (tmpvlen + suffixlen > obj->options.volnamelen) {
-            flags = CONV_FORCE;
-            tmpvlen = convert_charset(obj->options.unixcharset, CH_UTF8_MAC, 0, name, vlen, tmpname, obj->options.volnamelen - suffixlen, &flags);
-            tmpname[tmpvlen >= 0 ? tmpvlen : 0] = 0;
-        }
-        strcat(tmpname, suffix);
-        tmpvlen = strlen(tmpname);
-    }
-
-    /* Secondly convert name from UTF8-MAC to UCS2 */
-    if ( 0 >= ( u8mvlen = convert_string(CH_UTF8_MAC, CH_UCS2, tmpname, tmpvlen, u8mtmpname, AFPVOL_U8MNAMELEN*2)) )
-        return -1;
-
-    LOG(log_maxdebug, logtype_afpd, "createvol: Volume '%s' -> UTF8-MAC Name: '%s'", name, tmpname);
-
-    /* Maccharset Volume Name */
-    /* Firsty convert name from unixcharset to maccharset */
-    flags = CONV_IGNORE;
-    tmpvlen = convert_charset(obj->options.unixcharset, obj->options.maccharset, 0, name, vlen, tmpname, AFPVOL_U8MNAMELEN, &flags);
-    if (tmpvlen <= 0) {
-        strcpy(tmpname, "???");
-        tmpvlen = 3;
-    }
-
-    /* Do we have to mangle ? */
-    if ( (flags & CONV_REQMANGLE) || (tmpvlen > AFPVOL_MACNAMELEN)) {
-        if (tmpvlen + suffixlen > AFPVOL_MACNAMELEN) {
-            flags = CONV_FORCE;
-            tmpvlen = convert_charset(obj->options.unixcharset,
-                                      obj->options.maccharset,
-                                      0,
-                                      name,
-                                      vlen,
-                                      tmpname,
-                                      AFPVOL_MACNAMELEN - suffixlen,
-                                      &flags);
-            tmpname[tmpvlen >= 0 ? tmpvlen : 0] = 0;
-        }
-        strcat(tmpname, suffix);
-        tmpvlen = strlen(tmpname);
-    }
-
-    /* Secondly convert name from maccharset to UCS2 */
-    if ( 0 >= ( macvlen = convert_string(obj->options.maccharset,
-                                         CH_UCS2,
-                                         tmpname,
-                                         tmpvlen,
-                                         mactmpname,
-                                         AFPVOL_U8MNAMELEN*2)) )
-        return -1;
-
-    LOG(log_maxdebug, logtype_afpd, "createvol: Volume '%s' ->  Longname: '%s'", name, tmpname);
-
-    /* check duplicate */
-    for ( volume = Volumes; volume; volume = volume->v_next ) {
-        if ((utf8_encoding() && (strcasecmp_w(volume->v_u8mname, u8mtmpname) == 0))
-             ||
-            (!utf8_encoding() && (strcasecmp_w(volume->v_macname, mactmpname) == 0))) {
-            LOG (log_error, logtype_afpd,
-                 "Duplicate volume name, check AppleVolumes files: previous: \"%s\", new: \"%s\"",
-                 volume->v_localname, name);
-            if (volume->v_deleted) {
-                volume->v_new = hide = 1;
-            }
-            else {
-                return -1;  /* Won't be able to access it, anyway... */
-            }
-        }
-    }
-
-    if (!( volume = (struct vol *)calloc(1, sizeof( struct vol ))) ) {
-        LOG(log_error, logtype_afpd, "creatvol: malloc: %s", strerror(errno) );
-        return -1;
-    }
-    if ( NULL == ( volume->v_localname = strdup(name))) {
-        LOG(log_error, logtype_afpd, "creatvol: malloc: %s", strerror(errno) );
-        free(volume);
-        return -1;
-    }
-
-    if ( NULL == ( volume->v_u8mname = strdup_w(u8mtmpname))) {
-        LOG(log_error, logtype_afpd, "creatvol: malloc: %s", strerror(errno) );
-        volume_free(volume);
-        free(volume);
-        return -1;
-    }
-    if ( NULL == ( volume->v_macname = strdup_w(mactmpname))) {
-        LOG(log_error, logtype_afpd, "creatvol: malloc: %s", strerror(errno) );
-        volume_free(volume);
-        free(volume);
-        return -1;
-    }
-    if (!( volume->v_path = (char *)malloc( strlen( path ) + 1 )) ) {
-        LOG(log_error, logtype_afpd, "creatvol: malloc: %s", strerror(errno) );
-        volume_free(volume);
-        free(volume);
-        return -1;
-    }
-
-    volume->v_name = utf8_encoding()?volume->v_u8mname:volume->v_macname;
-    volume->v_hide = hide;
-    strcpy( volume->v_path, path );
-
-#ifdef __svr4__
-    volume->v_qfd = -1;
-#endif /* __svr4__ */
-    /* os X start at 1 and use network order ie. 1 2 3 */
-    volume->v_vid = ++lastvid;
-    volume->v_vid = htons(volume->v_vid);
-#ifdef HAVE_ACLS
-    if (!check_vol_acl_support(volume)) {
-        LOG(log_debug, logtype_afpd, "creatvol(\"%s\"): disabling ACL support", volume->v_path);
-        options[VOLOPT_FLAGS].i_value &= ~AFPVOL_ACLS;
-    }
-#endif
-
-    /* handle options */
-    if (options) {
-        volume->v_casefold = options[VOLOPT_CASEFOLD].i_value;
-        volume->v_flags |= options[VOLOPT_FLAGS].i_value;
-
-        if (options[VOLOPT_EA_VFS].i_value)
-            volume->v_vfs_ea = options[VOLOPT_EA_VFS].i_value;
-
-        volume->v_ad_options = 0;
-        if ((volume->v_flags & AFPVOL_NODEV))
-            volume->v_ad_options |= ADVOL_NODEV;
-        if ((volume->v_flags & AFPVOL_UNIX_PRIV))
-            volume->v_ad_options |= ADVOL_UNIXPRIV;
-        if ((volume->v_flags & AFPVOL_INV_DOTS))
-            volume->v_ad_options |= ADVOL_INVDOTS;
-
-        if (options[VOLOPT_PASSWORD].c_value)
-            volume->v_password = strdup(options[VOLOPT_PASSWORD].c_value);
-
-        if (options[VOLOPT_VETO].c_value)
-            volume->v_veto = strdup(options[VOLOPT_VETO].c_value);
-
-        if (options[VOLOPT_ENCODING].c_value)
-            volume->v_volcodepage = strdup(options[VOLOPT_ENCODING].c_value);
-
-        if (options[VOLOPT_MACCHARSET].c_value)
-            volume->v_maccodepage = strdup(options[VOLOPT_MACCHARSET].c_value);
-
-        if (options[VOLOPT_DBPATH].c_value)
-            volume->v_dbpath = volxlate(obj, NULL, MAXPATHLEN, options[VOLOPT_DBPATH].c_value, pwd, path, name);
-
-        if (options[VOLOPT_CNIDSCHEME].c_value)
-            volume->v_cnidscheme = strdup(options[VOLOPT_CNIDSCHEME].c_value);
-
-        if (options[VOLOPT_CNIDSERVER].c_value)
-            volume->v_cnidserver = strdup(options[VOLOPT_CNIDSERVER].c_value);
-
-        if (options[VOLOPT_CNIDPORT].c_value)
-            volume->v_cnidport = strdup(options[VOLOPT_CNIDPORT].c_value);
-
-        if (options[VOLOPT_UMASK].i_value)
-            volume->v_umask = (mode_t)options[VOLOPT_UMASK].i_value;
-
-        if (options[VOLOPT_DPERM].i_value)
-            volume->v_dperm = (mode_t)options[VOLOPT_DPERM].i_value;
-
-        if (options[VOLOPT_FPERM].i_value)
-            volume->v_fperm = (mode_t)options[VOLOPT_FPERM].i_value;
-
-        if (options[VOLOPT_DFLTPERM].i_value)
-            volume->v_perm = (mode_t)options[VOLOPT_DFLTPERM].i_value;
-
-        if (options[VOLOPT_ADOUBLE].i_value)
-            volume->v_adouble = options[VOLOPT_ADOUBLE].i_value;
-        else
-            volume->v_adouble = AD_VERSION;
-
-        if (options[VOLOPT_LIMITSIZE].i_value)
-            volume->v_limitsize = options[VOLOPT_LIMITSIZE].i_value;
-
-        /* Mac to Unix conversion flags*/
-        volume->v_mtou_flags = 0;
-        if (!(volume->v_flags & AFPVOL_NOHEX))
-            volume->v_mtou_flags |= CONV_ESCAPEHEX;
-        if (!(volume->v_flags & AFPVOL_USEDOTS))
-            volume->v_mtou_flags |= CONV_ESCAPEDOTS;
-        if ((volume->v_flags & AFPVOL_EILSEQ))
-            volume->v_mtou_flags |= CONV__EILSEQ;
-
-        if ((volume->v_casefold & AFPVOL_MTOUUPPER))
-            volume->v_mtou_flags |= CONV_TOUPPER;
-        else if ((volume->v_casefold & AFPVOL_MTOULOWER))
-            volume->v_mtou_flags |= CONV_TOLOWER;
-
-        /* Unix to Mac conversion flags*/
-        volume->v_utom_flags = CONV_IGNORE | CONV_UNESCAPEHEX;
-        if ((volume->v_casefold & AFPVOL_UTOMUPPER))
-            volume->v_utom_flags |= CONV_TOUPPER;
-        else if ((volume->v_casefold & AFPVOL_UTOMLOWER))
-            volume->v_utom_flags |= CONV_TOLOWER;
-
-        if ((volume->v_flags & AFPVOL_EILSEQ))
-            volume->v_utom_flags |= CONV__EILSEQ;
-
-        if (options[VOLOPT_PREEXEC].c_value)
-            volume->v_preexec = volxlate(obj, NULL, MAXPATHLEN, options[VOLOPT_PREEXEC].c_value, pwd, path, name);
-        volume->v_preexec_close = options[VOLOPT_PREEXEC].i_value;
-
-        if (options[VOLOPT_POSTEXEC].c_value)
-            volume->v_postexec = volxlate(obj, NULL, MAXPATHLEN, options[VOLOPT_POSTEXEC].c_value, pwd, path, name);
-
-        if (options[VOLOPT_ROOTPREEXEC].c_value)
-            volume->v_root_preexec = volxlate(obj, NULL, MAXPATHLEN, options[VOLOPT_ROOTPREEXEC].c_value, pwd, path,  name);
-        volume->v_root_preexec_close = options[VOLOPT_ROOTPREEXEC].i_value;
-
-        if (options[VOLOPT_ROOTPOSTEXEC].c_value)
-            volume->v_root_postexec = volxlate(obj, NULL, MAXPATHLEN, options[VOLOPT_ROOTPOSTEXEC].c_value, pwd, path,  name);
-    }
-    volume->v_dperm |= volume->v_perm;
-    volume->v_fperm |= volume->v_perm;
-
-    /* Check EA support on volume */
-    if (volume->v_vfs_ea == AFPVOL_EA_AUTO || volume->v_adouble == AD_VERSION_EA)
-        check_ea_support(volume);
-    initvol_vfs(volume);
-
-    /* get/store uuid from file in afpd master*/
-    if ((parent_or_child == 0) && (volume->v_flags & AFPVOL_TM)) {
-        char *uuid = get_vol_uuid(obj, volume->v_localname);
-        if (!uuid) {
-            LOG(log_error, logtype_afpd, "Volume '%s': couldn't get UUID",
-                volume->v_localname);
-        } else {
-            volume->v_uuid = uuid;
-            LOG(log_debug, logtype_afpd, "Volume '%s': UUID '%s'",
-                volume->v_localname, volume->v_uuid);
-        }
-    }
-
-    volume->v_next = Volumes;
-    Volumes = volume;
-    return 0;
-}
-
-/* ---------------- */
-static char *myfgets( char *buf, int size, FILE *fp)
-{
-    char    *p;
-    int     c;
-
-    p = buf;
-    while ((EOF != ( c = getc( fp )) ) && ( size > 1 )) {
-        if ( c == '\n' || c == '\r' ) {
-            if (p != buf && *(p -1) == '\\') {
-                p--;
-                size++;
-                continue;
-            }
-            *p++ = '\n';
-            break;
-        } else {
-            *p++ = c;
-        }
-        size--;
-    }
-
-    if ( p == buf ) {
-        return( NULL );
-    } else {
-        *p = '\0';
-        return( buf );
-    }
-}
-
-
-/* check access list. this function wants something of the following
- * form:
- *        @group,name,name2,@group2,name3
- *
- * a NULL argument allows everybody to have access.
- * we return three things:
- *     -1: no list
- *      0: list exists, but name isn't in it
- *      1: in list
- */
-
-#ifndef NO_REAL_USER_NAME
-/* authentication is case insensitive
- * FIXME should we do the same with group name?
- */
-#define access_strcmp strcasecmp
-
-#else
-#define access_strcmp strcmp
-
-#endif
-
-static int accessvol(const char *args, const char *name)
-{
-    char buf[MAXPATHLEN + 1], *p;
-    struct group *gr;
-
-    if (!args)
-        return -1;
-
-    strlcpy(buf, args, sizeof(buf));
-    if ((p = strtok(buf, ",")) == NULL) /* nothing, return okay */
-        return -1;
-
-    while (p) {
-        if (*p == '@') { /* it's a group */
-            if ((gr = getgrnam(p + 1)) && gmem(gr->gr_gid))
-                return 1;
-        } else if (access_strcmp(p, name) == 0) /* it's a user name */
-            return 1;
-        p = strtok(NULL, ",");
-    }
-
-    return 0;
-}
-
-static int hostaccessvol(int type, const char *volname, const char *args, const AFPObj *obj)
+static void closevol(struct vol *vol)
 {
-    int mask_int;
-    char buf[MAXPATHLEN + 1], *p, *b;
-    DSI *dsi = obj->dsi;
-    struct sockaddr_storage client;
-
-    if (!args)
-        return -1;
-
-    strlcpy(buf, args, sizeof(buf));
-    if ((p = strtok_r(buf, ",", &b)) == NULL) /* nothing, return okay */
-        return -1;
-
-    while (p) {
-        int ret;
-        char *ipaddr, *mask_char;
-        struct addrinfo hints, *ai;
-
-        ipaddr = strtok(p, "/");
-        mask_char = strtok(NULL,"/");
+    if (!vol)
+        return;
 
-        /* Get address from string with getaddrinfo */
-        memset(&hints, 0, sizeof hints);
-        hints.ai_family = AF_UNSPEC;
-        hints.ai_socktype = SOCK_STREAM;
-        if ((ret = getaddrinfo(ipaddr, NULL, &hints, &ai)) != 0) {
-            LOG(log_error, logtype_afpd, "hostaccessvol: getaddrinfo: %s\n", gai_strerror(ret));
-            continue;
-        }
+    vol->v_flags &= ~AFPVOL_OPEN;
 
-        /* netmask */
-        if (mask_char != NULL)
-            mask_int = atoi(mask_char); /* apply_ip_mask does range checking on it */
-        else {
-            if (ai->ai_family == AF_INET) /* IPv4 */
-                mask_int = 32;
-            else                          /* IPv6 */
-                mask_int = 128;
-        }
+    of_closevol(vol);
 
-        /* Apply mask to addresses */
-        client = dsi->client;
-        apply_ip_mask((struct sockaddr *)&client, mask_int);
-        apply_ip_mask(ai->ai_addr, mask_int);
-
-        if (compare_ip((struct sockaddr *)&client, ai->ai_addr) == 0) {
-            if (type == VOLOPT_DENIED_HOSTS)
-                LOG(log_info, logtype_afpd, "AFP access denied for client IP '%s' to volume '%s' by denied list",
-                    getip_string((struct sockaddr *)&client), volname);
-            freeaddrinfo(ai);
-            return 1;
-        }
-
-        /* next address */
-        freeaddrinfo(ai);
-        p = strtok_r(NULL, ",", &b);
+    dir_free( vol->v_root );
+    vol->v_root = NULL;
+    if (vol->v_cdb != NULL) {
+        cnid_close(vol->v_cdb);
+        vol->v_cdb = NULL;
     }
 
-    if (type == VOLOPT_ALLOWED_HOSTS)
-        LOG(log_info, logtype_afpd, "AFP access denied for client IP '%s' to volume '%s', not in allowed list",
-            getip_string((struct sockaddr *)&dsi->client), volname);
-    return 0;
-}
-
-/* ----------------------
- */
-static int volfile_changed(struct afp_options *p)
-{
-    struct stat      st;
-
-    if (!stat(p->configfile, &st) && st.st_mtime > p->volfile.mtime) {
-        p->volfile.mtime = st.st_mtime;
-        return 1;
+    if (vol->v_postexec) {
+        afprun(0, vol->v_postexec, NULL);
     }
-    return 0;
-}
-
-static int vol_section(const char *sec)
-{
-    if (STRCMP(sec, ==, INISEC_GLOBAL))
-        return 0;
-    if (STRCMP(sec, ==, INISEC_AFP))
-        return 0;
-    if (STRCMP(sec, ==, INISEC_CNID))
-        return 0;
-    return 1;
-}
-
-/* ----------------------
- * Read volumes from iniconfig and add the volumes contained within to
- * the global volume list. This gets called from the forked afpd childs.
- * The master now reads this too for Zeroconf announcements.
- */
-static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, struct passwd *pwent)
-{
-    char        path[MAXPATHLEN + 1];
-    char        volname[AFPVOL_U8MNAMELEN + 1];
-    char        tmp[MAXPATHLEN + 1];
-    char        *u;
-    const char  *p;
-    int         fd;
-    int         i;
-    struct passwd     *pw;
-    struct vol_option save_options[VOLOPT_NUM];
-    struct vol_option default_options[VOLOPT_NUM];
-    struct vol_option options[VOLOPT_NUM];
-
-    LOG(log_debug, logtype_afpd, "readvolfile: BEGIN");
-
-    memset(default_options, 0, sizeof(default_options));
-
-    /* Enable some default options for all volumes */
-    default_options[VOLOPT_FLAGS].i_value |= AFPVOL_USEDOTS | AFPVOL_UNIX_PRIV;
-#ifdef HAVE_ACLS
-    default_options[VOLOPT_FLAGS].i_value |= AFPVOL_ACLS;
-#endif
-    default_options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_AUTO;
-    default_options[VOLOPT_UMASK].i_value = obj->options.umask;
-    memcpy(save_options, default_options, sizeof(options));
-
-    int secnum = iniparser_getnsec(obj->iniconfig);    
-    LOG(log_debug, logtype_afpd, "readvolfile: sections: %d", secnum);
-    const char *secname;
-
-    for (i = 0; i < secnum; i++) { 
-        secname = iniparser_getsecname(obj->iniconfig, i);
-        if (!vol_section(secname))
-            continue;
-
-        strlcpy(volname, secname, AFPVOL_U8MNAMELEN);
-        LOG(log_debug, logtype_afpd, "readvolfile: volume: %s", volname);
-
-        if ((p = iniparser_getstrdup(obj->iniconfig, secname, "path", NULL)) == NULL)
-            continue;
-        strlcpy(path, p, MAXPATHLEN);
-        strcpy(tmp, path);
-
-
-        if (!pwent && obj->username)
-            pwent = getpwnam(obj->username);
-
-        if (volxlate(obj, path, sizeof(path) - 1, tmp, pwent, NULL, NULL) == NULL)
-            continue;
-
-        memcpy(options, default_options, sizeof(options));
-        volset(obj->iniconfig, secname, options, default_options);
-
-        /* check allow/deny lists (if not afpd master loading volumes for Zeroconf reg.):
-           allow -> either no list (-1), or in list (1)
-           deny -> either no list (-1), or not in list (0) */
-        if (parent_or_child == 0
-            ||
-            (accessvol(options[VOLOPT_ALLOW].c_value, obj->username) &&
-             (accessvol(options[VOLOPT_DENY].c_value, obj->username) < 1) &&
-             hostaccessvol(VOLOPT_ALLOWED_HOSTS, volname, options[VOLOPT_ALLOWED_HOSTS].c_value, obj) &&
-             (hostaccessvol(VOLOPT_DENIED_HOSTS, volname, options[VOLOPT_DENIED_HOSTS].c_value, obj) < 1))) {
-
-            /* handle read-only behaviour. semantics:
-             * 1) neither the rolist nor the rwlist exist -> rw
-             * 2) rolist exists -> ro if user is in it.
-             * 3) rwlist exists -> ro unless user is in it. */
-            if (parent_or_child == 1
-                &&
-                ((options[VOLOPT_FLAGS].i_value & AFPVOL_RO) == 0)
-                &&
-                ((accessvol(options[VOLOPT_ROLIST].c_value, obj->username) == 1) ||
-                 !accessvol(options[VOLOPT_RWLIST].c_value, obj->username)))
-                options[VOLOPT_FLAGS].i_value |= AFPVOL_RO;
-
-            /* do variable substitution for volname */
-            if (volxlate(obj, tmp, sizeof(tmp) - 1, volname, pwent, path, NULL) == NULL) {
-                volfree(options, default_options);
-                continue;
-            }
-
-            creatvol(obj, pwent, path, tmp, options);
-        }
-        volfree(options, default_options);
+    if (vol->v_root_postexec) {
+        afprun(1, vol->v_root_postexec, NULL);
     }
-    volfree(save_options, NULL);
-    p1->loaded = 1;
-    return( 0 );
-}
 
-/* ------------------------------- */
-static void volume_free(struct vol *vol)
-{
-    free(vol->v_localname);
-    vol->v_localname = NULL;
-    free(vol->v_u8mname);
-    vol->v_u8mname = NULL;
-    free(vol->v_macname);
-    vol->v_macname = NULL;
-    free(vol->v_path);
-    free(vol->v_password);
-    free(vol->v_veto);
-    free(vol->v_volcodepage);
-    free(vol->v_maccodepage);
-    free(vol->v_cnidscheme);
-    free(vol->v_dbpath);
-    free(vol->v_gvs);
-    if (vol->v_uuid)
-        free(vol->v_uuid);
-}
-
-/* ------------------------------- */
-static void free_volumes(void )
-{
-    struct vol  *vol;
-    struct vol  *nvol, *ovol;
-
-    for ( vol = Volumes; vol; vol = vol->v_next ) {
-        if (( vol->v_flags & AFPVOL_OPEN ) ) {
-            vol->v_deleted = 1;
-            continue;
-        }
+    if (vol->v_deleted) {
+        showvol(vol->v_name);
         volume_free(vol);
-    }
-
-    for ( vol = Volumes, ovol = NULL; vol; vol = nvol) {
-        nvol = vol->v_next;
-
-        if (vol->v_localname == NULL) {
-            if (Volumes == vol) {
-                Volumes = nvol;
-                ovol = Volumes;
-            }
-            else {
-                ovol->v_next = nvol;
-            }
-            free(vol);
-        }
-        else {
-            ovol = vol;
-        }
+        volume_unlink(vol);
+        free(vol);
     }
 }
 
-/* ------------------------------- */
-static void volume_unlink(struct vol *volume)
-{
-    struct vol *vol, *ovol, *nvol;
-
-    if (volume == Volumes) {
-        Volumes = Volumes->v_next;
-        return;
-    }
-    for ( vol = Volumes->v_next, ovol = Volumes; vol; vol = nvol) {
-        nvol = vol->v_next;
-
-        if (vol == volume) {
-            ovol->v_next = nvol;
-            break;
-        }
-        else {
-            ovol = vol;
-        }
-    }
-}
 /*!
  * Read band-size info from Info.plist XML file of an TM sparsebundle
  *
@@ -1238,7 +264,7 @@ EC_CLEANUP:
     EC_EXIT;
 }
 
-static int getvolspace(struct vol *vol,
+static int getvolspace(const AFPObj *obj, struct vol *vol,
                        uint32_t *bfree, uint32_t *btotal,
                        VolSpace *xbfree, VolSpace *xbtotal, uint32_t *bsize)
 {
@@ -1268,7 +294,7 @@ static int getvolspace(struct vol *vol,
 
 #ifndef NO_QUOTA_SUPPORT
     if ( spaceflag == AFPVOL_NONE || spaceflag == AFPVOL_UQUOTA ) {
-        if ( uquota_getvolspace( vol, &qfree, &qtotal, *bsize ) == AFP_OK ) {
+        if ( uquota_getvolspace(obj, vol, &qfree, &qtotal, *bsize ) == AFP_OK ) {
             vol->v_flags = ( ~AFPVOL_GVSMASK & vol->v_flags ) | AFPVOL_UQUOTA;
             *xbfree = MIN(*xbfree, qfree);
             *xbtotal = MIN(*xbtotal, qtotal);
@@ -1301,7 +327,7 @@ void vol_fce_tm_event(void)
 {
     static time_t last;
     time_t now = time(NULL);
-    struct vol  *vol = Volumes;
+    struct vol  *vol = getvolumes();
 
     if ((last + FCE_TM_DELTA) < now) {
         last = now;
@@ -1319,15 +345,15 @@ void vol_fce_tm_event(void)
 static void vol_setdate(uint16_t id, struct adouble *adp, time_t date)
 {
     struct vol  *volume;
-    struct vol  *vol = Volumes;
+    struct vol  *vol = getvolumes();
 
-    for ( volume = Volumes; volume; volume = volume->v_next ) {
+    for ( volume = getvolumes(); volume; volume = volume->v_next ) {
         if (volume->v_vid == id) {
             vol = volume;
         }
         else if ((time_t)(AD_DATE_FROM_UNIX(date)) == volume->v_ctime) {
             date = date+1;
-            volume = Volumes; /* restart */
+            volume = getvolumes(); /* restart */
         }
     }
     vol->v_ctime = AD_DATE_FROM_UNIX(date);
@@ -1335,7 +361,7 @@ static void vol_setdate(uint16_t id, struct adouble *adp, time_t date)
 }
 
 /* ----------------------- */
-static int getvolparams( uint16_t bitmap, struct vol *vol, struct stat *st, char *buf, size_t *buflen)
+static int getvolparams(const AFPObj *obj, uint16_t bitmap, struct vol *vol, struct stat *st, char *buf, size_t *buflen)
 {
     struct adouble  ad;
     int         bit = 0, isad = 1;
@@ -1384,7 +410,7 @@ static int getvolparams( uint16_t bitmap, struct vol *vol, struct stat *st, char
     if (( bitmap & ( (1<<VOLPBIT_BFREE)|(1<<VOLPBIT_BTOTAL) |
                      (1<<VOLPBIT_XBFREE)|(1<<VOLPBIT_XBTOTAL) |
                      (1<<VOLPBIT_BSIZE)) ) != 0 ) {
-        if ( getvolspace( vol, &bfree, &btotal, &xbfree, &xbtotal,
+        if ( getvolspace(obj, vol, &bfree, &btotal, &xbfree, &xbtotal,
                           &bsize) != AFP_OK ) {
             if ( isad ) {
                 ad_close( &ad, ADFLAGS_HF );
@@ -1538,7 +564,7 @@ static int getvolparams( uint16_t bitmap, struct vol *vol, struct stat *st, char
 }
 
 /* ------------------------- */
-static int stat_vol(uint16_t bitmap, struct vol *vol, char *rbuf, size_t *rbuflen)
+static int stat_vol(const AFPObj *obj, uint16_t bitmap, struct vol *vol, char *rbuf, size_t *rbuflen)
 {
     struct stat st;
     int     ret;
@@ -1552,7 +578,7 @@ static int stat_vol(uint16_t bitmap, struct vol *vol, char *rbuf, size_t *rbufle
     vol->v_dev = st.st_dev;
 
     buflen = *rbuflen - sizeof( bitmap );
-    if (( ret = getvolparams( bitmap, vol, &st,
+    if (( ret = getvolparams(obj, bitmap, vol, &st,
                               rbuf + sizeof( bitmap ), &buflen )) != AFP_OK ) {
         *rbuflen = 0;
         return( ret );
@@ -1564,74 +590,6 @@ static int stat_vol(uint16_t bitmap, struct vol *vol, char *rbuf, size_t *rbufle
 
 }
 
-/* ------------------------------- */
-void load_volumes(AFPObj *obj)
-{
-    EC_INIT;
-    int fd = -1;
-    struct passwd   *pwent;
-    struct stat         st;
-    int retries = 0;
-
-    if (parent_or_child == 0) {
-        LOG(log_debug, logtype_afpd, "load_volumes: AFP MASTER");
-    } else {
-        LOG(log_debug, logtype_afpd, "load_volumes: user: %s", obj->username);
-    }
-
-    if (Volumes) {
-        if (!volfile_changed(&obj->options))
-            return;
-        free_volumes();
-    }
-
-    /* try putting a read lock on the volume file twice, sleep 1 second if first attempt fails */
-
-    fd = open(obj->options.configfile, O_RDONLY);
-
-    while (retries < 2) {
-        if ((read_lock(fd, 0, SEEK_SET, 0)) != 0) {
-            retries++;
-            if (!retries) {
-                LOG(log_error, logtype_afpd, "readvolfile: can't lock configfile \"%s\"",
-                    obj->options.configfile);
-                EC_FAIL;
-            }
-            sleep(1);
-            continue;
-        }
-        break;
-    }
-
-    if (obj->iniconfig)
-        iniparser_freedict(obj->iniconfig);
-    LOG(log_debug, logtype_afpd, "load_volumes: reloading: %s", obj->options.configfile);
-    obj->iniconfig = iniparser_load(obj->options.configfile);
-
-    if (obj->username)
-        pwent = getpwnam(obj->username);
-    else
-        pwent = NULL;
-
-    readvolfile(obj, &obj->options.volfile, pwent);
-
-    if ( obj->options.flags & OPTION_CLOSEVOL) {
-        struct vol *vol;
-        for ( vol = Volumes; vol; vol = vol->v_next ) {
-            if (vol->v_deleted && !vol->v_new ) {
-                of_closevol(vol);
-                deletevol(vol);
-                vol = Volumes;
-            }
-        }
-    }
-
-EC_CLEANUP:
-    if (fd != -1)
-        (void)close(fd);
-    return;
-}
-
 /* ------------------------------- */
 int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
 {
@@ -1643,10 +601,10 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
     int         vcnt;
     size_t      len;
 
-    load_volumes(obj);
+    load_volumes(obj, of_closevol);
 
     data = rbuf + 5;
-    for ( vcnt = 0, volume = Volumes; volume; volume = volume->v_next ) {
+    for ( vcnt = 0, volume = getvolumes(); volume; volume = volume->v_next ) {
         if (!(volume->v_flags & AFPVOL_NOSTAT)) {
             struct maccess ma;
 
@@ -1658,7 +616,7 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
             if (!S_ISDIR(st.st_mode)) {
                 continue;       /* not a dir */
             }
-            accessmode(volume, volume->v_path, &ma, NULL, &st);
+            accessmode(obj, volume, volume->v_path, &ma, NULL, &st);
             if ((ma.ma_user & (AR_UREAD | AR_USEARCH)) != (AR_UREAD | AR_USEARCH)) {
                 continue;   /* no r-x access */
             }
@@ -1783,71 +741,6 @@ static int volume_openDB(const AFPObj *obj, struct vol *volume)
     return (!volume->v_cdb)?-1:0;
 }
 
-/*
-  Check if the underlying filesystem supports EAs.
-  If not, switch to ea:ad.
-  As we can't check (requires write access) on ro-volumes, we switch ea:auto
-  volumes that are options:ro to ea:none.
-*/
-static int do_check_ea_support(const struct vol *vol)
-{
-    int haseas;
-    char eaname[] = {"org.netatalk.supports-eas.XXXXXX"};
-    const char *eacontent = "yes";
-
-    if ((vol->v_flags & AFPVOL_RO) == AFPVOL_RO) {
-        LOG(log_note, logtype_afpd, "read-only volume '%s', can't test for EA support, assuming yes", vol->v_localname);
-        return 1;
-    }
-
-    mktemp(eaname);
-
-    become_root();
-
-    if ((sys_setxattr(vol->v_path, eaname, eacontent, 4, 0)) == 0) {
-        sys_removexattr(vol->v_path, eaname);
-        haseas = 1;
-    } else {
-        LOG(log_warning, logtype_afpd, "volume \"%s\" does not support Extended Attributes",
-            vol->v_localname);
-        haseas = 0;
-    }
-
-    unbecome_root();
-
-    return haseas;
-}
-
-static void check_ea_support(struct vol *vol)
-{
-    int haseas;
-    char eaname[] = {"org.netatalk.supports-eas.XXXXXX"};
-    const char *eacontent = "yes";
-
-    haseas = do_check_ea_support(vol);
-
-    if (vol->v_vfs_ea == AFPVOL_EA_AUTO) {
-        if ((vol->v_flags & AFPVOL_RO) == AFPVOL_RO) {
-            LOG(log_info, logtype_afpd, "read-only volume '%s', can't test for EA support, disabling EAs", vol->v_localname);
-            vol->v_vfs_ea = AFPVOL_EA_NONE;
-            return;
-        }
-
-        if (haseas) {
-            vol->v_vfs_ea = AFPVOL_EA_SYS;
-        } else {
-            LOG(log_warning, logtype_afpd, "volume \"%s\" does not support Extended Attributes, using ea:ad instead",
-                vol->v_localname);
-            vol->v_vfs_ea = AFPVOL_EA_AD;
-        }
-    }
-
-    if (vol->v_adouble == AD_VERSION_EA) {
-        if (!haseas)
-            vol->v_adouble = AD_VERSION2;
-    }
-}
-
 /* -------------------------
  * we are the user here
  */
@@ -1897,9 +790,9 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
     if ((len + 1) & 1) /* pad to an even boundary */
         ibuf++;
 
-    load_volumes(obj);
+    load_volumes(obj, of_closevol);
 
-    for ( volume = Volumes; volume; volume = volume->v_next ) {
+    for ( volume = getvolumes(); volume; volume = volume->v_next ) {
         if ( strcasecmp_w( (ucs2_t*) volname, volume->v_name ) == 0 ) {
             break;
         }
@@ -1916,7 +809,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
 
     if (( volume->v_flags & AFPVOL_OPEN  ) ) {
         /* the volume is already open */
-        return stat_vol(bitmap, volume, rbuf, rbuflen);
+        return stat_vol(obj, bitmap, volume, rbuf, rbuflen);
     }
 
     if (volume->v_root_preexec) {
@@ -2025,7 +918,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
         goto openvol_err;
     }
 
-    ret  = stat_vol(bitmap, volume, rbuf, rbuflen);
+    ret  = stat_vol(obj, bitmap, volume, rbuf, rbuflen);
 
     if (ret == AFP_OK) {
         handle_special_folders(volume);
@@ -2053,10 +946,6 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
                 goto openvol_err;
             }
         }
-        else {
-            p = Trash;
-            cname( volume, volume->v_root, &p );
-        }
         return( AFP_OK );
     }
 
@@ -2075,33 +964,12 @@ openvol_err:
     return ret;
 }
 
-/* ------------------------- */
-static void closevol(struct vol *vol)
-{
-    if (!vol)
-        return;
-
-    dir_free( vol->v_root );
-    vol->v_root = NULL;
-    if (vol->v_cdb != NULL) {
-        cnid_close(vol->v_cdb);
-        vol->v_cdb = NULL;
-    }
-
-    if (vol->v_postexec) {
-        afprun(0, vol->v_postexec, NULL);
-    }
-    if (vol->v_root_postexec) {
-        afprun(1, vol->v_root_postexec, NULL);
-    }
-}
-
 /* ------------------------- */
 void close_all_vol(void)
 {
     struct vol  *ovol;
     curdir = NULL;
-    for ( ovol = Volumes; ovol; ovol = ovol->v_next ) {
+    for ( ovol = getvolumes(); ovol; ovol = ovol->v_next ) {
         if ( (ovol->v_flags & AFPVOL_OPEN) ) {
             ovol->v_flags &= ~AFPVOL_OPEN;
             closevol(ovol);
@@ -2109,33 +977,6 @@ void close_all_vol(void)
     }
 }
 
-/* ------------------------- */
-static void deletevol(struct vol *vol)
-{
-    struct vol  *ovol;
-
-    vol->v_flags &= ~AFPVOL_OPEN;
-    for ( ovol = Volumes; ovol; ovol = ovol->v_next ) {
-        if ( (ovol->v_flags & AFPVOL_OPEN) ) {
-            break;
-        }
-    }
-    if ( ovol != NULL ) {
-        /* Even if chdir fails, we can't say afp_closevol fails. */
-        if ( chdir( ovol->v_path ) == 0 ) {
-            curdir = ovol->v_root;
-        }
-    }
-
-    closevol(vol);
-    if (vol->v_deleted) {
-        showvol(vol->v_name);
-        volume_free(vol);
-        volume_unlink(vol);
-        free(vol);
-    }
-}
-
 /* ------------------------- */
 int afp_closevol(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
 {
@@ -2149,31 +990,12 @@ int afp_closevol(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
         return( AFPERR_PARAM );
     }
 
-    deletevol(vol);
-    current_vol = NULL;
+    (void)chdir("/");
+    closevol(vol);
 
     return( AFP_OK );
 }
 
-/* ------------------------- */
-struct vol *getvolbyvid(const uint16_t vid )
-{
-    struct vol  *vol;
-
-    for ( vol = Volumes; vol; vol = vol->v_next ) {
-        if ( vid == vol->v_vid ) {
-            break;
-        }
-    }
-    if ( vol == NULL || ( vol->v_flags & AFPVOL_OPEN ) == 0 ) {
-        return( NULL );
-    }
-
-    current_vol = vol;
-
-    return( vol );
-}
-
 /* --------------------------
    poll if a volume is changed by other processes.
    return
@@ -2199,7 +1021,7 @@ int  pollvoltime(AFPObj *obj)
     if ( gettimeofday( &tv, NULL ) < 0 )
         return 0;
 
-    for ( vol = Volumes; vol; vol = vol->v_next ) {
+    for ( vol = getvolumes(); vol; vol = vol->v_next ) {
         if ( (vol->v_flags & AFPVOL_OPEN)  && vol->v_mtime + 30 < tv.tv_sec) {
             if ( !stat( vol->v_path, &st ) && vol->v_mtime != st.st_mtime ) {
                 vol->v_mtime = st.st_mtime;
@@ -2240,7 +1062,7 @@ void setvoltime(AFPObj *obj, struct vol *vol)
 }
 
 /* ------------------------- */
-int afp_getvolparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_,char *rbuf, size_t *rbuflen)
+int afp_getvolparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_,char *rbuf, size_t *rbuflen)
 {
     struct vol  *vol;
     uint16_t   vid, bitmap;
@@ -2256,7 +1078,7 @@ int afp_getvolparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_,char *rbuf,
         return( AFPERR_PARAM );
     }
 
-    return stat_vol(bitmap, vol, rbuf, rbuflen);
+    return stat_vol(obj, bitmap, vol, rbuf, rbuflen);
 }
 
 /* ------------------------- */
@@ -2386,131 +1208,12 @@ static int create_special_folder (const struct vol *vol, const struct _special_f
 static void handle_special_folders (const struct vol * vol)
 {
     const _special_folder *p = &special_folders[0];
-    uid_t process_uid;
 
-    process_uid = geteuid();
-    if (process_uid) {
-        if (seteuid(0) == -1) {
-            process_uid = 0;
-        }
-    }
+    become_root();
 
     for (; p->name != NULL; p++) {
         create_special_folder (vol, p);
     }
 
-    if (process_uid) {
-        if (seteuid(process_uid) == -1) {
-            LOG(log_error, logtype_logger, "can't seteuid back %s", strerror(errno));
-            exit(EXITERR_SYS);
-        }
-    }
-}
-
-const struct vol *getvolumes(void)
-{
-    return Volumes;
-}
-
-void unload_volumes(void)
-{
-    LOG(log_debug, logtype_afpd, "unload_volumes_and_extmap");
-    free_volumes();
-}
-
-/* 
- * Get a volumes UUID from the config file.
- * If there is none, it is generated and stored there.
- *
- * Returns pointer to allocated storage on success, NULL on error.
- */
-static char *get_vol_uuid(const AFPObj *obj, const char *volname)
-{
-    char *volname_conf;
-    char buf[1024], uuid[UUID_PRINTABLE_STRING_LENGTH], *p;
-    FILE *fp;
-    struct stat tmpstat;
-    int fd;
-    
-    if ((fp = fopen(obj->options.uuidconf, "r")) != NULL) {  /* read open? */
-        /* scan in the conf file */
-        while (fgets(buf, sizeof(buf), fp) != NULL) { 
-            p = buf;
-            while (p && isblank(*p))
-                p++;
-            if (!p || (*p == '#') || (*p == '\n'))
-                continue;                             /* invalid line */
-            if (*p == '"') {
-                p++;
-                if ((volname_conf = strtok( p, "\"" )) == NULL)
-                    continue;                         /* syntax error */
-            } else {
-                if ((volname_conf = strtok( p, " \t" )) == NULL)
-                    continue;                         /* syntax error: invalid name */
-            }
-            p = strchr(p, '\0');
-            p++;
-            if (*p == '\0')
-                continue;                             /* syntax error */
-            
-            if (strcmp(volname, volname_conf) != 0)
-                continue;                             /* another volume name */
-                
-            while (p && isblank(*p))
-                p++;
-
-            if (sscanf(p, "%36s", uuid) == 1 ) {
-                for (int i=0; uuid[i]; i++)
-                    uuid[i] = toupper(uuid[i]);
-                LOG(log_debug, logtype_afpd, "get_uuid('%s'): UUID: '%s'", volname, uuid);
-                fclose(fp);
-                return strdup(uuid);
-            }
-        }
-    }
-
-    if (fp)
-        fclose(fp);
-
-    /*  not found or no file, reopen in append mode */
-
-    if (stat(obj->options.uuidconf, &tmpstat)) {                /* no file */
-        if (( fd = creat(obj->options.uuidconf, 0644 )) < 0 ) {
-            LOG(log_error, logtype_afpd, "ERROR: Cannot create %s (%s).",
-                obj->options.uuidconf, strerror(errno));
-            return NULL;
-        }
-        if (( fp = fdopen( fd, "w" )) == NULL ) {
-            LOG(log_error, logtype_afpd, "ERROR: Cannot fdopen %s (%s).",
-                obj->options.uuidconf, strerror(errno));
-            close(fd);
-            return NULL;
-        }
-    } else if ((fp = fopen(obj->options.uuidconf, "a+")) == NULL) { /* not found */
-        LOG(log_error, logtype_afpd, "Cannot create or append to %s (%s).",
-            obj->options.uuidconf, strerror(errno));
-        return NULL;
-    }
-    fseek(fp, 0L, SEEK_END);
-    if(ftell(fp) == 0) {                     /* size = 0 */
-        fprintf(fp, "# DON'T TOUCH NOR COPY THOUGHTLESSLY!\n");
-        fprintf(fp, "# This file is auto-generated by afpd\n");
-        fprintf(fp, "# and stores UUIDs for TM volumes.\n\n");
-    } else {
-        fseek(fp, -1L, SEEK_END);
-        if(fgetc(fp) != '\n') fputc('\n', fp); /* last char is \n? */
-    }                    
-    
-    /* generate uuid and write to file */
-    atalk_uuid_t id;
-    const char *cp;
-    randombytes((void *)id, 16);
-    cp = uuid_bin2string(id);
-
-    LOG(log_debug, logtype_afpd, "get_uuid('%s'): generated UUID '%s'", volname, cp);
-
-    fprintf(fp, "\"%s\"\t%36s\n", volname, cp);
-    fclose(fp);
-    
-    return strdup(cp);
+    unbecome_root();
 }
index 90febbfee00803f6fc803058ffaac982ff599b8d..ed59b2444141f1514c8b18bc8ebdbc5b4b0998e0 100644 (file)
 #include <atalk/unicode.h>
 #include <atalk/globals.h>
 
-extern struct vol       *getvolbyvid (const uint16_t);
 extern int              ustatfs_getvolspace (const struct vol *,
-            VolSpace *, VolSpace *,
-            uint32_t *);
+                                             VolSpace *, VolSpace *,
+                                             uint32_t *);
 extern void             setvoltime (AFPObj *, struct vol *);
 extern int              pollvoltime (AFPObj *);
-extern void             load_volumes (AFPObj *obj);
-extern const struct vol *getvolumes(void);
-extern void             unload_volumes(void);
 extern void             vol_fce_tm_event(void);
 
 /* FP functions */
@@ -35,6 +31,4 @@ int afp_closevol     (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf,  size
 /* netatalk functions */
 extern void     close_all_vol   (void);
 
-struct vol *current_vol;        /* last volume from getvolbyvid() */
-
 #endif
index b8c980b7abd447d781cb767bc0669ccaa1b28acf..d59d7fdb1251f126bfaaaed328f9bac47e2d40e8 100644 (file)
@@ -8,6 +8,7 @@ atalkinclude_HEADERS = \
        vfs.h \
        cnid.h \
        logger.h \
+       netatalk_conf.h \
        paths.h \
        unicode.h \
        util.h \
index 5607b3294c6c45f136c61af2e7c59b9dd39d7477..2e27cde15c46c8c412c191a22e053e5a5a116d87 100644 (file)
@@ -32,6 +32,8 @@
 
 #define MAXUSERLEN 256
 
+#define DEFAULT_MAX_DIRCACHE_SIZE 8192
+
 #define OPTION_DEBUG         (1 << 0)
 #define OPTION_CLOSEVOL      (1 << 1)
 #define OPTION_SERVERNOTIF   (1 << 2)
 #define OPTION_NOZEROCONF    (1 << 9)
 #define OPTION_KEEPSESSIONS  (1 << 10) /* preserve sessions across master afpd restart with SIGQUIT */
 
+#define PASSWD_NONE     0
+#define PASSWD_SET     (1 << 0)
+#define PASSWD_NOSAVE  (1 << 1)
+#define PASSWD_ALL     (PASSWD_SET | PASSWD_NOSAVE)
+
 /**********************************************************************************************
  * Ini config sections
  **********************************************************************************************/
@@ -115,6 +122,10 @@ typedef struct AFPObj {
     struct session_info  sinfo;
     uid_t uid;         /* client running user id */
     int ipc_fd; /* anonymous PF_UNIX socket for IPC with afpd parent */
+
+    gid_t *groups;
+    int ngroups;
+
     /* Functions */
     void (*logout)(void);
     void (*exit)(int);
@@ -139,7 +150,6 @@ extern const char         *Cnid_port;
 extern int  get_afp_errno   (const int param);
 extern void afp_options_init (struct afp_options *);
 extern void afp_options_parse_cmdline(AFPObj *obj, int ac, char **av);
-extern int  afp_config_parse(AFPObj *AFPObj);
 extern void afp_options_free(struct afp_options *);
 extern void setmessage (const char *);
 extern void readmessage (AFPObj *);
diff --git a/include/atalk/netatalk_conf.h b/include/atalk/netatalk_conf.h
new file mode 100644 (file)
index 0000000..5b6ab57
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+   Copyright (c) 2012 Frank Lahm <franklahm@gmail.com>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+ */
+
+#ifndef AFP_CONFIG_H
+#define AFP_CONFIG_H
+
+#include <stdint.h>
+
+#include <atalk/globals.h>
+#include <atalk/volume.h>
+
+extern int        afp_config_parse(AFPObj *obj);
+
+extern int        load_volumes(AFPObj *obj, void (*delvol_fn)(const struct vol *));
+extern void       unload_volumes(void);
+extern struct vol *getvolumes(void);
+extern struct vol *getvolbyvid(const uint16_t);
+extern void       volume_free(struct vol *vol);
+extern void       volume_unlink(struct vol *volume);
+#endif
index 62303692b2668c6fa2f3daffd631d192bb1caaa1..24c1f7c5686e8d4063e655412d7e86f653b6e476 100644 (file)
@@ -1,5 +1,4 @@
 /*
-   $Id: unix.h,v 1.3 2010-03-12 15:16:49 franklahm Exp $
    Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
 
    This program is free software; you can redistribute it and/or modify
@@ -46,5 +45,6 @@ extern int copy_ea(const char *ea, int sfd, const char *src, const char *dst, mo
 
 extern void become_root(void);
 extern void unbecome_root(void);
+extern int gmem(gid_t gid, int ngroups, gid_t *groups);
 
 #endif  /* ATALK_UNIX_H */
index 42b8a170180f5c3bb74b855544cb41c8466b097e..c179e74b02fcf650b5253f2c808a37669e6a766e 100644 (file)
@@ -91,8 +91,11 @@ struct vol {
 #endif /*__svr4__*/
 };
 
-#define AFPVOL_OPEN (1<<0)
+/* load_volumes() flags */
+#define LV_ALL (1 << 0)
 
+/* volume flags */
+#define AFPVOL_OPEN (1<<0)
 /* flags  for AFS and quota 0xxx0 */
 #define AFPVOL_GVSMASK  (7<<2)
 #define AFPVOL_NONE     (0<<2)
index 17ae747cb9ac45c278996965d57d697f8df91a65..8c0927d408edf0230529ea43121afe69abce82c5 100644 (file)
@@ -6,6 +6,7 @@ noinst_LTLIBRARIES = libutil.la
 
 libutil_la_SOURCES = \
        bprint.c        \
+       config.c        \
        cnid.c          \
        fault.c         \
        getiface.c      \
@@ -21,7 +22,11 @@ libutil_la_SOURCES = \
        volinfo.c       \
        unix.c
 
-libutil_la_CFLAGS = -D_PATH_AFPDCONF=\"$(pkgconfdir)/afpd.conf\"
+libutil_la_CFLAGS = \
+       -D_PATH_CONFDIR=\"$(pkgconfdir)/\" \
+       -DSERVERTEXT=\"$(SERVERTEXT)/\" \
+       -D_PATH_AFPDPWFILE=\"$(pkgconfdir)/afppasswd\" \
+       -D_PATH_AFPDUAMPATH=\"$(UAMS_PATH)/\"
 
 if HAVE_ATFUNCS
 libutil_la_SOURCES += ftw.c
index 6d3be477980dd65c787322c6a6bbf7312a314c86..a7cdd2c12a402ecd8bd8d89a199ff4dd92b4cce2 100644 (file)
@@ -627,7 +627,7 @@ void setuplog(const char *logstr, const char *logfile)
 
     save = ptr = strdup(logstr);
 
-    ptr = strtok(ptr, ",");
+    ptr = strtok(ptr, ", ");
 
     while (ptr) {
         while (*ptr) {
@@ -649,7 +649,7 @@ void setuplog(const char *logstr, const char *logfile)
             setuplog_internal(loglevel, logtype, logfile);
             *ptr = c;
         }
-        ptr = strtok(NULL, ",");
+        ptr = strtok(NULL, ", ");
     }
 
     free(save);
index 88371e8a082f397f22d4ecbf4b7ee7eefbd0753c..5b0da03c5087e6f710b1d11a5a0717431efeb5b6 100644 (file)
@@ -272,3 +272,15 @@ void randombytes(void *buf, int n)
 
     return;
 }
+
+int gmem(gid_t gid, int ngroups, gid_t *groups)
+{
+    int                i;
+
+    for ( i = 0; i < ngroups; i++ ) {
+        if ( groups[ i ] == gid ) {
+            return( 1 );
+        }
+    }
+    return( 0 );
+}