diff options
Diffstat (limited to 'source/modules')
-rw-r--r-- | source/modules/nfs4_acls.c | 50 | ||||
-rw-r--r-- | source/modules/vfs_cap.c | 6 | ||||
-rw-r--r-- | source/modules/vfs_catia.c | 8 | ||||
-rw-r--r-- | source/modules/vfs_default.c | 46 | ||||
-rw-r--r-- | source/modules/vfs_full_audit.c | 60 | ||||
-rw-r--r-- | source/modules/vfs_netatalk.c | 8 | ||||
-rw-r--r-- | source/modules/vfs_recycle.c | 39 |
7 files changed, 156 insertions, 61 deletions
diff --git a/source/modules/nfs4_acls.c b/source/modules/nfs4_acls.c index 91ebba1f588..dd452408579 100644 --- a/source/modules/nfs4_acls.c +++ b/source/modules/nfs4_acls.c @@ -604,31 +604,33 @@ BOOL smb_set_nt_acl_nfs4(files_struct *fsp, if (smbacl4_GetFileOwner(fsp, &sbuf)) return False; - /* chown logic is a copy/paste from posix_acl.c:set_nt_acl */ - if (!unpack_nt_owners(SNUM(fsp->conn), &newUID, &newGID, security_info_sent, psd)) - { - DEBUG(8, ("unpack_nt_owners failed")); - return False; - } - if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) || - ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) { - need_chown = True; - } - if (need_chown) { - if ((newUID == (uid_t)-1 || newUID == current_user.ut.uid)) { - if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) { - DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, strerror(errno) )); - return False; + if (params.do_chown) { + /* chown logic is a copy/paste from posix_acl.c:set_nt_acl */ + if (!unpack_nt_owners(SNUM(fsp->conn), &newUID, &newGID, security_info_sent, psd)) + { + DEBUG(8, ("unpack_nt_owners failed")); + return False; + } + if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) || + ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) { + need_chown = True; + } + if (need_chown) { + if ((newUID == (uid_t)-1 || newUID == current_user.ut.uid)) { + if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) { + DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n", + fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, strerror(errno) )); + return False; + } + DEBUG(10,("chown %s, %u, %u succeeded.\n", + fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); + if (smbacl4_GetFileOwner(fsp, &sbuf)) + return False; + need_chown = False; + } else { /* chown is needed, but _after_ changing acl */ + sbuf.st_uid = newUID; /* OWNER@ in case of e_special */ + sbuf.st_gid = newGID; /* GROUP@ in case of e_special */ } - DEBUG(10,("chown %s, %u, %u succeeded.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); - if (smbacl4_GetFileOwner(fsp, &sbuf)) - return False; - need_chown = False; - } else { /* chown is needed, but _after_ changing acl */ - sbuf.st_uid = newUID; /* OWNER@ in case of e_special */ - sbuf.st_gid = newGID; /* GROUP@ in case of e_special */ } } diff --git a/source/modules/vfs_cap.c b/source/modules/vfs_cap.c index e058c9660c7..f89e149d0eb 100644 --- a/source/modules/vfs_cap.c +++ b/source/modules/vfs_cap.c @@ -131,11 +131,11 @@ static int cap_chdir(vfs_handle_struct *handle, const char *path) return SMB_VFS_NEXT_CHDIR(handle, cappath); } -static int cap_utime(vfs_handle_struct *handle, const char *path, struct utimbuf *times) +static int cap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2]) { pstring cappath; capencode(cappath, path); - return SMB_VFS_NEXT_UTIME(handle, cappath, times); + return SMB_VFS_NEXT_NTIMES(handle, cappath, ts); } @@ -327,7 +327,7 @@ static vfs_op_tuple cap_op_tuples[] = { {SMB_VFS_OP(cap_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(cap_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(cap_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_TRANSPARENT}, - {SMB_VFS_OP(cap_utime), SMB_VFS_OP_UTIME, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(cap_ntimes), SMB_VFS_OP_NTIMES, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(cap_symlink), SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(cap_readlink), SMB_VFS_OP_READLINK, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(cap_link), SMB_VFS_OP_LINK, SMB_VFS_LAYER_TRANSPARENT}, diff --git a/source/modules/vfs_catia.c b/source/modules/vfs_catia.c index 478dab6cbed..fe1ce830f7b 100644 --- a/source/modules/vfs_catia.c +++ b/source/modules/vfs_catia.c @@ -184,10 +184,10 @@ static char *catia_getwd(vfs_handle_struct *handle, char *buf) return SMB_VFS_NEXT_GETWD(handle, buf); } -static int catia_utime(vfs_handle_struct *handle, - const char *path, struct utimbuf *times) +static int catia_ntimes(vfs_handle_struct *handle, + const char *path, const struct timespec ts[2]) { - return SMB_VFS_NEXT_UTIME(handle, path, times); + return SMB_VFS_NEXT_NTIMES(handle, path, ts); } static BOOL catia_symlink(vfs_handle_struct *handle, @@ -278,7 +278,7 @@ SMB_VFS_LAYER_TRANSPARENT}, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(catia_getwd), SMB_VFS_OP_GETWD, SMB_VFS_LAYER_TRANSPARENT}, - {SMB_VFS_OP(catia_utime), SMB_VFS_OP_UTIME, + {SMB_VFS_OP(catia_ntimes), SMB_VFS_OP_NTIMES, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(catia_symlink), SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_TRANSPARENT}, diff --git a/source/modules/vfs_default.c b/source/modules/vfs_default.c index bd7bea5258a..4febc064d94 100644 --- a/source/modules/vfs_default.c +++ b/source/modules/vfs_default.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. Wrap disk only vfs functions to sidestep dodgy compilers. Copyright (C) Tim Potter 1998 + Copyright (C) Jeremy Allison 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -612,13 +613,35 @@ static char *vfswrap_getwd(vfs_handle_struct *handle, char *path) return result; } -static int vfswrap_utime(vfs_handle_struct *handle, const char *path, struct utimbuf *times) +/********************************************************************* + nsec timestamp resolution call. Convert down to whatever the underlying + system will support. +**********************************************************************/ + +static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2]) { int result; - START_PROFILE(syscall_utime); - result = utime(path, times); - END_PROFILE(syscall_utime); + START_PROFILE(syscall_ntimes); +#if defined(HAVE_UTIMES) + { + struct timeval tv[2]; + tv[0] = convert_timespec_to_timeval(ts[0]); + tv[1] = convert_timespec_to_timeval(ts[1]); + result = utimes(path, tv); + } +#elif defined(HAVE_UTIME) + { + struct utimebuf times; + times.actime = convert_timespec_to_time_t(ts[0]); + times.modtime = convert_timespec_to_time_t(ts[1]); + result = utime(path, times); + } +#else + errno = ENOSYS; + result = -1; +#endif + END_PROFILE(syscall_ntimes); return result; } @@ -786,7 +809,7 @@ static BOOL vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp, int fd, int leasetype) { - int result; + int result = -1; START_PROFILE(syscall_linux_setlease); @@ -796,7 +819,8 @@ static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp, return -1; result = linux_setlease(fd, leasetype); - +#else + errno = ENOSYS; #endif END_PROFILE(syscall_linux_setlease); return result; @@ -879,6 +903,12 @@ static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle, return NT_STATUS_OK; } +static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flags) +{ + errno = ENOSYS; + return -1; +} + static size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc) { size_t result; @@ -1238,7 +1268,7 @@ static vfs_op_tuple vfs_default_ops[] = { SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(vfswrap_getwd), SMB_VFS_OP_GETWD, SMB_VFS_LAYER_OPAQUE}, - {SMB_VFS_OP(vfswrap_utime), SMB_VFS_OP_UTIME, + {SMB_VFS_OP(vfswrap_ntimes), SMB_VFS_OP_NTIMES, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(vfswrap_ftruncate), SMB_VFS_OP_FTRUNCATE, SMB_VFS_LAYER_OPAQUE}, @@ -1262,6 +1292,8 @@ static vfs_op_tuple vfs_default_ops[] = { SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(vfswrap_notify_watch), SMB_VFS_OP_NOTIFY_WATCH, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_chflags), SMB_VFS_OP_CHFLAGS, + SMB_VFS_LAYER_OPAQUE}, /* NT ACL operations. */ diff --git a/source/modules/vfs_full_audit.c b/source/modules/vfs_full_audit.c index 6036e49fc15..62530fb09ce 100644 --- a/source/modules/vfs_full_audit.c +++ b/source/modules/vfs_full_audit.c @@ -151,8 +151,8 @@ static int smb_full_audit_chdir(vfs_handle_struct *handle, const char *path); static char *smb_full_audit_getwd(vfs_handle_struct *handle, char *path); -static int smb_full_audit_utime(vfs_handle_struct *handle, - const char *path, struct utimbuf *times); +static int smb_full_audit_ntimes(vfs_handle_struct *handle, + const char *path, const struct timespec ts[2]); static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len); static BOOL smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, @@ -174,6 +174,15 @@ static int smb_full_audit_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev); static char *smb_full_audit_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path); +static NTSTATUS smb_full_audit_notify_watch(struct vfs_handle_struct *handle, + struct sys_notify_context *ctx, + struct notify_entry *e, + void (*callback)(struct sys_notify_context *ctx, + void *private_data, + struct notify_event *ev), + void *private_data, void *handle_p); +static int smb_full_audit_chflags(vfs_handle_struct *handle, + const char *path, uint flags); static size_t smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc); @@ -375,7 +384,7 @@ static vfs_op_tuple audit_op_tuples[] = { SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_getwd), SMB_VFS_OP_GETWD, SMB_VFS_LAYER_LOGGER}, - {SMB_VFS_OP(smb_full_audit_utime), SMB_VFS_OP_UTIME, + {SMB_VFS_OP(smb_full_audit_ntimes), SMB_VFS_OP_NTIMES, SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_ftruncate), SMB_VFS_OP_FTRUNCATE, SMB_VFS_LAYER_LOGGER}, @@ -397,6 +406,10 @@ static vfs_op_tuple audit_op_tuples[] = { SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_realpath), SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_notify_watch),SMB_VFS_OP_NOTIFY_WATCH, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_chflags), SMB_VFS_OP_CHFLAGS, + SMB_VFS_LAYER_LOGGER}, /* NT ACL operations. */ @@ -549,7 +562,7 @@ static struct { { SMB_VFS_OP_FCHOWN, "fchown" }, { SMB_VFS_OP_CHDIR, "chdir" }, { SMB_VFS_OP_GETWD, "getwd" }, - { SMB_VFS_OP_UTIME, "utime" }, + { SMB_VFS_OP_NTIMES, "ntimes" }, { SMB_VFS_OP_FTRUNCATE, "ftruncate" }, { SMB_VFS_OP_LOCK, "lock" }, { SMB_VFS_OP_KERNEL_FLOCK, "kernel_flock" }, @@ -560,6 +573,8 @@ static struct { { SMB_VFS_OP_LINK, "link" }, { SMB_VFS_OP_MKNOD, "mknod" }, { SMB_VFS_OP_REALPATH, "realpath" }, + { SMB_VFS_OP_NOTIFY_WATCH, "notify_watch" }, + { SMB_VFS_OP_CHFLAGS, "chflags" }, { SMB_VFS_OP_FGET_NT_ACL, "fget_nt_acl" }, { SMB_VFS_OP_GET_NT_ACL, "get_nt_acl" }, { SMB_VFS_OP_FSET_NT_ACL, "fset_nt_acl" }, @@ -1267,14 +1282,14 @@ static char *smb_full_audit_getwd(vfs_handle_struct *handle, return result; } -static int smb_full_audit_utime(vfs_handle_struct *handle, - const char *path, struct utimbuf *times) +static int smb_full_audit_ntimes(vfs_handle_struct *handle, + const char *path, const struct timespec ts[2]) { int result; - result = SMB_VFS_NEXT_UTIME(handle, path, times); + result = SMB_VFS_NEXT_NTIMES(handle, path, ts); - do_log(SMB_VFS_OP_UTIME, (result >= 0), handle, "%s", path); + do_log(SMB_VFS_OP_NTIMES, (result >= 0), handle, "%s", path); return result; } @@ -1405,6 +1420,35 @@ static char *smb_full_audit_realpath(vfs_handle_struct *handle, return result; } +static NTSTATUS smb_full_audit_notify_watch(struct vfs_handle_struct *handle, + struct sys_notify_context *ctx, + struct notify_entry *e, + void (*callback)(struct sys_notify_context *ctx, + void *private_data, + struct notify_event *ev), + void *private_data, void *handle_p) +{ + NTSTATUS result; + + result = SMB_VFS_NEXT_NOTIFY_WATCH(handle, ctx, e, callback, private_data, handle_p); + + do_log(SMB_VFS_OP_NOTIFY_WATCH, NT_STATUS_IS_OK(result), handle, ""); + + return result; +} + +static int smb_full_audit_chflags(vfs_handle_struct *handle, + const char *path, uint flags) +{ + int result; + + result = SMB_VFS_NEXT_CHFLAGS(handle, path, flags); + + do_log(SMB_VFS_OP_CHFLAGS, (result != 0), handle, "%s", path); + + return result; +} + static size_t smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc) diff --git a/source/modules/vfs_netatalk.c b/source/modules/vfs_netatalk.c index 7176919a7dc..efcc9816794 100644 --- a/source/modules/vfs_netatalk.c +++ b/source/modules/vfs_netatalk.c @@ -241,7 +241,7 @@ static int atalk_rename(struct vfs_handle_struct *handle, const char *oldname, c if (atalk_build_paths(ctx, handle->conn->origpath, oldname, &adbl_path, &orig_path, &adbl_info, &orig_info) != 0) - return ret; + goto exit_rename; if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) { DEBUG(3, ("ATALK: %s has passed..\n", adbl_path)); @@ -297,7 +297,7 @@ static int atalk_unlink(struct vfs_handle_struct *handle, const char *path) if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path, &adbl_info, &orig_info) != 0) - return ret; + goto exit_unlink; if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) { DEBUG(3, ("ATALK: %s has passed..\n", adbl_path)); @@ -329,7 +329,7 @@ static int atalk_chmod(struct vfs_handle_struct *handle, const char *path, mode_ if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path, &adbl_info, &orig_info) != 0) - return ret; + goto exit_chmod; if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) { DEBUG(3, ("ATALK: %s has passed..\n", orig_path)); @@ -361,7 +361,7 @@ static int atalk_chown(struct vfs_handle_struct *handle, const char *path, uid_t if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path, &adbl_info, &orig_info) != 0) - return ret; + goto exit_chown; if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) { DEBUG(3, ("ATALK: %s has passed..\n", orig_path)); diff --git a/source/modules/vfs_recycle.c b/source/modules/vfs_recycle.c index 121454315fb..579cc94cf94 100644 --- a/source/modules/vfs_recycle.c +++ b/source/modules/vfs_recycle.c @@ -153,17 +153,30 @@ static const char **recycle_noversions(vfs_handle_struct *handle) return tmp_lp; } -static int recycle_maxsize(vfs_handle_struct *handle) +static SMB_OFF_T recycle_maxsize(vfs_handle_struct *handle) { - int maxsize; + SMB_OFF_T maxsize; - maxsize = lp_parm_int(SNUM(handle->conn), "recycle", "maxsize", -1); + maxsize = conv_str_size(lp_parm_const_string(SNUM(handle->conn), + "recycle", "maxsize", NULL)); - DEBUG(10, ("recycle: maxsize = %d\n", maxsize)); + DEBUG(10, ("recycle: maxsize = %lu\n", (long unsigned int)maxsize)); return maxsize; } +static SMB_OFF_T recycle_minsize(vfs_handle_struct *handle) +{ + SMB_OFF_T minsize; + + minsize = conv_str_size(lp_parm_const_string(SNUM(handle->conn), + "recycle", "minsize", NULL)); + + DEBUG(10, ("recycle: minsize = %lu\n", (long unsigned int)minsize)); + + return minsize; +} + static mode_t recycle_directory_mode(vfs_handle_struct *handle) { int dirmode; @@ -351,18 +364,16 @@ static BOOL matchparam(const char **haystack_list, const char *needle) static void recycle_do_touch(vfs_handle_struct *handle, const char *fname, BOOL touch_mtime) { SMB_STRUCT_STAT st; - struct utimbuf tb; - time_t currtime; + struct timespec ts[2]; if (SMB_VFS_NEXT_STAT(handle, fname, &st) != 0) { DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno))); return; } - currtime = time(&currtime); - tb.actime = currtime; - tb.modtime = touch_mtime ? currtime : st.st_mtime; + ts[0] = timespec_current(); /* atime */ + ts[1] = touch_mtime ? ts[0] : get_mtimespec(&st); /* mtime */ - if (SMB_VFS_NEXT_UTIME(handle, fname, &tb) == -1 ) { + if (SMB_VFS_NEXT_NTIMES(handle, fname, ts) == -1 ) { DEBUG(0, ("recycle: touching %s failed, reason = %s\n", fname, strerror(errno))); } } @@ -381,7 +392,7 @@ static int recycle_unlink(vfs_handle_struct *handle, const char *file_name) const char *base; char *repository = NULL; int i = 1; - int maxsize; + SMB_OFF_T maxsize, minsize; SMB_OFF_T file_size; /* space_avail; */ BOOL exist; int rc = -1; @@ -431,6 +442,12 @@ static int recycle_unlink(vfs_handle_struct *handle, const char *file_name) rc = SMB_VFS_NEXT_UNLINK(handle, file_name); goto done; } + minsize = recycle_minsize(handle); + if(minsize > 0 && file_size < minsize) { + DEBUG(3, ("recycle: File %s lowers minimum recycle size, purging... \n", file_name)); + rc = SMB_VFS_NEXT_UNLINK(handle, file_name); + goto done; + } /* FIXME: this is wrong: moving files with rename does not change the disk space * allocation |