summaryrefslogtreecommitdiff
path: root/source3/locking
diff options
context:
space:
mode:
Diffstat (limited to 'source3/locking')
-rw-r--r--source3/locking/locking.c93
1 files changed, 64 insertions, 29 deletions
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index cf6e02f248..91fe137fdc 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -630,11 +630,17 @@ static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
(lck->num_share_modes * sizeof(struct share_mode_entry)) +
data.u.s.delete_token_size;
- lck->filename = (const char *)dbuf.dptr + sizeof(struct locking_data) +
+ lck->base_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
(lck->num_share_modes * sizeof(struct share_mode_entry)) +
data.u.s.delete_token_size +
strlen(lck->servicepath) + 1;
+ lck->stream_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
+ (lck->num_share_modes * sizeof(struct share_mode_entry)) +
+ data.u.s.delete_token_size +
+ strlen(lck->servicepath) + 1 +
+ strlen(lck->base_name) + 1;
+
/*
* Ensure that each entry has a real process attached.
*/
@@ -666,7 +672,7 @@ static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
int i;
struct locking_data *data;
ssize_t offset;
- ssize_t sp_len;
+ ssize_t sp_len, bn_len, sn_len;
uint32 delete_token_size;
result.dptr = NULL;
@@ -683,6 +689,9 @@ static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
}
sp_len = strlen(lck->servicepath);
+ bn_len = strlen(lck->base_name);
+ sn_len = lck->stream_name != NULL ? strlen(lck->stream_name) : 0;
+
delete_token_size = (lck->delete_token ?
(sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
@@ -690,7 +699,8 @@ static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
lck->num_share_modes * sizeof(struct share_mode_entry) +
delete_token_size +
sp_len + 1 +
- strlen(lck->filename) + 1;
+ bn_len + 1 +
+ sn_len + 1;
result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize);
if (result.dptr == NULL) {
@@ -740,7 +750,10 @@ static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
safe_strcpy((char *)result.dptr + offset, lck->servicepath,
result.dsize - offset - 1);
offset += sp_len + 1;
- safe_strcpy((char *)result.dptr + offset, lck->filename,
+ safe_strcpy((char *)result.dptr + offset, lck->base_name,
+ result.dsize - offset - 1);
+ offset += bn_len + 1;
+ safe_strcpy((char *)result.dptr + offset, lck->stream_name,
result.dsize - offset - 1);
if (DEBUGLEVEL >= 10) {
@@ -789,7 +802,7 @@ static int share_mode_lock_destructor(struct share_mode_lock *lck)
static bool fill_share_mode_lock(struct share_mode_lock *lck,
struct file_id id,
const char *servicepath,
- const char *fname,
+ const struct smb_filename *smb_fname,
TDB_DATA share_mode_data,
const struct timespec *old_write_time)
{
@@ -797,7 +810,8 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck,
valid even if parse_share_modes fails. */
lck->servicepath = NULL;
- lck->filename = NULL;
+ lck->base_name = NULL;
+ lck->stream_name = NULL;
lck->id = id;
lck->num_share_modes = 0;
lck->share_modes = NULL;
@@ -811,13 +825,20 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck,
lck->fresh = (share_mode_data.dptr == NULL);
if (lck->fresh) {
- if (fname == NULL || servicepath == NULL
+ bool has_stream;
+ if (smb_fname == NULL || servicepath == NULL
|| old_write_time == NULL) {
return False;
}
- lck->filename = talloc_strdup(lck, fname);
+
+ has_stream = smb_fname->stream_name != NULL;
+
+ lck->base_name = talloc_strdup(lck, smb_fname->base_name);
+ lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
lck->servicepath = talloc_strdup(lck, servicepath);
- if (lck->filename == NULL || lck->servicepath == NULL) {
+ if (lck->base_name == NULL ||
+ (has_stream && lck->stream_name == NULL) ||
+ lck->servicepath == NULL) {
DEBUG(0, ("talloc failed\n"));
return False;
}
@@ -835,7 +856,7 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck,
struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
const struct file_id id,
const char *servicepath,
- const char *fname,
+ const struct smb_filename *smb_fname,
const struct timespec *old_write_time)
{
struct share_mode_lock *lck;
@@ -853,7 +874,7 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
return NULL;
}
- if (!fill_share_mode_lock(lck, id, servicepath, fname,
+ if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
lck->record->value, old_write_time)) {
DEBUG(3, ("fill_share_mode_lock failed\n"));
TALLOC_FREE(lck);
@@ -866,9 +887,7 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
}
struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
- const struct file_id id,
- const char *servicepath,
- const char *fname)
+ const struct file_id id)
{
struct share_mode_lock *lck;
struct file_id tmp;
@@ -886,7 +905,7 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
return NULL;
}
- if (!fill_share_mode_lock(lck, id, servicepath, fname, data, NULL)) {
+ if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
"around (file not open)\n"));
TALLOC_FREE(lck);
@@ -906,37 +925,49 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
bool rename_share_filename(struct messaging_context *msg_ctx,
struct share_mode_lock *lck,
const char *servicepath,
- const char *newname)
+ const struct smb_filename *smb_fname_dst)
{
size_t sp_len;
- size_t fn_len;
+ size_t bn_len;
+ size_t sn_len;
size_t msg_len;
char *frm = NULL;
int i;
+ bool strip_two_chars = false;
+ bool has_stream = smb_fname_dst->stream_name != NULL;
DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
- servicepath, newname));
+ servicepath, smb_fname_dst->base_name));
/*
* 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;
+ if (smb_fname_dst->base_name[0] &&
+ smb_fname_dst->base_name[1] &&
+ smb_fname_dst->base_name[0] == '.' &&
+ smb_fname_dst->base_name[1] == '/') {
+ strip_two_chars = true;
}
lck->servicepath = talloc_strdup(lck, servicepath);
- lck->filename = talloc_strdup(lck, newname);
- if (lck->filename == NULL || lck->servicepath == NULL) {
+ lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
+ (strip_two_chars ? 2 : 0));
+ lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
+ if (lck->base_name == NULL ||
+ (has_stream && lck->stream_name == NULL) ||
+ lck->servicepath == NULL) {
DEBUG(0, ("rename_share_filename: talloc failed\n"));
return False;
}
lck->modified = True;
sp_len = strlen(lck->servicepath);
- fn_len = strlen(lck->filename);
+ bn_len = strlen(lck->base_name);
+ sn_len = has_stream ? strlen(lck->stream_name) : 0;
- msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1;
+ msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
+ sn_len + 1;
/* Set up the name changed message. */
frm = TALLOC_ARRAY(lck, char, msg_len);
@@ -949,7 +980,9 @@ bool rename_share_filename(struct messaging_context *msg_ctx,
DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
safe_strcpy(&frm[24], lck->servicepath, sp_len);
- safe_strcpy(&frm[24 + sp_len + 1], lck->filename, fn_len);
+ safe_strcpy(&frm[24 + sp_len + 1], lck->base_name, bn_len);
+ safe_strcpy(&frm[24 + sp_len + 1 + bn_len + 1], lck->stream_name,
+ sn_len);
/* Send the messages. */
for (i=0; i<lck->num_share_modes; i++) {
@@ -962,11 +995,13 @@ bool rename_share_filename(struct messaging_context *msg_ctx,
continue;
}
- DEBUG(10,("rename_share_filename: sending rename message to pid %s "
- "file_id %s sharepath %s newname %s\n",
+ DEBUG(10,("rename_share_filename: sending rename message to "
+ "pid %s file_id %s sharepath %s base_name %s "
+ "stream_name %s\n",
procid_str_static(&se->pid),
file_id_string_tos(&lck->id),
- lck->servicepath, lck->filename ));
+ lck->servicepath, lck->base_name,
+ has_stream ? lck->stream_name : ""));
messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
(uint8 *)frm, msg_len);
@@ -989,7 +1024,7 @@ void get_file_infos(struct file_id id,
ZERO_STRUCTP(write_time);
}
- if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id, NULL, NULL))) {
+ if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
return;
}