s3: VFS: Modify mkdir to take a const struct smb_filename * instead of const char *
[samba.git] / source3 / modules / vfs_streams_depot.c
index 3ada92eeb5ee3417cc5b7261657341575e4c3343..38c76c1abb621dc260fded4a81cbea75a87c284d 100644 (file)
@@ -121,9 +121,11 @@ static char *stream_dir(vfs_handle_struct *handle,
        char *tmp;
        char *id_hex;
        struct file_id id;
-       uint8 id_buf[16];
+       uint8_t id_buf[16];
        bool check_valid;
        const char *rootdir;
+       struct smb_filename *rootdir_fname = NULL;
+       struct smb_filename *tmp_fname = NULL;
 
        check_valid = lp_parm_bool(SNUM(handle->conn),
                      "streams_depot", "check_valid", true);
@@ -139,6 +141,15 @@ static char *stream_dir(vfs_handle_struct *handle,
                SNUM(handle->conn), "streams_depot", "directory",
                tmp);
 
+       rootdir_fname = synthetic_smb_fname(talloc_tos(),
+                                       rootdir,
+                                       NULL,
+                                       NULL);
+       if (rootdir_fname == NULL) {
+               errno = ENOMEM;
+               goto fail;
+       }
+
        /* Stat the base file if it hasn't already been done. */
        if (base_sbuf == NULL) {
                struct smb_filename *smb_fname_base;
@@ -261,7 +272,7 @@ static char *stream_dir(vfs_handle_struct *handle,
                goto fail;
        }
 
-       if ((SMB_VFS_NEXT_MKDIR(handle, rootdir, 0755) != 0)
+       if ((SMB_VFS_NEXT_MKDIR(handle, rootdir_fname, 0755) != 0)
            && (errno != EEXIST)) {
                goto fail;
        }
@@ -272,12 +283,19 @@ static char *stream_dir(vfs_handle_struct *handle,
                goto fail;
        }
 
-       if ((SMB_VFS_NEXT_MKDIR(handle, tmp, 0755) != 0)
+       tmp_fname = synthetic_smb_fname(talloc_tos(), tmp, NULL, NULL);
+       if (tmp_fname == NULL) {
+               errno = ENOMEM;
+               goto fail;
+       }
+
+       if ((SMB_VFS_NEXT_MKDIR(handle, tmp_fname, 0755) != 0)
            && (errno != EEXIST)) {
                goto fail;
        }
 
        TALLOC_FREE(tmp);
+       TALLOC_FREE(tmp_fname);
 
        tmp = talloc_asprintf(result, "%s/%2.2X/%2.2X", rootdir, first,
                              second);
@@ -286,14 +304,22 @@ static char *stream_dir(vfs_handle_struct *handle,
                goto fail;
        }
 
-       if ((SMB_VFS_NEXT_MKDIR(handle, tmp, 0755) != 0)
+       tmp_fname = synthetic_smb_fname(talloc_tos(), tmp, NULL, NULL);
+       if (tmp_fname == NULL) {
+               errno = ENOMEM;
+               goto fail;
+       }
+
+       if ((SMB_VFS_NEXT_MKDIR(handle, tmp_fname, 0755) != 0)
            && (errno != EEXIST)) {
                goto fail;
        }
 
        TALLOC_FREE(tmp);
+       TALLOC_FREE(tmp_fname);
 
-       if ((SMB_VFS_NEXT_MKDIR(handle, result, 0755) != 0)
+       /* smb_fname_hash is the struct smb_filename version of 'result' */
+       if ((SMB_VFS_NEXT_MKDIR(handle, smb_fname_hash, 0755) != 0)
            && (errno != EEXIST)) {
                goto fail;
        }
@@ -302,10 +328,14 @@ static char *stream_dir(vfs_handle_struct *handle,
                goto fail;
        }
 
+       TALLOC_FREE(rootdir_fname);
+       TALLOC_FREE(tmp_fname);
        TALLOC_FREE(smb_fname_hash);
        return result;
 
  fail:
+       TALLOC_FREE(rootdir_fname);
+       TALLOC_FREE(tmp_fname);
        TALLOC_FREE(smb_fname_hash);
        TALLOC_FREE(result);
        return NULL;
@@ -646,7 +676,8 @@ static int streams_depot_unlink(vfs_handle_struct *handle,
                return -1;
        }
 
-       if (smb_fname_base->st.st_ex_nlink == 1) {
+       ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+       if (ret == 0) {
                char *dirname = stream_dir(handle, smb_fname_base,
                                           &smb_fname_base->st, false);
 
@@ -656,8 +687,6 @@ static int streams_depot_unlink(vfs_handle_struct *handle,
                TALLOC_FREE(dirname);
        }
 
-       ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
-
        TALLOC_FREE(smb_fname_base);
        return ret;
 }
@@ -690,7 +719,8 @@ static int streams_depot_rmdir(vfs_handle_struct *handle, const char *path)
                return -1;
        }
 
-       if (smb_fname_base->st.st_ex_nlink == 2) {
+       ret = SMB_VFS_NEXT_RMDIR(handle, path);
+       if (ret == 0) {
                char *dirname = stream_dir(handle, smb_fname_base,
                                           &smb_fname_base->st, false);
 
@@ -700,8 +730,6 @@ static int streams_depot_rmdir(vfs_handle_struct *handle, const char *path)
                TALLOC_FREE(dirname);
        }
 
-       ret = SMB_VFS_NEXT_RMDIR(handle, path);
-
        TALLOC_FREE(smb_fname_base);
        return ret;
 }
@@ -879,8 +907,19 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle,
        state.handle = handle;
        state.status = NT_STATUS_OK;
 
-       status = walk_streams(handle, smb_fname_base, NULL, collect_one_stream,
+       if (S_ISLNK(smb_fname_base->st.st_ex_mode)) {
+               /*
+                * Currently we do't have SMB_VFS_LLISTXATTR
+                * inside the VFS which means there's no way
+                * to cope with a symlink when lp_posix_pathnames().
+                * returns true. For now ignore links.
+                * FIXME - by adding SMB_VFS_LLISTXATTR. JRA.
+                */
+               status = NT_STATUS_OK;
+       } else {
+               status = walk_streams(handle, smb_fname_base, NULL, collect_one_stream,
                              &state);
+       }
 
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(state.streams);