]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/auth.c
Ensure our umask is not altered by eg pam_umask
[netatalk.git] / etc / afpd / auth.c
index cd2f73f3cfb7a384df8e7dc9f0ca8154eabba3af..40d3a5ac906b7e56a1de886dedd3f52a70f68546 100644 (file)
@@ -39,8 +39,8 @@ extern void afp_get_cmdline( int *ac, char ***av );
 #include <atalk/logger.h>
 #include <atalk/server_ipc.h>
 #include <atalk/uuid.h>
+#include <atalk/globals.h>
 
-#include "globals.h"
 #include "auth.h"
 #include "uam_auth.h"
 #include "switch.h"
@@ -69,22 +69,6 @@ gid_t   *groups;
 
 int ngroups;
 
-/*
- * These numbers are scattered throughout the code.
- */
-static struct afp_versions  afp_versions[] = {
-#ifndef NO_DDP
-    { "AFPVersion 1.1", 11 },
-    { "AFPVersion 2.0", 20 },
-    { "AFPVersion 2.1", 21 },
-#endif /* ! NO_DDP */
-    { "AFP2.2", 22 },
-    { "AFPX03", 30 },
-    { "AFP3.1", 31 },
-    { "AFP3.2", 32 },
-    { "AFP3.3", 33 }
-};
-
 static struct uam_mod uam_modules = {NULL, NULL, &uam_modules, &uam_modules};
 static struct uam_obj uam_login = {"", "", 0, {{NULL, NULL, NULL, NULL }}, &uam_login,
                                    &uam_login};
@@ -94,7 +78,11 @@ static struct uam_obj uam_changepw = {"", "", 0, {{NULL, NULL, NULL, NULL}}, &ua
 static struct uam_obj *afp_uam = NULL;
 
 
-void status_versions( char *data, const ASP asp, const DSI *dsi)
+void status_versions(char *data,
+#ifndef NO_DDP
+                     const ASP asp,
+#endif
+                     const DSI *dsi)
 {
     char                *start = data;
     u_int16_t           status;
@@ -250,16 +238,29 @@ static int set_auth_switch(int expired)
     return AFP_OK;
 }
 
+#define GROUPSTR_BUFSIZE 1024
+static const char *print_groups(int ngroups, gid_t *groups)
+{
+    static char groupsstr[GROUPSTR_BUFSIZE];
+    int i;
+    char *s = groupsstr;
+
+    if (ngroups == 0)
+        return "-";
+
+    for (i = 0; (i < ngroups) && (s < &groupsstr[GROUPSTR_BUFSIZE]); i++) {
+        s += snprintf(s, &groupsstr[GROUPSTR_BUFSIZE] - s, " %u", groups[i]);
+    }
+
+    return groupsstr;
+}
+
 static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expired)
 {
 #ifdef ADMIN_GRP
     int admin = 0;
 #endif /* ADMIN_GRP */
 
-#if 0
-    set_processname("afpd");
-#endif
-
     if ( pwd->pw_uid == 0 ) {   /* don't allow root login */
         LOG(log_error, logtype_afpd, "login: root login denied!" );
         return AFPERR_NOTAUTH;
@@ -391,28 +392,7 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi
     }
 #endif /* TRU64 */
 
-    if (ngroups > 0) {
-        #define GROUPSTR_BUFSIZE 1024
-        char groupsstr[GROUPSTR_BUFSIZE];
-        char *s = groupsstr;
-        int j = GROUPSTR_BUFSIZE;
-
-        int n = snprintf(groupsstr, GROUPSTR_BUFSIZE, "%u", groups[0]);
-        j -= n;
-        s += n;
-
-        for (int i = 1; i < ngroups; i++) {
-            n = snprintf(s, j, ", %u", groups[i]);
-            if (n == j) {
-                /* Buffer full */
-                LOG(log_debug, logtype_afpd, "login: group string buffer overflow");
-                break;
-            }
-            j -= n;
-            s += n;
-        }
-        LOG(log_debug, logtype_afpd, "login: %u supplementary groups: %s", ngroups, groupsstr);
-    }
+    LOG(log_debug, logtype_afpd, "login: supplementary groups: %s", print_groups(ngroups, groups));
 
     /* There's probably a better way to do this, but for now, we just play root */
 #ifdef ADMIN_GRP
@@ -432,16 +412,21 @@ 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 );
 }
 
 /* ---------------------- */
-int afp_zzz(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
+int afp_zzz(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
 {
     uint32_t data;
     DSI *dsi = (DSI *)AFPobj->handle;
 
     *rbuflen = 0;
+    ibuf += 2;
+    ibuflen -= 2;
 
     if (ibuflen < 4)
         return AFPERR_MISC;
@@ -457,19 +442,20 @@ int afp_zzz(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbu
     if (data & AFPZZZ_EXT_WAKEUP) {
         /* wakeup request from exetended sleep */
         if (dsi->flags & DSI_EXTSLEEP) {
-            LOG(log_debug, logtype_afpd, "afp_zzz: waking up from extended sleep");
+            LOG(log_note, logtype_afpd, "afp_zzz: waking up from extended sleep");
             dsi->flags &= ~(DSI_SLEEPING | DSI_EXTSLEEP);
         }
     } else {
         /* sleep request */
         dsi->flags |= DSI_SLEEPING;
         if (data & AFPZZZ_EXT_SLEEP) {
-            LOG(log_debug, logtype_afpd, "afp_zzz: entering extended sleep");
+            LOG(log_note, logtype_afpd, "afp_zzz: entering extended sleep");
             dsi->flags |= DSI_EXTSLEEP;
         } else {
-            LOG(log_debug, logtype_afpd, "afp_zzz: entering normal sleep");
+            LOG(log_note, logtype_afpd, "afp_zzz: entering normal sleep");
         }
     }
+
     /*
      * According to AFP 3.3 spec we should not return anything,
      * but eg 10.5.8 server still returns the numbers of hours
@@ -591,7 +577,13 @@ int afp_getsession(
             if (ibuflen < idlen || idlen > (90-10)) {
                 return AFPERR_PARAM;
             }
-            ipc_child_write(obj->ipc_fd, IPC_GETSESSION, idlen+8, p);
+            if (!obj->sinfo.clientid) {
+                obj->sinfo.clientid = malloc(idlen + 8);
+                memcpy(obj->sinfo.clientid, p, idlen + 8);
+                obj->sinfo.clientid_len = idlen + 8;
+            }
+            if (ipc_child_write(obj->ipc_fd, IPC_GETSESSION, idlen+8, p) != 0)
+                return AFPERR_MISC;
             tklen = obj->sinfo.sessiontoken_len;
             token = obj->sinfo.sessiontoken;
         }
@@ -673,7 +665,7 @@ int afp_disconnect(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_,
     setitimer(ITIMER_REAL, &none, NULL);
 
     /* check for old session, possibly transfering session from here to there */
-    if (ipc_child_write(obj->ipc_fd, IPC_DISCOLDSESSION, tklen, &token) == -1)
+    if (ipc_child_write(obj->ipc_fd, IPC_DISCOLDSESSION, tklen, &token) != 0)
         goto exit;
     /* write uint16_t DSI request ID */
     if (writet(obj->ipc_fd, &dsi->header.dsi_requestID, 2, 0, 2) != 2) {
@@ -932,11 +924,15 @@ int afp_logincont(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *r
 }
 
 
-int afp_logout(AFPObj *obj, char *ibuf _U_, size_t ibuflen  _U_, char *rbuf  _U_, size_t *rbuflen  _U_)
+int afp_logout(AFPObj *obj, char *ibuf _U_, size_t ibuflen  _U_, char *rbuf  _U_, size_t *rbuflen)
 {
+    DSI *dsi = (DSI *)(obj->handle);
+
     LOG(log_note, logtype_afpd, "AFP logout by %s", obj->username);
+    of_close_all_forks();
     close_all_vol();
-    obj->exit(0);
+    dsi->flags = DSI_AFP_LOGGED_OUT;
+    *rbuflen = 0;
     return AFP_OK;
 }