vfs_fruit: in fruit_rmdir() check ._ files before deleting them
authorRalph Boehme <slow@samba.org>
Fri, 9 Dec 2016 17:24:40 +0000 (18:24 +0100)
committerUri Simchoni <uri@samba.org>
Wed, 1 Mar 2017 23:32:21 +0000 (00:32 +0100)
This ensures we only delete valid AppleDouble files whose names begin
with "._", not just *any* file that matches "^._*".

Also use proper VFS functions instead of direclty calling the C library
functions.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12427

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Uri Simchoni <uri@samba.org>
source3/modules/vfs_fruit.c

index c479c2c1e2f9a4102e2c97fd31cc646cdce95985..070ff728425fc3f1c91d58e0575305d3fb73b965 100644 (file)
@@ -3109,7 +3109,6 @@ static int fruit_rmdir(struct vfs_handle_struct *handle,
        DIR *dh = NULL;
        struct dirent *de;
        struct fruit_config_data *config;
-       const char *path = smb_fname->base_name;
 
        SMB_VFS_HANDLE_GET_DATA(handle, config,
                                struct fruit_config_data, return -1);
@@ -3122,24 +3121,58 @@ static int fruit_rmdir(struct vfs_handle_struct *handle,
         * Due to there is no way to change bDeleteVetoFiles variable
         * from this module, need to clean up ourselves
         */
-       dh = opendir(path);
+
+       dh = SMB_VFS_OPENDIR(handle->conn, smb_fname, NULL, 0);
        if (dh == NULL) {
                goto exit_rmdir;
        }
 
-       while ((de = readdir(dh)) != NULL) {
-               if ((strncmp(de->d_name,
-                            ADOUBLE_NAME_PREFIX,
-                            strlen(ADOUBLE_NAME_PREFIX))) == 0) {
-                       char *p = talloc_asprintf(talloc_tos(),
-                                                 "%s/%s",
-                                                 path, de->d_name);
-                       if (p == NULL) {
-                               goto exit_rmdir;
-                       }
-                       DEBUG(10, ("fruit_rmdir: delete %s\n", p));
-                       (void)unlink(p);
+       while ((de = SMB_VFS_READDIR(handle->conn, dh, NULL)) != NULL) {
+               int match;
+               struct adouble *ad = NULL;
+               char *p = NULL;
+               struct smb_filename *ad_smb_fname = NULL;
+               int ret;
+
+               match = strncmp(de->d_name,
+                               ADOUBLE_NAME_PREFIX,
+                               strlen(ADOUBLE_NAME_PREFIX));
+               if (match != 0) {
+                       continue;
+               }
+
+               p = talloc_asprintf(talloc_tos(), "%s/%s",
+                                   smb_fname->base_name, de->d_name);
+               if (p == NULL) {
+                       DBG_ERR("talloc_asprintf failed\n");
+                       return -1;
+               }
+
+               /*
+                * Check whether it's a valid AppleDouble file, if
+                * yes, delete it, ignore it otherwise.
+                */
+               ad = ad_get(talloc_tos(), handle, p, ADOUBLE_RSRC);
+               if (ad == NULL) {
                        TALLOC_FREE(p);
+                       continue;
+               }
+               TALLOC_FREE(ad);
+
+               ad_smb_fname = synthetic_smb_fname(talloc_tos(), p,
+                                                   NULL, NULL,
+                                                   smb_fname->flags);
+               TALLOC_FREE(p);
+               if (ad_smb_fname == NULL) {
+                       DBG_ERR("synthetic_smb_fname failed\n");
+                       return -1;
+               }
+
+               ret = SMB_VFS_NEXT_UNLINK(handle, ad_smb_fname);
+               TALLOC_FREE(ad_smb_fname);
+               if (ret != 0) {
+                       DBG_ERR("Deleting [%s] failed\n",
+                               smb_fname_str_dbg(ad_smb_fname));
                }
        }