]> arthur.barton.de Git - netatalk.git/commitdiff
Merge branch 'release-3.0.6'
authorRalph Boehme <sloowfranklin@gmail.com>
Fri, 25 Oct 2013 15:28:09 +0000 (17:28 +0200)
committerRalph Boehme <sloowfranklin@gmail.com>
Fri, 25 Oct 2013 15:28:09 +0000 (17:28 +0200)
52 files changed:
NEWS
VERSION
bin/ad/ad_util.c
configure.ac
doc/manpages/man5/afp.conf.5.xml
doc/manual/upgrade.xml
doc/www/ReleaseNotes
etc/afpd/acl_mappings.h
etc/afpd/acls.c
etc/afpd/acls.h
etc/afpd/afp_config.c
etc/afpd/afp_dsi.c
etc/afpd/afp_mdns.c
etc/afpd/auth.c
etc/afpd/fork.c
etc/afpd/status.c
etc/afpd/uam.c
etc/afpd/uam_auth.h
etc/afpd/volume.c
etc/uams/uams_dhx2_pam.c
etc/uams/uams_dhx2_passwd.c
etc/uams/uams_dhx_pam.c
etc/uams/uams_dhx_passwd.c
etc/uams/uams_gss.c
etc/uams/uams_guest.c
etc/uams/uams_pam.c
etc/uams/uams_passwd.c
etc/uams/uams_pgp.c
etc/uams/uams_randnum.c
include/atalk/acl.h
include/atalk/adouble.h
include/atalk/afp.h
include/atalk/directory.h
include/atalk/ea.h
include/atalk/globals.h
include/atalk/ldapconfig.h
include/atalk/tdb.h
include/atalk/uam.h
include/atalk/vfs.h
libatalk/Makefile.am
libatalk/acl/ldap.c
libatalk/acl/unix.c
libatalk/adouble/ad_open.c
libatalk/cnid/tdb/Makefile.am
libatalk/dsi/dsi_getsess.c
libatalk/libatalk-3.0.6.abi [new file with mode: 0644]
libatalk/util/netatalk_conf.c
libatalk/vfs/acl.c
libatalk/vfs/vfs.c
macros/netatalk.m4
macros/summary.m4
man/man5/afp.conf.5.in

diff --git a/NEWS b/NEWS
index 98e2d2b5d969a81152012627bd00c48b2110f7aa..f9d88e2789eaa6878f86294d87f673c182adeef3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,26 @@
+Changes in 3.0.6
+================
+* FIX: charset conversion failed when copying from Mac OS 9. Bug #523.
+* UPD: Don't force S_ISGID for directories on FreeBSD. Bug #525.
+* NEW: Add support for ZFS ACLs on FreeBSD with libsunacl. From FR#83.
+* FIX: Active Directory LDAP queries for ACL support with new options
+       "ldap user filter" and "ldap group filter". Bug #526.
+* NEW: Option "vol dbnest", when set to true, the CNID database for
+       a volume is stored in the volume root of a share in a directory
+       .AppleDB like in Netatalk 2. Defaults to false. From FR#84.
+* FIX: Small fix in the DSI tickle handling. Bug #528.
+* UPD: Enhance handling of connection attempts when hitting the
+       connection limit. Bug #529.
+* FIX: Saving from Word to a folder that is a symlink to a folder on
+       another filesystem results in a crash of the afpd process and
+       the save to fail. This happens only if the option
+       "follow symlinks" is enabled. Bug #532.
+* FIX: Disable Kerberos UAM if AFP service principal name can't be
+       evaluated. Fixes bug #531.
+* FIX: Fix handling of large number of volumes. Bug #527.
+* NEW: Configure option --with-tbd which can be used to disable the
+       use of the bundled tdb and use a system installed version.
+
 Changes in 3.0.5
 ================
 * FIX: Fix a crash when using pam_winbind. Fixes bug #516.
@@ -5,7 +28,7 @@ Changes in 3.0.5
 * FIX: "afp listen" option failed to take IPv6 addresses. Bug #515.
 * FIX: Fix a possible crash in set_groups. Bug #518.
 * NEW: Send optional AFP messages for vetoed files, new option
-       "veto messages" can be used to enable sending messages.
+       "veto message" can be used to enable sending messages.
        Then whenever a client tries to access any file or directory
        with a vetoed name, it will be sent an AFP message indicating
        the name and the directory. From FR #81.
@@ -25,7 +48,7 @@ Changes in 3.0.4
        lead to a failure setting the size of a files ressource fork.
        This affected application like Adobe Photoshop where saving
        files may fail. Fixes bug #511.
-* UPD: Enhance ACL mapping, change global ACL option 'map acl' to take
+* UPD: Enhance ACL mapping, change global ACL option 'map acls' to take
        the following options: "none", "rights" (default), "mode".
        none   = no mapping, this resembles the previous false/no setting
        rights = map ACLs to Finder UARights, this resembles the previous
diff --git a/VERSION b/VERSION
index 7da3c16870e856cce1a539d478294b4030dac60d..8ffc1ad6404cd25651874ae352a84feb1ac5c3bb 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.0.5
\ No newline at end of file
+3.0.6
\ No newline at end of file
index fbe85235c2af51201ec331e5e0ea67d27ed93f86..340dc5685e66426f80244b87bc3d3976fd1b6f18 100644 (file)
@@ -51,6 +51,9 @@
 #ifdef HAVE_SOLARIS_ACLS
 #include <sys/acl.h>
 #endif  /* HAVE_SOLARIS_ACLS */
+#ifdef HAVE_FREEBSD_SUNACL
+#include <sunacl.h>
+#endif
 
 #ifdef HAVE_POSIX_ACLS
 #include <sys/types.h>
index c3c695cebf6918dff60efd9cd8b340fd7c8b0584..6f56cdc3e85b6e4d90eed5d4b9d563247016e8a5 100644 (file)
@@ -182,6 +182,9 @@ AC_NETATALK_SENDFILE
 dnl Check whether bundled libevent shall not be used
 AC_NETATALK_LIBEVENT
 
+dnl Check whether bundled tdb shall be used
+AC_NETATALK_TDB
+
 dnl libatalk API checks
 AC_DEVELOPER
 
@@ -210,7 +213,7 @@ AC_SUBST(UAMS_PATH)
 AM_CONDITIONAL(SOLARIS_MODULE, test x$solaris_module = xyes)
 AM_CONDITIONAL(HAVE_LIBGCRYPT, test x$neta_cv_have_libgcrypt = xyes)
 AM_CONDITIONAL(HAVE_OPENSSL, test x$neta_cv_have_openssl = xyes)
-AM_CONDITIONAL(HAVE_ACLS, test x"$with_acl_support" = x"yes")
+AM_CONDITIONAL(HAVE_ACLS, test x"$ac_cv_have_acls" = x"yes")
 AM_CONDITIONAL(HAVE_LDAP, test x"$netatalk_cv_ldap" = x"yes")
 AM_CONDITIONAL(USE_DHX, test x$neta_cv_compile_dhx = xyes)
 AM_CONDITIONAL(USE_DHX2, test x$neta_cv_compile_dhx2 = xyes)
index 27e8b14e81d3aff738e6a25aeeeea572392e252c..026fef0fef30658df7711e00a812a1a24283eebd 100644 (file)
@@ -5,7 +5,7 @@
 
     <manvolnum>5</manvolnum>
 
-    <refmiscinfo class="date">30 Apr 2013</refmiscinfo>
+    <refmiscinfo class="date">13 Sep 2013</refmiscinfo>
 
     <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
   </refmeta>
 
           <listitem>
             <para>This specifies the DSI server quantum. The default value is
-            1 MB. The maximum value is 0xFFFFFFFFF, the minimum is 32000. If
-            you specify a value that is out of range, the default value will
-            be set. Do not change this value unless you're absolutely sure,
-            what you're doing</para>
+            0x100000 (1 MiB). The maximum value is 0xFFFFFFFFF, the minimum is
+            32000. If you specify a value that is out of range, the default
+            value will be set. Do not change this value unless you're
+            absolutely sure, what you're doing</para>
           </listitem>
         </varlistentry>
 
           <emphasis>no</emphasis>) <type>(G)</type></term>
 
           <listitem>
-            <para>Use section <option>name</option> as option preset for all
-            volumes (when set in the [Global] section) or for one volume (when
-            set in that volume's section).</para>
+            <para>Send optional AFP messages for vetoed files. Then whenever a
+            client tries to access any file or directory with a vetoed name,
+            it will be sent an AFP message indicating the name and the
+            directory.</para>
           </listitem>
         </varlistentry>
 
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term>vol dbnest = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(G)</type></term>
+
+          <listitem>
+            <para>Setting this option to true brings back Netatalk 2
+            behaviour of storing the CNID database in a folder called
+            .AppleDB inside the volume root of each share.</para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term>volnamelen = <replaceable>number</replaceable>
           <type>(G)</type></term>
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term>ldap group attr = <parameter>dn</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Name of the LDAP attribute with the groups short
+            name.</para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term>ldap uuid string = <parameter>STRING</parameter>
           <type>(G)</type></term>
             internal UUID representation is converted to and from the binary
             format used in the objectGUID attribute found on objects in Active
             Directory when interacting with the server.</para>
-
+            <para>See also the options <option>ldap user filter</option> and
+            <option>ldap group filter</option>.</para>
             <para><variablelist>
                 <varlistentry>
                   <term>string</term>
         </varlistentry>
 
         <varlistentry>
-          <term>ldap group attr = <parameter>dn</parameter>
+          <term>ldap user filter = <parameter>STRING (default: unused)</parameter>
           <type>(G)</type></term>
 
           <listitem>
-            <para>Name of the LDAP attribute with the groups short
-            name.</para>
+            <para>Optional LDAP filter that matches user objects. This is necessary for Active Directory
+            environments where users and groups are stored in the same directory subtree.</para>
+            <para>Recommended setting for Active Directory: <parameter>objectClass=user</parameter>.</para>
           </listitem>
         </varlistentry>
+
+        <varlistentry>
+          <term>ldap group filter = <parameter>STRING (default: unused)</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Optional LDAP filter that matches group objects. This is necessary for Active Directory
+            environments where users and groups are stored in the same directory subtree.</para>
+            <para>Recommended setting for Active Directory: <parameter>objectClass=group</parameter>.</para>
+          </listitem>
+        </varlistentry>
+
       </variablelist>
     </refsect2>
   </refsect1>
             Setting the option to true causes afpd to follow symlinks on the
             server. symlinks may point outside of the AFP volume, currently
             afpd doesn't do any checks for "wide symlinks".</para>
+            <note>
+              <para>This option will subtly break when the symlinks point
+              across filesystem boundaries.</para>
+            </note>
           </listitem>
         </varlistentry>
 
index 43e5e6967fcff4abcc729cf79f1cb996acf112a3..2d85e74c9fec5fd71e70f834a76c7aedc9318419 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <chapter id="upgrade">
   <chapterinfo>
-    <date>7.29.2013</date>
+    <date>9.6.2013</date>
 
     <author>
       <firstname>Frank</firstname>
@@ -9,7 +9,7 @@
       <surname>Lahm</surname>
     </author>
 
-    <pubdate>29 Jul, 2013</pubdate>
+    <pubdate>6 Sep, 2013</pubdate>
   </chapterinfo>
 
   <title>Upgrading from Netatalk 2</title>
             <row>
               <entry>-server_quantum</entry>
               <entry>server quantum</entry>
-              <entry>303840</entry>
-              <entry>303840</entry>
+              <entry><emphasis role="bold">303840</emphasis></entry>
+              <entry><emphasis role="bold">1048576</emphasis></entry>
               <entry>(G)</entry>
               <entry>-</entry>
             </row>
index 850be9eadea0428c7814604bdb43439644b86efa..5ebaade881435df98734a992a3459897a260bb61 100644 (file)
@@ -1,9 +1,9 @@
-Netatalk 3.0.5
+Netatalk 3.0.6
 ==============
 
-The Netatalk development team is proud to announce version 3.0.5 of
+The Netatalk development team is proud to announce version 3.0.6 of
 the Netatalk File Sharing suite. This is the latest update to the 3.0
-release series. All users are encouraged to upgrade their systems to 3.0.5.
+release series. All users are encouraged to upgrade their systems to 3.0.6.
 
 Netatalk is a freely-available Open Source AFP fileserver.
 A *NIX/*BSD system running Netatalk is capable of serving many Macintosh
@@ -43,6 +43,29 @@ at:
 
   http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 
+Changes in 3.0.6
+~~~~~~~~~~~~~~~~
+* FIX: charset conversion failed when copying from Mac OS 9. Bug #523.
+* UPD: Don't force S_ISGID for directories on FreeBSD. Bug #525.
+* NEW: Add support for ZFS ACLs on FreeBSD with libsunacl. From FR#83.
+* FIX: Active Directory LDAP queries for ACL support with new options
+       "ldap user filter" and "ldap group filter". Bug #526.
+* NEW: Option "vol dbnest", when set to true, the CNID database for
+       a volume is stored in the volume root of a share in a directory
+       .AppleDB like in Netatalk 2. Defaults to false. From FR#84.
+* FIX: Small fix in the DSI tickle handling. Bug #528.
+* UPD: Enhance handling of connection attempts when hitting the
+       connection limit. Bug #529.
+* FIX: Saving from Word to a folder that is a symlink to a folder on
+       another filesystem results in a crash of the afpd process and
+       the save to fail. This happens only if the option
+       "follow symlinks" is enabled. Bug #532.
+* FIX: Disable Kerberos UAM if AFP service principal name can't be
+       evaluated. Fixes bug #531.
+* FIX: Fix handling of large number of volumes. Bug #527.
+* NEW: Configure option --with-tbd which can be used to disable the
+       use of the bundled tdb and use a system installed version.
+
 Changes in 3.0.5
 ~~~~~~~~~~~~~~~~
 * FIX: Fix a crash when using pam_winbind. Fixes bug #516.
@@ -336,4 +359,4 @@ We would like to thank all contributors to the Netatalk project for
 their commitment.  Without the many suggestions, bug and problem reports,
 patches, and reviews this project wouldn't be where it is.
 
- - The Netatalk Development Team, August 2013
+ - The Netatalk Development Team, October 2013
index 87ff5decefdc75d9c09feab9af8c8d971fa54b14..7906aeec6769f036fd2eddad9b0c0de249693820 100644 (file)
@@ -18,6 +18,9 @@
 #ifdef HAVE_SOLARIS_ACLS
 #include <sys/acl.h>
 #endif
+#ifdef HAVE_FREEBSD_SUNACL
+#include <sunacl.h>
+#endif
 
 #include "acls.h"
 
@@ -35,7 +38,7 @@ struct ace_rights_map {
     uint32_t to;
 };
 
-#ifdef HAVE_SOLARIS_ACLS
+#if (defined HAVE_SOLARIS_ACLS || defined HAVE_FREEBSD_SUNACL)
 struct ace_rights_map nfsv4_to_darwin_rights[] = {
     {ACE_READ_DATA,         DARWIN_ACE_READ_DATA},
     {ACE_WRITE_DATA,        DARWIN_ACE_WRITE_DATA},
@@ -97,6 +100,6 @@ struct darwin_to_nfsv4_flags_map darwin_to_nfsv4_flags[] = {
     {DARWIN_ACE_FLAGS_INHERITED,         ACE_INHERITED_ACE},
     {0,0}
 };
-#endif /* HAVE_SOLARIS_ACLS */
+#endif /* HAVE_SOLARIS_ACLS || HAVE_FREEBSD_SUNACL */
 
 #endif /* ACL_MAPPINGS */
index d162b994e7af71d09436f0b937d80a2cd2b3bffa..f914c8e4754753e55033f5b77222edd6688808bf 100644 (file)
@@ -27,6 +27,9 @@
 #ifdef HAVE_SOLARIS_ACLS
 #include <sys/acl.h>
 #endif
+#ifdef HAVE_FREEBSD_SUNACL
+#include <sunacl.h>
+#endif
 #ifdef HAVE_POSIX_ACLS
 #include <sys/acl.h>
 #endif
@@ -76,7 +79,7 @@
  * Solaris funcs
  ********************************************************/
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
 
 /*! 
  * Compile access rights for a user to one file-system object
@@ -362,7 +365,7 @@ EC_CLEANUP:
         free(name);
     EC_EXIT;
 }
-#endif /* HAVE_SOLARIS_ACLS */
+#endif /* HAVE_NFSV4_ACLS */
 
 /********************************************************
  * POSIX 1e funcs
@@ -975,7 +978,7 @@ static int map_acl(int type, void *acl, darwin_ace_t *buf, int ace_count)
 
     switch (type & MAP_MASK) {
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
     case SOLARIS_2_DARWIN:
         mapped_aces = map_aces_solaris_to_darwin( acl, buf, ace_count);
         break;
@@ -983,7 +986,7 @@ static int map_acl(int type, void *acl, darwin_ace_t *buf, int ace_count)
     case DARWIN_2_SOLARIS:
         mapped_aces = map_aces_darwin_to_solaris( buf, acl, ace_count);
         break;
-#endif /* HAVE_SOLARIS_ACLS */
+#endif /* HAVE_NFSV4_ACLS */
 
 #ifdef HAVE_POSIX_ACLS
     case POSIX_DEFAULT_2_DARWIN:
@@ -1019,7 +1022,7 @@ static int get_and_map_acl(char *name, char *rbuf, size_t *rbuflen)
     int mapped_aces = 0;
     int dirflag;
     char *darwin_ace_count = rbuf;
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
     int ace_count = 0;
     ace_t *aces = NULL;
 #endif
@@ -1033,10 +1036,10 @@ static int get_and_map_acl(char *name, char *rbuf, size_t *rbuflen)
     *rbuf = 0;
     rbuf += 4;
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
     EC_NEG1(ace_count = get_nfsv4_acl(name, &aces));
     EC_NEG1(mapped_aces = map_acl(SOLARIS_2_DARWIN, aces, (darwin_ace_t *)rbuf, ace_count));
-#endif /* HAVE_SOLARIS_ACLS */
+#endif /* HAVE_NFSV4_ACLS */
 
 #ifdef HAVE_POSIX_ACLS
     acl_t defacl = NULL , accacl = NULL;
@@ -1074,7 +1077,7 @@ static int get_and_map_acl(char *name, char *rbuf, size_t *rbuflen)
     EC_STATUS(0);
 
 EC_CLEANUP:
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
     if (aces) free(aces);
 #endif
 #ifdef HAVE_POSIX_ACLS
@@ -1092,7 +1095,7 @@ static int remove_acl(const struct vol *vol,const char *path, int dir)
 {
     int ret = AFP_OK;
 
-#if (defined HAVE_SOLARIS_ACLS || defined HAVE_POSIX_ACLS)
+#if (defined HAVE_NFSV4_ACLS || defined HAVE_POSIX_ACLS)
     /* Ressource etc. first */
     if ((ret = vol->vfs->vfs_remove_acl(vol, path, dir)) != AFP_OK)
         return ret;
@@ -1110,7 +1113,7 @@ static int remove_acl(const struct vol *vol,const char *path, int dir)
   We will store inherited ACEs first, which is Darwins canonical order.
   - returns AFPerror code
 */
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
 static int set_acl(const struct vol *vol,
                    char *name,
                    int inherit,
@@ -1186,28 +1189,27 @@ static int set_acl(const struct vol *vol,
     if ((ret = (vol->vfs->vfs_acl(vol, name, ACE_SETACL, new_aces_count, new_aces))) != 0) {
         LOG(log_debug, logtype_afpd, "set_acl: error setting acl: %s", strerror(errno));
         switch (errno) {
-        case EACCES:
-        case EPERM:
-            EC_STATUS(AFPERR_ACCESS);
-            break;
         case ENOENT:
-            EC_STATUS(AFP_OK);
             break;
+        case EACCES:
+        case EPERM:
+            EC_EXIT_STATUS(AFPERR_ACCESS);
         default:
-            EC_STATUS(AFPERR_MISC);
-            break;
+            EC_EXIT_STATUS(AFPERR_MISC);
         }
-        goto EC_CLEANUP;
     }
+
     if ((ret = (acl(name, ACE_SETACL, new_aces_count, new_aces))) != 0) {
         LOG(log_error, logtype_afpd, "set_acl: error setting acl: %s", strerror(errno));
-        if (errno == (EACCES | EPERM))
-            EC_STATUS(AFPERR_ACCESS);
-        else if (errno == ENOENT)
-            EC_STATUS(AFPERR_NOITEM);
-        else
-            EC_STATUS(AFPERR_MISC);
-        goto EC_CLEANUP;
+        switch (errno) {
+        case EACCES:
+        case EPERM:
+            EC_EXIT_STATUS(AFPERR_ACCESS);
+        case ENOENT:
+            EC_EXIT_STATUS(AFPERR_NOITEM);
+        default:
+            EC_EXIT_STATUS(AFPERR_MISC);
+        }
     }
 
     EC_STATUS(AFP_OK);
@@ -1219,7 +1221,7 @@ EC_CLEANUP:
     LOG(log_debug9, logtype_afpd, "set_acl: END");
     EC_EXIT;
 }
-#endif /* HAVE_SOLARIS_ACLS */
+#endif /* HAVE_NFSV4_ACLS */
 
 #ifdef HAVE_POSIX_ACLS
 #ifndef HAVE_ACL_FROM_MODE
@@ -1420,7 +1422,7 @@ static int check_acl_access(const AFPObj *obj,
         allowed_rights = curdir->d_rights_cache;
         LOG(log_debug, logtype_afpd, "check_access: allowed rights from dircache: 0x%08x", allowed_rights);
     } else {
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
         EC_ZERO_LOG(solaris_acl_rights(obj, path, &st, NULL, &allowed_rights));
 #endif
 #ifdef HAVE_POSIX_ACLS
@@ -1453,7 +1455,7 @@ static int check_acl_access(const AFPObj *obj,
             LOG(log_debug, logtype_afpd,"parent: %s", cfrombstr(parent));
             EC_ZERO_LOG_ERR(lstat(cfrombstr(parent), &st), AFPERR_MISC);
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
             EC_ZERO_LOG(solaris_acl_rights(obj, cfrombstr(parent), &st, NULL, &parent_rights));
 #endif
 #ifdef HAVE_POSIX_ACLS
@@ -1766,7 +1768,7 @@ int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct
     LOG(log_maxdebug, logtype_afpd, "acltoownermode(\"%s/%s\", 0x%02x)",
         getcwdpath(), path, ma->ma_user);
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
     EC_ZERO_LOG(solaris_acl_rights(obj, path, st, ma, NULL));
 #endif
 
index c48f03a9b4ab6da3b3e7e4c4950f8c7868617ac9..4d423af5df73ff715d1f44871e5b3c1a581ada49 100644 (file)
@@ -18,6 +18,9 @@
 #ifdef HAVE_SOLARIS_ACLS
 #include <sys/acl.h>
 #endif
+#ifdef HAVE_FREEBSD_SUNACL
+#include <sunacl.h>
+#endif
 
 #include <atalk/uuid.h>                /* for atalk_uuid_t */
 
  * the wire! We will ignore and spoil em.
  */
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
 /* Some stuff for the handling of NFSv4 ACLs */
 #define ACE_TRIVIAL (ACE_OWNER | ACE_GROUP | ACE_EVERYONE)
-#endif /* HAVE_SOLARIS_ACLS */
+#endif /* HAVE_NFSV4_ACLS */
 
 /* FPGet|Set Bitmap */
 enum {
index 94adb9938e0a668e6988355117cadd4a27323d09..149593431373c52dc3f56a41511cbfb9a4cf220f 100644 (file)
@@ -93,7 +93,7 @@ int configinit(AFPObj *obj)
     int family, s;
     static char interfaddr[NI_MAXHOST];
 
-    auth_load(obj->options.uampath, obj->options.uamlist);
+    auth_load(obj, obj->options.uampath, obj->options.uamlist);
     set_signature(&obj->options);
 #ifdef HAVE_LDAP
     acl_ldap_freeconfig();
index 5082ee70fea0f83d6d528fcc49a875520376d99c..e68b63a47e9386162c881ba8b8071b16bedec9db 100644 (file)
@@ -321,9 +321,10 @@ static void alarm_handler(int sig _U_)
         return;
     }
 
-    if ((err = pollvoltime(AFPobj)) == 0)
+    if ((err = pollvoltime(AFPobj)) == 0) {
         LOG(log_debug, logtype_afpd, "afp_alarm: sending DSI tickle");
         err = dsi_tickle(AFPobj->dsi);
+    }
     if (err <= 0) {
         if (geteuid() == 0) {
             LOG(log_note, logtype_afpd, "afp_alarm: unauthenticated user, connection problem");
index 3158ce7b7fee9ef3058563309151defdc211b53b..2387edad4f542fbe20acef3acf6fb7cdcf9a5152 100644 (file)
@@ -36,13 +36,13 @@ static pthread_t       poller;
 /*
  * Its easier to use asprintf to set the TXT record values
  */
-#define TXTRecordPrintf(rec, key, args...) {            \
+#define TXTRecordPrintf(rec, key, args, ...) {           \
         char *str;                                      \
         asprintf(&str, args);                           \
         TXTRecordSetValue(rec, key, strlen(str), str);  \
         free(str);                                      \
     }
-#define TXTRecordKeyPrintf(rec, k, var, args...) {      \
+#define TXTRecordKeyPrintf(rec, k, var, args, ...) {     \
         char *key, *str;                                \
         asprintf(&key, k, var);                         \
         asprintf(&str, args);                           \
index bec624dc6cd32efc72b9838381a5b8f12ad6593b..27e678c23b65097371046530bde03174c78c4e29 100644 (file)
@@ -222,6 +222,11 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi
         return AFPERR_NOTAUTH;
     }
 
+    if (obj->cnx_cnt > obj->cnx_max) {
+        LOG(log_error, logtype_dsi, "login: too many connections, limit: %d", obj->cnx_max);
+        return AFPERR_MAXSESS;
+    }
+
     LOG(log_note, logtype_afpd, "%s Login by %s",
         afp_versions[afp_version_index].av_name, pwd->pw_name);
 
@@ -1012,7 +1017,7 @@ int auth_register(const int type, struct uam_obj *uam)
 }
 
 /* load all of the modules */
-int auth_load(const char *path, const char *list)
+int auth_load(AFPObj *obj, const char *path, const char *list)
 {
     char name[MAXPATHLEN + 1], buf[MAXPATHLEN + 1], *p;
     struct uam_mod *mod;
@@ -1039,7 +1044,7 @@ int auth_load(const char *path, const char *list)
           if ((stat(name, &st) == 0) && (mod = uam_load(name, p))) {
         */
         if (stat(name, &st) == 0) {
-            if ((mod = uam_load(name, p))) {
+            if ((mod = uam_load(obj, name, p))) {
                 uam_attach(&uam_modules, mod);
                 LOG(log_debug, logtype_afpd, "uam: %s loaded", p);
             } else {
index 0c988828d609660bc096c8cf01c944f6f8e633dc..350b57113a4eb72f9e43367a16074a74bd21e251 100644 (file)
@@ -66,10 +66,10 @@ static int getforkparams(const AFPObj *obj, struct ofork *ofork, uint16_t bitmap
     vol = ofork->of_vol;
     dir = dirlookup(vol, ofork->of_did);
 
-    if (NULL == (path.m_name = utompath(vol, of_name(ofork), dir->d_did, utf8_encoding(obj)))) {
+    if (NULL == (path.u_name = mtoupath(vol, of_name(ofork), dir->d_did, utf8_encoding(obj)))) {
         return( AFPERR_MISC );
     }
-    path.u_name = of_name(ofork);
+    path.m_name = of_name(ofork);
     path.id = 0;
     st = &path.st;
     if ( bitmap & ( (1<<FILPBIT_DFLEN) | (1<<FILPBIT_EXTDFLEN) |
index 35e088499db21c56483139df30e3c7b3d5c7f9de..edf744664038965aeb0fffd3f673b587d198d64c 100644 (file)
@@ -311,39 +311,6 @@ static size_t status_netaddress(char *data, int *servoffset,
     return (data - begin);
 }
 
-static bool append_directoryname(char **pdata,
-                                 size_t offset,
-                                 size_t *size,
-                                 char* DirectoryNamesCount,
-                                 size_t len,
-                                 char *principal)
-{
-    if (sizeof(uint8_t) + len  > maxstatuslen - offset - *size) {
-        LOG(log_error, logtype_afpd,
-            "status:DirectoryNames: out of space for principal '%s' (len=%d)",
-            principal, len);
-        return false;
-    } else if (len > 255) {
-        LOG(log_error, logtype_afpd,
-            "status:DirectoryNames: principal '%s' (len=%d) too long (max=255)",
-            principal, len);
-        return false;
-    }
-
-    LOG(log_info, logtype_afpd,
-        "DirectoryNames[%d]=%s",
-        *DirectoryNamesCount, principal);
-
-    *DirectoryNamesCount += 1;
-    char *data = *pdata;
-    *data++ = len;
-    strncpy(data, principal, len);
-
-    *pdata += len + 1;
-    *size += sizeof(uint8_t) + len;
-
-    return true;
-}
 
 /**
  * DirectoryNamesCount offset: uint16_t
@@ -354,7 +321,7 @@ static bool append_directoryname(char **pdata,
 static size_t status_directorynames(char *data,
                                     int *diroffset,
                                     const DSI *dsi _U_,
-                                    const struct afp_options *options _U_)
+                                    const struct afp_options *options)
 {
     char *begin = data;
     uint16_t offset;
@@ -363,130 +330,14 @@ static size_t status_directorynames(char *data,
     offset = ntohs(offset);
     data += offset;
 
-    char *DirectoryNamesCount = data++;
-    size_t size = sizeof(uint8_t);
-    *DirectoryNamesCount = 0;
-
-    if (!uam_gss_enabled())
-        goto offset_calc;
-
-#ifdef HAVE_KERBEROS
-    krb5_context context;
-    krb5_error_code ret;
-    const char *error_msg;
-
-    if (krb5_init_context(&context)) {
-        LOG(log_error, logtype_afpd,
-            "status:DirectoryNames failed to intialize a krb5_context");
-        goto offset_calc;
-    }
-
-    krb5_keytab keytab;
-    if ((ret = krb5_kt_default(context, &keytab)))
-        goto krb5_error;
-
-    // figure out which service principal to use
-    krb5_keytab_entry entry;
-    char *principal;
-    if (options->k5service && options->fqdn && options->k5realm) {
-        LOG(log_debug, logtype_afpd,
-            "status:DirectoryNames: using service principal specified in options");
-
-        krb5_principal service_principal;
-        if ((ret = krb5_build_principal(context,
-                                        &service_principal,
-                                        strlen(options->k5realm),
-                                        options->k5realm,
-                                        options->k5service,
-                                        options->fqdn,
-                                        NULL)))
-            goto krb5_error;
-
-        // try to get the given service principal from keytab
-        ret = krb5_kt_get_entry(context,
-                                keytab,
-                                service_principal,
-                                0, // kvno - wildcard
-                                0, // enctype - wildcard
-                                &entry);
-        if (ret == KRB5_KT_NOTFOUND) {
-            krb5_unparse_name(context, service_principal, &principal);
-            LOG(log_error, logtype_afpd,
-                "status:DirectoryNames: specified service principal '%s' not found in keytab",
-                principal);
-            // XXX: should this be krb5_xfree?
-#ifdef HAVE_KRB5_FREE_UNPARSED_NAME
-            krb5_free_unparsed_name(context, principal);
-#else
-           krb5_xfree(principal);
-#endif
-            goto krb5_cleanup;
-        }
-        krb5_free_principal(context, service_principal);
-        if (ret)
-            goto krb5_error;
+    if (!uam_gss_enabled() || !options->k5principal) {
+        *data = 0;
+        data++;
     } else {
-        LOG(log_debug, logtype_afpd,
-            "status:DirectoryNames: using first entry from keytab as service principal");
-
-        krb5_kt_cursor cursor;
-        if ((ret = krb5_kt_start_seq_get(context, keytab, &cursor)))
-            goto krb5_error;
-
-        ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
-        krb5_kt_end_seq_get(context, keytab, &cursor);
-        if (ret)
-            goto krb5_error;
+        memcpy(data, options->k5principal, options->k5principal_buflen);
+        data += options->k5principal_buflen;
     }
 
-    krb5_unparse_name(context, entry.principal, &principal);
-#ifdef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS
-    krb5_free_keytab_entry_contents(context, &entry);
-#elif defined(HAVE_KRB5_KT_FREE_ENTRY)
-    krb5_kt_free_entry(context, &entry);
-#endif
-    append_directoryname(&data,
-                         offset,
-                         &size,
-                         DirectoryNamesCount,
-                         strlen(principal),
-                         principal);
-
-    free(principal);
-    goto krb5_cleanup;
-
-krb5_error:
-    if (ret) {
-        error_msg = krb5_get_error_message(context, ret);
-        LOG(log_note, logtype_afpd, "Can't get principal from default keytab: %s",
-            (char *)error_msg);
-#ifdef HAVE_KRB5_FREE_ERROR_MESSAGE
-        krb5_free_error_message(context, error_msg);
-#else
-       krb5_xfree(error_msg);
-#endif
-    }
-
-krb5_cleanup:
-    krb5_kt_close(context, keytab);
-    krb5_free_context(context);
-#else
-    if (!options->k5service || !options->fqdn || !options->k5realm)
-        goto offset_calc;
-
-    char principal[255];
-    size_t len = snprintf(principal, sizeof(principal), "%s/%s@%s",
-                          options->k5service, options->fqdn, options->k5realm);
-
-    append_directoryname(&data,
-                         offset,
-                         &size,
-                         DirectoryNamesCount,
-                         strlen(principal),
-                         principal);
-#endif // HAVE_KERBEROS
-
-offset_calc:
     /* Calculate and store offset for UTF8ServerName */
     *diroffset += sizeof(uint16_t);
     offset = htons(data - begin);
index 208c9ff234313dd8194a7ac9e488b609b6f9ef99..04e54cbbd2f60c1999337a917412bb4cb87b91d1 100644 (file)
@@ -46,7 +46,7 @@
 /* --- server uam functions -- */
 
 /* uam_load. uams must have a uam_setup function. */
-struct uam_mod *uam_load(const char *path, const char *name)
+struct uam_mod *uam_load(AFPObj *obj, const char *path, const char *name)
 {
     char buf[MAXPATHLEN + 1], *p;
     struct uam_mod *mod;
@@ -82,7 +82,7 @@ struct uam_mod *uam_load(const char *path, const char *name)
     /* version check would go here */
 
     if (!mod->uam_fcn->uam_setup ||
-            ((*mod->uam_fcn->uam_setup)(name) < 0)) {
+        ((*mod->uam_fcn->uam_setup)(obj, name) < 0)) {
         LOG(log_error, logtype_afpd, "uam_load(%s): uam_setup failed", name);
         goto uam_load_err;
     }
index a553ffabff4aaac03c3f787c4e42b77d27c69a39..4eb3bf0464b7251dd89774c7d3109989a62c4603 100644 (file)
@@ -51,11 +51,11 @@ struct uam_obj {
     (a)->uam_next->uam_prev = (a)->uam_prev; \
 } while (0)
 
-extern struct uam_mod *uam_load (const char *, const char *);
+extern struct uam_mod *uam_load (AFPObj *, const char *, const char *);
 extern void uam_unload (struct uam_mod *);
 
 /* auth.c */
-int auth_load (const char *, const char *);
+int auth_load (AFPObj *, const char *, const char *);
 int auth_register (const int, struct uam_obj *);
 #define auth_unregister(a) uam_detach(a)
 struct uam_obj *auth_uamfind (const int, const char *, const int);
index 5f0d8a3786b3c945b84b5d59372e8d34cace4495..4efa659f02ee02eccb4f4f4fe53216ca606e5852 100644 (file)
@@ -535,7 +535,7 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
     load_volumes(obj);
 
     data = rbuf + 5;
-    for ( vcnt = 0, volume = getvolumes(); volume; volume = volume->v_next ) {
+    for ( vcnt = 0, volume = getvolumes(); volume && vcnt < 255; volume = volume->v_next ) {
         if (!(volume->v_flags & AFPVOL_NOSTAT)) {
             struct maccess ma;
 
@@ -562,6 +562,14 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
         if (len == (size_t)-1)
             continue;
 
+        /*
+         * There seems to be an undocumented limit on how big our reply can get
+         * before the client chokes and closes the connection.
+         * Testing with 10.8.4 found the limit at ~4600 bytes. Go figure. 
+         */
+        if (((data + len + 3) - rbuf) > 4600)
+            break;
+
         /* set password bit if there's a volume password */
         *data = (volume->v_password) ? AFPSRVR_PASSWD : 0;
 
index 76e9143f6a97bd20e6cab84f8027cff6e44a64ce..8857759d2f41b12c1e345b5d060d0db16515655e 100644 (file)
@@ -923,7 +923,7 @@ static int dhx2_changepw(void *obj _U_, char *uname,
     return ret;
 }
 
-static int uam_setup(const char *path)
+static int uam_setup(void *obj, const char *path)
 {
     if (uam_register(UAM_SERVER_LOGIN_EXT, path, "DHX2", pam_login,
                      pam_logincont, pam_logout, pam_login_ext) < 0)
index a2737d0f920f90b746df9efc8c0495409a7cba7e..b74cc124f7b59cd2127713e90a7ea049db6c24cf 100644 (file)
@@ -603,7 +603,7 @@ static int passwd_logincont(void *obj, struct passwd **uam_pwd,
     return ret;
 }
 
-static int uam_setup(const char *path)
+static int uam_setup(void *obj, const char *path)
 {
     if (uam_register(UAM_SERVER_LOGIN_EXT, path, "DHX2", passwd_login,
                      passwd_logincont, NULL, passwd_login_ext) < 0)
index bc19c7851b294f7eb151f1a384db4c23e23465e5..631f84d9f97ae1c9753549e29ec4a283573fcfbf 100644 (file)
@@ -719,7 +719,7 @@ static int pam_changepw(void *obj, char *username,
 }
 
 
-static int uam_setup(const char *path)
+static int uam_setup(void *obj, const char *path)
 {
   if (uam_register(UAM_SERVER_LOGIN_EXT, path, "DHCAST128", pam_login, 
                   pam_logincont, pam_logout, pam_login_ext) < 0)
index d390f76b4da29d556fb07bdf559849e3610e9362..e407d9d05f773c392c38214f4ee8376cb4ceff8d 100644 (file)
@@ -371,7 +371,7 @@ static int passwd_logincont(void *obj, struct passwd **uam_pwd,
 }
 
 
-static int uam_setup(const char *path)
+static int uam_setup(void *obj, const char *path)
 {
   if (uam_register(UAM_SERVER_LOGIN_EXT, path, "DHCAST128",
                   passwd_login, passwd_logincont, NULL, passwd_login_ext) < 0)
index 29ea36c04842ebf85c8aeb87195ad407eb54b952..28ed7444f4ea3bef2ebab93b7d071bef95da8eb3 100644 (file)
@@ -21,6 +21,7 @@
 #include <atalk/uam.h>
 #include <atalk/util.h>
 #include <atalk/compat.h>
+#include <atalk/globals.h>
 
 /* Kerberos includes */
 #ifdef HAVE_GSSAPI_GSSAPI_H
 #include <gssapi.h>
 #endif // HAVE_GSSAPI_GSSAPI_H
 
+#ifdef HAVE_KERBEROS
+#ifdef HAVE_KRB5_KRB5_H
+#include <krb5/krb5.h>
+#else
+#include <krb5.h>
+#endif /* HAVE_KRB5_KRB5_H */
+#endif /* HAVE_KERBEROS */
+
 #define LOG_UAMS(log_level, ...) \
     LOG(log_level, logtype_uams, __VA_ARGS__)
 
@@ -479,8 +488,140 @@ static int gss_login_ext(void *obj,
     return gss_login(obj, uam_pwd, ibuf, ibuflen, rbuf, rbuflen);
 }
 
-static int uam_setup(const char *path)
+static int set_principal(AFPObj *obj, char *principal)
 {
+    size_t len = strlen(principal);
+
+    if (len > 255) {
+        LOG(log_error, logtype_afpd, "set_principal: principal '%s' too long (max=255)", principal, len);
+        return -1;
+    }
+
+    /* We store: 1 byte number principals (1) + 1 byte principal name length + zero terminated principal */
+    if ((obj->options.k5principal = malloc(len + 3)) == NULL) {
+        LOG(log_error, logtype_afpd, "set_principal: OOM");
+        return -1;
+    }
+
+    LOG(log_info, logtype_afpd, "Using AFP Kerberos service principal name: %s", principal);
+
+    obj->options.k5principal[0] = 1;
+    obj->options.k5principal[1] = (unsigned char)len;
+    obj->options.k5principal_buflen = len + 2;
+    strncpy(obj->options.k5principal + 2, principal, len);
+
+    return 0;
+}
+
+static int gss_create_principal(AFPObj *obj)
+{
+    int rv = -1;
+#ifdef HAVE_KERBEROS
+    krb5_context context;
+    krb5_error_code ret;
+    const char *error_msg;
+    krb5_keytab keytab;
+    krb5_keytab_entry entry;
+    krb5_principal service_principal;
+    char *principal;
+    krb5_kt_cursor cursor;
+
+    if (krb5_init_context(&context)) {
+        LOG(log_error, logtype_afpd, "gss_create_principal: failed to intialize a krb5_context");
+        goto exit;
+    }
+    if ((ret = krb5_kt_default(context, &keytab)))
+        goto krb5_error;
+
+    if (obj->options.k5service && obj->options.fqdn && obj->options.k5realm) {
+        LOG(log_debug, logtype_afpd, "gss_create_principal: using service principal specified in options");
+            
+        if ((ret = krb5_build_principal(context,
+                                        &service_principal,
+                                        strlen(obj->options.k5realm),
+                                        obj->options.k5realm,
+                                        obj->options.k5service,
+                                        obj->options.fqdn,
+                                        NULL)))
+            goto krb5_error;
+
+        if ((ret = krb5_kt_get_entry(context,
+                                     keytab,
+                                     service_principal,
+                                     0, // kvno - wildcard
+                                     0, // enctype - wildcard
+                                     &entry)) == KRB5_KT_NOTFOUND) {
+            krb5_unparse_name(context, service_principal, &principal);
+            LOG(log_error, logtype_afpd, "gss_create_principal: specified service principal '%s' not found in keytab", principal);
+#ifdef HAVE_KRB5_FREE_UNPARSED_NAME
+            krb5_free_unparsed_name(context, principal);
+#else
+            krb5_xfree(principal);
+#endif
+            goto krb5_cleanup;
+        }
+        krb5_free_principal(context, service_principal);
+        if (ret)
+            goto krb5_error;
+    } else {
+        LOG(log_debug, logtype_afpd, "gss_create_principal: using first entry from keytab as service principal");
+        if ((ret = krb5_kt_start_seq_get(context, keytab, &cursor)))
+            goto krb5_error;
+        ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
+        krb5_kt_end_seq_get(context, keytab, &cursor);
+        if (ret)
+            goto krb5_error;
+    }
+
+    krb5_unparse_name(context, entry.principal, &principal);
+#ifdef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS
+    krb5_free_keytab_entry_contents(context, &entry);
+#elif defined(HAVE_KRB5_KT_FREE_ENTRY)
+    krb5_kt_free_entry(context, &entry);
+#endif
+    set_principal(obj, principal);
+    free(principal);
+    rv = 0;
+    goto krb5_cleanup;
+
+krb5_error:
+    if (ret) {
+        error_msg = krb5_get_error_message(context, ret);
+        LOG(log_note, logtype_afpd, "Can't get principal from default keytab: %s",
+            (char *)error_msg);
+#ifdef HAVE_KRB5_FREE_ERROR_MESSAGE
+        krb5_free_error_message(context, error_msg);
+#else
+        krb5_xfree(error_msg);
+#endif
+    }
+
+krb5_cleanup:
+    krb5_kt_close(context, keytab);
+    krb5_free_context(context);
+
+#else /* ! HAVE_KERBEROS */
+
+    if (!options->k5service || !options->fqdn || !options->k5realm)
+        goto exit;
+
+    char principal[255];
+    size_t len = snprintf(principal, sizeof(principal), "%s/%s@%s",
+                          options->k5service, options->fqdn, options->k5realm);
+    (void)set_principal(&obj, principal);
+    rv = 0;
+#endif /* HAVE_KERBEROS */
+
+exit:
+    return rv;
+}
+
+static int uam_setup(void *handle, const char *path)
+{
+    AFPObj *obj = (AFPObj *)handle;
+    if (gss_create_principal(obj) != 0)
+        return -1;
+
     return uam_register(UAM_SERVER_LOGIN_EXT, path, "Client Krb v2",
                         gss_login, gss_logincont, gss_logout, gss_login_ext);
 }
index 82ee43ef5d552dc3fe7fc78441942c125a368bd0..baaf9eb2e611560d4360dc713905acb767fc73fd 100644 (file)
@@ -121,7 +121,7 @@ static int noauth_printer(char *start, char *stop, char *username, struct papfil
 }
 
 
-static int uam_setup(const char *path)
+static int uam_setup(void *handle, const char *path)
 {
   if (uam_register(UAM_SERVER_LOGIN_EXT, path, "No User Authent",
                    noauth_login, NULL, NULL, noauth_login_ext) < 0)
index b490c2ee20aaf81cd5d5f61888a49a03680e4cc2..da5be62132a0dd073f53abdc880c6f4e2e06faf6 100644 (file)
@@ -445,7 +445,7 @@ static int pam_printer(char *start, char *stop, char *username, struct papfile *
 }
 
 
-static int uam_setup(const char *path)
+static int uam_setup(void *obj, const char *path)
 {
   if (uam_register(UAM_SERVER_LOGIN_EXT, path, "Cleartxt Passwrd", 
                   pam_login, NULL, pam_logout, pam_login_ext) < 0)
index bec45a360813bd502affc3a9ac5eed8902f6fae3..9cd738cc08a723e4458b60592c4731212ebd9256 100644 (file)
@@ -353,7 +353,7 @@ static int passwd_printer(char      *start, char *stop, char *username, struct papfil
     return(0);
 }
 
-static int uam_setup(const char *path)
+static int uam_setup(void *obj, const char *path)
 {
     if (uam_register(UAM_SERVER_LOGIN_EXT, path, "Cleartxt Passwrd",
                      passwd_login, NULL, NULL, passwd_login_ext) < 0)
index 6a2994401c493d5cadd33a5f86161904d17f644c..679a160117770a6d2914b4abbba84cf2cc92451b 100644 (file)
@@ -174,7 +174,7 @@ static int pgp_logincont(void *obj, struct passwd **uam_pwd,
 }
 
 
-static int uam_setup(const char *path)
+static int uam_setup(void *obj, const char *path)
 {
   if (uam_register(UAM_SERVER_LOGIN, path, "PGPuam 1.0",
                   pgp_login, pgp_logincont, NULL) < 0)
index 22687fcc8921cf74304f23791390580c326b8b2e..50ce6ce5fadc05c594be6f541ba2827ce415b363 100644 (file)
@@ -531,7 +531,7 @@ static int randnum_login_ext(void *obj, char *uname, struct passwd **uam_pwd,
     return (rand_login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen));
 }
 
-static int uam_setup(const char *path)
+static int uam_setup(void *obj, const char *path)
 {
   if (uam_register(UAM_SERVER_LOGIN_EXT, path, "Randnum exchange", 
                   randnum_login, randnum_logincont, NULL, randnum_login_ext) < 0)
index d30a25c1d72168123f40ed4e92963c97a2acded0..e639cfa6ac12b27053ba96901bcb3429b6d86e30 100644 (file)
 
 #ifdef HAVE_SOLARIS_ACLS
 #include <sys/acl.h>
+#endif
+#ifdef HAVE_FREEBSD_SUNACL
+#include <sunacl.h>
+#endif
+
+#ifdef HAVE_NFSV4_ACLS
 
 #define chmod_acl nfsv4_chmod
 
@@ -34,7 +40,7 @@ extern int strip_nontrivial_aces(ace_t **saces, int sacecount);
 extern ace_t *concat_aces(ace_t *aces1, int ace1count, ace_t *aces2, int ace2count);
 extern int nfsv4_chmod(char *name, mode_t mode);
 
-#endif  /* HAVE_SOLARIS_ACLS */
+#endif  /* HAVE_NFSV4_ACLS */
 
 #ifdef HAVE_POSIX_ACLS
 #include <sys/types.h>
index 3b764a7689e42299e9d2b8f008dbfa78bd378ace..0a66ad2683517602f8b6349064e91104f28b22ae 100644 (file)
@@ -219,7 +219,7 @@ struct adouble {
     int                 ad_reso_refcount;
     off_t               ad_rlen;           /* ressource fork len with AFP 3.0         *
                                             * the header parameter size is too small. */
-    char                *ad_name;          /* name (UTF8-MAC)                         */
+    char                *ad_name;          /* mac name (maccharset or UTF8-MAC)       */
     struct adouble_fops *ad_ops;
     uint16_t            ad_open_forks;     /* open forks (by others)                  */
     char                ad_data[AD_DATASZ_MAX];
index 76315aa41acd661b4e7b8b6c8dc454496ce6b38c..0c2489ea906d4d884c1a2b87f41c971db45e26e4 100644 (file)
@@ -49,6 +49,7 @@ typedef uint16_t AFPUserBytes;
 #define AFPSRVRINFO_FASTBOZO     (1<<15) /* fast copying */
 
 #define AFP_OK         0
+#define AFPERR_MAXSESS  -1068   /* maximum number of allowed sessions reached */
 #define AFPERR_DID1     -4000   /* not an afp error DID is 1*/
 #define AFPERR_ACCESS  -5000   /* permission denied */
 #define AFPERR_AUTHCONT        -5001   /* logincont */
index a2759aa18ca1cb455d73b0c1c6c3479a3c941882..d3764e53c339c15fd03add5e6518ca3c87899973 100644 (file)
@@ -36,7 +36,7 @@
 
 /* setgid directories */
 #ifndef DIRBITS
-# ifdef AFS
+# if (defined AFS) || (defined FREEBSD)
 #  define DIRBITS 0
 # else /* AFS */
 #  define DIRBITS S_ISGID
index 228970373a54567e6e35eec6935034938c5dffaf..fbbafafabef4169cc746e72dc3afa2aad2905a91 100644 (file)
 #include <sys/extattr.h>
 #endif
 
+/* FIXME: are the ACL includes really neccessary here ? */
 #ifdef HAVE_SOLARIS_ACLS
 #include <sys/acl.h>
 #endif
+#ifdef HAVE_FREEBSD_SUNACL
+#include <sunacl.h>
+#endif
 
 #ifndef ENOATTR
 #define ENOATTR ENODATA
index 61cf247fe9987ce9f1cbe74d621c7eac4ed981cb..9095e2e309b39dca6afa0a1fc23b9e8d6ec35edd 100644 (file)
@@ -105,6 +105,8 @@ struct afp_options {
     char *signatureopt;
     unsigned char signature[16];
     char *k5service, *k5realm, *k5keytab;
+    size_t k5principal_buflen;
+    char *k5principal;
     char *unixcodepage, *maccodepage, *volcodepage;
     charset_t maccharset, unixcharset; 
     mode_t umask;
@@ -138,6 +140,7 @@ typedef struct AFPObj {
     gid_t *groups;
     int ngroups;
     int afp_version;
+    int cnx_cnt, cnx_max;
     /* Functions */
     void (*logout)(void);
     void (*exit)(int);
index adc2a99d441ad31414b6ea392800db191a790c50..f01e0a064cce17e3216358a1bd2ad05e2eca4134 100644 (file)
@@ -21,6 +21,8 @@ extern char *ldap_uuid_string;
 extern char *ldap_name_attr;
 extern char *ldap_group_attr;
 extern char *ldap_uid_attr;
+extern char *ldap_userfilter;
+extern char *ldap_groupfilter;
 extern int  ldap_uuid_encoding;
 
 typedef enum {
index 789649a1a6ded108932ddd9d90f52b0be10a4b14..b13ee350a2fe1c79071f658dc3d57c57d4865980 100644 (file)
@@ -1,5 +1,8 @@
-#ifndef __TDB_H__
-#define __TDB_H__
+#ifndef USE_BUILTIN_TDB
+#  include <tdb.h>
+#else
+#  ifndef __TDB_H__
+#    define __TDB_H__
 
 /* 
    Unix SMB/CIFS implementation.
@@ -174,4 +177,5 @@ extern TDB_DATA tdb_null;
 }
 #endif
 
-#endif /* tdb.h */
+#  endif /* tdb.h */
+#endif /* USE_BUILTIN_TDB */
index dcb32e99d2e726b7feaaf67c0799e9454f35de59..d2890e75674cdd0c978fed8c87b575a5567e22b6 100644 (file)
@@ -60,7 +60,7 @@
  * support is braindead. it also allows me to do a little versioning. */
 struct uam_export {
   int uam_type, uam_version;
-  int (*uam_setup)(const char *);
+  int (*uam_setup)(void *, const char *);
   void (*uam_cleanup)(void);
 };
 
index 0bd5079655c56c0dea583c537bfd1d3da1247070..6021c150987db56b02c701a5bac934ef54c90aa4 100644 (file)
@@ -62,7 +62,7 @@
 #define VFS_FUNC_ARGS_COPYFILE const struct vol *vol, int sfd, const char *src, const char *dst
 #define VFS_FUNC_VARS_COPYFILE vol, sfd, src, dst
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
 #define VFS_FUNC_ARGS_ACL const struct vol *vol, const char *path, int cmd, int count, void *aces
 #define VFS_FUNC_VARS_ACL vol, path, cmd, count, aces
 #endif
index 06e869a332e97583d5052a33acfb787a929494de..beafce4862e394a4b8d104a13576d6bbae50f582 100644 (file)
@@ -18,7 +18,7 @@
 #        current+1:0:0
 #
 
-VERSION_INFO = 6:0:0
+VERSION_INFO = 7:0:0
 
 # History:          VERSION_INFO
 #
@@ -33,8 +33,9 @@ VERSION_INFO = 6:0:0
 #   3.0.3           4:0:0
 #   3.0.4           5:0:0
 #   3.0.5           6:0:0
+#   3.0.6           7:0:0
 
-SUBDIRS = acl adouble bstring compat cnid dsi iniparser tdb util unicode vfs
+SUBDIRS = acl adouble bstring compat cnid dsi iniparser util unicode vfs
 
 lib_LTLIBRARIES = libatalk.la
 
@@ -52,7 +53,6 @@ libatalk_la_LIBADD  = \
        compat/libcompat.la     \
        dsi/libdsi.la           \
        iniparser/libiniparser.la \
-       tdb/libtdb.la       \
        unicode/libunicode.la \
        util/libutil.la         \
        vfs/libvfs.la
@@ -65,13 +65,18 @@ libatalk_la_DEPENDENCIES = \
        compat/libcompat.la     \
        dsi/libdsi.la           \
        iniparser/libiniparser.la \
-       tdb/libtdb.la       \
        unicode/libunicode.la \
        util/libutil.la         \
        vfs/libvfs.la
 
 libatalk_la_LDFLAGS = -version-info $(VERSION_INFO)
 
+if USE_BUILTIN_TDB
+SUBDIRS += tdb
+libatalk_la_LIBADD += tdb/libtdb.la
+libatalk_la_DEPENDENCIES += tdb/libtdb.la
+endif
+
 if DEVELOPER
 all-local: .libs/libatalk.so
        @$(top_srcdir)/abigen.sh .libs/libatalk.so > libatalk.abi.tmp
@@ -99,4 +104,6 @@ EXTRA_DIST = \
        libatalk-3.0.1.abi \
        libatalk-3.0.2.abi \
        libatalk-3.0.3.abi \
-       libatalk-3.0.4.abi
+       libatalk-3.0.4.abi \
+       libatalk-3.0.5.abi \
+       libatalk-3.0.6.abi
index f04c5aef1ed106df95247757e97581c08ff86ef5..e805a990542deb3c883a4419e1757c101977867c 100644 (file)
@@ -31,6 +31,7 @@
 #include <atalk/afp.h>
 #include <atalk/uuid.h>
 #include <atalk/ldapconfig.h>   /* For struct ldap_pref */
+#include <atalk/errchk.h>
 
 typedef enum {
     KEEPALIVE = 1
@@ -54,6 +55,8 @@ char *ldap_uuid_string;
 char *ldap_name_attr;
 char *ldap_group_attr;
 char *ldap_uid_attr;
+char *ldap_userfilter;
+char *ldap_groupfilter;
 int  ldap_uuid_encoding;
 
 struct ldap_pref ldap_prefs[] = {
@@ -72,6 +75,9 @@ struct ldap_pref ldap_prefs[] = {
     {&ldap_group_attr,     "ldap group attr",     0, 0, -1, -1},
     {&ldap_uid_attr,       "ldap uid attr",       0, 0,  0,  0},
     {&ldap_uuid_encoding,  "ldap uuid encoding",  1, 1,  0,  0},
+    {&ldap_userfilter,     "ldap user filter",    0, 0,  0,  0},
+    {&ldap_groupfilter,    "ldap group filter",   0, 0,  0,  0},
+    {&ldap_auth_pw,        "ldap auth pw",        0, 0,  0,  0},
     {NULL,                 NULL,                  0, 0,  0,  0}
 };
 
@@ -256,6 +262,69 @@ cleanup:
     return ret;
 }
 
+/*!
+ * Generate LDAP filter string for UUID query
+
+ * @param[in] uuidstr      the UUID as string
+ * @param[in] attr_filter  optional attribute
+ * @returns   pointer to static filter string
+ */
+static char *gen_uuid_filter(const char *uuidstr_in, const char *attr_filter)
+{
+    EC_INIT;
+    int len;
+    const char *uuidstr = uuidstr_in;
+
+#define MAX_FILTER_SIZE 512
+    static char filter[MAX_FILTER_SIZE];
+    char stripped[MAX_FILTER_SIZE];
+
+#define LDAP_BIN_UUID_LEN 49 /* LDAP Binary Notation is \XX * 16 bytes of UUID + terminator = 49 */
+    char ldap_bytes[LDAP_BIN_UUID_LEN];
+
+    if (ldap_uuid_encoding == LDAP_UUID_ENCODING_MSGUID) {
+        /* Convert to LDAP-safe binary encoding for direct query of AD objectGUID attribute */
+        int i = 0, s = 0;
+        char c;
+        while ((c = uuidstr[i])) {
+            if((c >='a' && c <= 'f')
+                || (c >= 'A' && c <= 'F')
+                || (c >= '0' && c <= '9')) {
+                stripped[s++] = toupper(c);
+            }
+            i++;
+        }
+
+        snprintf(ldap_bytes, LDAP_BIN_UUID_LEN,
+                 "\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c"
+                 "\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c",
+                 /* Data1 (uint32) */
+                 stripped[6], stripped[7], stripped[4], stripped[5],
+                 stripped[2], stripped[3], stripped[0], stripped[1],
+                 /* Data2 (uint16) */
+                 stripped[10], stripped[11], stripped[8], stripped[9],
+                 /* Data3 (uint16) */
+                 stripped[14], stripped[15], stripped[12], stripped[13],
+                 /* Data4 (uint64) */
+                 stripped[16], stripped[17], stripped[18], stripped[19],
+                 stripped[20], stripped[21], stripped[22], stripped[23],
+                 stripped[24], stripped[25], stripped[26], stripped[27],
+                 stripped[28], stripped[29], stripped[30], stripped[31]);
+        uuidstr = ldap_bytes;
+    }
+
+    if (attr_filter) {
+        len = snprintf(filter, 256, "(&(%s=%s)(%s))", ldap_uuid_attr, uuidstr, attr_filter);
+    } else {
+        len = snprintf(filter, 256, "%s=%s", ldap_uuid_attr, uuidstr);
+    }
+
+EC_CLEANUP:
+    if (ret != 0)
+        return NULL;
+    return filter;
+}
+
 /********************************************************
  * Interface
  ********************************************************/
@@ -332,76 +401,50 @@ int ldap_getuuidfromname( const char *name, uuidtype_t type, char **uuid_string)
  * returns 0 on success, -1 on errror
  */
 int ldap_getnamefromuuid( const char *uuidstr, char **name, uuidtype_t *type) {
-    int ret;
-    int len;
-    char filter[256];       /* this should really be enough. we dont want to malloc everything! */
+    EC_INIT;
+    char *filter;
     char *attributes[]  = { NULL, NULL};
 
     if (!ldap_config_valid)
-        return -1;
-
-    if(ldap_uuid_encoding == LDAP_UUID_ENCODING_MSGUID) {
-        /* Convert to LDAP-safe binary encoding for direct query of AD objectGUID attribute */
-        char* stripped = malloc(strlen(uuidstr));
-
-        int i = 0;
-        int s = 0;
-        char c;
-        while ((c = uuidstr[i])) {
-            if((c >='a' && c <= 'f')
-                || (c >= 'A' && c <= 'F')
-                || (c >= '0' && c <= '9')) {
-                stripped[s++] = toupper(c);
-            }
-            i++;
-        }
+        EC_FAIL;
 
-        /* LDAP Binary Notation is \XX * 16 bytes of UUID + terminator = 49 */
-        char* ldap_bytes = malloc(49);
-        snprintf(ldap_bytes, 49,
-            "\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c"
-            "\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c\\%c%c",
-            /* Data1 (uint32) */
-            stripped[6], stripped[7], stripped[4], stripped[5],
-            stripped[2], stripped[3], stripped[0], stripped[1],
-            /* Data2 (uint16) */
-            stripped[10], stripped[11], stripped[8], stripped[9],
-            /* Data3 (uint16) */
-            stripped[14], stripped[15], stripped[12], stripped[13],
-            /* Data4 (uint64) */
-            stripped[16], stripped[17], stripped[18], stripped[19],
-            stripped[20], stripped[21], stripped[22], stripped[23],
-            stripped[24], stripped[25], stripped[26], stripped[27],
-            stripped[28], stripped[29], stripped[30], stripped[31]);
-        len = snprintf( filter, 256, "%s=%s", ldap_uuid_attr, ldap_bytes);
-
-        free(ldap_bytes);
-        free(stripped);
-    } else {
-        len = snprintf( filter, 256, "%s=%s", ldap_uuid_attr, uuidstr);
-    }
+    /*
+     * Search groups first as group acls are probably used more often.
+     * Note the special case of AD where users and groups are stored
+     * under the same subtree.
+     */
 
-    if (len >= 256 || len == -1) {
-        LOG(log_error, logtype_default, "ldap_getnamefromuuid: filter overflow:%d, \"%s\"", len, filter);
-        return -1;
-    }
-    /* search groups first. group acls are probably used more often */
     attributes[0] = ldap_group_attr;
-    ret = ldap_getattr_fromfilter_withbase_scope( ldap_groupbase, filter, attributes, ldap_groupscope, KEEPALIVE, name);
-    if (ret == -1)
-        return -1;
+    EC_NULL( filter = gen_uuid_filter(uuidstr, ldap_groupfilter) );
+    EC_NEG1( ret = ldap_getattr_fromfilter_withbase_scope(
+                 ldap_groupbase,
+                 filter,
+                 attributes,
+                 ldap_groupscope,
+                 KEEPALIVE,
+                 name) );
     if (ret == 1) {
         *type = UUID_GROUP;
-        return 0;
+        EC_EXIT_STATUS(0);
     }
 
     attributes[0] = ldap_name_attr;
-    ret = ldap_getattr_fromfilter_withbase_scope( ldap_userbase, filter, attributes, ldap_userscope, KEEPALIVE, name);
+    EC_NULL( filter = gen_uuid_filter(uuidstr, ldap_userfilter) );
+    EC_NEG1( ret = ldap_getattr_fromfilter_withbase_scope(
+                 ldap_userbase,
+                 filter,
+                 attributes,
+                 ldap_userscope,
+                 KEEPALIVE,
+                 name) );
     if (ret == 1) {
         *type = UUID_USER;
-        return 0;
+        EC_EXIT_STATUS(0);
     }
 
-    return -1;
+    EC_FAIL;
+
+EC_CLEANUP:
+    EC_EXIT;
 }
 #endif  /* HAVE_LDAP */
index cc69d8ade3299bd20fbced73d3c5485b0f4f8132..9b22511e2f5325f1116d2de8d590848add4daaca 100644 (file)
@@ -35,7 +35,7 @@
 #include <atalk/acl.h>
 #include <atalk/unix.h>
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
 
 /* Get ACL. Allocates storage as needed. Caller must free.
  * Returns no of ACEs or -1 on error.  */
@@ -276,7 +276,7 @@ exit:
     return ret;
 }
 
-#endif /* HAVE_SOLARIS_ACLS */
+#endif /* HAVE_NFSV4_ACLS */
 
 #ifdef HAVE_POSIX_ACLS
 
index 06c3c71e49a7cfaca6ada37276237d0a4ae66f4f..1708d08b18e8200f35d85bb86698d4424b4e15ae 100644 (file)
@@ -1897,7 +1897,7 @@ int ad_openat(struct adouble  *ad,
     mode_t mode = 0;
 
     if (dirfd != -1) {
-        if ((cwdfd = open(".", O_RDONLY) == -1) || (fchdir(dirfd) != 0))
+        if (((cwdfd = open(".", O_RDONLY)) == -1) || (fchdir(dirfd) != 0))
             EC_FAIL;
     }
 
index 58a4f7225215aa33208a19eeeeabd2d2b9172b72..93c289aa5faa53a633f09916f1d4807f592bd42c 100644 (file)
@@ -14,4 +14,7 @@ libcnid_tdb_la_SOURCES = cnid_tdb_add.c \
                         cnid_tdb_update.c \
                         cnid_tdb.h
 
+libcnid_tdb_la_CFLAGS = @TDB_CFLAGS@
+libcnid_tdb_la_LIBADD = @TDB_LIBS@
+
 EXTRA_DIST = README cnid_tdb_nextid.c
index a928d34ee38d8f23f9fd34350198d00fffc91e75..89af152b76aa6e312de2d0096002ea8283fec737 100644 (file)
@@ -65,7 +65,7 @@ int dsi_getsession(DSI *dsi, server_child_t *serv_children, int tickleval, afp_c
       LOG(log_error, logtype_dsi, "dsi_getsess: %s", strerror(errno));
       close(ipc_fds[0]);
       dsi->header.dsi_flags = DSIFL_REPLY;
-      dsi->header.dsi_data.dsi_code = DSIERR_SERVBUSY;
+      dsi->header.dsi_data.dsi_code = htonl(DSIERR_SERVBUSY);
       dsi_send(dsi);
       dsi->header.dsi_data.dsi_code = DSIERR_OK;
       kill(pid, SIGKILL);
@@ -75,16 +75,9 @@ int dsi_getsession(DSI *dsi, server_child_t *serv_children, int tickleval, afp_c
     return 0;
   }
   
-  /* child: check number of open connections. this is one off the
-   * actual count. */
-  if ((serv_children->servch_count >= serv_children->servch_nsessions) &&
-      (dsi->header.dsi_command == DSIFUNC_OPEN)) {
-    LOG(log_info, logtype_dsi, "dsi_getsess: too many connections");
-    dsi->header.dsi_flags = DSIFL_REPLY;
-    dsi->header.dsi_data.dsi_code = DSIERR_TOOMANY;
-    dsi_send(dsi);
-    exit(EXITERR_CLNT);
-  }
+  /* Save number of existing and maximum connections */
+  dsi->AFPobj->cnx_cnt = serv_children->servch_count;
+  dsi->AFPobj->cnx_max = serv_children->servch_nsessions;
 
   /* get rid of some stuff */
   dsi->AFPobj->ipc_fd = ipc_fds[1];
diff --git a/libatalk/libatalk-3.0.6.abi b/libatalk/libatalk-3.0.6.abi
new file mode 100644 (file)
index 0000000..57fa789
--- /dev/null
@@ -0,0 +1,570 @@
+acl_ldap_freeconfig: void (void)
+acl_ldap_readconfig: int (dictionary *)
+ad_close: int (struct adouble *, int)
+ad_convert: int (const char *, const struct stat *, const struct vol *, const char **)
+ad_copy_header: int (struct adouble *, struct adouble *)
+add_cachebyname: int (const char *, const uuidp_t, const uuidtype_t, const long unsigned int)
+add_cachebyuuid: int (uuidp_t, const char *, uuidtype_t, const long unsigned int)
+add_charset: charset_t (const char *)
+ad_dir: char *(const char *)
+ad_dtruncate: int (struct adouble *, const off_t)
+adflags2logstr: const char *(int)
+ad_flush: int (struct adouble *)
+ad_forcegetid: uint32_t (struct adouble *)
+adf_pread: ssize_t (struct ad_fd *, void *, size_t, off_t)
+adf_pwrite: ssize_t (struct ad_fd *, const void *, size_t, off_t)
+ad_getattr: int (const struct adouble *, uint16_t *)
+ad_getdate: int (const struct adouble *, unsigned int, uint32_t *)
+ad_getentryoff: off_t (const struct adouble *, int)
+ad_getfuid: uid_t (void)
+ad_getid: uint32_t (struct adouble *, const dev_t, const ino_t, const cnid_t, const void *)
+ad_hf_mode: mode_t (mode_t)
+ad_init: void (struct adouble *, const struct vol *)
+ad_init_offsets: int (struct adouble *)
+ad_init_old: void (struct adouble *, int, int)
+ad_lock: int (struct adouble *, uint32_t, int, off_t, off_t, int)
+ad_metadata: int (const char *, int, struct adouble *)
+ad_metadataat: int (int, const char *, int, struct adouble *)
+ad_mkdir: int (const char *, mode_t)
+ad_mode: int (const char *, mode_t)
+ad_open: int (struct adouble *, const char *, int, ...)
+ad_openat: int (struct adouble *, int, const char *, int, ...)
+ad_openforks: uint16_t (struct adouble *, uint16_t)
+ad_path: const char *(const char *, int)
+ad_path_ea: const char *(const char *, int)
+ad_path_osx: const char *(const char *, int)
+ad_read: ssize_t (struct adouble *, const uint32_t, off_t, char *, const size_t)
+ad_readfile_init: int (const struct adouble *, const int, off_t *, const int)
+ad_rebuild_adouble_header_ea: int (struct adouble *)
+ad_rebuild_adouble_header_v2: int (struct adouble *)
+ad_refresh: int (const char *, struct adouble *)
+ad_reso_size: off_t (const char *, int, struct adouble *)
+ad_rtruncate: int (struct adouble *, const char *, const off_t)
+ad_setattr: int (const struct adouble *, const uint16_t)
+ad_setdate: int (struct adouble *, unsigned int, uint32_t)
+ad_setfuid: int (const uid_t)
+ad_setid: int (struct adouble *, const dev_t, const ino_t, const uint32_t, const cnid_t, const void *)
+ad_setname: int (struct adouble *, const char *)
+ad_size: off_t (const struct adouble *, const uint32_t)
+ad_stat: int (const char *, struct stat *)
+ad_testlock: int (struct adouble *, int, const off_t)
+ad_tmplock: int (struct adouble *, uint32_t, int, off_t, off_t, int)
+ad_unlock: void (struct adouble *, const int, int)
+ad_valid_header_osx: int (const char *)
+ad_write: ssize_t (struct adouble *, uint32_t, off_t, int, const char *, size_t)
+afp_config_free: void (AFPObj *)
+afp_config_parse: int (AFPObj *, char *)
+allow_severity: 5
+apply_ip_mask: void (struct sockaddr *, int)
+atalkdict_del: void (dictionary *)
+atalkdict_dump: void (dictionary *, FILE *)
+atalkdict_get: const char *(const dictionary *, const char *, const char *, const char *)
+atalkdict_hash: unsigned int (char *)
+atalkdict_new: dictionary *(int)
+atalkdict_set: int (dictionary *, char *, char *, char *)
+atalkdict_unset: void (dictionary *, char *, char *)
+atalk_iconv: size_t (atalk_iconv_t, const char **, size_t *, char **, size_t *)
+atalk_iconv_close: int (atalk_iconv_t)
+atalk_iconv_open: atalk_iconv_t (const char *, const char *)
+atalk_iniparser_dump: void (const dictionary *, FILE *)
+atalk_iniparser_dump_ini: void (const dictionary *, FILE *)
+atalk_iniparser_find_entry: int (const dictionary *, const char *)
+atalk_iniparser_freedict: void (dictionary *)
+atalk_iniparser_getboolean: int (const dictionary *, const char *, const char *, int)
+atalk_iniparser_getdouble: double (const dictionary *, const char *, const char *, double)
+atalk_iniparser_getint: int (const dictionary *, const char *, const char *, int)
+atalk_iniparser_getnsec: int (const dictionary *)
+atalk_iniparser_getsecname: const char *(const dictionary *, int)
+atalk_iniparser_getstrdup: char *(const dictionary *, const char *, const char *, const char *)
+atalk_iniparser_getstring: const char *(const dictionary *, const char *, const char *, const char *)
+atalk_iniparser_load: dictionary *(const char *)
+atalk_iniparser_set: int (dictionary *, char *, char *, char *)
+atalk_iniparser_unset: void (dictionary *, char *, char *)
+atalk_register_charset: int (struct charset_functions *)
+balloc: int (bstring, int)
+ballocmin: int (bstring, int)
+basename_safe: const char *(const char *)
+bassign: int (bstring, const_bstring)
+bassignblk: int (bstring, const void *, int)
+bassigncstr: int (bstring, const char *)
+bassignformat: int (bstring, const char *, ...)
+bassigngets: int (bstring, bNgetc, void *, char)
+bassignmidstr: int (bstring, const_bstring, int, int)
+bcatblk: int (bstring, const void *, int)
+bcatcstr: int (bstring, const char *)
+bconcat: int (bstring, const_bstring)
+bconchar: int (bstring, char)
+bcstrfree: int (char *)
+bdelete: int (bstring, int, int)
+bdestroy: int (bstring)
+become_root: void (void)
+bfindreplace: int (bstring, const_bstring, const_bstring, int)
+bfindreplacecaseless: int (bstring, const_bstring, const_bstring, int)
+bformat: bstring (const char *, ...)
+bformata: int (bstring, const char *, ...)
+bfromcstr: bstring (const char *)
+bfromcstralloc: bstring (int, const char *)
+bgetsa: int (bstring, bNgetc, void *, char)
+bgetstream: bstring (bNgetc, void *, char)
+binchr: int (const_bstring, int, const_bstring)
+binchrr: int (const_bstring, int, const_bstring)
+binsert: int (bstring, int, const_bstring, unsigned char)
+binsertch: int (bstring, int, int, unsigned char)
+binstr: int (const_bstring, int, const_bstring)
+binstrcaseless: int (const_bstring, int, const_bstring)
+binstrr: int (const_bstring, int, const_bstring)
+binstrrcaseless: int (const_bstring, int, const_bstring)
+biseq: int (const_bstring, const_bstring)
+biseqcaseless: int (const_bstring, const_bstring)
+biseqcstr: int (const_bstring, const char *)
+biseqcstrcaseless: int (const_bstring, const char *)
+bisstemeqblk: int (const_bstring, const void *, int)
+bisstemeqcaselessblk: int (const_bstring, const void *, int)
+bjoin: bstring (const struct bstrList *, const_bstring)
+bjoinInv: bstring (const struct bstrList *, const_bstring)
+blk2bstr: bstring (const void *, int)
+bltrimws: int (bstring)
+bmidstr: bstring (const_bstring, int, int)
+bninchr: int (const_bstring, int, const_bstring)
+bninchrr: int (const_bstring, int, const_bstring)
+bpattern: int (bstring, int)
+bread: bstring (bNread, void *)
+breada: int (bstring, bNread, void *)
+brefcstr: bstring (char *)
+breplace: int (bstring, int, int, const_bstring, unsigned char)
+brtrimws: int (bstring)
+bsbufflength: int (struct bStream *, int)
+bsclose: void *(struct bStream *)
+bseof: int (const struct bStream *)
+bsetstr: int (bstring, int, const_bstring, unsigned char)
+bsopen: struct bStream *(bNread, void *)
+bspeek: int (bstring, const struct bStream *)
+bsplit: struct bstrList *(const_bstring, unsigned char)
+bsplitcb: int (const_bstring, unsigned char, int, int (*)(void *, int, int), void *)
+bsplits: struct bstrList *(const_bstring, const_bstring)
+bsplitscb: int (const_bstring, const_bstring, int, int (*)(void *, int, int), void *)
+bsplitstr: struct bstrList *(const_bstring, const_bstring)
+bsplitstrcb: int (const_bstring, const_bstring, int, int (*)(void *, int, int), void *)
+bsread: int (bstring, struct bStream *, int)
+bsreada: int (bstring, struct bStream *, int)
+bsreadln: int (bstring, struct bStream *, char)
+bsreadlna: int (bstring, struct bStream *, char)
+bsreadlns: int (bstring, struct bStream *, const_bstring)
+bsreadlnsa: int (bstring, struct bStream *, const_bstring)
+bssplitscb: int (struct bStream *, const_bstring, int (*)(void *, int, const_bstring), void *)
+bssplitstrcb: int (struct bStream *, const_bstring, int (*)(void *, int, const_bstring), void *)
+bstr2cstr: char *(const_bstring, char)
+bstrchrp: int (const_bstring, int, int)
+bstrcmp: int (const_bstring, const_bstring)
+bstrcpy: bstring (const_bstring)
+bstricmp: int (const_bstring, const_bstring)
+bstrListAlloc: int (struct bstrList *, int)
+bstrListAllocMin: int (struct bstrList *, int)
+bstrListCreate: struct bstrList *(void)
+bstrListCreateMin: struct bstrList *(int)
+bstrListDestroy: int (struct bstrList *)
+bstrListPop: bstring (struct bstrList *)
+bstrListPush: int (struct bstrList *, bstring)
+bstrncmp: int (const_bstring, const_bstring, int)
+bstrnicmp: int (const_bstring, const_bstring, int)
+bstrrchrp: int (const_bstring, int, int)
+bsunread: int (struct bStream *, const_bstring)
+btolower: int (bstring)
+btoupper: int (bstring)
+btrimws: int (bstring)
+btrunc: int (bstring, int)
+bunrefcstr: int (bstring)
+bvcformata: int (bstring, int, const char *, struct __va_list_tag *)
+charset_decompose: size_t (charset_t, char *, size_t, char *, size_t)
+charset_mac_centraleurope: {name = "MAC_CENTRALEUROPE", kTextEncoding = 29, pull = <mac_centraleurope_pull>, push = <mac_centraleurope_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_chinese_simp: {name = "MAC_CHINESE_SIMP", kTextEncoding = 25, pull = <mac_chinese_simp_pull>, push = <mac_chinese_simp_push>, flags = 85, iname = "EUC-CN", prev = 0x0, next = 0x0}
+charset_mac_chinese_trad: {name = "MAC_CHINESE_TRAD", kTextEncoding = 2, pull = <mac_chinese_trad_pull>, push = <mac_chinese_trad_push>, flags = 85, iname = "BIG-5", prev = 0x0, next = 0x0}
+charset_mac_cyrillic: {name = "MAC_CYRILLIC", kTextEncoding = 7, pull = <mac_cyrillic_pull>, push = <mac_cyrillic_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_greek: {name = "MAC_GREEK", kTextEncoding = 6, pull = <mac_greek_pull>, push = <mac_greek_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_hebrew: {name = "MAC_HEBREW", kTextEncoding = 5, pull = <mac_hebrew_pull>, push = <mac_hebrew_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_japanese: {name = "MAC_JAPANESE", kTextEncoding = 1, pull = <mac_japanese_pull>, push = <mac_japanese_push>, flags = 85, iname = "SHIFT_JIS", prev = 0x0, next = 0x0}
+charset_mac_korean: {name = "MAC_KOREAN", kTextEncoding = 3, pull = <mac_korean_pull>, push = <mac_korean_push>, flags = 85, iname = "EUC-KR", prev = 0x0, next = 0x0}
+charset_mac_roman: {name = "MAC_ROMAN", kTextEncoding = 0, pull = <mac_roman_pull>, push = <mac_roman_push>, flags = 21, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_turkish: {name = "MAC_TURKISH", kTextEncoding = 35, pull = <mac_turkish_pull>, push = <mac_turkish_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_precompose: size_t (charset_t, char *, size_t, char *, size_t)
+charset_strlower: size_t (charset_t, const char *, size_t, char *, size_t)
+charset_strupper: size_t (charset_t, const char *, size_t, char *, size_t)
+charset_to_ucs2_allocate: size_t (charset_t, uint16_t **, const char *)
+charset_to_utf8_allocate: size_t (charset_t, char **, const char *)
+charset_utf8: {name = "UTF8", kTextEncoding = 134217987, pull = <utf8_pull>, push = <utf8_push>, flags = 22, iname = 0x0, prev = 0x0, next = 0x0}
+charset_utf8_mac: {name = "UTF8-MAC", kTextEncoding = 134217987, pull = <utf8_pull>, push = <utf8_push>, flags = 27, iname = 0x0, prev = 0x0, next = 0x0}
+check_lockfile: int (const char *, const char *)
+cjk_char_pull: size_t (uint16_t, uint16_t *, const uint32_t *)
+cjk_char_push: size_t (uint16_t, uint8_t *)
+cjk_compose: uint16_t (uint16_t, uint16_t, const uint32_t *, size_t)
+cjk_compose_seq: uint16_t (const uint16_t *, size_t *, const uint32_t *, size_t)
+cjk_generic_pull: size_t (size_t (*)(uint16_t *, const uint8_t *, size_t *), void *, char **, size_t *, char **, size_t *)
+cjk_generic_push: size_t (size_t (*)(uint8_t *, const uint16_t *, size_t *), void *, char **, size_t *, char **, size_t *)
+cjk_lookup: uint16_t (uint16_t, const cjk_index_t *, const uint16_t *)
+cnid_add: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, const char *, const size_t, cnid_t)
+cnid_close: void (struct _cnid_db *)
+cnid_dbd_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_dbd_close: void (struct _cnid_db *)
+cnid_dbd_delete: int (struct _cnid_db *, const cnid_t)
+cnid_dbd_find: int (struct _cnid_db *, const char *, size_t, void *, size_t)
+cnid_dbd_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t)
+cnid_dbd_getstamp: int (struct _cnid_db *, void *, const size_t)
+cnid_dbd_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t)
+cnid_dbd_module: {name = "dbd", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 0}
+cnid_dbd_open: struct _cnid_db *(struct cnid_open_args *)
+cnid_dbd_rebuild_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_dbd_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_dbd_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t)
+cnid_dbd_wipe: int (struct _cnid_db *)
+cnid_delete: int (struct _cnid_db *, cnid_t)
+cnid_find: int (struct _cnid_db *, const char *, size_t, void *, size_t)
+cnid_get: cnid_t (struct _cnid_db *, const cnid_t, char *, const size_t)
+cnid_getstamp: int (struct _cnid_db *, void *, const size_t)
+cnid_init: void (void)
+cnid_last_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_last_close: void (struct _cnid_db *)
+cnid_last_delete: int (struct _cnid_db *, const cnid_t)
+cnid_last_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t)
+cnid_last_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t)
+cnid_last_module: {name = "last", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 0}
+cnid_last_open: struct _cnid_db *(struct cnid_open_args *)
+cnid_last_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_last_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t)
+cnid_lookup: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t)
+cnid_open: struct _cnid_db *(const char *, mode_t, char *, int, const char *, const char *)
+cnid_rebuild_add: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t, cnid_t)
+cnid_register: void (struct _cnid_module *)
+cnid_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_tdb_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_tdb_close: void (struct _cnid_db *)
+cnid_tdb_delete: int (struct _cnid_db *, const cnid_t)
+cnid_tdb_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t)
+cnid_tdb_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t)
+cnid_tdb_module: {name = "tdb", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 12}
+cnid_tdb_open: struct _cnid_db *(struct cnid_open_args *)
+cnid_tdb_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_tdb_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t)
+cnid_update: int (struct _cnid_db *, const cnid_t, const struct stat *, const cnid_t, char *, const size_t)
+cnid_wipe: int (struct _cnid_db *)
+compare_ip: int (const struct sockaddr *, const struct sockaddr *)
+convert_charset: size_t (charset_t, charset_t, charset_t, const char *, size_t, char *, size_t, uint16_t *)
+convert_string: size_t (charset_t, charset_t, const void *, size_t, void *, size_t)
+convert_string_allocate: size_t (charset_t, charset_t, const void *, size_t, char **)
+copy_ea: int (const char *, int, const char *, const char *, mode_t)
+copy_file: int (int, const char *, const char *, mode_t)
+copy_file_fd: int (int, int)
+copy_fork: int (int, struct adouble *, struct adouble *)
+create_lockfile: int (const char *, const char *)
+daemonize: int (int, int)
+decompose_w: size_t (uint16_t *, size_t, uint16_t *, size_t *)
+deny_severity: 3
+dequeue: void *(q_t *)
+_diacasemap: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 231, 203, 229, 128, 204, 129, 130, 131, 233, 230, 232, 234, 237, 235, 236, 132, 238, 241, 239, 133, 205, 242, 244, 243, 134, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 198, 183, 184, 184, 186, 187, 188, 189, 174, 175, 192, 193, 194, 195, 196, 197, 198, 199...}
+_dialowermap: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 138, 140, 141, 142, 150, 154, 159, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 132, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 190, 191, 176, 177, 178, 179, 180, 181, 198, 183, 185, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199...}
+dir_rx_set: int (mode_t)
+dsi_attention: int (DSI *, AFPUserBytes)
+dsi_close: void (DSI *)
+dsi_cmdreply: int (DSI *, const int)
+dsi_disconnect: int (DSI *)
+dsi_free: void (DSI *)
+dsi_getsession: int (DSI *, server_child_t *, int, afp_child_t **)
+dsi_getstatus: void (DSI *)
+dsi_init: DSI *(AFPObj *, const char *, const char *, const char *)
+dsi_opensession: void (DSI *)
+dsi_read: ssize_t (DSI *, void *, const size_t)
+dsi_readdone: void (DSI *)
+dsi_readinit: ssize_t (DSI *, void *, const size_t, const size_t, const int)
+dsi_stream_read: size_t (DSI *, void *, const size_t)
+dsi_stream_read_file: ssize_t (DSI *, const int, off_t, const size_t, const int)
+dsi_stream_receive: int (DSI *)
+dsi_stream_send: int (DSI *, void *, size_t)
+dsi_stream_write: ssize_t (DSI *, void *, const size_t, int)
+dsi_tcp_init: int (DSI *, const char *, const char *, const char *)
+dsi_tickle: int (DSI *)
+dsi_write: size_t (DSI *, void *, const size_t)
+dsi_writeflush: void (DSI *)
+dsi_writeinit: size_t (DSI *, void *, const size_t)
+ea_chmod_dir: int (const struct vol *, const char *, mode_t, struct stat *)
+ea_chmod_file: int (const struct vol *, const char *, mode_t, struct stat *)
+ea_chown: int (const struct vol *, const char *, uid_t, gid_t)
+ea_close: int (struct ea *)
+ea_copyfile: int (const struct vol *, int, const char *, const char *)
+ea_deletefile: int (const struct vol *, int, const char *)
+ea_open: int (const struct vol *, const char *, eaflags_t, struct ea *)
+ea_openat: int (const struct vol *, int, const char *, eaflags_t, struct ea *)
+ea_path: char *(const struct ea *, const char *, int)
+ea_renamefile: int (const struct vol *, int, const char *, const char *)
+enqueue: qnode_t *(q_t *, void *)
+fault_setup: void (void (*)(void *))
+fdset_add_fd: void (int, struct pollfd **, struct polldata **, int *, int *, int, enum fdtype, void *)
+fdset_del_fd: void (struct pollfd **, struct polldata **, int *, int *, int)
+find_charset_functions: struct charset_functions *(const char *)
+_fini: <text variable, no debug info>
+free_charset_names: void (void)
+freeifacelist: void (char **)
+fullpathname: const char *(const char *)
+getcwdpath: const char *(void)
+getdefextmap: struct extmap *(void)
+get_eacontent: int (const struct vol *, char *, size_t *, const char *, int, const char *, int)
+get_easize: int (const struct vol *, char *, size_t *, const char *, int, const char *)
+getextmap: struct extmap *(const char *)
+getifacelist: char **(void)
+getip_port: unsigned int (const struct sockaddr *)
+getip_string: const char *(const struct sockaddr *)
+getnamefromuuid: int (const uuidp_t, char **, uuidtype_t *)
+getuuidfromname: int (const char *, uuidtype_t, unsigned char *)
+getvolbyname: struct vol *(const char *)
+getvolbypath: struct vol *(AFPObj *, const char *)
+getvolbyvid: struct vol *(const uint16_t)
+getvolumes: struct vol *(void)
+gmem: int (gid_t, int, gid_t *)
+_init: <text variable, no debug info>
+init_iconv: void (void)
+initline: void (int, char *)
+initvol_vfs: void (struct vol *)
+ipc_child_state: int (AFPObj *, uint16_t)
+ipc_child_write: int (int, uint16_t, int, void *)
+ipc_server_read: int (server_child_t *, int)
+islower_sp: int (uint32_t)
+islower_w: int (uint16_t)
+isupper_sp: int (uint32_t)
+isupper_w: int (uint16_t)
+ldap_auth_dn: 0x0
+ldap_auth_method: 0
+ldap_auth_pw: 0x0
+ldap_config_valid: 0
+ldap_getnamefromuuid: int (const char *, char **, uuidtype_t *)
+ldap_getuuidfromname: int (const char *, uuidtype_t, char **)
+ldap_group_attr: 0x0
+ldap_groupbase: 0x0
+ldap_groupfilter: 0x0
+ldap_groupscope: 0
+ldap_name_attr: 0x0
+ldap_prefs: {{pref = 0x0, name = "ldap server", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap auth method", strorint = 1, intfromarray = 1, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap auth dn", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap auth pw", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap userbase", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap userscope", strorint = 1, intfromarray = 1, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap groupbase", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap groupscope", strorint = 1, intfromarray = 1, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap uuid attr", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap uuid string", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap name attr", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap group attr", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap uid attr", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap uuid encoding", strorint = 1, intfromarray = 1, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap user filter", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap group filter", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap auth pw", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = 0x0, strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}}
+ldap_server: 0x0
+ldap_uid_attr: 0x0
+ldap_userbase: 0x0
+ldap_userfilter: 0x0
+ldap_userscope: 0
+ldap_uuid_attr: 0x0
+ldap_uuid_encoding: 0
+ldap_uuid_string: 0x0
+list_eas: int (const struct vol *, char *, size_t *, const char *, int)
+load_charset: int (struct vol *)
+load_volumes: int (AFPObj *)
+localuuid_from_id: void (unsigned char *, uuidtype_t, unsigned int)
+lock_reg: int (int, int, int, off_t, int, off_t)
+log_config: {inited = false, syslog_opened = false, console = false, processname = '\0' <repeats 15 times>, syslog_facility = 0, syslog_display_options = 0}
+make_log_entry: void (enum loglevels, enum logtypes, const char *, int, char *, ...)
+make_tdb_data: unsigned char *(uint32_t, const struct stat *, const cnid_t, const char *, const size_t)
+mb_generic_pull: size_t (int (*)(uint16_t *, const unsigned char *), void *, char **, size_t *, char **, size_t *)
+mb_generic_push: size_t (int (*)(unsigned char *, uint16_t), void *, char **, size_t *, char **, size_t *)
+netatalk_panic: void (const char *)
+netatalk_rmdir: int (int, const char *)
+netatalk_rmdir_all_errors: int (int, const char *)
+netatalk_unlink: int (const char *)
+netatalk_unlinkat: int (int, const char *)
+nftw: int (const char *, nftw_func_t, dir_notification_func_t, int, int)
+ochdir: int (const char *, int)
+ochmod: int (char *, mode_t, const struct stat *, int)
+ochown: int (const char *, uid_t, gid_t, int)
+opendirat: DIR *(int, const char *)
+openflags2logstr: const char *(int)
+ostat: int (const char *, struct stat *, int)
+ostatat: int (int, const char *, struct stat *, int)
+parseline: int (int, char *)
+posix_chmod: int (const char *, mode_t)
+posix_fchmod: int (int, mode_t)
+precompose_w: size_t (uint16_t *, size_t, uint16_t *, size_t *)
+prefs_array: {{pref = "ldap auth method", valuestring = "none", value = 0}, {pref = "ldap auth method", valuestring = "simple", value = 128}, {pref = "ldap auth method", valuestring = "sasl", value = 163}, {pref = "ldap userscope", valuestring = "base", value = 0}, {pref = "ldap userscope", valuestring = "one", value = 1}, {pref = "ldap userscope", valuestring = "sub", value = 2}, {pref = "ldap groupscope", valuestring = "base", value = 0}, {pref = "ldap groupscope", valuestring = "one", value = 1}, {pref = "ldap groupscope", valuestring = "sub", value = 2}, {pref = "ldap uuid encoding", valuestring = "ms-guid", value = 1}, {pref = "ldap uuid encoding", valuestring = "string", value = 0}, {pref = 0x0, valuestring = 0x0, value = 0}}
+prequeue: qnode_t *(q_t *, void *)
+print_groups: const char *(int, gid_t *)
+queue_destroy: void (q_t *, void (*)(void *))
+queue_init: q_t *(void)
+randombytes: void (void *, int)
+readt: ssize_t (int, void *, const size_t, int, int)
+realpath_safe: char *(const char *)
+recv_fd: int (int, int)
+rel_path_in_vol: bstring (const char *, const char *)
+remove_acl_vfs: int (const char *)
+remove_ea: int (const struct vol *, const char *, const char *, int)
+run_cmd: int (const char *, char **)
+search_cachebyname: int (const char *, uuidtype_t *, unsigned char *)
+search_cachebyuuid: int (uuidp_t, char **, uuidtype_t *)
+send_fd: int (int, int)
+server_child_add: afp_child_t *(server_child_t *, pid_t, int)
+server_child_alloc: server_child_t *(int)
+server_child_free: void (server_child_t *)
+server_child_kill: void (server_child_t *, int)
+server_child_kill_one_by_id: void (server_child_t *, pid_t, uid_t, uint32_t, char *, uint32_t)
+server_child_remove: int (server_child_t *, pid_t)
+server_child_resolve: afp_child_t *(server_child_t *, id_t)
+server_child_transfer_session: int (server_child_t *, pid_t, uid_t, int, uint16_t)
+server_lock: pid_t (char *, char *, int)
+server_reset_signal: void (void)
+set_charset_name: int (charset_t, const char *)
+set_ea: int (const struct vol *, const char *, const char *, const char *, size_t, int)
+setfilmode: int (const struct vol *, const char *, mode_t, struct stat *)
+set_groups: int (AFPObj *, struct passwd *)
+setnonblock: int (int, int)
+set_processname: void (const char *)
+setuplog: void (const char *, const char *)
+statat: int (int, const char *, struct stat *)
+strcasechr_sp: uint16_t *(const uint16_t *, uint32_t)
+strcasechr_w: uint16_t *(const uint16_t *, uint16_t)
+strcasecmp_w: int (const uint16_t *, const uint16_t *)
+strcasestr_w: uint16_t *(const uint16_t *, const uint16_t *)
+strcat_w: uint16_t *(uint16_t *, const uint16_t *)
+strchr_w: uint16_t *(const uint16_t *, uint16_t)
+strcmp_w: int (const uint16_t *, const uint16_t *)
+strdiacasecmp: int (const char *, const char *)
+strdup_w: uint16_t *(const uint16_t *)
+stripped_slashes_basename: char *(char *)
+strlcat: size_t (char *, const char *, size_t)
+strlcpy: size_t (char *, const char *, size_t)
+strlen_w: size_t (const uint16_t *)
+strlower_w: int (uint16_t *)
+strncasecmp_w: int (const uint16_t *, const uint16_t *, size_t)
+strncat_w: uint16_t *(uint16_t *, const uint16_t *, const size_t)
+strncmp_w: int (const uint16_t *, const uint16_t *, size_t)
+strncpy_w: uint16_t *(uint16_t *, const uint16_t *, const size_t)
+strndiacasecmp: int (const char *, const char *, size_t)
+strndup_w: uint16_t *(const uint16_t *, size_t)
+strnlen_w: size_t (const uint16_t *, size_t)
+strstr_w: uint16_t *(const uint16_t *, const uint16_t *)
+strtok_quote: char *(char *, const char *)
+strupper_w: int (uint16_t *)
+sys_ea_copyfile: int (const struct vol *, int, const char *, const char *)
+sys_fgetxattr: ssize_t (int, const char *, void *, size_t)
+sys_fsetxattr: int (int, const char *, const void *, size_t, int)
+sys_ftruncate: int (int, off_t)
+sys_get_eacontent: int (const struct vol *, char *, size_t *, const char *, int, const char *, int)
+sys_get_easize: int (const struct vol *, char *, size_t *, const char *, int, const char *)
+sys_getxattr: ssize_t (const char *, const char *, void *, size_t)
+sys_getxattrfd: int (int, const char *, int, ...)
+sys_lgetxattr: ssize_t (const char *, const char *, void *, size_t)
+sys_list_eas: int (const struct vol *, char *, size_t *, const char *, int)
+sys_listxattr: ssize_t (const char *, char *, size_t)
+sys_llistxattr: ssize_t (const char *, char *, size_t)
+sys_lremovexattr: int (const char *, const char *)
+sys_lsetxattr: int (const char *, const char *, const void *, size_t, int)
+sys_remove_ea: int (const struct vol *, const char *, const char *, int)
+sys_removexattr: int (const char *, const char *)
+sys_sendfile: ssize_t (int, int, off_t *, size_t)
+sys_set_ea: int (const struct vol *, const char *, const char *, const char *, size_t, int)
+sys_setxattr: int (const char *, const char *, const void *, size_t, int)
+tdb_add_flags: void (struct tdb_context *, unsigned int)
+tdb_allocate: tdb_off_t (struct tdb_context *, tdb_len_t, struct tdb_record *)
+tdb_alloc_read: unsigned char *(struct tdb_context *, tdb_off_t, tdb_len_t)
+tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA)
+tdb_brlock: int (struct tdb_context *, tdb_off_t, int, int, int, size_t)
+tdb_brlock_upgrade: int (struct tdb_context *, tdb_off_t, size_t)
+tdb_chainlock: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_read: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA)
+tdb_chainunlock: int (struct tdb_context *, TDB_DATA)
+tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA)
+tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *)
+tdb_close: int (struct tdb_context *)
+tdb_convert: void *(void *, uint32_t)
+tdb_delete: int (struct tdb_context *, TDB_DATA)
+tdb_do_delete: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_dump_all: void (struct tdb_context *)
+tdb_enable_seqnum: void (struct tdb_context *)
+tdb_error: enum TDB_ERROR (struct tdb_context *)
+tdb_errorstr: const char *(struct tdb_context *)
+tdb_exists: int (struct tdb_context *, TDB_DATA)
+tdb_expand: int (struct tdb_context *, tdb_off_t)
+tdb_fd: int (struct tdb_context *)
+tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA)
+tdb_find_lock_hash: tdb_off_t (struct tdb_context *, TDB_DATA, uint32_t, int, struct tdb_record *)
+tdb_firstkey: TDB_DATA (struct tdb_context *)
+tdb_free: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_freelist_size: int (struct tdb_context *)
+tdb_get_flags: int (struct tdb_context *)
+tdb_get_logging_private: void *(struct tdb_context *)
+tdb_get_seqnum: int (struct tdb_context *)
+tdb_hash_size: int (struct tdb_context *)
+tdb_increment_seqnum_nonblock: void (struct tdb_context *)
+tdb_io_init: void (struct tdb_context *)
+tdb_lock: int (struct tdb_context *, int, int)
+tdb_lockall: int (struct tdb_context *)
+tdb_lockall_mark: int (struct tdb_context *)
+tdb_lockall_nonblock: int (struct tdb_context *)
+tdb_lockall_read: int (struct tdb_context *)
+tdb_lockall_read_nonblock: int (struct tdb_context *)
+tdb_lockall_unmark: int (struct tdb_context *)
+tdb_lock_nonblock: int (struct tdb_context *, int, int)
+tdb_lock_record: int (struct tdb_context *, tdb_off_t)
+tdb_log_fn: tdb_log_func (struct tdb_context *)
+tdb_map_size: size_t (struct tdb_context *)
+tdb_mmap: void (struct tdb_context *)
+tdb_munmap: int (struct tdb_context *)
+tdb_name: const char *(struct tdb_context *)
+tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA)
+tdb_null: {dptr = 0x0, dsize = 0}
+tdb_ofs_read: int (struct tdb_context *, tdb_off_t, tdb_off_t *)
+tdb_ofs_write: int (struct tdb_context *, tdb_off_t, tdb_off_t *)
+tdb_open: struct tdb_context *(const char *, int, int, int, mode_t)
+tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func)
+tdb_parse_data: int (struct tdb_context *, TDB_DATA, tdb_off_t, tdb_len_t, int (*)(TDB_DATA, TDB_DATA, void *), void *)
+tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *)
+tdb_printfreelist: int (struct tdb_context *)
+tdb_rec_free_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_rec_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_rec_write: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_remove_flags: void (struct tdb_context *, unsigned int)
+tdb_reopen: int (struct tdb_context *)
+tdb_reopen_all: int (int)
+tdb_repack: int (struct tdb_context *)
+tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *)
+tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *)
+tdb_set_max_dead: void (struct tdb_context *, int)
+tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int)
+_tdb_transaction_cancel: int (struct tdb_context *)
+tdb_transaction_cancel: int (struct tdb_context *)
+tdb_transaction_commit: int (struct tdb_context *)
+tdb_transaction_lock: int (struct tdb_context *, int)
+tdb_transaction_prepare_commit: int (struct tdb_context *)
+tdb_transaction_recover: int (struct tdb_context *)
+tdb_transaction_start: int (struct tdb_context *)
+tdb_transaction_unlock: int (struct tdb_context *)
+tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *)
+tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *)
+tdb_unlock: int (struct tdb_context *, int, int)
+tdb_unlockall: int (struct tdb_context *)
+tdb_unlockall_read: int (struct tdb_context *)
+tdb_unlock_record: int (struct tdb_context *, tdb_off_t)
+tdb_validate_freelist: int (struct tdb_context *, int *)
+tdb_wipe_all: int (struct tdb_context *)
+tdb_write_lock_record: int (struct tdb_context *, tdb_off_t)
+tdb_write_unlock_record: int (struct tdb_context *, tdb_off_t)
+tokenize_ip_port: int (const char *, char **, char **)
+tolower_sp: uint32_t (uint32_t)
+tolower_w: uint16_t (uint16_t)
+toupper_sp: uint32_t (uint32_t)
+toupper_w: uint16_t (uint16_t)
+type_configs: {{set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}}
+ucs2_to_charset: size_t (charset_t, const uint16_t *, char *, size_t)
+ucs2_to_charset_allocate: size_t (charset_t, char **, const uint16_t *)
+unbecome_root: void (void)
+unix_rename: int (int, const char *, int, const char *)
+unix_strlower: size_t (const char *, size_t, char *, size_t)
+unix_strupper: size_t (const char *, size_t, char *, size_t)
+unload_volumes: void (AFPObj *)
+utf8_charlen: size_t (char *)
+utf8_decompose: size_t (char *, size_t, char *, size_t)
+utf8_precompose: size_t (char *, size_t, char *, size_t)
+utf8_strlen_validate: size_t (char *)
+utf8_strlower: size_t (const char *, size_t, char *, size_t)
+utf8_strupper: size_t (const char *, size_t, char *, size_t)
+utf8_to_charset_allocate: size_t (charset_t, char **, const char *)
+uuid_bin2string: const char *(const unsigned char *)
+uuidcache_dump: void (void)
+uuid_string2bin: void (const char *, unsigned char *)
+uuidtype: {"", "USER", "GROUP", "LOCAL"}
+volume_free: void (struct vol *)
+volume_unlink: void (struct vol *)
+writet: ssize_t (int, void *, const size_t, int, int)
index 02ed81f086e4721750212525b5ffc72018fce82d..9ed1c776d845097939cfd3fd689d41d534a00679 100644 (file)
@@ -232,7 +232,7 @@ static int check_vol_acl_support(const struct vol *vol)
 {
     int ret = 0;
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
     ace_t *aces = NULL;
     ret = 1;
     if (get_nfsv4_acl(vol->v_path, &aces) == -1)
@@ -245,7 +245,7 @@ static int check_vol_acl_support(const struct vol *vol)
         ret = 0;
 #endif
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
     if (aces) free(aces);
 #endif
 #ifdef HAVE_POSIX_ACLS
@@ -667,11 +667,16 @@ static struct vol *creatvol(AFPObj *obj,
     for(i = 0; i < vlen; i++)
         if(tmpname[i] == '/') tmpname[i] = ':';
 
-    bstring dbpath;
-    EC_NULL( val = atalk_iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "vol dbpath", _PATH_STATEDIR "CNID/") );
-    EC_NULL( dbpath = bformat("%s/%s/", val, tmpname) );
-    EC_NULL( volume->v_dbpath = strdup(cfrombstr(dbpath)) );
-    bdestroy(dbpath);
+
+    if (!atalk_iniparser_getboolean(obj->iniconfig, INISEC_GLOBAL, "vol dbnest", 0)) {
+        bstring dbpath;
+        EC_NULL( val = atalk_iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "vol dbpath", _PATH_STATEDIR "CNID/") );
+        EC_NULL( dbpath = bformat("%s/%s/", val, tmpname) );
+        EC_NULL( volume->v_dbpath = strdup(cfrombstr(dbpath)) );
+        bdestroy(dbpath);
+    } else {
+        EC_NULL( volume->v_dbpath = strdup(path) );
+    }
 
     if ((val = getoption(obj->iniconfig, section, "cnid scheme", preset, NULL)))
         EC_NULL( volume->v_cnidscheme = strdup(val) );
@@ -1978,6 +1983,8 @@ void afp_config_free(AFPObj *obj)
         CONFIG_ARG_FREE(obj->options.k5service);
     if (obj->options.k5realm)
         CONFIG_ARG_FREE(obj->options.k5realm);
+    if (obj->options.k5principal)
+        CONFIG_ARG_FREE(obj->options.k5principal);
     if (obj->options.listen)
         CONFIG_ARG_FREE(obj->options.listen);
     if (obj->options.interfaces)
index d7c8eb62b46470d2caed350b0b095d48d5ea1b05..027aba1b27a1112abb781138a7cf47189b02a395 100644 (file)
@@ -30,7 +30,7 @@
 #include <atalk/errchk.h>
 #include <atalk/acl.h>
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
 
 /* Removes all non-trivial ACLs from object. Returns full AFPERR code. */
 int remove_acl_vfs(const char *name)
@@ -86,7 +86,7 @@ exit:
     return ret;
 }
 
-#endif  /* HAVE_SOLARIS_ACLS */
+#endif  /* HAVE_NFSV4_ACLS */
 
 #ifdef HAVE_POSIX_ACLS
 /*!
index a793cd283f5aa34c394981be77cde3f33425a6e1..52c6ea84945b3bffe491df06942d266cc138b404 100644 (file)
@@ -348,7 +348,7 @@ EC_CLEANUP:
     EC_EXIT;
 }
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
 static int RF_solaris_acl(VFS_FUNC_ARGS_ACL)
 {
     static char buf[ MAXPATHLEN + 1];
@@ -791,7 +791,7 @@ static struct vfs_ops netatalk_ea_sys = {
  * Tertiary VFS modules for ACLs
  */
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
 static struct vfs_ops netatalk_solaris_acl_adouble = {
     /* validupath:        */ NULL,
     /* rf_chown:          */ NULL,
@@ -859,7 +859,7 @@ void initvol_vfs(struct vol *vol)
     }
 
     /* ACLs */
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_NFSV4_ACLS
     vol->vfs_modules[2] = &netatalk_solaris_acl_adouble;
 #endif
 #ifdef HAVE_POSIX_ACLS
index 4a87efcec2ea8e8d07bf42c910aa0fe02d63d146..be0fb3a6a2af22a294b62ece9308e883f3c676af 100644 (file)
@@ -156,6 +156,31 @@ AC_DEFUN([AC_NETATALK_LIBEVENT], [
     AM_CONDITIONAL(USE_BUILTIN_LIBEVENT, test x"$use_bundled_libevent" = x"yes")
 ])
 
+dnl Whether to disable bundled tdb
+AC_DEFUN([AC_NETATALK_TDB], [
+    AC_ARG_WITH(
+        tdb,
+        [AS_HELP_STRING([--with-tdb],[whether to use the bundled tdb (default: yes)])],
+        use_bundled_tdb=$withval,
+        use_bundled_tdb=yes
+    )
+    AC_MSG_CHECKING([whether to use bundled tdb])
+    AC_MSG_RESULT([$use_bundled_tdb])
+
+    if test x"$use_bundled_tdb" = x"yes" ; then
+        AC_DEFINE(USE_BUILTIN_TDB, 1, [Use internal tbd])
+    else
+        if test -z "$TDB_LIBS" ; then
+            PKG_CHECK_MODULES(TDB, tdb, , [AC_MSG_ERROR([couldn't find tdb with pkg-config])])
+        fi
+        use_bundled_tdb=no
+    fi        
+
+    AC_SUBST(TDB_CFLAGS)
+    AC_SUBST(TDB_LIBS)
+    AM_CONDITIONAL(USE_BUILTIN_TDB, test x"$use_bundled_tdb" = x"yes")
+])
+
 dnl Filesystem Hierarchy Standard (FHS) compatibility
 AC_DEFUN([AC_NETATALK_FHS], [
 AC_MSG_CHECKING([whether to use Filesystem Hierarchy Standard (FHS) compatibility])
@@ -691,7 +716,7 @@ dnl Check for LDAP support, for client-side ACL visibility
 AC_DEFUN([AC_NETATALK_LDAP], [
 AC_MSG_CHECKING(for LDAP (necessary for client-side ACL visibility))
 AC_ARG_WITH(ldap,
-    [AS_HELP_STRING([--with-ldap],
+    [AS_HELP_STRING([--with-ldap[[=PATH]]],
         [LDAP support (default=auto)])],
         netatalk_cv_ldap=$withval,
         netatalk_cv_ldap=auto
@@ -744,6 +769,7 @@ LIBS="$save_LIBS"
 
 dnl Check for ACL support
 AC_DEFUN([AC_NETATALK_ACL], [
+ac_cv_have_acls=no
 AC_MSG_CHECKING(whether to support ACLs)
 AC_ARG_WITH(acls,
     [AS_HELP_STRING([--with-acls],
@@ -761,112 +787,125 @@ AC_MSG_RESULT($with_acl_support)
 
 if test x"$with_acl_support" = x"no"; then
        AC_MSG_RESULT(Disabling ACL support)
-       AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support should be built in])
-else
-    with_acl_support=yes
 fi
 
-if test x"$with_acl_support" = x"yes" ; then
-       AC_MSG_NOTICE(checking whether ACL support is available:)
+# Platform specific checks
+if test x"$with_acl_support" != x"no" ; then
        case "$host_os" in
-       *sysv5*)
-               AC_MSG_NOTICE(Using UnixWare ACLs)
-               AC_DEFINE(HAVE_UNIXWARE_ACLS,1,[Whether UnixWare ACLs are available])
-               ;;
        *solaris*)
                AC_MSG_NOTICE(Using solaris ACLs)
-               AC_DEFINE(HAVE_SOLARIS_ACLS,1,[Whether solaris ACLs are available])
+               AC_DEFINE(HAVE_SOLARIS_ACLS,1,[Whether Solaris ACLs are available])
+               AC_DEFINE(HAVE_NFSV4_ACLS,1,[Whether NFSv4 ACLs are available])
                ACL_LIBS="$ACL_LIBS -lsec"
+               ac_cv_have_acls=yes
                ;;
-       *hpux*)
-               AC_MSG_NOTICE(Using HPUX ACLs)
-               AC_DEFINE(HAVE_HPUX_ACLS,1,[Whether HPUX ACLs are available])
-               ;;
-       *irix*)
-               AC_MSG_NOTICE(Using IRIX ACLs)
-               AC_DEFINE(HAVE_IRIX_ACLS,1,[Whether IRIX ACLs are available])
-               ;;
-       *aix*)
-               AC_MSG_NOTICE(Using AIX ACLs)
-               AC_DEFINE(HAVE_AIX_ACLS,1,[Whether AIX ACLs are available])
-               ;;
-       *osf*)
-               AC_MSG_NOTICE(Using Tru64 ACLs)
-               AC_DEFINE(HAVE_TRU64_ACLS,1,[Whether Tru64 ACLs are available])
-               ACL_LIBS="$ACL_LIBS -lpacl"
+       *freebsd*)
+               AC_MSG_NOTICE(checking whether libsunacl is available)
+               sunacl_include_path="/usr/local/include"
+               sunacl_lib_path="/usr/local/lib"
+
+               save_CPPFLAGS=$CPPFLAGS
+               save_LDFLAGS=$LDFLAGS
+               save_LIBS=$LIBS
+
+               CPPFLAGS="-I$sunacl_include_path $CPPFLAGS"
+               AC_CHECK_HEADER([sunacl.h])
+
+               LDFLAGS="-L$sunacl_lib_path $LDFLAGS"
+               AC_CHECK_LIB([sunacl], [acl])
+
+               if test x"$ac_cv_header_sunacl_h" = x"yes" -a x"$ac_cv_lib_sunacl_acl" = x"yes" ; then
+                       AC_MSG_NOTICE([Enabling support for ZFS ACLs using libsunacl])
+                       ac_cv_have_acls=yes
+                       CFLAGS="-I$sunacl_include_path $CFLAGS"
+                       ACL_LIBS="$ACL_LIBS -L$sunacl_lib_path -lsunacl"
+                       AC_DEFINE(HAVE_FREEBSD_SUNACL, 1, [Whether FreeBSD ZFS ACLs with libsunacl are available])
+                       AC_DEFINE(HAVE_NFSV4_ACLS,1,[Whether NFSv4 ACLs are available])
+               else
+                       AC_MSG_NOTICE([libsunacl not found, disabling ZFS ACL support])
+               fi
+
+               CPPFLAGS=$save_CPPFLAGS
+               LDFLAGS=$save_LDFLAGS
+               LIBS=$save_LIBS
                ;;
-       *darwin*)
-               AC_MSG_NOTICE(ACLs on Darwin currently not supported)
-               AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support is available])
+       esac
+fi
+
+if test x"$with_acl_support" != x"no" -a x"$ac_cv_have_acls" != x"yes" ; then
+       # Runtime checks for POSIX ACLs
+       AC_CHECK_LIB(acl,acl_get_file,[ACL_LIBS="$ACL_LIBS -lacl"])
+       case "$host_os" in
+       *linux*)
+               AC_CHECK_LIB(attr,getxattr,[ACL_LIBS="$ACL_LIBS -lattr"])
                ;;
-       *)
-               AC_CHECK_LIB(acl,acl_get_file,[ACL_LIBS="$ACL_LIBS -lacl"])
-               case "$host_os" in
-               *linux*)
-                       AC_CHECK_LIB(attr,getxattr,[ACL_LIBS="$ACL_LIBS -lattr"])
-                       ;;
-               esac
-               AC_CACHE_CHECK([for POSIX ACL support],netatalk_cv_HAVE_POSIX_ACLS,[
+       esac
+
+       AC_CACHE_CHECK([for POSIX ACL support],netatalk_cv_HAVE_POSIX_ACLS,[
+               acl_LIBS=$LIBS
+               LIBS="$LIBS $ACL_LIBS"
+               AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+                       #include <sys/types.h>
+                       #include <sys/acl.h>
+               ]], [[
+                       acl_t acl;
+                       int entry_id;
+                       acl_entry_t *entry_p;
+                       return acl_get_entry(acl, entry_id, entry_p);
+               ]])],
+                       [netatalk_cv_HAVE_POSIX_ACLS=yes; ac_cv_have_acls=yes],
+                       [netatalk_cv_HAVE_POSIX_ACLS=no; ac_cv_have_acls=no]
+               )
+               LIBS=$acl_LIBS
+       ])
+
+       if test x"$netatalk_cv_HAVE_POSIX_ACLS" = x"yes"; then
+               AC_MSG_NOTICE(Using POSIX ACLs)
+               AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether POSIX ACLs are available])
+
+               AC_CACHE_CHECK([for acl_get_perm_np],netatalk_cv_HAVE_ACL_GET_PERM_NP,[
                        acl_LIBS=$LIBS
                        LIBS="$LIBS $ACL_LIBS"
                        AC_LINK_IFELSE([AC_LANG_PROGRAM([[
                                #include <sys/types.h>
                                #include <sys/acl.h>
                        ]], [[
-                               acl_t acl;
-                               int entry_id;
-                               acl_entry_t *entry_p;
-                               return acl_get_entry(acl, entry_id, entry_p);
-                       ]])],[netatalk_cv_HAVE_POSIX_ACLS=yes],[netatalk_cv_HAVE_POSIX_ACLS=no
-                with_acl_support=no])
+                               acl_permset_t permset_d;
+                               acl_perm_t perm;
+                               return acl_get_perm_np(permset_d, perm);
+                       ]])],[netatalk_cv_HAVE_ACL_GET_PERM_NP=yes],[netatalk_cv_HAVE_ACL_GET_PERM_NP=no])
                        LIBS=$acl_LIBS
                ])
-               if test x"$netatalk_cv_HAVE_POSIX_ACLS" = x"yes"; then
-                       AC_MSG_NOTICE(Using POSIX ACLs)
-                       AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether POSIX ACLs are available])
-                       AC_CACHE_CHECK([for acl_get_perm_np],netatalk_cv_HAVE_ACL_GET_PERM_NP,[
-                               acl_LIBS=$LIBS
-                               LIBS="$LIBS $ACL_LIBS"
-                               AC_LINK_IFELSE([AC_LANG_PROGRAM([[
-                                       #include <sys/types.h>
-                                       #include <sys/acl.h>
-                               ]], [[
-                                       acl_permset_t permset_d;
-                                       acl_perm_t perm;
-                                       return acl_get_perm_np(permset_d, perm);
-                               ]])],[netatalk_cv_HAVE_ACL_GET_PERM_NP=yes],[netatalk_cv_HAVE_ACL_GET_PERM_NP=no])
-                               LIBS=$acl_LIBS
-                       ])
-                       if test x"$netatalk_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then
-                               AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available])
-                       fi
-
-
-                       AC_CACHE_CHECK([for acl_from_mode], netatalk_cv_HAVE_ACL_FROM_MODE,[
-                               acl_LIBS=$LIBS
-                               LIBS="$LIBS $ACL_LIBS"
-                AC_CHECK_FUNCS(acl_from_mode,
-                               [netatalk_cv_HAVE_ACL_FROM_MODE=yes],
-                               [netatalk_cv_HAVE_ACL_FROM_MODE=no])
-                               LIBS=$acl_LIBS
-                       ])
-                       if test x"netatalk_cv_HAVE_ACL_FROM_MODE" = x"yes"; then
-                               AC_DEFINE(HAVE_ACL_FROM_MODE,1,[Whether acl_from_mode() is available])
-                       fi
+               if test x"$netatalk_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then
+                       AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available])
+               fi
 
-               else
-                       AC_MSG_NOTICE(ACL support is not avaliable)
-                       AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support is available])
+               AC_CACHE_CHECK([for acl_from_mode], netatalk_cv_HAVE_ACL_FROM_MODE,[
+                       acl_LIBS=$LIBS
+                       LIBS="$LIBS $ACL_LIBS"
+                       AC_CHECK_FUNCS(acl_from_mode,
+                               [netatalk_cv_HAVE_ACL_FROM_MODE=yes],
+                               [netatalk_cv_HAVE_ACL_FROM_MODE=no]
+                       )
+                       LIBS=$acl_LIBS
+               ])
+               if test x"netatalk_cv_HAVE_ACL_FROM_MODE" = x"yes"; then
+                  AC_DEFINE(HAVE_ACL_FROM_MODE,1,[Whether acl_from_mode() is available])
                fi
-               ;;
-    esac
+       fi
 fi
 
-if test x"$with_acl_support" = x"yes" ; then
-   AC_CHECK_HEADERS([acl/libacl.h])
-    AC_DEFINE(HAVE_ACLS,1,[Whether ACLs support is available])
-    AC_SUBST(ACL_LIBS)
+if test x"$ac_cv_have_acls" = x"no" ; then
+       if test x"$with_acl_support" = x"yes" ; then
+               AC_MSG_ERROR(ACL support requested but not found)
+       else
+               AC_MSG_NOTICE(ACL support is not avaliable)
+       fi
+else
+       AC_CHECK_HEADERS([acl/libacl.h])
+       AC_DEFINE(HAVE_ACLS,1,[Whether ACLs support is available])
 fi
+AC_SUBST(ACL_LIBS)
 ])
 
 dnl Check for Extended Attributes support
index 3a4b2a3cd2f3e45b6255f11eaf56c6d4d2f796d8..810c896613267920b99faccba5b1c9a5de3bcce9 100644 (file)
@@ -11,7 +11,7 @@ AC_DEFUN([AC_NETATALK_CONFIG_SUMMARY], [
        fi
        AC_MSG_RESULT([    AFP:])
        AC_MSG_RESULT([         Extended Attributes: $neta_cv_eas])
-       AC_MSG_RESULT([         ACL support: $with_acl_support])
+       AC_MSG_RESULT([         ACL support: $ac_cv_have_acls])
        AC_MSG_RESULT([    CNID:])
        AC_MSG_RESULT([         backends: $compiled_backends])
        AC_MSG_RESULT([    UAMS:])
@@ -142,4 +142,12 @@ AC_DEFUN([AC_NETATALK_LIBS_SUMMARY], [
                AC_MSG_RESULT([        LIBS   = $LIBEVENT_CFLAGS])
                AC_MSG_RESULT([        CFLAGS = $LIBEVENT_LDFLAGS])
     fi
+
+    AC_MSG_RESULT([    TDB:])
+    if test x"$use_bundled_tdb" = x"yes"; then
+               AC_MSG_RESULT([        bundled])
+    else
+               AC_MSG_RESULT([        LIBS   = $TDB_LIBS])
+               AC_MSG_RESULT([        CFLAGS = $TDB_CFLAGS])
+    fi
 ])
index 7a1f56d5af83129550089c83264f302815e8022a..462670d64d2632b0d64de3d383ecee592c1c605e 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: afp.conf
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 30 Apr 2013
+.\"      Date: 13 Sep 2013
 .\"    Manual: @NETATALK_VERSION@
 .\"    Source: @NETATALK_VERSION@
 .\"  Language: English
 .\"
-.TH "AFP\&.CONF" "5" "30 Apr 2013" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.TH "AFP\&.CONF" "5" "13 Sep 2013" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -472,7 +472,7 @@ Sets the maximum number of clients that can simultaneously connect to the server
 .PP
 server quantum = \fInumber\fR \fB(G)\fR
 .RS 4
-This specifies the DSI server quantum\&. The default value is 1 MB\&. The maximum value is 0xFFFFFFFFF, the minimum is 32000\&. If you specify a value that is out of range, the default value will be set\&. Do not change this value unless you\*(Aqre absolutely sure, what you\*(Aqre doing
+This specifies the DSI server quantum\&. The default value is 0x100000 (1 MiB)\&. The maximum value is 0xFFFFFFFFF, the minimum is 32000\&. If you specify a value that is out of range, the default value will be set\&. Do not change this value unless you\*(Aqre absolutely sure, what you\*(Aqre doing
 .RE
 .PP
 sleep time = \fInumber\fR \fB(G)\fR
@@ -597,9 +597,7 @@ Use share reservations on Solaris\&. Solaris CIFS server uses this too, so this
 .PP
 veto message = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
 .RS 4
-Use section
-\fBname\fR
-as option preset for all volumes (when set in the [Global] section) or for one volume (when set in that volume\*(Aqs section)\&.
+Send optional AFP messages for vetoed files\&. Then whenever a client tries to access any file or directory with a vetoed name, it will be sent an AFP message indicating the name and the directory\&.
 .RE
 .PP
 vol dbpath = \fIpath\fR \fB(G)\fR
@@ -608,6 +606,11 @@ Sets the database information to be stored in path\&. You have to specify a writ
 @localstatedir@/netatalk/CNID/\&.
 .RE
 .PP
+vol dbnest = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
+.RS 4
+Setting this option to true brings back Netatalk 2 behaviour of storing the CNID database in a folder called \&.AppleDB inside the volume root of each share\&.
+.RE
+.PP
 volnamelen = \fInumber\fR \fB(G)\fR
 .RS 4
 Max length of UTF8\-MAC volume name for Mac OS X\&. Note that Hangul is especially sensitive to this\&.
@@ -821,6 +824,11 @@ ldap name attr = \fIdn\fR \fB(G)\fR
 Name of the LDAP attribute with the users short name\&.
 .RE
 .PP
+ldap group attr = \fIdn\fR \fB(G)\fR
+.RS 4
+Name of the LDAP attribute with the groups short name\&.
+.RE
+.PP
 ldap uuid string = \fISTRING\fR \fB(G)\fR
 .RS 4
 Format of the uuid string in the directory\&. A series of x and \-, where every x denotes a value 0\-9a\-f and every \- is a separator\&.
@@ -831,6 +839,11 @@ Default: xxxxxxxx\-xxxx\-xxxx\-xxxx\-xxxxxxxxxxxx
 ldap uuid encoding = \fIstring | ms\-guid (default: string)\fR \fB(G)\fR
 .RS 4
 Format of the UUID of the LDAP attribute, allows usage of the binary objectGUID fields from Active Directory\&. If left unspecified, string is the default, which passes through the ASCII UUID returned by most other LDAP stores\&. If set to ms\-guid, the internal UUID representation is converted to and from the binary format used in the objectGUID attribute found on objects in Active Directory when interacting with the server\&.
+.sp
+See also the options
+\fBldap user filter\fR
+and
+\fBldap group filter\fR\&.
 .PP
 string
 .RS 4
@@ -843,9 +856,20 @@ Binary objectGUID from Active Directory
 .RE
 .RE
 .PP
-ldap group attr = \fIdn\fR \fB(G)\fR
+ldap user filter = \fISTRING (default: unused)\fR \fB(G)\fR
 .RS 4
-Name of the LDAP attribute with the groups short name\&.
+Optional LDAP filter that matches user objects\&. This is necessary for Active Directory environments where users and groups are stored in the same directory subtree\&.
+.sp
+Recommended setting for Active Directory:
+\fIobjectClass=user\fR\&.
+.RE
+.PP
+ldap group filter = \fISTRING (default: unused)\fR \fB(G)\fR
+.RS 4
+Optional LDAP filter that matches group objects\&. This is necessary for Active Directory environments where users and groups are stored in the same directory subtree\&.
+.sp
+Recommended setting for Active Directory:
+\fIobjectClass=group\fR\&.
 .RE
 .SH "EXPLANATION OF VOLUME PARAMETERS"
 .SS "Parameters"
@@ -1073,6 +1097,21 @@ If this option is set to yes, then Netatalk will attempt to recursively delete a
 follow symlinks = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
 .RS 4
 The default setting is false thus symlinks are not followed on the server\&. This is the same behaviour as OS X\*(Aqs AFP server\&. Setting the option to true causes afpd to follow symlinks on the server\&. symlinks may point outside of the AFP volume, currently afpd doesn\*(Aqt do any checks for "wide symlinks"\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This option will subtly break when the symlinks point across filesystem boundaries\&.
+.sp .5v
+.RE
 .RE
 .PP
 invisible dots = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR