Ejemplo n.º 1
0
/*
 * 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);
}
Ejemplo n.º 2
0
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;
}