]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/volume.c
Reset options every time a :DEFAULT: line is found in a AppleVolumes file
[netatalk.git] / etc / afpd / volume.c
index faf142c402bbe21c99029b135cfc3f23f8ed8a14..dd580cb80747bd4bfffff97829fd1b5e7817aa4c 100644 (file)
@@ -265,6 +265,7 @@ static char *volxlate(AFPObj *obj,
         } else if (is_var(p, "$c")) {
             if (afpmaster && xlatevolname)
                 return NULL;
+#ifndef NO_DDP
             if (obj->proto == AFPPROTO_ASP) {
                 ASP asp = obj->handle;
 
@@ -273,7 +274,9 @@ static char *volxlate(AFPObj *obj,
                 dest += len;
                 destlen -= len;
 
-            } else if (obj->proto == AFPPROTO_DSI) {
+            }
+#endif
+            if (obj->proto == AFPPROTO_DSI) {
                 DSI *dsi = obj->handle;
                 len = sprintf(dest, "%s:%u",
                               getip_string((struct sockaddr *)&dsi->client),
@@ -302,14 +305,16 @@ static char *volxlate(AFPObj *obj,
         } else if (is_var(p, "$i")) {
             if (afpmaster && xlatevolname)
                 return NULL;
+#ifndef NO_DDP
             if (obj->proto == AFPPROTO_ASP) {
                 ASP asp = obj->handle;
-
                 len = sprintf(dest, "%u", ntohs(asp->asp_sat.sat_addr.s_net));
                 dest += len;
                 destlen -= len;
 
-            } else if (obj->proto == AFPPROTO_DSI) {
+            }
+#endif
+            if (obj->proto == AFPPROTO_DSI) {
                 DSI *dsi = obj->handle;
                 q = getip_string((struct sockaddr *)&dsi->client);
             }
@@ -505,6 +510,8 @@ static void volset(struct vol_option *options, struct vol_option *save,
                 options[VOLOPT_FLAGS].i_value |= AFPVOL_SEARCHDB;
             else if (strcasecmp(p, "nonetids") == 0)
                 options[VOLOPT_FLAGS].i_value |= AFPVOL_NONETIDS;
+            else if (strcasecmp(p, "noacls") == 0)
+                options[VOLOPT_FLAGS].i_value &= ~AFPVOL_ACLS;
             p = strtok(NULL, ",");
         }
 
@@ -745,9 +752,10 @@ static int creatvol(AFPObj *obj, struct passwd *pwd,
     volume->v_vid = ++lastvid;
     volume->v_vid = htons(volume->v_vid);
 #ifdef HAVE_ACLS
-    if (check_vol_acl_support(volume))
-        volume->v_flags |= AFPVOL_ACLS
-;
+    if (!check_vol_acl_support(volume)) {
+        LOG(log_debug, logtype_afpd, "creatvol(\"%s\"): disabling ACL support", volume->v_path);
+        options[VOLOPT_FLAGS].i_value &= ~AFPVOL_ACLS;
+    }
 #endif
 
     /* handle options */
@@ -1181,6 +1189,7 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
     int         i;
     struct passwd   *pw;
     struct vol_option   save_options[VOLOPT_NUM];
+    struct vol_option   default_options[VOLOPT_NUM];
     struct vol_option   options[VOLOPT_NUM];
     struct stat         st;
 
@@ -1223,14 +1232,18 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
         break;
     }
 
-    memset(save_options, 0, sizeof(save_options));
+    memset(default_options, 0, sizeof(default_options));
 
     /* Enable some default options for all volumes */
-    save_options[VOLOPT_FLAGS].i_value |= AFPVOL_CACHE;
-    save_options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_AUTO;
+    default_options[VOLOPT_FLAGS].i_value |= AFPVOL_CACHE;
+#ifdef HAVE_ACLS
+    default_options[VOLOPT_FLAGS].i_value |= AFPVOL_ACLS;
+#endif
+    default_options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_AUTO;
     LOG(log_maxdebug, logtype_afpd, "readvolfile: seeding default umask: %04o",
         obj->options.umask);
-    save_options[VOLOPT_UMASK].i_value = obj->options.umask;
+    default_options[VOLOPT_UMASK].i_value = obj->options.umask;
+    memcpy(save_options, default_options, sizeof(options));
 
     LOG(log_debug, logtype_afpd, "readvolfile: \"%s\"", path);
 
@@ -1245,12 +1258,14 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
         case ':':
             /* change the default options for this file */
             if (strncmp(path, VOLOPT_DEFAULT, VOLOPT_DEFAULT_LEN) == 0) {
+                volfree(default_options, save_options);
+                memcpy(default_options, save_options, sizeof(options));
                 *tmp = '\0';
                 for (i = 0; i < VOLOPT_NUM; i++) {
                     if (parseline( sizeof( path ) - VOLOPT_DEFAULT_LEN - 1,
                                    path + VOLOPT_DEFAULT_LEN) < 0)
                         break;
-                    volset(save_options, NULL, tmp, sizeof(tmp) - 1,
+                    volset(default_options, NULL, tmp, sizeof(tmp) - 1,
                            path + VOLOPT_DEFAULT_LEN);
                 }
             }
@@ -1289,7 +1304,7 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
              * able to specify things in any order, but i don't want to
              * re-write everything. */
 
-            memcpy(options, save_options, sizeof(options));
+            memcpy(options, default_options, sizeof(options));
             *volname = '\0';
 
             /* read in up to VOLOP_NUM possible options */
@@ -1297,7 +1312,7 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
                 if (parseline( sizeof( tmp ) - 1, tmp ) < 0)
                     break;
 
-                volset(options, save_options, volname, sizeof(volname) - 1, tmp);
+                volset(options, default_options, volname, sizeof(volname) - 1, tmp);
             }
 
             /* check allow/deny lists (if not afpd master loading volumes for Zeroconf reg.):
@@ -1328,7 +1343,7 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
 
                 creatvol(obj, pwent, path, tmp, options, p2 != NULL);
             }
-            volfree(options, save_options);
+            volfree(options, default_options);
             break;
 
         case '.' :
@@ -2311,14 +2326,13 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
     }
 
     ret  = stat_vol(bitmap, volume, rbuf, rbuflen);
+
     if (ret == AFP_OK) {
+        handle_special_folders(volume);
+        savevolinfo(volume,
+                    volume->v_cnidserver ? volume->v_cnidserver : Cnid_srv,
+                    volume->v_cnidport   ? volume->v_cnidport   : Cnid_port);
 
-        if (!(volume->v_flags & AFPVOL_RO)) {
-            handle_special_folders( volume );
-            savevolinfo(volume,
-                        volume->v_cnidserver ? volume->v_cnidserver : Cnid_srv,
-                        volume->v_cnidport   ? volume->v_cnidport   : Cnid_port);
-        }
 
         /*
          * If you mount a volume twice, the second time the trash appears on
@@ -2737,13 +2751,25 @@ static int create_special_folder (const struct vol *vol, const struct _special_f
 static void handle_special_folders (const struct vol * vol)
 {
     const _special_folder *p = &special_folders[0];
+    uid_t process_uid;
 
-    if ((vol->v_flags & AFPVOL_RO))
-        return;
+    process_uid = geteuid();
+    if (process_uid) {
+        if (seteuid(0) == -1) {
+            process_uid = 0;
+        }
+    }
 
     for (; p->name != NULL; p++) {
         create_special_folder (vol, p);
     }
+
+    if (process_uid) {
+        if (seteuid(process_uid) == -1) {
+            LOG(log_error, logtype_logger, "can't seteuid back %s", strerror(errno));
+            exit(EXITERR_SYS);
+        }
+    }
 }
 
 const struct vol *getvolumes(void)