diff options
author | Jeremy Allison <jra@samba.org> | 2005-12-12 22:07:36 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:05:49 -0500 |
commit | 7d2771e758d4e8ef0adb45e55775b524de4dba9a (patch) | |
tree | f9886027f65a557ce7d76659f638591c55f17fdf /source3 | |
parent | 3f6d9a7b9d35331992fdd069b7752f3082fe0b1b (diff) | |
download | samba-7d2771e758d4e8ef0adb45e55775b524de4dba9a.tar.gz |
r12203: Add the share path into the sharemode db. This involves
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)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/include/smb.h | 1 | ||||
-rw-r--r-- | source3/libsmb/smb_share_modes.c | 37 | ||||
-rw-r--r-- | source3/locking/locking.c | 84 | ||||
-rw-r--r-- | source3/smbd/close.c | 4 | ||||
-rw-r--r-- | source3/smbd/open.c | 15 | ||||
-rw-r--r-- | source3/smbd/oplock.c | 6 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 14 | ||||
-rw-r--r-- | source3/utils/status.c | 8 | ||||
-rw-r--r-- | source3/web/statuspage.c | 2 |
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, |