Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Jul 2008 09:44:13 GMT
From:      Alexander Zagrebin <alexz@visp.ru>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   ports/125739: net/samba3: After changing of dos attributes stored in extended attributes, file modification time is also changing
Message-ID:  <200807180944.m6I9iDdb062608@www.freebsd.org>
Resent-Message-ID: <200807180950.m6I9o2S7036908@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         125739
>Category:       ports
>Synopsis:       net/samba3: After changing of dos attributes stored in extended attributes, file modification time is also changing
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jul 18 09:50:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Alexander Zagrebin
>Release:        7.0-RELEASE-p1
>Organization:
>Environment:
FreeBSD <hidden> 7.0-RELEASE-p1 FreeBSD 7.0-RELEASE-p1 #0: Mon Jun 23 16:07:06 MSD 2008     root@<hidden>:/usr/src/sys/i386/compile/KERNEL  i386
>Description:
I'm using extended attributes for storing dos attributes on samba's shares.
So smb.conf contains:
store dos attributes = yes
map system = no
map hidden = no
map archive = no
map read only = no

I have noticed, that after change of dos attribute of a file its modification time is changing also. This isn't a dos/windows behavior.
It seems the reason is in extattr_set_<...>, which changes the file's modification time on setting extending attribute.
>How-To-Repeat:
1. Add "store dos attributes = yes" to /usr/local/etc/smb.conf
2. Select an any file on samba share
3. Look at the modification time of this file
4. Change any dos attribute (readonly, archive, hidden, system) of this file
5. Look at the file modification time again
>Fix:
Samba may use an extended attributes for storing dos attributes, acl inheritance flag, and so on. So i wrote the patch for lib/system.c instead smbd/dosmode.c.
This patch stores file's access and modification times before extattr_set_...
and restores its after.
See the attached file

Patch attached with submission follows:

--- lib/system.c.orig	2008-07-03 10:16:55.000000000 +0400
+++ lib/system.c	2008-07-18 11:18:58.000000000 +0400
@@ -2250,7 +2250,22 @@
 			}
 		}
 	}
-	retval = extattr_set_file(path, attrnamespace, attrname, value, size);
+	{
+	    int             rv;
+	    SMB_STRUCT_STAT st;
+	    struct timeval  tv[2];
+	    
+	    if (rv = sys_stat(path, &st))
+		DEBUG(1, ("sys_setxattr: sys_stat on %s failed (%s)\n", path, strerror(errno)));
+	    retval = extattr_set_file(path, attrnamespace, attrname, value, size);
+	    if (!rv && retval != -1)
+	    {
+		TIMESPEC_TO_TIMEVAL(&tv[0], &st.st_atimespec);
+		TIMESPEC_TO_TIMEVAL(&tv[1], &st.st_mtimespec);
+		if (utimes(path, tv))
+		    DEBUG(1, ("sys_setxattr: utimes on %s failed (%s)\n", path, strerror(errno)));
+	    }
+	}
 	return (retval < 0) ? -1 : 0;
 #elif defined(HAVE_ATTR_SET)
 	int myflags = 0;
@@ -2314,7 +2329,22 @@
 		}
 	}
 
-	retval = extattr_set_link(path, attrnamespace, attrname, value, size);
+	{
+	    int             rv;
+	    SMB_STRUCT_STAT st;
+	    struct timeval  tv[2];
+	    
+	    if (rv = sys_lstat(path, &st))
+		DEBUG(1, ("sys_lsetxattr: sys_lstat on %s failed (%s)\n", path, strerror(errno)));
+	    retval = extattr_set_link(path, attrnamespace, attrname, value, size);
+	    if (!rv && retval != -1)
+	    {
+		TIMESPEC_TO_TIMEVAL(&tv[0], &st.st_atimespec);
+		TIMESPEC_TO_TIMEVAL(&tv[1], &st.st_mtimespec);
+		if (lutimes(path, tv))
+		    DEBUG(1, ("sys_lsetxattr: lutimes on %s failed (%s)\n", path, strerror(errno)));
+	    }
+	}
 	return (retval < 0) ? -1 : 0;
 #elif defined(HAVE_ATTR_SET)
 	int myflags = ATTR_DONTFOLLOW;
@@ -2379,7 +2409,22 @@
 			}
 		}
 	}
-	retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
+	{
+	    int             rv;
+	    SMB_STRUCT_STAT st;
+	    struct timeval  tv[2];
+	    
+	    if (rv = sys_fstat(filedes, &st))
+		DEBUG(1, ("sys_fsetxattr: sys_fstat on fd %i failed (%s)\n", filedes, strerror(errno)));
+	    retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
+	    if (!rv && retval != -1)
+	    {
+		TIMESPEC_TO_TIMEVAL(&tv[0], &st.st_atimespec);
+		TIMESPEC_TO_TIMEVAL(&tv[1], &st.st_mtimespec);
+		if (futimes(filedes, tv))
+		    DEBUG(1, ("sys_fsetxattr: futimes on fd %i failed (%s)\n", filedes, strerror(errno)));
+	    }
+	}
 	return (retval < 0) ? -1 : 0;
 #elif defined(HAVE_ATTR_SETF)
 	int myflags = 0;


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807180944.m6I9iDdb062608>