]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/afp_dsi.c
Merge master
[netatalk.git] / etc / afpd / afp_dsi.c
index dfebaca0fb8f20e1781d46388afc469635a9bd07..bde1818bd7a1598ceedb48626671b45de674e9e6 100644 (file)
 #endif /* HAVE_SYS_STAT_H */
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <atalk/logger.h>
 #include <setjmp.h>
+#include <time.h>
 
+#include <atalk/logger.h>
 #include <atalk/dsi.h>
 #include <atalk/compat.h>
 #include <atalk/util.h>
 #include <atalk/locking.h>
+#include <atalk/uuid.h>
+#include <atalk/paths.h>
+#include <atalk/server_ipc.h>
+#include <atalk/fce_api.h>
+#include <atalk/globals.h>
 
-#include "globals.h"
 #include "switch.h"
 #include "auth.h"
 #include "fork.h"
@@ -125,6 +130,25 @@ static void afp_dsi_die(int sig)
     }
 }
 
+/* SIGQUIT handler */
+static void ipc_reconnect_handler(int sig _U_)
+{
+    DSI *dsi = (DSI *)AFPobj->handle;
+
+    if (reconnect_ipc(AFPobj) != 0) {
+        LOG(log_error, logtype_afpd, "ipc_reconnect_handler: failed IPC reconnect");
+        afp_dsi_close(AFPobj);
+        exit(EXITERR_SYS);        
+    }
+
+    if (ipc_child_write(AFPobj->ipc_fd, IPC_GETSESSION, AFPobj->sinfo.clientid_len, AFPobj->sinfo.clientid) != 0) {
+        LOG(log_error, logtype_afpd, "ipc_reconnect_handler: failed IPC ID resend");
+        afp_dsi_close(AFPobj);
+        exit(EXITERR_SYS);        
+    }
+    LOG(log_note, logtype_afpd, "ipc_reconnect_handler: IPC reconnect done");
+}
+
 /* SIGURG handler (primary reconnect) */
 static void afp_dsi_transfer_session(int sig _U_)
 {
@@ -287,6 +311,10 @@ static void alarm_handler(int sig _U_)
     } 
 
     if (dsi->flags & DSI_DISCONNECTED) {
+        if (geteuid() == 0) {
+            LOG(log_note, logtype_afpd, "afp_alarm: unauthenticated user, connection problem");
+            afp_dsi_die(EXITERR_CLNT);
+        }
         if (dsi->tickle > AFPobj->options.disconnected) {
             LOG(log_error, logtype_afpd, "afp_alarm: reconnect timer expired, goodbye");
             afp_dsi_die(EXITERR_CLNT);
@@ -297,8 +325,8 @@ static void alarm_handler(int sig _U_)
     /* if we're in the midst of processing something, don't die. */        
     if ( !(dsi->flags & DSI_RUNNING) && (dsi->tickle >= AFPobj->options.timeout)) {
         LOG(log_error, logtype_afpd, "afp_alarm: child timed out, entering disconnected state");
-        dsi->proto_close(dsi);
-        dsi->flags |= DSI_DISCONNECTED;
+        if (dsi_disconnect(dsi) != 0)
+            afp_dsi_die(EXITERR_CLNT);
         return;
     }
 
@@ -306,9 +334,13 @@ static void alarm_handler(int sig _U_)
         LOG(log_debug, logtype_afpd, "afp_alarm: sending DSI tickle");
         err = dsi_tickle(AFPobj->handle);
     if (err <= 0) {
+        if (geteuid() == 0) {
+            LOG(log_note, logtype_afpd, "afp_alarm: unauthenticated user, connection problem");
+            afp_dsi_die(EXITERR_CLNT);
+        }
         LOG(log_error, logtype_afpd, "afp_alarm: connection problem, entering disconnected state");
-        dsi->proto_close(dsi);
-        dsi->flags |= DSI_DISCONNECTED;
+        if (dsi_disconnect(dsi) != 0)
+            afp_dsi_die(EXITERR_CLNT);
     }
 }
 
@@ -348,22 +380,18 @@ void afp_over_dsi(AFPObj *obj)
     struct sigaction action;
 
     AFPobj = obj;
+    dsi->AFPobj = obj;
     obj->exit = afp_dsi_die;
     obj->reply = (int (*)()) dsi_cmdreply;
     obj->attention = (int (*)(void *, AFPUserBytes)) dsi_attention;
     dsi->tickle = 0;
 
     memset(&action, 0, sizeof(action));
+    sigfillset(&action.sa_mask);
+    action.sa_flags = SA_RESTART;
 
     /* install SIGHUP */
     action.sa_handler = afp_dsi_reload;
-    sigemptyset( &action.sa_mask );
-    sigaddset(&action.sa_mask, SIGALRM);
-    sigaddset(&action.sa_mask, SIGTERM);
-    sigaddset(&action.sa_mask, SIGUSR1);
-    sigaddset(&action.sa_mask, SIGINT);
-    sigaddset(&action.sa_mask, SIGUSR2);
-    action.sa_flags = SA_RESTART;
     if ( sigaction( SIGHUP, &action, NULL ) < 0 ) {
         LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
         afp_dsi_die(EXITERR_SYS);
@@ -371,13 +399,6 @@ void afp_over_dsi(AFPObj *obj)
 
     /* install SIGURG */
     action.sa_handler = afp_dsi_transfer_session;
-    sigemptyset( &action.sa_mask );
-    sigaddset(&action.sa_mask, SIGALRM);
-    sigaddset(&action.sa_mask, SIGTERM);
-    sigaddset(&action.sa_mask, SIGUSR1);
-    sigaddset(&action.sa_mask, SIGINT);
-    sigaddset(&action.sa_mask, SIGUSR2);
-    action.sa_flags = SA_RESTART;
     if ( sigaction( SIGURG, &action, NULL ) < 0 ) {
         LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
         afp_dsi_die(EXITERR_SYS);
@@ -385,27 +406,20 @@ void afp_over_dsi(AFPObj *obj)
 
     /* install SIGTERM */
     action.sa_handler = afp_dsi_die;
-    sigemptyset( &action.sa_mask );
-    sigaddset(&action.sa_mask, SIGALRM);
-    sigaddset(&action.sa_mask, SIGHUP);
-    sigaddset(&action.sa_mask, SIGUSR1);
-    sigaddset(&action.sa_mask, SIGINT);
-    sigaddset(&action.sa_mask, SIGUSR2);
-    action.sa_flags = SA_RESTART;
     if ( sigaction( SIGTERM, &action, NULL ) < 0 ) {
         LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
         afp_dsi_die(EXITERR_SYS);
     }
 
-    /* Added for server message support */
+    /* install SIGQUIT */
+    action.sa_handler = ipc_reconnect_handler;
+    if ( sigaction(SIGQUIT, &action, NULL ) < 0 ) {
+        LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
+        afp_dsi_die(EXITERR_SYS);
+    }
+
+    /* SIGUSR2 - server message support */
     action.sa_handler = afp_dsi_getmesg;
-    sigemptyset( &action.sa_mask );
-    sigaddset(&action.sa_mask, SIGALRM);
-    sigaddset(&action.sa_mask, SIGTERM);
-    sigaddset(&action.sa_mask, SIGUSR1);
-    sigaddset(&action.sa_mask, SIGHUP);
-    sigaddset(&action.sa_mask, SIGINT);
-    action.sa_flags = SA_RESTART;
     if ( sigaction( SIGUSR2, &action, NULL) < 0 ) {
         LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
         afp_dsi_die(EXITERR_SYS);
@@ -413,12 +427,6 @@ void afp_over_dsi(AFPObj *obj)
 
     /*  SIGUSR1 - set down in 5 minutes  */
     action.sa_handler = afp_dsi_timedown;
-    sigemptyset( &action.sa_mask );
-    sigaddset(&action.sa_mask, SIGALRM);
-    sigaddset(&action.sa_mask, SIGHUP);
-    sigaddset(&action.sa_mask, SIGTERM);
-    sigaddset(&action.sa_mask, SIGINT);
-    sigaddset(&action.sa_mask, SIGUSR2);
     action.sa_flags = SA_RESTART;
     if ( sigaction( SIGUSR1, &action, NULL) < 0 ) {
         LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
@@ -427,23 +435,14 @@ void afp_over_dsi(AFPObj *obj)
 
     /*  SIGINT - enable max_debug LOGging to /tmp/afpd.PID.XXXXXX */
     action.sa_handler = afp_dsi_debug;
-    sigfillset( &action.sa_mask );
-    action.sa_flags = SA_RESTART;
     if ( sigaction( SIGINT, &action, NULL) < 0 ) {
         LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
         afp_dsi_die(EXITERR_SYS);
     }
 
 #ifndef DEBUGGING
-    /* tickle handler */
+    /* SIGALRM - tickle handler */
     action.sa_handler = alarm_handler;
-    sigemptyset(&action.sa_mask);
-    sigaddset(&action.sa_mask, SIGHUP);
-    sigaddset(&action.sa_mask, SIGTERM);
-    sigaddset(&action.sa_mask, SIGUSR1);
-    sigaddset(&action.sa_mask, SIGINT);
-    sigaddset(&action.sa_mask, SIGUSR2);
-    action.sa_flags = SA_RESTART;
     if ((sigaction(SIGALRM, &action, NULL) < 0) ||
             (setitimer(ITIMER_REAL, &dsi->timer, NULL) < 0)) {
         afp_dsi_die(EXITERR_SYS);
@@ -489,15 +488,25 @@ void afp_over_dsi(AFPObj *obj)
                 dsi->flags &= ~DSI_RECONSOCKET;
                 continue;
             }
-            /* Some error on the client connection, enter disconnected state */
-            dsi->flags |= DSI_DISCONNECTED;
 
             /* the client sometimes logs out (afp_logout) but doesn't close the DSI session */
             if (dsi->flags & DSI_AFP_LOGGED_OUT) {
+                LOG(log_note, logtype_afpd, "afp_over_dsi: client logged out, terminating DSI session");
                 afp_dsi_close(obj);
                 exit(0);
             }
 
+            /*  got ECONNRESET in read from client => exit*/
+            if (dsi->flags & DSI_GOT_ECONNRESET) {
+                LOG(log_note, logtype_afpd, "afp_over_dsi: client connection reset");
+                afp_dsi_close(obj);
+                exit(0);
+            }
+
+            /* Some error on the client connection, enter disconnected state */
+            if (dsi_disconnect(dsi) != 0)
+                afp_dsi_die(EXITERR_CLNT);
+
             pause(); /* gets interrupted by SIGALARM or SIGURG tickle */
             continue; /* continue receiving until disconnect timer expires
                        * or a primary reconnect succeeds  */
@@ -520,6 +529,7 @@ void afp_over_dsi(AFPObj *obj)
             debug_request = 0;
 
             dircache_dump();
+            uuidcache_dump();
 
             if (debugging) {
                 if (obj->options.logconfig)
@@ -616,7 +626,8 @@ void afp_over_dsi(AFPObj *obj)
 
             if (!dsi_cmdreply(dsi, err)) {
                 LOG(log_error, logtype_afpd, "dsi_cmdreply(%d): %s", dsi->socket, strerror(errno) );
-                dsi->flags |= DSI_DISCONNECTED;
+                if (dsi_disconnect(dsi) != 0)
+                    afp_dsi_die(EXITERR_CLNT);
             }
             break;
 
@@ -644,7 +655,8 @@ void afp_over_dsi(AFPObj *obj)
 
             if (!dsi_wrtreply(dsi, err)) {
                 LOG(log_error, logtype_afpd, "dsi_wrtreply: %s", strerror(errno) );
-                dsi->flags |= DSI_DISCONNECTED;
+                if (dsi_disconnect(dsi) != 0)
+                    afp_dsi_die(EXITERR_CLNT);
             }
             break;
 
@@ -661,6 +673,8 @@ void afp_over_dsi(AFPObj *obj)
             break;
         }
         pending_request(dsi);
+
+        vol_fce_tm_event();
     }
 
     /* error */