smbd: Add file_rename_message in idl
authorVolker Lendecke <vl@samba.org>
Fri, 17 May 2019 08:41:25 +0000 (10:41 +0200)
committerJeremy Allison <jra@samba.org>
Sat, 18 May 2019 19:06:23 +0000 (19:06 +0000)
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/include/smb.h
source3/librpc/idl/open_files.idl
source3/locking/locking.c
source3/smbd/open.c

index dfdb79cba5674db55871c0d5a2ab4a244831a59e..41c27806489c7571ccbc77d428d6b2ce632c456d 100644 (file)
@@ -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.
  */
index a823e3f9134bb2683fbd1e80744f8c3e7c34552e..8111cb6360f1a34a302d88210b279eaf02df2d8c 100644 (file)
@@ -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;
 }
index 10e9606d134a3395dba2833bdfb4ded9308af445..f46391faf458b6418ff266f1f12e718383d00a91 100644 (file)
@@ -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) {
                /*
index 2d5815069f2ee28c6bba215e85e9a31551f4f571..43690e54fda0e74f4e58c3721c401202912f319a 100644 (file)
@@ -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);
 }
 
 /*