]> arthur.barton.de Git - netatalk.git/commitdiff
Merge branch 'master' of git://netatalk.git.sourceforge.net/gitroot/netatalk/netatalk...
authorAlexander Barton <alex@barton.de>
Tue, 20 Mar 2012 01:04:54 +0000 (02:04 +0100)
committerAlexander Barton <alex@barton.de>
Tue, 20 Mar 2012 01:04:54 +0000 (02:04 +0100)
* 'master' of git://netatalk.git.sourceforge.net/gitroot/netatalk/netatalk:
  Fix a possible bug handling disconnected sessions, NetAFP Bug ID #16
  Cleanup respawn throttling code
  For the future, conf file version is clarified
  Fix dependencie on LDAP
  Check if server_name might is GSS_C_NO_NAME
  Update news
  Fixes, from Riccardo Magliocchetti
  Fix, from Riccardo Magliocchetti
  Fixes, from Riccardo Magliocchetti
  ldap_uuid_string
  configure summary and afpd -V: show mDNSResponder or Avahi
  Support for mdnsresponder, from Lee Essen
  Use GSS_C_NO_NAME as server principal when Kerberos options -fqdn and -krb5service are not set, from Jamie Gilbertson
  Update new
  Dont use search db when doing partial name search
  Fix an error message
  Fix broken sendfile on FreeBSD, from Denis Ahrens
  Ensure our umask is not altered by eg pam_umask

33 files changed:
NEWS
VERSION
config/AppleVolumes.default.tmpl
config/AppleVolumes.system
config/afp_ldap.conf
config/afpd.conf.tmpl
config/netatalk.conf
etc/afpd/Makefile.am
etc/afpd/afp_avahi.c
etc/afpd/afp_avahi.h
etc/afpd/afp_mdns.c [new file with mode: 0644]
etc/afpd/afp_mdns.h [new file with mode: 0644]
etc/afpd/afp_options.c
etc/afpd/afp_zeroconf.c
etc/afpd/afp_zeroconf.h
etc/afpd/afs.c
etc/afpd/appl.c
etc/afpd/auth.c
etc/afpd/catsearch.c
etc/afpd/directory.c
etc/cnid_dbd/cnid_metad.c
etc/cnid_dbd/main.c
etc/uams/uams_gss.c
include/atalk/ldapconfig.h
include/atalk/uuid.h
libatalk/acl/ldap.c
libatalk/acl/ldap_config.c
libatalk/acl/uuid.c
libatalk/adouble/ad_sendfile.c
libatalk/dsi/dsi_stream.c
libatalk/util/volinfo.c
macros/summary.m4
macros/zeroconf.m4

diff --git a/NEWS b/NEWS
index 7a9153bbaa628b807724664291ea9025adbac769..4b68c54f96a42aaa7e29b5880aeb610eb4cf2590 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,16 @@
-Changes in ?.?.?
+Changes in 2.2.3
 ================
 
+* NEW: afpd: support for mdnsresponder
+* NEW: afpd: new LDAP config option ldap_uuid_string
 * UPD: based on Unicode 6.1.0
 * UPD: experimental systemd service files: always run both afpd and cnid_metad
+* UPD: afpd: Ensure our umask is not altered by eg pam_umask
+* UPD: afpd: Use GSS_C_NO_NAME as server principal when Kerberos options -fqdn
+       and -krb5service are not set, from Jamie Gilbertson
+* FIX: afpd: sendfile() on FreeBSD was broken, courtesy of Denis Ahrens
+* FIX: afpd: Dont use searchdb when doing partial name search
+* FIX: afpd: Fix a possible bug handling disconnected sessions, NetAFP Bug ID #16
 
 Changes in 2.2.2
 ================
diff --git a/VERSION b/VERSION
index 7e541aec69b34fe38bdf6f049e78b9a67003307f..00e2c4e8a5f2f766f43c61e17861fb6ba4bd05fd 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.2
\ No newline at end of file
+2.2.3dev
\ No newline at end of file
index eeb20a859d7971a01c69d88581d5ef3a9a6aad9b..d402389540b05354f2aa4b9a50675faf7a1e5702 100644 (file)
@@ -1,3 +1,4 @@
+# Netatalk 2.x afp volume cofiguration
 # This file looks empty when viewed with "vi".  In fact, there is one
 # '~', so users with no AppleVolumes file in their home directory get
 # their home directory by default.
index d75e4c9426d7684e56f77dea3f82ee5d353dea65..ee79b9cfe3d503439bab0df24ae4407b2f83928c 100644 (file)
@@ -1,4 +1,4 @@
-# ($Id)
+# Netatalk 2.x afp volume configuration
 ###
 ### Delete a '#' character at the head of line if you need.
 ### If clients are Mac OS X only, it is not especially necessary.
index dff15686949a7a3521496370dc8d01151a2251ef..f1700c01fc27f5e2487dfc325970105cc79d0049 100644 (file)
@@ -1,3 +1,5 @@
+# Netatalk 2.x LDAP configuration
+
 # ldap_server      = localhost
 # ldap_auth_method = simple
 # ldap_auth_dn     = cn=admin,dc=domain,dc=org
index 71f2d50b49280e6158c1344dcd1c654d7353bb87..325ce6a6f3d1ed23c847a33ab33944037dfec679 100644 (file)
@@ -1,5 +1,5 @@
 #
-# CONFIGURATION FOR AFPD
+# CONFIGURATION FOR AFPD (Netatalk 2.x)
 #
 # Each single line defines a virtual server that should be available.
 # Though, using "\" character, newline escaping is supported.
index cb873a3ee9f39a72a1442b95b055fed748187af1..a050460f59f99b297cf01572f0207a30863aa8d4 100644 (file)
@@ -1,4 +1,4 @@
-# Netatalk configuration
+# Netatalk 2.x configuration
 
 #########################################################################
 # Global configuration
index 4e9c02155e90281691d48deca067c41656316263..7a6ed52d56140fd06e29c8a06aff4ccf1543768a 100644 (file)
@@ -10,6 +10,7 @@ afpd_SOURCES = \
        afp_avahi.c \
        afp_config.c \
        afp_dsi.c \
+       afp_mdns.c \
        afp_options.c \
        afp_util.c \
        afp_zeroconf.c \
@@ -73,7 +74,7 @@ endif
 noinst_HEADERS = auth.h afp_config.h desktop.h directory.h fce_api_internal.h file.h \
         filedir.h fork.h icon.h mangle.h misc.h status.h switch.h \
         uam_auth.h uid.h unix.h volume.h hash.h acls.h acl_mappings.h extattrs.h \
-        dircache.h afp_zeroconf.h afp_avahi.h
+        dircache.h afp_zeroconf.h afp_avahi.h afp_mdns.h
 
 hash_SOURCES = hash.c
 hash_CFLAGS = -DKAZLIB_TEST_MAIN -I$(top_srcdir)/include
index 351e00190c9912c118eb592a0a2c3a22578c338c..837fa87ef7221bf576cad6a2c1fb3c64ab61bed9 100644 (file)
@@ -21,6 +21,7 @@
 #include <atalk/dsi.h>
 #include <atalk/unicode.h>
 
+#include "afp_zeroconf.h"
 #include "afp_avahi.h"
 #include "afp_config.h"
 #include "volume.h"
index e516408c6a79e17cc27ad95e7230e3e70e1830bd..9a6563ba8f75d89782fe6d2ab589f8b5dc468f89 100644 (file)
 
 #include "afp_config.h"
 
-#define AFP_DNS_SERVICE_TYPE "_afpovertcp._tcp"
-#define ADISK_SERVICE_TYPE "_adisk._tcp"
-#define DEV_INFO_SERVICE_TYPE "_device-info._tcp"
-
-#define MAXINSTANCENAMELEN 63
-
 struct context {
        /* Avahi stuff */
   int               thread_running;
diff --git a/etc/afpd/afp_mdns.c b/etc/afpd/afp_mdns.c
new file mode 100644 (file)
index 0000000..2088402
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Author:   Lee Essen <lee.essen@nowonline.co.uk>
+ * Based on: avahi support from Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ * Purpose:  mdns based Zeroconf support
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_MDNS
+
+#include <unistd.h>
+#include <time.h>
+#include <pthread.h>
+#include <poll.h>
+
+#include <atalk/logger.h>
+#include <atalk/util.h>
+#include <atalk/dsi.h>
+#include <atalk/unicode.h>
+
+#include "afp_zeroconf.h"
+#include "afp_mdns.h"
+#include "afp_config.h"
+#include "volume.h"
+
+/*
+ * We'll store all the DNSServiceRef's here so that we can
+ * deallocate them later
+ */
+static DNSServiceRef   *svc_refs = NULL;
+static int             svc_ref_count = 0;
+static pthread_t       poller;
+
+/*
+ * Its easier to use asprintf to set the TXT record values
+ */
+#define TXTRecordPrintf(rec, key, args...) {            \
+        char *str;                                      \
+        asprintf(&str, args);                           \
+        TXTRecordSetValue(rec, key, strlen(str), str);  \
+        free(str);                                      \
+    }
+#define TXTRecordKeyPrintf(rec, k, var, args...) {      \
+        char *key, *str;                                \
+        asprintf(&key, k, var);                         \
+        asprintf(&str, args);                           \
+        TXTRecordSetValue(rec, key, strlen(str), str);  \
+        free(str); free(key);                           \
+    }
+
+
+/*
+ * This is the thread that polls the filehandles
+ */
+void *polling_thread(void *arg) {
+    // First we loop through getting the filehandles and adding them to our poll, we
+    // need to allocate our pollfd's
+    DNSServiceErrorType error;
+    struct pollfd           *fds = calloc(svc_ref_count, sizeof(struct pollfd));
+    assert(fds);
+
+    for(int i=0; i < svc_ref_count; i++) {
+        int fd = DNSServiceRefSockFD(svc_refs[i]);
+        fds[i].fd = fd;
+        fds[i].events = POLLIN;
+    }
+
+    // Now we can poll and process the results...
+    while(poll(fds, svc_ref_count, -1) > 0) {
+        for(int i=0; i < svc_ref_count; i++) {
+            if(fds[i].revents & POLLIN) {
+                error = DNSServiceProcessResult(svc_refs[i]);
+            }
+        }
+    }
+    return(NULL);
+}
+
+
+/*
+ * This is the callback for the service register function ... actually there isn't a lot
+ * we can do if we get problems, so we don't really need to do anything other than report
+ * the issue.
+ */
+void RegisterReply(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
+                   const char *name, const char *regtype, const char *domain, void *context) {
+
+    if(errorCode != kDNSServiceErr_NoError) {
+        LOG(log_error, logtype_afpd, "Failed to register mDNS service: %s%s%s: code=%d",
+            name, regtype, domain, errorCode);
+    }
+}
+
+
+/*
+ * This function unregisters anything we have already
+ * registered and frees associated memory
+ */
+static void unregister_stuff() {
+    pthread_kill(poller, SIGKILL);
+    if(svc_refs) {
+        for(int i=0; i < svc_ref_count; i++) {
+            DNSServiceRefDeallocate(svc_refs[i]);
+        }
+        free(svc_refs);
+        svc_refs = NULL;
+        svc_ref_count = 0;
+    }
+}
+
+/*
+ * This function tries to register the AFP DNS
+ * SRV service type.
+ */
+static void register_stuff(const AFPConfig *configs) {
+    uint                                        port;
+    const AFPConfig                 *config;
+    const struct vol                *volume;
+    DSI                                         *dsi;
+    char                                        name[MAXINSTANCENAMELEN+1];
+    DNSServiceErrorType         error;
+    TXTRecordRef                        txt_adisk;
+    TXTRecordRef                        txt_devinfo;
+    char                                        tmpname[256];
+
+    // If we had already registered, then we will unregister and re-register
+    if(svc_refs) unregister_stuff();
+
+    /* Register our service, prepare the TXT record */
+    TXTRecordCreate(&txt_adisk, 0, NULL);
+    TXTRecordPrintf(&txt_adisk, "sys", "waMa=0,adVF=0x100");
+
+    /* Build AFP volumes list */
+    int i = 0;
+
+    for (volume = getvolumes(); volume; volume = volume->v_next) {
+
+        if (convert_string(CH_UCS2, CH_UTF8_MAC, volume->v_name, -1, tmpname, 255) <= 0) {
+            LOG ( log_error, logtype_afpd, "Could not set Zeroconf volume name for TimeMachine");
+            goto fail;
+        }
+
+        if (volume->v_flags & AFPVOL_TM) {
+            if (volume->v_uuid) {
+                LOG(log_info, logtype_afpd, "Registering volume '%s' with UUID: '%s' for TimeMachine",
+                    volume->v_localname, volume->v_uuid);
+                TXTRecordKeyPrintf(&txt_adisk, "dk%u", i++, "adVN=%s,adVF=0xa1,adVU=%s",
+                                   tmpname, volume->v_uuid);
+            } else {
+                LOG(log_warning, logtype_afpd, "Registering volume '%s' for TimeMachine. But UUID is invalid.",
+                    volume->v_localname);
+                TXTRecordKeyPrintf(&txt_adisk, "dk%u", i++, "adVN=%s,adVF=0xa1", tmpname);
+            }
+        }
+    }
+
+    // Now we can count the configs so we know how many service
+    // records to allocate
+    for (config = configs; config; config = config->next) {
+        svc_ref_count++;                    // AFP_DNS_SERVICE_TYPE
+        if(i) svc_ref_count++;      // ADISK_SERVICE_TYPE
+        if (config->obj.options.mimicmodel) svc_ref_count++;        // DEV_INFO_SERVICE_TYPE
+    }
+
+    // Allocate the memory to store our service refs
+    svc_refs = calloc(svc_ref_count, sizeof(DNSServiceRef));
+    assert(svc_ref);
+    svc_ref_count = 0;
+
+    /* AFP server */
+    for (config = configs; config; config = config->next) {
+
+        dsi = (DSI *)config->obj.handle;
+        port = getip_port((struct sockaddr *)&dsi->server);
+
+        if (convert_string(config->obj.options.unixcharset,
+                           CH_UTF8,
+                           config->obj.options.server ?
+                           config->obj.options.server :
+                           config->obj.options.hostname,
+                           -1,
+                           name,
+                           MAXINSTANCENAMELEN) <= 0) {
+            LOG(log_error, logtype_afpd, "Could not set Zeroconf instance name");
+            goto fail;
+        }
+        if ((dsi->bonjourname = strdup(name)) == NULL) {
+            LOG(log_error, logtype_afpd, "Could not set Zeroconf instance name");
+            goto fail;
+
+        }
+        LOG(log_info, logtype_afpd, "Registering server '%s' with Bonjour",
+            dsi->bonjourname);
+
+        error = DNSServiceRegister(&svc_refs[svc_ref_count++],
+                                   0,               // no flags
+                                   0,               // all network interfaces
+                                   dsi->bonjourname,
+                                   AFP_DNS_SERVICE_TYPE,
+                                   "",            // default domains
+                                   NULL,            // default host name
+                                   htons(port),
+                                   0,               // length of TXT
+                                   NULL,            // no TXT
+                                   RegisterReply,           // callback
+                                   NULL);       // no context
+        if(error != kDNSServiceErr_NoError) {
+            LOG(log_error, logtype_afpd, "Failed to add service: %s, error=%d",
+                AFP_DNS_SERVICE_TYPE, error);
+            goto fail;
+        }
+
+        if(i) {
+            error = DNSServiceRegister(&svc_refs[svc_ref_count++],
+                                       0,               // no flags
+                                       0,               // all network interfaces
+                                       dsi->bonjourname,
+                                       ADISK_SERVICE_TYPE,
+                                       "",            // default domains
+                                       NULL,            // default host name
+                                       htons(port),
+                                       TXTRecordGetLength(&txt_adisk),
+                                       TXTRecordGetBytesPtr(&txt_adisk),
+                                       RegisterReply,           // callback
+                                       NULL);       // no context
+            if(error != kDNSServiceErr_NoError) {
+                LOG(log_error, logtype_afpd, "Failed to add service: %s, error=%d",
+                    ADISK_SERVICE_TYPE, error);
+                goto fail;
+            }
+        }
+
+        if (config->obj.options.mimicmodel) {
+            TXTRecordCreate(&txt_devinfo, 0, NULL);
+            TXTRecordPrintf(&txt_devinfo, "model", config->obj.options.mimicmodel);
+            error = DNSServiceRegister(&svc_refs[svc_ref_count++],
+                                       0,               // no flags
+                                       0,               // all network interfaces
+                                       dsi->bonjourname,
+                                       DEV_INFO_SERVICE_TYPE,
+                                       "",            // default domains
+                                       NULL,            // default host name
+                                       htons(port),
+                                       TXTRecordGetLength(&txt_devinfo),
+                                       TXTRecordGetBytesPtr(&txt_devinfo),
+                                       RegisterReply,           // callback
+                                       NULL);       // no context
+            TXTRecordDeallocate(&txt_devinfo);
+            if(error != kDNSServiceErr_NoError) {
+                LOG(log_error, logtype_afpd, "Failed to add service: %s, error=%d",
+                    DEV_INFO_SERVICE_TYPE, error);
+                goto fail;
+            }
+        } /* if (config->obj.options.mimicmodel) */
+    }   /* for config*/
+
+        /*
+         * Now we can create the thread that will poll for the results
+         * and handle the calling of the callbacks
+         */
+    if(pthread_create(&poller, NULL, polling_thread, NULL) != 0) {
+        LOG(log_error, logtype_afpd, "Unable to start mDNS polling thread");
+        goto fail;
+    }
+
+fail:
+    TXTRecordDeallocate(&txt_adisk);
+    return;
+}
+
+/************************************************************************
+ * Public funcions
+ ************************************************************************/
+
+/*
+ * Tries to setup the Zeroconf thread and any
+ * neccessary config setting.
+ */
+void md_zeroconf_register(const AFPConfig *configs) {
+    int error;
+
+    register_stuff(configs);
+    return;
+}
+
+/*
+ * Tries to shutdown this loop impl.
+ * Call this function from inside this thread.
+ */
+int md_zeroconf_unregister() {
+    unregister_stuff();
+    return 0;
+}
+
+#endif /* USE_MDNS */
+
diff --git a/etc/afpd/afp_mdns.h b/etc/afpd/afp_mdns.h
new file mode 100644 (file)
index 0000000..fee1b58
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Author:   Lee Essen <lee.essen@nowonline.co.uk>
+ * Based on: avahi support from Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ * Purpose:  mdns based Zeroconf support
+ */
+
+#ifndef AFPD_MDNS_H
+#define AFPD_MDNS_H
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include <dns_sd.h>
+
+#include <atalk/logger.h>
+
+#include "afp_config.h"
+
+/* prototype definitions */
+void md_zeroconf_register(const AFPConfig *configs);
+int md_zeroconf_unregister(void);
+
+#endif   /* AFPD_MDNS_H */
index a66ef8a9c783d35a7e4828b99d0e22470029fc44..673e0bacb8baf11442a363be118f6befc0c040f9 100644 (file)
@@ -596,8 +596,10 @@ static void show_version_extended(void )
 #endif
 
        printf( "      Zeroconf support:\t" );
-#ifdef USE_ZEROCONF
-       puts( "Yes" );
+#if defined (HAVE_MDNS)
+       puts( "mDNSResponder" );
+#elif defined (HAVE_AVAHI)
+       puts( "Avahi" );
 #else
        puts( "No" );
 #endif
index d6fa657728b568ee1fe5b9a547ab02fc3b10990b..f8bbcf6fb4ed19297f954a4591c6f6141f157537 100644 (file)
@@ -14,7 +14,9 @@
 #include "afp_zeroconf.h"
 #include "afp_config.h"
 
-#ifdef HAVE_AVAHI
+#ifdef HAVE_MDNS
+#include "afp_mdns.h"
+#elif defined (HAVE_AVAHI)
 #include "afp_avahi.h"
 #endif
 
  */
 void zeroconf_register(const AFPConfig *configs)
 {
-#if defined (HAVE_AVAHI)
+#if defined (HAVE_MDNS)
+  LOG(log_debug, logtype_afpd, "Attempting to register with mDNS using mDNSResponder");
+
+       md_zeroconf_register(configs);
+#elif defined (HAVE_AVAHI)
   LOG(log_debug, logtype_afpd, "Attempting to register with mDNS using Avahi");
 
        av_zeroconf_register(configs);
@@ -33,7 +39,10 @@ void zeroconf_register(const AFPConfig *configs)
 
 void zeroconf_deregister(void)
 {
-#if defined (HAVE_AVAHI)
+#if defined (HAVE_MDNS)
+  LOG(log_debug, logtype_afpd, "Attempting to de-register mDNS using mDNSResponder");
+       md_zeroconf_unregister();
+#elif defined (HAVE_AVAHI)
   LOG(log_debug, logtype_afpd, "Attempting to de-register mDNS using Avahi");
        av_zeroconf_unregister();
 #endif
index e2711afb3a4a680d7c1f8ad063a2922b616f409e..8c370fd226d3515096309d538d69ffaf762b5888 100644 (file)
 
 #include "afp_config.h"
 
+#define AFP_DNS_SERVICE_TYPE "_afpovertcp._tcp"
+#define ADISK_SERVICE_TYPE "_adisk._tcp"
+#define DEV_INFO_SERVICE_TYPE "_device-info._tcp"
+
+#define MAXINSTANCENAMELEN 63
+
 /*
  * Prototype Definitions
  */
index 377d5fb5a6389c2d99a3faf0f0b220f8dc71a741..9d6835f4d79592f5dc5e774b31df38580437a0a4 100644 (file)
 #include "misc.h"
 #include "unix.h"
 
-int afs_getvolspace( vol, bfree, btotal, bsize )
-struct vol     *vol;
-VolSpace       *bfree, *btotal;
-u_int32_t   *bsize;
+int afs_getvolspace(struct vol *vol, VolSpace *bfree, VolSpace *btotal, u_int32_t *bsize)
 {
     struct ViceIoctl   vi;
     struct VolumeStatus        *vs;
@@ -129,12 +126,7 @@ int afp_getdiracl(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *r
     #undef accessmode
 #endif
 
-void afsmode( vol, path, ma, dir, st )
-const struct volume *vol;
-char           *path;
-struct maccess *ma;
-struct dir      *dir;
-struct stat     *st;
+void afsmode(const struct volume *vol, char *path, struct maccess *ma, struct dir *dir, struct stat *st)
 {
     struct ViceIoctl   vi;
     char               buf[ 1024 ];
index d791d280843e842e61ea8f7ddbcd891a3a1101c5..78b7587d8b829c7c89b4fb6fd828b10aea07a323 100644 (file)
@@ -335,6 +335,7 @@ int afp_rmvappl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, siz
     mpath = obj->newtmp;
     mp = makemacpath( vol, mpath, AFPOBJ_TMPSIZ, curdir, path->m_name );
     if (!mp) {
+        close(tfd);
         return AFPERR_PARAM ;
     }
 
index 5220493e09d00632285a63a9fba1c413148ee76f..40d3a5ac906b7e56a1de886dedd3f52a70f68546 100644 (file)
@@ -412,6 +412,9 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi
     save_uidgid ( &obj->uidgid );
 #endif
 
+    /* pam_umask or similar might have changed our umask */
+    (void)umask(obj->options.umask);
+
     return( AFP_OK );
 }
 
index 71d1a44608af098cefa519234a15bdb216461e1d..89a6d5733aed67b6c13de4d41f8b3f357928d0c2 100644 (file)
@@ -119,25 +119,38 @@ struct dsitem {
 
 #define DS_BSIZE 128
 static int save_cidx = -1; /* Saved index of currently scanned directory. */
-
 static struct dsitem *dstack = NULL; /* Directory stack data... */
 static int dssize = 0;              /* Directory stack (allocated) size... */
 static int dsidx = 0;               /* First free item index... */
-
 static struct scrit c1, c2;          /* search criteria */
 
+/* Clears directory stack. */
+static void clearstack(void) 
+{
+       save_cidx = -1;
+       while (dsidx > 0) {
+               dsidx--;
+               free(dstack[dsidx].path);
+       }
+}
+
 /* Puts new item onto directory stack. */
 static int addstack(char *uname, struct dir *dir, int pidx)
 {
        struct dsitem *ds;
        size_t         l, u;
+    struct dsitem *tmpds = NULL;
 
        /* check if we have some space on stack... */
        if (dsidx >= dssize) {
                dssize += DS_BSIZE;
-               dstack = realloc(dstack, dssize * sizeof(struct dsitem));       
-               if (dstack == NULL)
+               tmpds = realloc(dstack, dssize * sizeof(struct dsitem));        
+               if (tmpds == NULL) {
+            clearstack();
+            free(dstack);
                        return -1;
+        }
+        dstack = tmpds;
        }
 
        /* Put new element. Allocate and copy lname and path. */
@@ -182,16 +195,6 @@ static int reducestack(void)
        return -1;
 } 
 
-/* Clears directory stack. */
-static void clearstack(void) 
-{
-       save_cidx = -1;
-       while (dsidx > 0) {
-               dsidx--;
-               free(dstack[dsidx].path);
-       }
-} 
-
 /* Looks up for an opened adouble structure, opens resource fork of selected file. 
  * FIXME What about noadouble?
 */
@@ -1047,6 +1050,7 @@ static int catsearch_afp(AFPObj *obj _U_, char *ibuf, size_t ibuflen,
     /* Call search */
     *rbuflen = 24;
     if ((c1.rbitmap & (1 << FILPBIT_PDINFO))
+        && !(c1.rbitmap & (1<<CATPBIT_PARTIAL))
         && (strcmp(vol->v_cnidscheme, "dbd") == 0)
         && (vol->v_flags & AFPVOL_SEARCHDB))
         /* we've got a name and it's a dbd volume, so search CNID database */
index 78670ac1cfb1c6b339ae7d71f7f07c3d0ab87cda..a6b194b176626222cd925cdbcc376dc884cc8b86 100644 (file)
@@ -2389,7 +2389,7 @@ int deletecurdir(struct vol *vol)
     err = vol->vfs->vfs_deletecurdir(vol);
     if (err) {
         LOG(log_error, logtype_afpd, "deletecurdir: error deleting .AppleDouble in \"%s\"",
-            curdir->d_fullpath);
+            cfrombstr(curdir->d_fullpath));
         return err;
     }
 
index aec73ecac842f11657aa1b3582f7d15473b6f3d2..f44d70b89b9c7c905f372ed15a3b9eb0074a4d88 100644 (file)
@@ -102,7 +102,7 @@ static volatile sig_atomic_t sigchild = 0;
 static uint maxvol;
 
 #define MAXSPAWN   3                   /* Max times respawned in.. */
-#define TESTTIME   42                  /* this much seconds apfd client tries to  *
+#define TESTTIME   10                  /* this much seconds apfd client tries to  *
                                         * to reconnect every 5 secondes, catch it */
 #define MAXVOLS    4096
 #define DEFAULTHOST  "localhost"
@@ -112,7 +112,7 @@ struct server {
     struct volinfo *volinfo;
     pid_t pid;
     time_t tm;                    /* When respawned last */
-    int count;                    /* Times respawned in the last TESTTIME secondes */
+    unsigned int count;           /* Times respawned in the last TESTTIME secondes */
     int control_fd;               /* file descriptor to child cnid_dbd process */
 };
 
@@ -197,25 +197,30 @@ static int maybe_start_dbd(char *dbdpn, struct volinfo *volinfo)
             return -1;
         }
     } else {
-        /* we have a slot but no process, check for respawn too fast */
-        if ( (t < (up->tm + TESTTIME)) /* We're in the respawn time window */
-             &&
-             (up->count > MAXSPAWN) ) { /* ...and already tried to fork too often */
-            LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: respawn too fast just exiting");
-            return -1; /* just exit, dont sleep, because we might have work to do for another client  */
-        }
-        if ( t >= (up->tm + TESTTIME) ) { /* out of respawn too fast windows reset the count */
-            LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: respawn window ended");
-            up->tm = t;
-            up->count = 0;
+        /* we have a slot but no process */
+        if (up->count > 0) {
+            /* check for respawn too fast */
+            if (t < (up->tm + TESTTIME)) {
+                /* We're in the respawn time window */
+                if (up->count > MAXSPAWN) {
+                    /* ...and already tried to fork too often */
+                    LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: respawning too fast");
+                    return -1; /* just exit, dont sleep, because we might have work to do for another client  */
+                }
+            } else {
+                /* out of respawn too fast windows reset the count */
+                LOG(log_info, logtype_cnid, "maybe_start_dbd: respawn window ended");
+                up->count = 0;
+            }
         }
         up->count++;
-        LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: respawn count now is: %u", up->count);
+        up->tm = t;
+        LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: respawn count: %u", up->count);
         if (up->count > MAXSPAWN) {
             /* We spawned too fast. From now until the first time we tried + TESTTIME seconds
                we will just return -1 above */
-            LOG(log_maxdebug, logtype_cnid, "maybe_start_dbd: reached MAXSPAWN threshhold");
-        }
+            LOG(log_info, logtype_cnid, "maybe_start_dbd: reached MAXSPAWN threshhold");
+       }
     }
 
     /* 
@@ -561,11 +566,15 @@ int main(int argc, char *argv[])
                 }
             }
             if (WIFEXITED(status)) {
-                LOG(log_info, logtype_cnid, "cnid_dbd pid %i exited with exit code %i",
+                LOG(log_info, logtype_cnid, "cnid_dbd[%i] exited with exit code %i",
                     pid, WEXITSTATUS(status));
+            } else {
+                /* cnid_dbd did a clean exit probably on idle timeout, reset bookkeeping */
+                srv[i].tm = 0;
+                srv[i].count = 0;
             }
-            else if (WIFSIGNALED(status)) {
-                LOG(log_info, logtype_cnid, "cnid_dbd pid %i exited with signal %i",
+            if (WIFSIGNALED(status)) {
+                LOG(log_info, logtype_cnid, "cnid_dbd[%i] received signal %i",
                     pid, WTERMSIG(status));
             }
             sigchild = 0;
index e050a0e5137c4c1010f98ffc30865edffd4d384a..a4883d8264f6b26d6afb3e5aa627ffc75361a160 100644 (file)
@@ -247,7 +247,7 @@ static void switch_to_user(char *dir)
         exit(1);
     }
     if (!getuid()) {
-        LOG(log_info, logtype_cnid, "Setting uid/gid to %i/%i", st.st_uid, st.st_gid);
+        LOG(log_debug, logtype_cnid, "Setting uid/gid to %i/%i", st.st_uid, st.st_gid);
         if (setgid(st.st_gid) < 0 || setuid(st.st_uid) < 0) {
             LOG(log_error, logtype_cnid, "uid/gid: %s", strerror(errno));
             exit(1);
index 044dd278bac78dea2d88ac3e72e8555ccf440812..c513bcf752092f7b52130cde6e6cf9796f15b843 100644 (file)
@@ -126,6 +126,8 @@ static void log_ctx_flags( OM_uint32 flags )
 static void log_principal(gss_name_t server_name)
 {
 #if 0
+    if (server_name == GSS_C_NO_NAME)
+        return;
     /* FIXME: must call gss_canonicalize_name before gss_export_name */
     OM_uint32 major_status = 0, minor_status = 0;
     gss_buffer_desc exported_name;
@@ -146,7 +148,7 @@ static int get_afpd_principal(void *obj, gss_name_t *server_name)
     size_t principal_length;
     gss_buffer_desc s_princ_buffer;
 
-    /* get all the required information from afpd */
+    /* get information from afpd */
     if (uam_afpserver_option(obj, UAM_OPTION_FQDN, (void*) &fqdn, &fqdnlen) < 0)
         return 1;
     LOG(log_debug, logtype_uams, "get_afpd_principal: fqdn: %s", fqdn);
@@ -155,11 +157,13 @@ static int get_afpd_principal(void *obj, gss_name_t *server_name)
         return 1;
     LOG(log_debug, logtype_uams, "get_afpd_principal: service: %s", service);
 
-    /* we need all the info, log error and return if one's missing */
+    /* if we don't have all the info, log that and return GSS_C_NO_NAME */
     if (!service || !servicelen || !fqdn || !fqdnlen) {
-        LOG(log_error, logtype_uams,
-            "get_afpd_principal: could not retrieve required information from afpd.");
-        return 1;
+        LOG(log_note, logtype_uams,
+            "get_afpd_principal: could not retrieve information from afpd, using default service principal(s)");
+
+              *server_name = GSS_C_NO_NAME;
+        return 0;
     }
 
     /* allocate memory to hold the temporary principal string */
@@ -446,7 +450,8 @@ static int do_gss_auth(void *obj, char *ibuf, int ticket_len,
     gss_release_cred( &status, &server_creds );
 
 cleanup_vars:
-    gss_release_name( &status, &server_name );
+    if (server_name != GSS_C_NO_NAME)
+        gss_release_name( &status, &server_name );
 
     return ret;
 }
index 5a5b657061ff467c5a52c8b0d819927588460243..f170f036d01c8deebd591f6cf4bec44295b42b2d 100644 (file)
@@ -14,6 +14,7 @@ extern char *ldap_auth_pw;
 extern char *ldap_userbase;
 extern char *ldap_groupbase;
 extern char *ldap_uuid_attr;
+extern char *ldap_uuid_string;
 extern char *ldap_name_attr;
 extern char *ldap_group_attr;
 extern char *ldap_uid_attr;
index 93bad6b31df7358b598e6b72003173d2e0136c5a..024ac7a0535895a38f6841f2f9cfaeebf383eb00 100644 (file)
@@ -16,7 +16,6 @@
 #define AFP_UUID_H
 
 #define UUID_BINSIZE 16
-#define UUID_STRINGSIZE 36
 
 typedef unsigned char *uuidp_t;
 typedef unsigned char atalk_uuid_t[UUID_BINSIZE];
@@ -28,18 +27,6 @@ typedef enum {UUID_USER   = 1,
 #define UUIDTYPESTR_MASK 3
 extern char *uuidtype[];
 
-/* afp_options.c needs these. defined in libatalk/ldap.c */
-extern char *ldap_host;
-extern int  ldap_auth_method;
-extern char *ldap_auth_dn;
-extern char *ldap_auth_pw;
-extern char *ldap_userbase;
-extern char *ldap_groupbase;
-extern char *ldap_uuid_attr;
-extern char *ldap_name_attr;
-extern char *ldap_group_attr;
-extern char *ldap_uid_attr;
-
 /******************************************************** 
  * Interface
  ********************************************************/
index 724ac4d5ba8e59d59bf4aa2f73c2cc3450165765..122abb5ba1b433ec17a5770bde0864d94419f581 100644 (file)
@@ -49,6 +49,7 @@ int  ldap_userscope;
 char *ldap_groupbase;
 int  ldap_groupscope;
 char *ldap_uuid_attr;
+char *ldap_uuid_string;
 char *ldap_name_attr;
 char *ldap_group_attr;
 char *ldap_uid_attr;
@@ -63,6 +64,7 @@ struct ldap_pref ldap_prefs[] = {
     {&ldap_groupbase,  "ldap_groupbase",   0, 0, -1},
     {&ldap_groupscope, "ldap_groupscope",  1 ,1, -1},
     {&ldap_uuid_attr,  "ldap_uuid_attr",   0, 0, -1},
+    {&ldap_uuid_string,"ldap_uuid_string", 0, 0,  0},
     {&ldap_name_attr,  "ldap_name_attr",   0, 0, -1},
     {&ldap_group_attr, "ldap_group_attr",  0, 0, -1},
     {&ldap_uid_attr,   "ldap_uid_attr",    0, 0,  0},
index da37fb97027638370904806aba70aeef27003061..e0440a6b770514d72543fb0edfffcc1192c02bb2 100644 (file)
@@ -48,10 +48,10 @@ static int getpref(char *buf, char **R_pref, char **R_val)
         val++;
     if ((val = strtok(val, " \n")) == NULL)
         return -1;
-    if ((val = strdup(val)) == NULL)
-        return -1;
     if ((pref = strtok(p, " =")) == NULL)
         return -1;
+    if ((val = strdup(val)) == NULL)
+        return -1;
 
     *R_pref = pref;
     *R_val = val;
index 7c0cf12e4fec035d9e81808aeeed5d5da49ad8c5..1ab48a7e391d8ed9331290fae89a3aae63dcc5e3 100644 (file)
@@ -28,6 +28,7 @@
 #include <atalk/logger.h>
 #include <atalk/afp.h>
 #include <atalk/uuid.h>
+#include <atalk/ldapconfig.h>
 #include <atalk/util.h>
 
 #include "aclldap.h"
@@ -75,8 +76,8 @@ void uuid_string2bin( const char *uuidstring, uuidp_t uuid) {
     int nibble = 1;
     int i = 0;
     unsigned char c, val = 0;
-
-    while (*uuidstring) {
+    
+    while (*uuidstring && i < UUID_BINSIZE) {
         c = *uuidstring;
         if (c == '-') {
             uuidstring++;
@@ -102,21 +103,30 @@ void uuid_string2bin( const char *uuidstring, uuidp_t uuid) {
 
 /*!
  * Convert 16 byte binary uuid to neat ascii represantation including dashes.
- *
+ * Use defined or default ascii mask for dash placement
  * Returns pointer to static buffer.
  */
 const char *uuid_bin2string(unsigned char *uuid) {
-    static char uuidstring[UUID_STRINGSIZE + 1];
-
+    static char uuidstring[64];
+    const char *uuidmask;
     int i = 0;
     unsigned char c;
 
-    while (i < UUID_STRINGSIZE) {
+#ifdef HAVE_LDAP
+    if (ldap_uuid_string)
+        uuidmask = ldap_uuid_string;
+    else
+#endif
+        uuidmask = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
+
+    LOG(log_debug, logtype_afpd, "uuid_bin2string{uuid}: mask: %s", uuidmask);
+               
+    while (i < strlen(uuidmask)) {
         c = *uuid;
         uuid++;
         sprintf(uuidstring + i, "%02X", c);
         i += 2;
-        if (i==8 || i==13 || i==18 || i==23)
+        if (uuidmask[i] == '-')
             uuidstring[i++] = '-';
     }
     uuidstring[i] = 0;
index aabb61ce106eff5f80e69d09ab06149facbfdb51..0e7b27835e69bc3f6dd3de803a07c091f3be2a46 100644 (file)
@@ -67,7 +67,16 @@ ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 #include <sys/uio.h>
 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 {
-  return sendfile(fromfd, tofd, *offset, count, NULL, offset, 0);
+    off_t len;
+    int ret;
+
+    ret = sendfile(fromfd, tofd, *offset, count, NULL, &len, 0);
+
+    *offset += len;
+
+    if (ret != 0)
+        return -1;
+    return len;
 }
 
 #else
index bc84a5fa2bb47849ac5cc2129116e5ad2f137aba..ab1339184b48b1394a89415c481f2689ad0d83c9 100644 (file)
@@ -62,6 +62,9 @@ static int dsi_peek(DSI *dsi)
     maxfd = dsi->socket + 1;
 
     while (1) {
+        if (dsi->socket == -1)
+            /* eg dsi_disconnect() might have disconnected us */
+            return -1;
         FD_ZERO(&readfds);
         FD_ZERO(&writefds);
 
index c6cb1f21b454b1045e13ae5abe87608e337388ff..671f57f27816957b72b7ff392becb7d9827f06b1 100644 (file)
@@ -521,6 +521,7 @@ int savevolinfo(const struct vol *vol, const char *Cnid_srv, const char *Cnid_po
     lock.l_type   = F_WRLCK;
 
     if (fcntl(fd, F_SETLK, &lock) < 0) {
+        close(fd);
         if (errno == EACCES || errno == EAGAIN) {
             /* ignore, other process already writing the file */
             return 0;
index 4c87d8965b712029721b90777dac39676108fd84..dac5fa2cb6b217b9575c18621710b5767fa3590b 100644 (file)
@@ -121,4 +121,9 @@ AC_DEFUN([AC_NETATALK_LIBS_SUMMARY], [
                AC_MSG_RESULT([        LIBS   = $CUPS_LIBS])
                AC_MSG_RESULT([        CFLAGS = $CUPS_CFLAGS])
        fi
+       if test x"$netatalk_cv_zeroconf" = x"yes"; then
+               AC_MSG_RESULT([    ZEROCONF:])
+               AC_MSG_RESULT([        LIBS   = $ZEROCONF_LIBS])
+               AC_MSG_RESULT([        CFLAGS = $ZEROCONF_CFLAGS])
+       fi
 ])
index 10d9cefd263e0a6a231faf920e9966e58c30bc03..8a64b10e6b54fc6804f918900b44bf4c92772b6a 100644 (file)
@@ -25,32 +25,48 @@ AC_DEFUN([NETATALK_ZEROCONF], [
                        zeroconf_dir="$zeroconf"
                fi
 
-    # mDNS support using Avahi
-    AC_CHECK_HEADER(
-        avahi-client/client.h,
-        AC_CHECK_LIB(
-           avahi-client,
-           avahi_client_new,
-           AC_DEFINE(USE_ZEROCONF, 1, [Use DNS-SD registration]))
-    )
+        # mDNS support using mDNSResponder
+        AC_CHECK_HEADER(
+            dns_sd.h,
+            AC_CHECK_LIB(
+                dns_sd,
+                DNSServiceRegister,
+                AC_DEFINE(USE_ZEROCONF, 1, [Use DNS-SD registration]))
+        )
 
-    case "$ac_cv_lib_avahi_client_avahi_client_new" in
-      yes)
-      PKG_CHECK_MODULES(AVAHI, [ avahi-client >= 0.6 ])
-      PKG_CHECK_MODULES(AVAHI_TPOLL, [ avahi-client >= 0.6.4 ],
-        [AC_DEFINE(HAVE_AVAHI_THREADED_POLL, 1, [Uses Avahis threaded poll implementation])],
-        [AC_MSG_WARN(This Avahi implementation is not supporting threaded poll objects. Maybe this is not what you want.)])
-      ZEROCONF_LIBS="$AVAHI_LIBS"
-      ZEROCONF_CFLAGS="$AVAHI_CFLAGS"
-      AC_DEFINE(HAVE_AVAHI, 1, [Use Avahi/DNS-SD registration])
-      found_zeroconf=yes
-      ;;
-    esac
+        if test "$ac_cv_lib_dns_sd_DNSServiceRegister" = yes; then
+            ZEROCONF_LIBS="-ldns_sd"
+            AC_DEFINE(HAVE_MDNS, 1, [Use mDNSRespnder/DNS-SD registration])
+            found_zeroconf=yes
+        fi
 
-               CPPFLAGS="$savedcppflags"
-               LDFLAGS="$savedldflags"
+        # mDNS support using Avahi
+        if test x"$found_zeroconf" != x"yes" ; then
+            AC_CHECK_HEADER(
+                avahi-client/client.h,
+                AC_CHECK_LIB(
+                    avahi-client,
+                    avahi_client_new,
+                    AC_DEFINE(USE_ZEROCONF, 1, [Use DNS-SD registration]))
+            )
+
+            case "$ac_cv_lib_avahi_client_avahi_client_new" in
+            yes)
+                PKG_CHECK_MODULES(AVAHI, [ avahi-client >= 0.6 ])
+                PKG_CHECK_MODULES(AVAHI_TPOLL, [ avahi-client >= 0.6.4 ],
+                    [AC_DEFINE(HAVE_AVAHI_THREADED_POLL, 1, [Uses Avahis threaded poll implementation])],
+                    [AC_MSG_WARN(This Avahi implementation is not supporting threaded poll objects. Maybe this is not what you want.)])
+                ZEROCONF_LIBS="$AVAHI_LIBS"
+                ZEROCONF_CFLAGS="$AVAHI_CFLAGS"
+                AC_DEFINE(HAVE_AVAHI, 1, [Use Avahi/DNS-SD registration])
+                found_zeroconf=yes
+                ;;
+            esac
+               CPPFLAGS="$savedcppflags"
+                   LDFLAGS="$savedldflags"
+       fi
        fi
-       
+
        netatalk_cv_zeroconf=no
        AC_MSG_CHECKING([whether to enable Zerconf support])
        if test "x$found_zeroconf" = "xyes"; then