r23105: Add lchown to the vfs layer. We need this in the POSIX code.
authorJeremy Allison <jra@samba.org>
Wed, 23 May 2007 23:55:12 +0000 (23:55 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:22:46 +0000 (12:22 -0500)
Jeremy.
(This used to be commit 932523cbb508db869b726768e86bfa8e248f768b)

12 files changed:
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/configure.in
source3/include/smbprofile.h
source3/include/vfs.h
source3/include/vfs_macros.h
source3/lib/system.c
source3/modules/vfs_cap.c
source3/modules/vfs_catia.c
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_netatalk.c

index 7103d0c27b7b3a1697d417ad820804e3d35ea817..6204ef47f4c9463464c8a192ed4d667e91e991cc 100644 (file)
@@ -206,6 +206,11 @@ static int skel_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid
        return vfswrap_fchown(NULL, fsp, fd, uid, gid);
 }
 
+static int skel_lchown(vfs_handle_struct *handle,  const char *path, uid_t uid, gid_t gid)
+{
+       return vfswrap_lchown(NULL,  path, uid, gid);
+}
+
 static int skel_chdir(vfs_handle_struct *handle,  const char *path)
 {
        return vfswrap_chdir(NULL,  path);
@@ -600,6 +605,7 @@ static vfs_op_tuple skel_op_tuples[] = {
        {SMB_VFS_OP(skel_fchmod),                       SMB_VFS_OP_FCHMOD,              SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_chown),                        SMB_VFS_OP_CHOWN,               SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_fchown),                       SMB_VFS_OP_FCHOWN,              SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(skel_lchown),                       SMB_VFS_OP_LCHOWN,              SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_chdir),                        SMB_VFS_OP_CHDIR,               SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_getwd),                        SMB_VFS_OP_GETWD,               SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_ntimes),                       SMB_VFS_OP_NTIMES,              SMB_VFS_LAYER_OPAQUE},
index 2efb3d54a78f49b3742db0feb8dd7009da4214f3..a422b7ce003320d70fb44bc716ba635b7c901f8b 100644 (file)
@@ -200,6 +200,11 @@ static int skel_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid
        return SMB_VFS_NEXT_FCHOWN(handle, fsp, fd, uid, gid);
 }
 
+static int skel_lchown(vfs_handle_struct *handle,  const char *path, uid_t uid, gid_t gid)
+{
+       return SMB_VFS_NEXT_LCHOWN(handle, path, uid, gid);
+}
+
 static int skel_chdir(vfs_handle_struct *handle,  const char *path)
 {
        return SMB_VFS_NEXT_CHDIR(handle, path);
@@ -561,6 +566,7 @@ static vfs_op_tuple skel_op_tuples[] = {
        {SMB_VFS_OP(skel_fchmod),                       SMB_VFS_OP_FCHMOD,              SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(skel_chown),                        SMB_VFS_OP_CHOWN,               SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(skel_fchown),                       SMB_VFS_OP_FCHOWN,              SMB_VFS_LAYER_TRANSPARENT},
+       {SMB_VFS_OP(skel_lchown),                       SMB_VFS_OP_LCHOWN,              SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(skel_chdir),                        SMB_VFS_OP_CHDIR,               SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(skel_getwd),                        SMB_VFS_OP_GETWD,               SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(skel_ntimes),                       SMB_VFS_OP_NTIMES,              SMB_VFS_LAYER_TRANSPARENT},
index 04baf8aafbf619878d2b1f7be6b7fb7220114a9a..cdf34d9fff2332b87b23ad368969313523373504 100644 (file)
@@ -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)
index cc501739c163ea54ee99f39bbb93063f26a7f657..7b04a185b4f720b68830234b35b93b83b36756ae 100644 (file)
@@ -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)
index 5e7048bb54cca7d44350d5b605a89263dfed1d19..eac9eced165991fa0b52dccec2930cebbc65a9a8 100644 (file)
@@ -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;
index 2ff313b42ce664c970c266700d6d3ac1f393dd55..48321ddad05a95d03195c18d9e892cb7b2e1cea6 100644 (file)
@@ -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)))
 #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)))
 #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)))
index eaebc7190f05492423e38475041b19f75cd7cf01..d7321501ad59902a2dec8391eeed749deac42b61 100644 (file)
@@ -641,6 +641,25 @@ int sys_chown(const char *fname,uid_t uid,gid_t gid)
 #endif
 }
 
+/*******************************************************************
+ 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
 ********************************************************************/
index d495ed5d1464da900af14bd536f8ebdf1d0e1741..ab99031e4d638c73935532c4f1d30b061cc65b5c 100644 (file)
@@ -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},
index fe1ce830f7b7a5bba31476f89a3e1efb8b5fbd0d..d9a5cbd0f09c3b63a2895650d8bc37c30ef8b919 100644 (file)
@@ -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)
 {
@@ -273,6 +283,8 @@ SMB_VFS_LAYER_TRANSPARENT},
         {SMB_VFS_OP(catia_chmod),                       SMB_VFS_OP_CHMOD,  
 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},
index 1fc03e046f0f9f00cc20f674aa3e5201fb4a33fc..28fe4d4ea7827aef9e40b570d741d1d054dd93f4 100644 (file)
@@ -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,
index 62530fb09cedb1d204171f2e91901aa15b09fcd5..cd434f1951fd72cf1edaa4faeeffcc0001fff136 100644 (file)
@@ -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)
 {
index efcc98167945c9e9059e192b9c7fd1196ac68299..6ff53760f573d9cf1ec5999897b07c38ba1259e2 100644 (file)
@@ -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 */