diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/smb.h | 19 | ||||
-rw-r--r-- | source3/librpc/idl/open_files.idl | 7 | ||||
-rw-r--r-- | source3/locking/locking.c | 95 | ||||
-rw-r--r-- | source3/smbd/open.c | 75 |
4 files changed, 81 insertions, 115 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h index dfdb79cba56..41c27806489 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -605,25 +605,6 @@ Offset Data length. */ #define MSG_SMB_KERNEL_BREAK_SIZE 28 -/* file_renamed_message definition. - -struct file_renamed_message { - uint64_t dev; - uint64_t inode; - char names[1]; A variable area containing sharepath and filename. -}; - -Offset Data length. -0 uint64_t dev 8 bytes -8 uint64_t inode 8 bytes -16 unit64_t extid 8 bytes -24 char [] name zero terminated namelen bytes -minimum length == 24. - -*/ - -#define MSG_FILE_RENAMED_MIN_SIZE 24 - /* * On the wire return values for oplock types. */ diff --git a/source3/librpc/idl/open_files.idl b/source3/librpc/idl/open_files.idl index a823e3f9134..8111cb6360f 100644 --- a/source3/librpc/idl/open_files.idl +++ b/source3/librpc/idl/open_files.idl @@ -104,4 +104,11 @@ interface open_files udlong share_file_id; uint8 break_to; } oplock_break_message; + + typedef [public] struct { + file_id id; + [string,charset(UTF8)] char *servicepath; + [string,charset(UTF8)] char *base_name; + [string,charset(UTF8)] char *stream_name; + } file_rename_message; } diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 10e9606d134..f46391faf45 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -501,14 +501,15 @@ bool rename_share_filename(struct messaging_context *msg_ctx, const struct smb_filename *smb_fname_dst) { struct share_mode_data *d = lck->data; - size_t sp_len; - size_t bn_len; - size_t sn_len; - size_t msg_len; - char *frm = NULL; + struct file_rename_message msg = { + .id = id, + .servicepath = servicepath, + .base_name = smb_fname_dst->base_name, + .stream_name = smb_fname_dst->stream_name, + }; + DATA_BLOB blob; + enum ndr_err_code ndr_err; uint32_t i; - bool strip_two_chars = false; - bool has_stream = smb_fname_dst->stream_name != NULL; struct server_id self_pid = messaging_server_id(msg_ctx); bool ok; @@ -519,51 +520,35 @@ bool rename_share_filename(struct messaging_context *msg_ctx, * rename_internal_fsp() and rename_internals() add './' to * head of newname if newname does not contain a '/'. */ - 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; - } - - d->servicepath = talloc_strdup(d, servicepath); - d->base_name = talloc_strdup(d, smb_fname_dst->base_name + - (strip_two_chars ? 2 : 0)); - d->stream_name = talloc_strdup(d, smb_fname_dst->stream_name); - if (d->base_name == NULL || - (has_stream && d->stream_name == NULL) || - d->servicepath == NULL) { - DEBUG(0, ("rename_share_filename: talloc failed\n")); - return False; - } - d->modified = True; - sp_len = strlen(d->servicepath); - bn_len = strlen(d->base_name); - sn_len = has_stream ? strlen(d->stream_name) : 0; - - 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(d, char, msg_len); - if (!frm) { - return False; + if (strncmp(msg.base_name, "./", 2) == 0) { + msg.base_name += 2; } - push_file_id_24(frm, &id); - - DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len )); + d->servicepath = talloc_strdup(d, msg.servicepath); + d->base_name = talloc_strdup(d, msg.base_name); + d->stream_name = talloc_strdup(d, msg.stream_name); + if ((d->servicepath == NULL) || + (d->base_name == NULL) || + ((msg.stream_name != NULL) && (d->stream_name == NULL))) { + DBG_WARNING("talloc failed\n"); + return false; + } + d->modified = True; - strlcpy(&frm[24], - d->servicepath ? d->servicepath : "", - sp_len+1); - strlcpy(&frm[24 + sp_len + 1], - d->base_name ? d->base_name : "", - bn_len+1); - strlcpy(&frm[24 + sp_len + 1 + bn_len + 1], - d->stream_name ? d->stream_name : "", - sn_len+1); + ndr_err = ndr_push_struct_blob( + &blob, + talloc_tos(), + &msg, + (ndr_push_flags_fn_t)ndr_push_file_rename_message); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DBG_DEBUG("ndr_push_file_rename_message failed: %s\n", + ndr_errstr(ndr_err)); + return false; + } + if (DEBUGLVL(10)) { + NDR_PRINT_DEBUG(file_rename_message, &msg); + } /* Send the messages. */ for (i=0; i<d->num_share_modes; i++) { @@ -591,18 +576,14 @@ 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 base_name %s " - "stream_name %s\n", - server_id_str_buf(se->pid, &tmp), - file_id_string_tos(&id), - d->servicepath, d->base_name, - has_stream ? d->stream_name : "")); + DBG_DEBUG("sending rename message to %s\n", + server_id_str_buf(se->pid, &tmp)); - messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, - (uint8_t *)frm, msg_len); + messaging_send(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, &blob); } + TALLOC_FREE(blob.data); + ok = share_mode_forall_leases(lck, rename_lease_fn, NULL); if (!ok) { /* diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 2d5815069f2..43690e54fda 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -4416,62 +4416,60 @@ NTSTATUS create_directory(connection_struct *conn, struct smb_request *req, smbd process. ****************************************************************************/ -void msg_file_was_renamed(struct messaging_context *msg, +void msg_file_was_renamed(struct messaging_context *msg_ctx, void *private_data, uint32_t msg_type, - struct server_id server_id, + struct server_id src, DATA_BLOB *data) { + struct file_rename_message *msg = NULL; + enum ndr_err_code ndr_err; files_struct *fsp; - char *frm = (char *)data->data; - struct file_id id; - const char *sharepath; - const char *base_name; - const char *stream_name; struct smb_filename *smb_fname = NULL; - size_t sp_len, bn_len; NTSTATUS status; struct smbd_server_connection *sconn = talloc_get_type_abort(private_data, struct smbd_server_connection); - if (data->data == NULL - || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) { - DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n", - (int)data->length)); - return; - } + msg = talloc(talloc_tos(), struct file_rename_message); + if (msg == NULL) { + DBG_WARNING("talloc failed\n"); + return; + } - /* Unpack the message. */ - pull_file_id_24(frm, &id); - sharepath = &frm[24]; - sp_len = strlen(sharepath); - base_name = sharepath + sp_len + 1; - bn_len = strlen(base_name); - stream_name = sharepath + sp_len + 1 + bn_len + 1; + ndr_err = ndr_pull_struct_blob_all( + data, + msg, + msg, + (ndr_pull_flags_fn_t)ndr_pull_file_rename_message); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n", + ndr_errstr(ndr_err)); + goto out; + } + if (DEBUGLVL(10)) { + struct server_id_buf buf; + DBG_DEBUG("Got rename message from %s\n", + server_id_str_buf(src, &buf)); + NDR_PRINT_DEBUG(file_rename_message, msg); + } /* stream_name must always be NULL if there is no stream. */ - if (stream_name[0] == '\0') { - stream_name = NULL; + if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) { + msg->stream_name = NULL; } - smb_fname = synthetic_smb_fname(talloc_tos(), - base_name, - stream_name, - NULL, - 0); + smb_fname = synthetic_smb_fname( + msg, msg->base_name, msg->stream_name, NULL, 0); if (smb_fname == NULL) { - return; + DBG_DEBUG("synthetic_smb_fname failed\n"); + goto out; } - DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, " - "file_id %s\n", - sharepath, smb_fname_str_dbg(smb_fname), - file_id_string_tos(&id))); - - for(fsp = file_find_di_first(sconn, id); fsp; + for(fsp = file_find_di_first(sconn, msg->id); fsp; fsp = file_find_di_next(fsp)) { - if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) { + + if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) { DEBUG(10,("msg_file_was_renamed: renaming file %s from %s -> %s\n", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp), @@ -4488,15 +4486,14 @@ void msg_file_was_renamed(struct messaging_context *msg, "not sharepath %s) " "%s from %s -> %s\n", fsp->conn->connectpath, - sharepath, + msg->servicepath, fsp_fnum_dbg(fsp), fsp_str_dbg(fsp), smb_fname_str_dbg(smb_fname))); } } out: - TALLOC_FREE(smb_fname); - return; + TALLOC_FREE(msg); } /* |