Extend NTIMES to allow setting create_time
[metze/samba/wip.git] / source3 / modules / vfs_default.c
index 372cdf2d5334923457bce21542ba97e1be6a84d1..a9aabab76854ca43ee82a5ecbc21a1654bb75b72 100644 (file)
@@ -40,10 +40,10 @@ static void vfswrap_disconnect(vfs_handle_struct *handle)
 
 /* Disk operations */
 
-static SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle,  const char *path, bool small_query, SMB_BIG_UINT *bsize,
-                              SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
+static uint64_t vfswrap_disk_free(vfs_handle_struct *handle,  const char *path, bool small_query, uint64_t *bsize,
+                              uint64_t *dfree, uint64_t *dsize)
 {
-       SMB_BIG_UINT result;
+       uint64_t result;
 
        result = sys_disk_free(handle->conn, path, small_query, bsize, dfree, dsize);
        return result;
@@ -150,12 +150,17 @@ static int vfswrap_mkdir(vfs_handle_struct *handle,  const char *path, mode_t mo
 {
        int result;
        bool has_dacl = False;
+       char *parent = NULL;
 
        START_PROFILE(syscall_mkdir);
 
-       if (lp_inherit_acls(SNUM(handle->conn)) && (has_dacl = directory_has_default_acl(handle->conn, parent_dirname(path))))
+       if (lp_inherit_acls(SNUM(handle->conn))
+           && parent_dirname(talloc_tos(), path, &parent, NULL)
+           && (has_dacl = directory_has_default_acl(handle->conn, parent)))
                mode = 0777;
 
+       TALLOC_FREE(parent);
+
        result = mkdir(path, mode);
 
        if (result == 0 && !has_dacl) {
@@ -208,6 +213,32 @@ static int vfswrap_open(vfs_handle_struct *handle,  const char *fname,
        return result;
 }
 
+static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle,
+                                   struct smb_request *req,
+                                   uint16_t root_dir_fid,
+                                   const char *fname,
+                                   uint32_t create_file_flags,
+                                   uint32_t access_mask,
+                                   uint32_t share_access,
+                                   uint32_t create_disposition,
+                                   uint32_t create_options,
+                                   uint32_t file_attributes,
+                                   uint32_t oplock_request,
+                                   uint64_t allocation_size,
+                                   struct security_descriptor *sd,
+                                   struct ea_list *ea_list,
+                                   files_struct **result,
+                                   int *pinfo,
+                                   SMB_STRUCT_STAT *psbuf)
+{
+       return create_file_default(handle->conn, req, root_dir_fid, fname,
+                                  create_file_flags, access_mask, share_access,
+                                  create_disposition, create_options,
+                                  file_attributes, oplock_request,
+                                  allocation_size, sd, ea_list, result, pinfo,
+                                  psbuf);
+}
+
 static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp)
 {
        int result;
@@ -596,7 +627,7 @@ static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid,
        int result;
 
        START_PROFILE(syscall_chown);
-       result = sys_chown(path, uid, gid);
+       result = chown(path, uid, gid);
        END_PROFILE(syscall_chown);
        return result;
 }
@@ -621,7 +652,7 @@ static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid
        int result;
 
        START_PROFILE(syscall_lchown);
-       result = sys_lchown(path, uid, gid);
+       result = lchown(path, uid, gid);
        END_PROFILE(syscall_lchown);
        return result;
 }
@@ -651,25 +682,26 @@ static char *vfswrap_getwd(vfs_handle_struct *handle,  char *path)
  system will support.
 **********************************************************************/
 
-static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2])
+static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path,
+                         struct smb_file_time *ft)
 {
        int result;
 
        START_PROFILE(syscall_ntimes);
 #if defined(HAVE_UTIMES)
-       if (ts != NULL) {
+       if (ft != NULL) {
                struct timeval tv[2];
-               tv[0] = convert_timespec_to_timeval(ts[0]);
-               tv[1] = convert_timespec_to_timeval(ts[1]);
+               tv[0] = convert_timespec_to_timeval(ft->atime);
+               tv[1] = convert_timespec_to_timeval(ft->mtime);
                result = utimes(path, tv);
        } else {
                result = utimes(path, NULL);
        }
 #elif defined(HAVE_UTIME)
-       if (ts != NULL) {
+       if (ft != NULL) {
                struct utimbuf times;
-               times.actime = convert_timespec_to_time_t(ts[0]);
-               times.modtime = convert_timespec_to_time_t(ts[1]);
+               times.actime = convert_timespec_to_time_t(ft->atime);
+               times.modtime = convert_timespec_to_time_t(ft->mtime);
                result = utime(path, times);
        } else {
                result = utime(path, NULL);
@@ -714,6 +746,20 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
        if (st.st_size > len)
                return sys_ftruncate(fsp->fh->fd, len);
 
+       /* available disk space is enough or not? */
+       if (lp_strict_allocate(SNUM(fsp->conn))){
+               uint64_t space_avail;
+               uint64_t bsize,dfree,dsize;
+
+               space_avail = get_dfree_info(fsp->conn,fsp->fsp_name,false,&bsize,&dfree,&dsize);
+               /* space_avail is 1k blocks */
+               if (space_avail == (uint64_t)-1 ||
+                               ((uint64_t)space_to_write/1024 > space_avail) ) {
+                       errno = ENOSPC;
+                       return -1;
+               }
+       }
+
        /* Write out the real space on disk. */
        if (SMB_VFS_LSEEK(fsp, st.st_size, SEEK_SET) != st.st_size)
                return -1;
@@ -869,7 +915,7 @@ static int vfswrap_symlink(vfs_handle_struct *handle,  const char *oldpath, cons
        int result;
 
        START_PROFILE(syscall_symlink);
-       result = sys_symlink(oldpath, newpath);
+       result = symlink(oldpath, newpath);
        END_PROFILE(syscall_symlink);
        return result;
 }
@@ -879,7 +925,7 @@ static int vfswrap_readlink(vfs_handle_struct *handle,  const char *path, char *
        int result;
 
        START_PROFILE(syscall_readlink);
-       result = sys_readlink(path, buf, bufsiz);
+       result = readlink(path, buf, bufsiz);
        END_PROFILE(syscall_readlink);
        return result;
 }
@@ -889,7 +935,7 @@ static int vfswrap_link(vfs_handle_struct *handle,  const char *oldpath, const c
        int result;
 
        START_PROFILE(syscall_link);
-       result = sys_link(oldpath, newpath);
+       result = link(oldpath, newpath);
        END_PROFILE(syscall_link);
        return result;
 }
@@ -909,7 +955,7 @@ static char *vfswrap_realpath(vfs_handle_struct *handle,  const char *path, char
        char *result;
 
        START_PROFILE(syscall_realpath);
-       result = sys_realpath(path, resolved_path);
+       result = realpath(path, resolved_path);
        END_PROFILE(syscall_realpath);
        return result;
 }
@@ -1012,6 +1058,16 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
        return NT_STATUS_OK;
 }
 
+static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
+                                    const char *path,
+                                    const char *name,
+                                    TALLOC_CTX *mem_ctx,
+                                    char **found_name)
+{
+       return get_real_filename(handle->conn, path, name, mem_ctx,
+                                found_name);
+}
+
 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
                                    files_struct *fsp,
                                    uint32 security_info, SEC_DESC **ppdesc)
@@ -1359,6 +1415,8 @@ static vfs_op_tuple vfs_default_ops[] = {
 
        {SMB_VFS_OP(vfswrap_open),      SMB_VFS_OP_OPEN,
         SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_create_file),       SMB_VFS_OP_CREATE_FILE,
+        SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_close),     SMB_VFS_OP_CLOSE,
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_read),      SMB_VFS_OP_READ,
@@ -1431,6 +1489,8 @@ static vfs_op_tuple vfs_default_ops[] = {
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_streaminfo),        SMB_VFS_OP_STREAMINFO,
         SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_get_real_filename), SMB_VFS_OP_GET_REAL_FILENAME,
+        SMB_VFS_LAYER_OPAQUE},
 
        /* NT ACL operations. */