diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/configure.in | 2 | ||||
-rw-r--r-- | source3/include/smbprofile.h | 4 | ||||
-rw-r--r-- | source3/include/vfs.h | 6 | ||||
-rw-r--r-- | source3/include/vfs_macros.h | 3 | ||||
-rw-r--r-- | source3/lib/system.c | 19 | ||||
-rw-r--r-- | source3/modules/vfs_cap.c | 8 | ||||
-rw-r--r-- | source3/modules/vfs_catia.c | 12 | ||||
-rw-r--r-- | source3/modules/vfs_default.c | 14 | ||||
-rw-r--r-- | source3/modules/vfs_full_audit.c | 18 | ||||
-rw-r--r-- | source3/modules/vfs_netatalk.c | 33 |
10 files changed, 116 insertions, 3 deletions
diff --git a/source3/configure.in b/source3/configure.in index 04baf8aafb..cdf34d9fff 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1331,7 +1331,7 @@ if test x"$ac_cv_func_execl" = x"no"; then EXTRA_BIN_PROGS="$EXTRA_BIN_PROGS bin/smbrun\$(EXEEXT)" fi -AC_CHECK_FUNCS(waitpid getcwd strdup strndup strnlen strerror chown fchown chmod fchmod chroot link mknod mknod64) +AC_CHECK_FUNCS(waitpid getcwd strdup strndup strnlen strerror chown fchown lchown chmod fchmod chroot link mknod mknod64) AC_CHECK_FUNCS(strtol strtoll strtoul strtoull strtouq __strtoull) AC_CHECK_FUNCS(fstat strchr utime utimes chflags) AC_CHECK_FUNCS(getrlimit fsync memset strlcpy strlcat setpgid) diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index cc501739c1..7b04a185b4 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -144,6 +144,10 @@ enum profile_stats_values #define syscall_fchown_count __profile_stats_value(PR_VALUE_SYSCALL_FCHOWN, count) #define syscall_fchown_time __profile_stats_value(PR_VALUE_SYSCALL_FCHOWN, time) + PR_VALUE_SYSCALL_LCHOWN, +#define syscall_lchown_count __profile_stats_value(PR_VALUE_SYSCALL_LCHOWN, count) +#define syscall_lchown_time __profile_stats_value(PR_VALUE_SYSCALL_LCHOWN, time) + PR_VALUE_SYSCALL_CHDIR, #define syscall_chdir_count __profile_stats_value(PR_VALUE_SYSCALL_CHDIR, count) #define syscall_chdir_time __profile_stats_value(PR_VALUE_SYSCALL_CHDIR, time) diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 5e7048bb54..eac9eced16 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -70,7 +70,8 @@ /* Changed to version 20, use ntimes call instead of utime (greater * timestamp resolition. JRA. */ /* Changed to version21 to add chflags operation -- jpeach */ -#define SMB_VFS_INTERFACE_VERSION 21 +/* Changed to version22 to add lchown operation -- jra */ +#define SMB_VFS_INTERFACE_VERSION 22 /* to bug old modules which are trying to compile with the old functions */ @@ -145,6 +146,7 @@ typedef enum _vfs_op_type { SMB_VFS_OP_FCHMOD, SMB_VFS_OP_CHOWN, SMB_VFS_OP_FCHOWN, + SMB_VFS_OP_LCHOWN, SMB_VFS_OP_CHDIR, SMB_VFS_OP_GETWD, SMB_VFS_OP_NTIMES, @@ -271,6 +273,7 @@ struct vfs_ops { int (*fchmod)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, mode_t mode); int (*chown)(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid); int (*fchown)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uid_t uid, gid_t gid); + int (*lchown)(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid); int (*chdir)(struct vfs_handle_struct *handle, const char *path); char *(*getwd)(struct vfs_handle_struct *handle, char *buf); int (*ntimes)(struct vfs_handle_struct *handle, const char *path, const struct timespec ts[2]); @@ -395,6 +398,7 @@ struct vfs_ops { struct vfs_handle_struct *fchmod; struct vfs_handle_struct *chown; struct vfs_handle_struct *fchown; + struct vfs_handle_struct *lchown; struct vfs_handle_struct *chdir; struct vfs_handle_struct *getwd; struct vfs_handle_struct *ntimes; diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 2ff313b42c..48321ddad0 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -65,6 +65,7 @@ #define SMB_VFS_FCHMOD(fsp, fd, mode) ((fsp)->conn->vfs.ops.fchmod((fsp)->conn->vfs.handles.fchmod, (fsp), (fd), (mode))) #define SMB_VFS_CHOWN(conn, path, uid, gid) ((conn)->vfs.ops.chown((conn)->vfs.handles.chown, (path), (uid), (gid))) #define SMB_VFS_FCHOWN(fsp, fd, uid, gid) ((fsp)->conn->vfs.ops.fchown((fsp)->conn->vfs.handles.fchown, (fsp), (fd), (uid), (gid))) +#define SMB_VFS_LCHOWN(conn, path, uid, gid) ((conn)->vfs.ops.lchown((conn)->vfs.handles.lchown, (path), (uid), (gid))) #define SMB_VFS_CHDIR(conn, path) ((conn)->vfs.ops.chdir((conn)->vfs.handles.chdir, (path))) #define SMB_VFS_GETWD(conn, buf) ((conn)->vfs.ops.getwd((conn)->vfs.handles.getwd, (buf))) #define SMB_VFS_NTIMES(conn, path, ts) ((conn)->vfs.ops.ntimes((conn)->vfs.handles.ntimes, (path), (ts))) @@ -181,6 +182,7 @@ #define SMB_VFS_OPAQUE_FCHMOD(fsp, fd, mode) ((fsp)->conn->vfs_opaque.ops.fchmod((fsp)->conn->vfs_opaque.handles.fchmod, (fsp), (fd), (mode))) #define SMB_VFS_OPAQUE_CHOWN(conn, path, uid, gid) ((conn)->vfs_opaque.ops.chown((conn)->vfs_opaque.handles.chown, (path), (uid), (gid))) #define SMB_VFS_OPAQUE_FCHOWN(fsp, fd, uid, gid) ((fsp)->conn->vfs_opaque.ops.fchown((fsp)->conn->vfs_opaque.handles.fchown, (fsp), (fd), (uid), (gid))) +#define SMB_VFS_OPAQUE_LCHOWN(conn, path, uid, gid) ((conn)->vfs_opaque.ops.lchown((conn)->vfs_opaque.handles.lchown, (path), (uid), (gid))) #define SMB_VFS_OPAQUE_CHDIR(conn, path) ((conn)->vfs_opaque.ops.chdir((conn)->vfs_opaque.handles.chdir, (path))) #define SMB_VFS_OPAQUE_GETWD(conn, buf) ((conn)->vfs_opaque.ops.getwd((conn)->vfs_opaque.handles.getwd, (buf))) #define SMB_VFS_OPAQUE_NTIMES(conn, path, ts) ((conn)->vfs_opaque.ops.ntimes((conn)->vfs_opaque.handles.ntimes, (path), (ts))) @@ -298,6 +300,7 @@ #define SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode) ((handle)->vfs_next.ops.fchmod((handle)->vfs_next.handles.fchmod, (fsp), (fd), (mode))) #define SMB_VFS_NEXT_CHOWN(handle, path, uid, gid) ((handle)->vfs_next.ops.chown((handle)->vfs_next.handles.chown, (path), (uid), (gid))) #define SMB_VFS_NEXT_FCHOWN(handle, fsp, fd, uid, gid) ((handle)->vfs_next.ops.fchown((handle)->vfs_next.handles.fchown, (fsp), (fd), (uid), (gid))) +#define SMB_VFS_NEXT_LCHOWN(handle, path, uid, gid) ((handle)->vfs_next.ops.lchown((handle)->vfs_next.handles.lchown, (path), (uid), (gid))) #define SMB_VFS_NEXT_CHDIR(handle, path) ((handle)->vfs_next.ops.chdir((handle)->vfs_next.handles.chdir, (path))) #define SMB_VFS_NEXT_GETWD(handle, buf) ((handle)->vfs_next.ops.getwd((handle)->vfs_next.handles.getwd, (buf))) #define SMB_VFS_NEXT_NTIMES(handle, path, ts) ((handle)->vfs_next.ops.ntimes((handle)->vfs_next.handles.ntimes, (path), (ts))) diff --git a/source3/lib/system.c b/source3/lib/system.c index eaebc7190f..d7321501ad 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -642,6 +642,25 @@ int sys_chown(const char *fname,uid_t uid,gid_t gid) } /******************************************************************* + Wrapper for lchown. +********************************************************************/ + +int sys_lchown(const char *fname,uid_t uid,gid_t gid) +{ +#ifndef HAVE_LCHOWN + static int done; + if (!done) { + DEBUG(1,("WARNING: no lchown!\n")); + done=1; + } + errno = ENOSYS; + return -1; +#else + return(lchown(fname,uid,gid)); +#endif +} + +/******************************************************************* os/2 also doesn't have chroot ********************************************************************/ int sys_chroot(const char *dname) diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index d495ed5d14..ab99031e4d 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -123,6 +123,13 @@ static int cap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid return SMB_VFS_NEXT_CHOWN(handle, cappath, uid, gid); } +static int cap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) +{ + pstring cappath; + capencode(cappath, path); + return SMB_VFS_NEXT_LCHOWN(handle, cappath, uid, gid); +} + static int cap_chdir(vfs_handle_struct *handle, const char *path) { pstring cappath; @@ -326,6 +333,7 @@ static vfs_op_tuple cap_op_tuples[] = { {SMB_VFS_OP(cap_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, {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_lchown), SMB_VFS_OP_LCHOWN, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(cap_chdir), SMB_VFS_OP_CHDIR, 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}, diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index fe1ce830f7..d9a5cbd0f0 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -169,6 +169,16 @@ static int catia_chown(vfs_handle_struct *handle, return SMB_VFS_NEXT_CHOWN(handle, name, uid, gid); } +static int catia_lchown(vfs_handle_struct *handle, + const char *path, uid_t uid, gid_t gid) +{ + pstring name; + pstrcpy(name, path); + to_unix(name); + + return SMB_VFS_NEXT_LCHOWN(handle, name, uid, gid); +} + static int catia_chdir(vfs_handle_struct *handle, const char *path) { @@ -274,6 +284,8 @@ SMB_VFS_LAYER_TRANSPARENT}, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(catia_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(catia_lchown), SMB_VFS_OP_LCHOWN, +SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(catia_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(catia_getwd), SMB_VFS_OP_GETWD, diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 1fc03e046f..28fe4d4ea7 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -568,7 +568,7 @@ static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, return result; } -static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) +static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) { int result; @@ -593,6 +593,16 @@ static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, #endif } +static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) +{ + int result; + + START_PROFILE(syscall_lchown); + result = sys_lchown(path, uid, gid); + END_PROFILE(syscall_lchown); + return result; +} + static int vfswrap_chdir(vfs_handle_struct *handle, const char *path) { int result; @@ -1272,6 +1282,8 @@ static vfs_op_tuple vfs_default_ops[] = { SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(vfswrap_fchown), SMB_VFS_OP_FCHOWN, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_lchown), SMB_VFS_OP_LCHOWN, + SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(vfswrap_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(vfswrap_getwd), SMB_VFS_OP_GETWD, diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 62530fb09c..cd434f1951 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -147,6 +147,8 @@ static int smb_full_audit_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid); static int smb_full_audit_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid); +static int smb_full_audit_lchown(vfs_handle_struct *handle, + const char *path, uid_t uid, gid_t gid); static int smb_full_audit_chdir(vfs_handle_struct *handle, const char *path); static char *smb_full_audit_getwd(vfs_handle_struct *handle, @@ -380,6 +382,8 @@ static vfs_op_tuple audit_op_tuples[] = { SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_fchown), SMB_VFS_OP_FCHOWN, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_lchown), SMB_VFS_OP_LCHOWN, + SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_getwd), SMB_VFS_OP_GETWD, @@ -560,6 +564,7 @@ static struct { { SMB_VFS_OP_FCHMOD, "fchmod" }, { SMB_VFS_OP_CHOWN, "chown" }, { SMB_VFS_OP_FCHOWN, "fchown" }, + { SMB_VFS_OP_LCHOWN, "lchown" }, { SMB_VFS_OP_CHDIR, "chdir" }, { SMB_VFS_OP_GETWD, "getwd" }, { SMB_VFS_OP_NTIMES, "ntimes" }, @@ -1258,6 +1263,19 @@ static int smb_full_audit_fchown(vfs_handle_struct *handle, files_struct *fsp, i return result; } +static int smb_full_audit_lchown(vfs_handle_struct *handle, + const char *path, uid_t uid, gid_t gid) +{ + int result; + + result = SMB_VFS_NEXT_LCHOWN(handle, path, uid, gid); + + do_log(SMB_VFS_OP_LCHOWN, (result >= 0), handle, "%s|%ld|%ld", + path, (long int)uid, (long int)gid); + + return result; +} + static int smb_full_audit_chdir(vfs_handle_struct *handle, const char *path) { diff --git a/source3/modules/vfs_netatalk.c b/source3/modules/vfs_netatalk.c index efcc981679..6ff53760f5 100644 --- a/source3/modules/vfs_netatalk.c +++ b/source3/modules/vfs_netatalk.c @@ -375,6 +375,38 @@ exit_chown: return ret; } +static int atalk_lchown(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid) +{ + int ret = 0; + char *adbl_path = 0; + char *orig_path = 0; + SMB_STRUCT_STAT adbl_info; + SMB_STRUCT_STAT orig_info; + TALLOC_CTX *ctx; + + ret = SMB_VFS_NEXT_CHOWN(handle, path, uid, gid); + + if (!path) return ret; + + if (!(ctx = talloc_init("lchown_file"))) + return ret; + + if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path, + &adbl_info, &orig_info) != 0) + goto exit_lchown; + + if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) { + DEBUG(3, ("ATALK: %s has passed..\n", orig_path)); + goto exit_lchown; + } + + sys_lchown(adbl_path, uid, gid); + +exit_lchown: + talloc_destroy(ctx); + return ret; +} + static vfs_op_tuple atalk_ops[] = { /* Directory operations */ @@ -388,6 +420,7 @@ static vfs_op_tuple atalk_ops[] = { {SMB_VFS_OP(atalk_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(atalk_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(atalk_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(atalk_lchown), SMB_VFS_OP_LCHOWN, SMB_VFS_LAYER_TRANSPARENT}, /* Finish VFS operations definition */ |