VFS examples

Christian Jaeger christian.jaeger at sl.ethz.ch
Thu Dec 6 01:02:08 GMT 2001


At 11:12 Uhr +0000 02.11.2001, smh at sophos.com wrote:
>Alternatively you could try this patch to Samba-2.2.2
>Let me know if it works, skel.c won't quite work with the patch but audit.c
>will

Thanks for the patch.

audit.c works, I've also worked with skel.c (basically changed skel.c 
to "audit" all functions) but I'm now getting strange results. What I 
wanted to do (just for testing) is mirror the real filesystem for the 
most part (use default ops for most operations), but let every file 
virtually "contain" the same string, some "hello world", instead of 
the original. By returning a smaller number from my_read than n, the 
client doesn't finish reading - it will retrieve as many bytes as are 
in the original file, which are \0 bytes after my "Hallo Welt\n". So 
I thought that somehow samba or the client reads the real file length 
first and tried to fake this, too, by changing my_stat and my_fstat, 
but surprisingly these changes are not honoured (details see below).

Is this a problem with samba2.2.2/the patch, or is there any other explanation?


<snippet of my modified skel.c>

const char hellotext[]= "Hallo Welt\n";

ssize_t my_read(struct files_struct *fsp, int fd, void *data, size_t n)
{
     syslog(SYSLOG_PRIORITY, "faking read(fd=%i, n=%i)\n", fd, n);
     strncpy(data, hellotext, sizeof(hellotext));
     return sizeof(hellotext); // is not honoured as expected,
                         // thus I want to fake the length in stat, too
}


static int fakestat (int rv, SMB_STRUCT_STAT *sbuf)
{
     if (sbuf->st_mode & 16384) {
         syslog(SYSLOG_PRIORITY, "  (is a directory)\n");
     } else if (sbuf->st_mode & 32768) {
         syslog(SYSLOG_PRIORITY, "  (is a file, FAKING SIZE)\n");
         sbuf->st_size= sizeof(hellotext);
     } else {
         syslog(SYSLOG_PRIORITY, "  (is not file nor directory??)\n");
     }
     sbuf->st_uid=0;
     sbuf->st_mtime= sbuf->st_atime= sbuf->st_ctime= 365*24*60*60 *10;
     return rv;
}

int my_stat(struct connection_struct *conn, char *fname, SMB_STRUCT_STAT *sbuf)
{
     syslog(SYSLOG_PRIORITY, "stat(.., fname=%s, ..)\n",fname);
     return fakestat( default_vfs_ops.stat(conn, fname, sbuf), sbuf);
}

int my_fstat(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
{
     syslog(SYSLOG_PRIORITY, "fstat(.., fd=%i, ..)\n",fd);
     return fakestat( default_vfs_ops.fstat(fsp, fd, sbuf), sbuf);
}

</snippet>

smbmount //lombi/audit mnt/LOMBI/audit/ -o credentials=.sambacredentials
cd mnt/LOMBI/audit
chris at lombi audit > stat altecd_ar4
   File: "altecd_ar4"
   Size: 179863      Blocks: 352        IO Block: 4096   Regular File
Device: 9h/9d   Inode: 462         Links: 1   
Access: (0775/-rwxrwxr-x)  Uid: ( 1001/   chris)   Gid: ( 1001/   chris)
Access: Tue Nov 23 18:31:44 1971
Modify: Fri Nov 23 08:28:16 2001
Change: Tue Nov 23 18:31:44 1971

Without my stat changes, it gives:

chris at lombi audit > stat altecd_ar4
   File: "altecd_ar4"
   Size: 179863      Blocks: 352        IO Block: 4096   Regular File
Device: 9h/9d   Inode: 475         Links: 1   
Access: (0775/-rwxrwxr-x)  Uid: ( 1001/   chris)   Gid: ( 1001/   chris)
Access: Tue Dec  4 14:42:44 2001
Modify: Fri Nov 23 08:28:16 2001
Change: Fri Nov 23 08:28:16 2001

Note that
- the size is not altered
- the modify time is not altered
- the access and change times *are* altered, though the date is 
rather strange since
     perl -e 'print localtime(365*24*60*60 *10)."\n"'
     Sun Dec 30 01:00:00 1979

A directory listing with ls -l gives in both cases:
-rwxrwxr-x    1 chris    chris      173515 Jan  1  1970 altecd_ar4.3
(Where does *this* date come from?)


Thanks
Christian
-- 
Christian Jaeger  Programmer & System Engineer  +41 1 430 45 26
ETHLife CMS Project - warehouse.ch/ethlife/www - www.ethlife.ethz.ch




More information about the samba-technical mailing list