1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

smbd: Use share_mode_forall_entries() in rename_share_filename()

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Volker Lendecke 2019-08-16 15:40:55 +02:00 committed by Jeremy Allison
parent fb0b107ac2
commit 4340285184

View File

@ -502,6 +502,65 @@ static bool rename_lease_fn(struct share_mode_lock *lck,
Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
********************************************************************/
struct rename_share_filename_state {
struct messaging_context *msg_ctx;
struct server_id self;
uint32_t orig_name_hash;
uint32_t new_name_hash;
struct file_rename_message msg;
};
static bool rename_share_filename_fn(
struct share_mode_entry *e,
bool *modified,
void *private_data)
{
struct rename_share_filename_state *state = private_data;
DATA_BLOB blob;
enum ndr_err_code ndr_err;
bool ok;
/*
* If this is a hardlink to the inode with a different name,
* skip this.
*/
if (e->name_hash != state->orig_name_hash) {
return false;
}
e->name_hash = state->new_name_hash;
*modified = true;
ok = serverid_equal(&e->pid, &state->self);
if (ok) {
return false;
}
state->msg.share_file_id = e->share_file_id;
ndr_err = ndr_push_struct_blob(
&blob,
talloc_tos(),
&state->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 (DEBUGLEVEL >= 10) {
struct server_id_buf tmp;
DBG_DEBUG("sending rename message to %s\n",
server_id_str_buf(e->pid, &tmp));
NDR_PRINT_DEBUG(file_rename_message, &state->msg);
}
messaging_send(state->msg_ctx, e->pid, MSG_SMB_FILE_RENAME, &blob);
TALLOC_FREE(blob.data);
return false;
}
bool rename_share_filename(struct messaging_context *msg_ctx,
struct share_mode_lock *lck,
struct file_id id,
@ -510,15 +569,17 @@ bool rename_share_filename(struct messaging_context *msg_ctx,
uint32_t new_name_hash,
const struct smb_filename *smb_fname_dst)
{
struct share_mode_data *d = lck->data;
struct file_rename_message msg = {
.id = id,
.servicepath = servicepath,
.base_name = smb_fname_dst->base_name,
.stream_name = smb_fname_dst->stream_name,
struct rename_share_filename_state state = {
.msg_ctx = msg_ctx,
.self = messaging_server_id(msg_ctx),
.orig_name_hash = orig_name_hash,
.new_name_hash = new_name_hash,
.msg.id = id,
.msg.servicepath = servicepath,
.msg.base_name = smb_fname_dst->base_name,
.msg.stream_name = smb_fname_dst->stream_name,
};
uint32_t i;
struct server_id self_pid = messaging_server_id(msg_ctx);
struct share_mode_data *d = lck->data;
bool ok;
DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
@ -529,70 +590,25 @@ bool rename_share_filename(struct messaging_context *msg_ctx,
* head of newname if newname does not contain a '/'.
*/
if (strncmp(msg.base_name, "./", 2) == 0) {
msg.base_name += 2;
if (strncmp(state.msg.base_name, "./", 2) == 0) {
state.msg.base_name += 2;
}
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);
d->servicepath = talloc_strdup(d, state.msg.servicepath);
d->base_name = talloc_strdup(d, state.msg.base_name);
d->stream_name = talloc_strdup(d, state.msg.stream_name);
if ((d->servicepath == NULL) ||
(d->base_name == NULL) ||
((msg.stream_name != NULL) && (d->stream_name == NULL))) {
((state.msg.stream_name != NULL) && (d->stream_name == NULL))) {
DBG_WARNING("talloc failed\n");
return false;
}
d->modified = True;
/* Send the messages. */
for (i=0; i<d->num_share_modes; i++) {
struct share_mode_entry *se = &d->share_modes[i];
DATA_BLOB blob;
enum ndr_err_code ndr_err;
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;
}
msg.share_file_id = se->share_file_id;
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 (DEBUGLEVEL >= 10) {
struct server_id_buf tmp;
DBG_DEBUG("sending rename message to %s\n",
server_id_str_buf(se->pid, &tmp));
NDR_PRINT_DEBUG(file_rename_message, &msg);
}
messaging_send(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, &blob);
TALLOC_FREE(blob.data);
ok = share_mode_forall_entries(
lck, rename_share_filename_fn, &state);
if (!ok) {
DBG_WARNING("share_mode_forall_entries failed\n");
}
ok = share_mode_forall_leases(lck, rename_lease_fn, NULL);