r12203: Add the share path into the sharemode db. This involves
authorJeremy Allison <jra@samba.org>
Mon, 12 Dec 2005 22:07:36 +0000 (22:07 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:05:49 +0000 (11:05 -0500)
revving the minor version number for libsmbsharemodes (we
now have a new _ex interface that takes the share path
as well as the filename). Needed for #3303. Some code written
by SATOH Fumiyasu <fumiya@samba.gr.jp> included in the changes
to locking/locking.c. The smbstatus output is a bit of a mess
and needs overhauling...
Jeremy.
(This used to be commit 9d93af713f8520ca506730dd32aa2b994937eaba)

source3/Makefile.in
source3/include/smb.h
source3/libsmb/smb_share_modes.c
source3/locking/locking.c
source3/smbd/close.c
source3/smbd/open.c
source3/smbd/oplock.c
source3/smbd/trans2.c
source3/utils/status.c
source3/web/statuspage.c

index 092d11bc80fc2df9ef062adf7d42884f21b9c028..9d00cb72a1d966d1147baa95815d884d8d25ebfc 100644 (file)
@@ -104,7 +104,7 @@ LIBMSRPC_MINOR=1
 
 LIBSMBSHAREMODES=bin/libsmbsharemodes.a @LIBSMBSHAREMODES_SHARED@
 LIBSMBSHAREMODES_MAJOR=0
-LIBSMBSHAREMODES_MINOR=1
+LIBSMBSHAREMODES_MINOR=2
 
 FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/tdb @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir) -D_SAMBA_BUILD_
 FLAGS2 = 
index a3dce53a4caccff6ddde67451f4eb5d52160ce3d..6e995b81988fdfe9ed4783f31b31a3179c2a604c 100644 (file)
@@ -629,6 +629,7 @@ struct share_mode_entry {
 };
 
 struct share_mode_lock {
+       const char *servicepath; /* canonicalized. */
        const char *filename;
        SMB_DEV_T dev;
        SMB_INO_T ino;
index 40ccf15f9464a94e31f127beddbcb92c823b67ad..43f25cd37872fdeba8f87045ca7c30045209ad98 100644 (file)
@@ -255,11 +255,12 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
  * Create an entry in the Samba share mode db.
  */
 
-int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
+int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
                                uint64_t dev,
                                uint64_t ino,
                                const struct smb_share_mode_entry *new_entry,
-                               const char *filename) /* Must be abolute utf8 path. */
+                               const char *sharepath, /* Must be absolute utf8 path. */
+                               const char *filename) /* Must be relative utf8 path. */
 {
        TDB_DATA db_data;
        TDB_DATA locking_key =  get_locking_key(dev, ino);
@@ -272,7 +273,9 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
        db_data = tdb_fetch(db_ctx->smb_tdb, locking_key);
        if (!db_data.dptr) {
                /* We must create the entry. */
-               db_data.dptr = malloc((2*sizeof(struct share_mode_entry)) + strlen(filename) + 1);
+               db_data.dptr = malloc((2*sizeof(struct share_mode_entry)) +
+                                       strlen(sharepath) + 1 +
+                                       strlen(filename) + 1);
                if (!db_data.dptr) {
                        return -1;
                }
@@ -281,11 +284,18 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
                ld->u.s.delete_on_close = 0;
                shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
                create_share_mode_entry(shares, new_entry);
+
                memcpy(db_data.dptr + 2*sizeof(struct share_mode_entry),
+                       sharepath,
+                       strlen(sharepath) + 1);
+               memcpy(db_data.dptr + 2*sizeof(struct share_mode_entry) +
+                       strlen(sharepath) + 1,
                        filename,
                        strlen(filename) + 1);
 
-               db_data.dsize = 2*sizeof(struct share_mode_entry) + strlen(filename) + 1;
+               db_data.dsize = 2*sizeof(struct share_mode_entry) +
+                                       strlen(sharepath) + 1 +
+                                       strlen(filename) + 1;
                if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_INSERT) == -1) {
                        free(db_data.dptr);
                        return -1;
@@ -336,6 +346,25 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
        return 0;
 }
 
+/* 
+ * Create an entry in the Samba share mode db. Original interface - doesn't
+ * Distinguish between share path and filename. Fudge this by using a
+ * sharepath of / and a relative filename of (filename+1).
+ */
+
+int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
+                               uint64_t dev,
+                               uint64_t ino,
+                               const struct smb_share_mode_entry *new_entry,
+                               const char *filename) /* Must be absolute utf8 path. */
+{
+       if (*filename != '/') {
+               abort();
+       }
+       return smb_create_share_mode_entry_ex(db_ctx, dev, ino, new_entry,
+                                               "/", &filename[1]);
+}
+
 int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
                                uint64_t dev,
                                uint64_t ino,
index 322824ea2f4810e004a58dfb7897082b950406e2..2debc2c23e5abe1d837525035f3bb098065a4e3c 100644 (file)
@@ -464,10 +464,15 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
                }
        }
 
-       /* Save off the associated filename. */
+       /* Save off the associated service path and filename. */
+       lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
+                                     (lck->num_share_modes *
+                                     sizeof(struct share_mode_entry)));
+
        lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
-                                     lck->num_share_modes *
-                                     sizeof(struct share_mode_entry));
+                                     (lck->num_share_modes *
+                                     sizeof(struct share_mode_entry)) +
+                                     strlen(lck->servicepath) + 1 );
 
        /*
         * Ensure that each entry has a real process attached.
@@ -495,6 +500,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
        int i;
        struct locking_data *data;
        ssize_t offset;
+       ssize_t sp_len;
 
        result.dptr = NULL;
        result.dsize = 0;
@@ -509,8 +515,11 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
                return result;
        }
 
+       sp_len = strlen(lck->servicepath);
+
        result.dsize = sizeof(*data) +
                lck->num_share_modes * sizeof(struct share_mode_entry) +
+               sp_len + 1 +
                strlen(lck->filename) + 1;
        result.dptr = talloc_size(lck, result.dsize);
 
@@ -529,6 +538,9 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
               sizeof(struct share_mode_entry)*lck->num_share_modes);
        offset = sizeof(*data) +
                sizeof(struct share_mode_entry)*lck->num_share_modes;
+       safe_strcpy(result.dptr + offset, lck->servicepath,
+                   result.dsize - offset - 1);
+       offset += sp_len + 1;
        safe_strcpy(result.dptr + offset, lck->filename,
                    result.dsize - offset - 1);
        print_share_mode_table(data);
@@ -569,8 +581,9 @@ static int share_mode_lock_destructor(void *p)
 }
 
 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
-                                           SMB_DEV_T dev, SMB_INO_T ino,
-                                           const char *fname)
+                                               SMB_DEV_T dev, SMB_INO_T ino,
+                                               const char *servicepath,
+                                               const char *fname)
 {
        struct share_mode_lock *lck;
        TDB_DATA key = locking_key(dev, ino);
@@ -599,13 +612,15 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
        lck->fresh = (data.dptr == NULL);
 
        if (lck->fresh) {
-               if (fname == NULL) {
-                       DEBUG(0, ("New file, but no filename supplied\n"));
+
+               if (fname == NULL || servicepath == NULL) {
+                       DEBUG(0, ("New file, but no filename or servicepath supplied\n"));
                        talloc_free(lck);
                        return NULL;
                }
                lck->filename = talloc_strdup(lck, fname);
-               if (lck->filename == NULL) {
+               lck->servicepath = talloc_strdup(lck, servicepath);
+               if (lck->filename == NULL || lck->servicepath == NULL) {
                        DEBUG(0, ("talloc failed\n"));
                        talloc_free(lck);
                        return NULL;
@@ -625,12 +640,41 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
        return lck;
 }
 
-BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode,
-                             const char *fname)
+/*******************************************************************
+ Sets the service name and filename for rename.
+ At this point we should emit "rename" smbd messages to all
+ interested process id's.
+********************************************************************/
+
+BOOL rename_share_filename(struct share_mode_lock *lck,
+                       const char *servicepath,
+                       const char *newname)
+{
+       /*
+        * rename_internal_fsp() and rename_internals() add './' to
+        * head of newname if newname does not contain a '/'.
+        */
+       while (newname[0] && newname[1] && newname[0] == '.' && newname[1] == '/') {
+               newname += 2;
+       }
+
+       lck->filename = talloc_strdup(lck, newname);
+       lck->servicepath = talloc_strdup(lck, servicepath);
+       if (lck->filename == NULL || lck->servicepath == NULL) {
+               DEBUG(0, ("rename_share_filename: talloc failed\n"));
+               return False;
+       }
+       lck->modified = True;
+       return True;
+}
+
+BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode)
 {
        BOOL result;
-       struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode,
-                                                         fname);
+       struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode, NULL, NULL);
+       if (!lck) {
+               return False;
+       }
        result = lck->delete_on_close;
        talloc_free(lck);
        return result;
@@ -964,7 +1008,7 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
                return True;
        }
 
-       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
+       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
        if (lck == NULL) {
                return False;
        }
@@ -982,9 +1026,10 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
 {
        struct locking_data *data;
        struct share_mode_entry *shares;
-       char *name;
+       const char *sharepath;
+       const char *fname;
        int i;
-       void (*traverse_callback)(struct share_mode_entry *, char *) = state;
+       void (*traverse_callback)(struct share_mode_entry *, const char *, const char *) = state;
 
        /* Ensure this is a locking_key record. */
        if (kbuf.dsize != sizeof(struct locking_key))
@@ -992,11 +1037,14 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
 
        data = (struct locking_data *)dbuf.dptr;
        shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
-       name = dbuf.dptr + sizeof(*data) +
+       sharepath = dbuf.dptr + sizeof(*data) +
                data->u.s.num_share_mode_entries*sizeof(*shares);
+       fname = dbuf.dptr + sizeof(*data) +
+               data->u.s.num_share_mode_entries*sizeof(*shares) +
+               strlen(sharepath) + 1;
 
        for (i=0;i<data->u.s.num_share_mode_entries;i++) {
-               traverse_callback(&shares[i], name);
+               traverse_callback(&shares[i], sharepath, fname);
        }
        return 0;
 }
@@ -1006,7 +1054,7 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
  share mode system.
 ********************************************************************/
 
-int share_mode_forall(void (*fn)(const struct share_mode_entry *, char *))
+int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, const char *))
 {
        if (tdb == NULL)
                return 0;
index 43049a46a4de2698d13c5c8056746ac84fca374c..d84b9f925bf672d1cff1caef263214d1fc4a8946 100644 (file)
@@ -192,7 +192,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
         * This prevents race conditions with the file being created. JRA.
         */
 
-       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
+       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
 
        if (lck == NULL) {
                DEBUG(0, ("close_file: Could not get share mode lock for file %s\n", fsp->fsp_name));
@@ -305,7 +305,7 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
         * reference to a directory also.
         */
 
-       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
+       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
 
        if (lck == NULL) {
                DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name));
index 42e1da839fbde88348a50f09710508ca98b5c61a..b3f0589dc7b2f8cba2bff0c957fa9a1c0d4f15ab 100644 (file)
@@ -1123,8 +1123,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
                   spurious oplock break. */
 
                /* Now remove the deferred open entry under lock. */
-               lck = get_share_mode_lock(NULL, state->dev, state->inode,
-                                         fname);
+               lck = get_share_mode_lock(NULL, state->dev, state->inode, NULL, NULL);
                if (lck == NULL) {
                        DEBUG(0, ("could not get share mode lock\n"));
                } else {
@@ -1334,7 +1333,9 @@ files_struct *open_file_ntcreate(connection_struct *conn,
                dev = psbuf->st_dev;
                inode = psbuf->st_ino;
 
-               lck = get_share_mode_lock(NULL, dev, inode, fname);
+               lck = get_share_mode_lock(NULL, dev, inode,
+                                       conn->connectpath,
+                                       fname);
 
                if (lck == NULL) {
                        DEBUG(0, ("Could not get share mode lock\n"));
@@ -1533,7 +1534,9 @@ files_struct *open_file_ntcreate(connection_struct *conn,
                dev = fsp->dev;
                inode = fsp->inode;
 
-               lck = get_share_mode_lock(NULL, dev, inode, fname);
+               lck = get_share_mode_lock(NULL, dev, inode,
+                                       conn->connectpath,
+                                       fname);
 
                if (lck == NULL) {
                        DEBUG(0, ("open_file_ntcreate: Could not get share mode lock for %s\n", fname));
@@ -1940,7 +1943,9 @@ files_struct *open_directory(connection_struct *conn,
        fsp->is_stat = False;
        string_set(&fsp->fsp_name,fname);
 
-       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, fname);
+       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode,
+                               conn->connectpath,
+                               fname);
 
        if (lck == NULL) {
                DEBUG(0, ("open_directory: Could not get share mode lock for %s\n", fname));
index 385f998b1ce31ac46a8cc19c056c984175b0b3c8..f6c97c3df48ceae1d0f25fbb1f4d2277ccc954b7 100644 (file)
@@ -182,7 +182,7 @@ BOOL remove_oplock(files_struct *fsp)
        struct share_mode_lock *lck;
 
        /* Remove the oplock flag from the sharemode. */
-       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
+       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
        if (lck == NULL) {
                DEBUG(0,("remove_oplock: failed to lock share entry for "
                         "file %s\n", fsp->fsp_name ));
@@ -210,7 +210,7 @@ BOOL downgrade_oplock(files_struct *fsp)
        BOOL ret;
        struct share_mode_lock *lck;
 
-       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
+       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
        if (lck == NULL) {
                DEBUG(0,("downgrade_oplock: failed to lock share entry for "
                         "file %s\n", fsp->fsp_name ));
@@ -627,7 +627,7 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
        if (!LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
                return;
 
-       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
+       lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
        if (lck == NULL) {
                DEBUG(0,("release_level_2_oplocks_on_change: failed to lock "
                         "share mode entry for file %s.\n", fsp->fsp_name ));
index ee6bed9afdf2ac8a6dced570deafe372ff085ecf..c165ea186295769642ad75ef90c665ddfa2b9a21 100644 (file)
@@ -2824,10 +2824,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
                                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
                        }
 
-                       delete_pending =
-                               get_delete_on_close_flag(sbuf.st_dev,
-                                                        sbuf.st_ino,
-                                                        fname);
+                       delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
                } else {
                        /*
                         * Original code - this is an open file.
@@ -2840,10 +2837,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
                                return(UNIXERROR(ERRDOS,ERRbadfid));
                        }
                        pos = fsp->fh->position_information;
-                       delete_pending = 
-                               get_delete_on_close_flag(sbuf.st_dev,
-                                                        sbuf.st_ino,
-                                                        fname);
+                       delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
                        access_mask = fsp->access_mask;
                }
        } else {
@@ -2885,9 +2879,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
                        return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
                }
 
-               delete_pending = get_delete_on_close_flag(sbuf.st_dev,
-                                                         sbuf.st_ino,
-                                                         fname);
+               delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
                if (delete_pending) {
                        return ERROR_NT(NT_STATUS_DELETE_PENDING);
                }
index a495d07f0475779b9a88b4c593fcef9830e24358..2c5756106a25b4340123eabfd16d3feeab21fdac 100644 (file)
@@ -98,13 +98,13 @@ static BOOL Ucrit_addPid( pid_t pid )
        return True;
 }
 
-static void print_share_mode(const struct share_mode_entry *e, char *fname)
+static void print_share_mode(const struct share_mode_entry *e, const char *sharepath, const char *fname)
 {
        static int count;
        if (count==0) {
                d_printf("Locked files:\n");
-               d_printf("Pid    DenyMode   Access      R/W        Oplock           Name\n");
-               d_printf("--------------------------------------------------------------\n");
+               d_printf("Pid    DenyMode   Access      R/W        Oplock           SharePath           Name\n");
+               d_printf("----------------------------------------------------------------------------------\n");
        }
        count++;
 
@@ -150,7 +150,7 @@ static void print_share_mode(const struct share_mode_entry *e, char *fname)
                        d_printf("NONE            ");
                }
 
-               d_printf(" %s   %s",fname, asctime(localtime((time_t *)&e->time.tv_sec)));
+               d_printf(" %s   %s   %s",sharepath, fname, asctime(localtime((time_t *)&e->time.tv_sec)));
        }
 }
 
index 6447f95bac4c332d470e858e6c2d9c6c7915c0e2..24d7eaf72e7fba3e93cb8611b99b91fee90cef5d 100644 (file)
@@ -106,7 +106,7 @@ static char *tstring(time_t t)
        return buf;
 }
 
-static void print_share_mode(const struct share_mode_entry *e, char *fname)
+static void print_share_mode(const struct share_mode_entry *e, const char *sharepath, const char *fname)
 {
        char           *utf8_fname;
        int deny_mode = map_share_mode_to_deny_mode(e->share_access,