/* * helper function used by the kernel oplock backends to post the break message */ void break_kernel_oplock(struct messaging_context *msg_ctx, files_struct *fsp) { uint8_t msg[MSG_SMB_KERNEL_BREAK_SIZE]; /* Put the kernel break info into the message. */ push_file_id_24((char *)msg, &fsp->file_id); SIVAL(msg,24,fsp->fh->gen_id); /* Don't need to be root here as we're only ever sending to ourselves. */ messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx), MSG_SMB_KERNEL_BREAK, msg, MSG_SMB_KERNEL_BREAK_SIZE); }
bool rename_share_filename(struct messaging_context *msg_ctx, struct share_mode_lock *lck, const char *servicepath, uint32_t orig_name_hash, uint32_t new_name_hash, 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; int 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); DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n", servicepath, smb_fname_dst->base_name)); /* * 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; } push_file_id_24(frm, &d->id); DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len )); 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); /* Send the messages. */ for (i=0; i<d->num_share_modes; i++) { struct share_mode_entry *se = &d->share_modes[i]; if (!is_valid_share_mode_entry(se)) { continue; } /* If this is a hardlink to the inode with a different name, skip this. */ if (se->name_hash != orig_name_hash) { continue; } se->name_hash = new_name_hash; /* But not to ourselves... */ if (serverid_equal(&se->pid, &self_pid)) { continue; } if (share_mode_stale_pid(d, i)) { continue; } 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(&d->id), d->servicepath, d->base_name, has_stream ? d->stream_name : "")); messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, (uint8 *)frm, msg_len); } return True; }