summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in2
-rw-r--r--source3/include/smb.h1
-rw-r--r--source3/libsmb/smb_share_modes.c37
-rw-r--r--source3/locking/locking.c84
-rw-r--r--source3/smbd/close.c4
-rw-r--r--source3/smbd/open.c15
-rw-r--r--source3/smbd/oplock.c6
-rw-r--r--source3/smbd/trans2.c14
-rw-r--r--source3/utils/status.c8
-rw-r--r--source3/web/statuspage.c2
10 files changed, 124 insertions, 49 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 092d11bc80..9d00cb72a1 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -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 =
diff --git a/source3/include/smb.h b/source3/include/smb.h
index a3dce53a4c..6e995b8198 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -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;
diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c
index 40ccf15f94..43f25cd378 100644
--- a/source3/libsmb/smb_share_modes.c
+++ b/source3/libsmb/smb_share_modes.c
@@ -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,
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 322824ea2f..2debc2c23e 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -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;
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 43049a46a4..d84b9f925b 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -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));
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 42e1da839f..b3f0589dc7 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -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));
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 385f998b1c..f6c97c3df4 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -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 ));
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index ee6bed9afd..c165ea1862 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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);
}
diff --git a/source3/utils/status.c b/source3/utils/status.c
index a495d07f04..2c5756106a 100644
--- a/source3/utils/status.c
+++ b/source3/utils/status.c
@@ -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)));
}
}
diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c
index 6447f95bac..24d7eaf72e 100644
--- a/source3/web/statuspage.c
+++ b/source3/web/statuspage.c
@@ -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,