From: Volker Lendecke Date: Wed, 20 Sep 2023 23:54:40 +0000 (-0700) Subject: libsmb: Factor out cli_create_reparse_point() from cli_symlink() X-Git-Tag: tevent-0.16.0~520 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d19a28fdb4d05f8ac001d1a00415feb72df56c10;p=thirdparty%2Fsamba.git libsmb: Factor out cli_create_reparse_point() from cli_symlink() Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- diff --git a/source3/libsmb/clisymlink.c b/source3/libsmb/clisymlink.c index 5cf2646961f..59887d3585e 100644 --- a/source3/libsmb/clisymlink.c +++ b/source3/libsmb/clisymlink.c @@ -30,65 +30,70 @@ #include "libcli/smb/reparse.h" #include "libcli/smb/reparse_symlink.h" -struct cli_symlink_state { +struct cli_create_reparse_point_state { struct tevent_context *ev; struct cli_state *cli; - const char *link_target; - const char *newpath; - uint32_t flags; - + DATA_BLOB reparse_blob; uint16_t fnum; - DATA_BLOB in; - NTSTATUS set_reparse_status; }; -static void cli_symlink_create_done(struct tevent_req *subreq); -static void cli_symlink_set_reparse_done(struct tevent_req *subreq); -static void cli_symlink_delete_on_close_done(struct tevent_req *subreq); -static void cli_symlink_close_done(struct tevent_req *subreq); +static void cli_create_reparse_point_opened(struct tevent_req *subreq); +static void cli_create_reparse_point_done(struct tevent_req *subreq); +static void cli_create_reparse_point_doc_done(struct tevent_req *subreq); +static void cli_create_reparse_point_closed(struct tevent_req *subreq); -struct tevent_req *cli_symlink_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct cli_state *cli, - const char *link_target, - const char *newpath, - uint32_t flags) +struct tevent_req *cli_create_reparse_point_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *fname, + DATA_BLOB reparse_blob) { - struct tevent_req *req, *subreq; - struct cli_symlink_state *state; + struct tevent_req *req = NULL, *subreq = NULL; + struct cli_create_reparse_point_state *state = NULL; - req = tevent_req_create(mem_ctx, &state, struct cli_symlink_state); + req = tevent_req_create(mem_ctx, + &state, + struct cli_create_reparse_point_state); if (req == NULL) { return NULL; } state->ev = ev; state->cli = cli; - state->link_target = link_target; - state->newpath = newpath; - state->flags = flags; + state->reparse_blob = reparse_blob; + /* + * The create arguments were taken from a Windows->Windows + * symlink create call. + */ subreq = cli_ntcreate_send( - state, ev, cli, state->newpath, 0, - SYNCHRONIZE_ACCESS|DELETE_ACCESS| - FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES, - FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_CREATE, - FILE_OPEN_REPARSE_POINT|FILE_SYNCHRONOUS_IO_NONALERT| - FILE_NON_DIRECTORY_FILE, - SMB2_IMPERSONATION_IMPERSONATION, 0); + state, + ev, + cli, + fname, + 0, + SYNCHRONIZE_ACCESS | DELETE_ACCESS | FILE_READ_ATTRIBUTES | + FILE_WRITE_ATTRIBUTES, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_NONE, + FILE_CREATE, + FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT | + FILE_NON_DIRECTORY_FILE, + SMB2_IMPERSONATION_IMPERSONATION, + 0); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, cli_symlink_create_done, req); + tevent_req_set_callback(subreq, cli_create_reparse_point_opened, req); return req; } -static void cli_symlink_create_done(struct tevent_req *subreq) +static void cli_create_reparse_point_opened(struct tevent_req *subreq) { - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct cli_symlink_state *state = tevent_req_data( - req, struct cli_symlink_state); + struct tevent_req *req = + tevent_req_callback_data(subreq, struct tevent_req); + struct cli_create_reparse_point_state *state = + tevent_req_data(req, struct cli_create_reparse_point_state); NTSTATUS status; status = cli_ntcreate_recv(subreq, &state->fnum, NULL); @@ -97,33 +102,25 @@ static void cli_symlink_create_done(struct tevent_req *subreq) return; } - if (!symlink_reparse_buffer_marshall( - state->link_target, NULL, 0, state->flags, state, - &state->in.data, &state->in.length)) { - tevent_req_oom(req); - return; - } - - subreq = cli_fsctl_send( - state, - state->ev, - state->cli, - state->fnum, - FSCTL_SET_REPARSE_POINT, - &state->in, - 0); + subreq = cli_fsctl_send(state, + state->ev, + state->cli, + state->fnum, + FSCTL_SET_REPARSE_POINT, + &state->reparse_blob, + 0); if (tevent_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq, cli_symlink_set_reparse_done, req); + tevent_req_set_callback(subreq, cli_create_reparse_point_done, req); } -static void cli_symlink_set_reparse_done(struct tevent_req *subreq) +static void cli_create_reparse_point_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); - struct cli_symlink_state *state = tevent_req_data( - req, struct cli_symlink_state); + struct cli_create_reparse_point_state *state = + tevent_req_data(req, struct cli_create_reparse_point_state); state->set_reparse_status = cli_fsctl_recv(subreq, NULL, NULL); TALLOC_FREE(subreq); @@ -134,7 +131,9 @@ static void cli_symlink_set_reparse_done(struct tevent_req *subreq) if (tevent_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq, cli_symlink_close_done, req); + tevent_req_set_callback(subreq, + cli_create_reparse_point_closed, + req); return; } subreq = cli_nt_delete_on_close_send( @@ -142,15 +141,17 @@ static void cli_symlink_set_reparse_done(struct tevent_req *subreq) if (tevent_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq, cli_symlink_delete_on_close_done, req); + tevent_req_set_callback(subreq, + cli_create_reparse_point_doc_done, + req); } -static void cli_symlink_delete_on_close_done(struct tevent_req *subreq) +static void cli_create_reparse_point_doc_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); - struct cli_symlink_state *state = tevent_req_data( - req, struct cli_symlink_state); + struct cli_create_reparse_point_state *state = + tevent_req_data(req, struct cli_create_reparse_point_state); /* * Ignore status, we can't do much anyway in case of failure @@ -163,15 +164,15 @@ static void cli_symlink_delete_on_close_done(struct tevent_req *subreq) if (tevent_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq, cli_symlink_close_done, req); + tevent_req_set_callback(subreq, cli_create_reparse_point_closed, req); } -static void cli_symlink_close_done(struct tevent_req *subreq) +static void cli_create_reparse_point_closed(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); - struct cli_symlink_state *state = tevent_req_data( - req, struct cli_symlink_state); + struct cli_create_reparse_point_state *state = + tevent_req_data(req, struct cli_create_reparse_point_state); NTSTATUS status; status = cli_close_recv(subreq); @@ -186,6 +187,61 @@ static void cli_symlink_close_done(struct tevent_req *subreq) tevent_req_done(req); } +NTSTATUS cli_create_reparse_point_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +struct cli_symlink_state { + uint8_t dummy; +}; + +static void cli_symlink_done(struct tevent_req *subreq); + +struct tevent_req *cli_symlink_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *link_target, + const char *newpath, + uint32_t flags) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct cli_symlink_state *state = NULL; + DATA_BLOB blob = {}; + bool ok; + + req = tevent_req_create(mem_ctx, &state, struct cli_symlink_state); + if (req == NULL) { + return NULL; + } + + ok = symlink_reparse_buffer_marshall(link_target, + NULL, + 0, + flags, + state, + &blob.data, + &blob.length); + + if (!ok) { + tevent_req_oom(req); + return tevent_req_post(req, ev); + } + + subreq = cli_create_reparse_point_send(state, ev, cli, newpath, blob); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_symlink_done, req); + return req; +} + +static void cli_symlink_done(struct tevent_req *subreq) +{ + NTSTATUS status = cli_symlink_recv(subreq); + tevent_req_simple_finish_ntstatus(subreq, status); +} + NTSTATUS cli_symlink_recv(struct tevent_req *req) { return tevent_req_simple_recv_ntstatus(req); diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index a7c58264f0e..0ca6fd01d01 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -1024,6 +1024,13 @@ NTSTATUS cli_trans(TALLOC_CTX *mem_ctx, struct cli_state *cli, /* The following definitions come from libsmb/clisymlink.c */ +struct tevent_req *cli_create_reparse_point_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *fname, + DATA_BLOB reparse_blob); +NTSTATUS cli_create_reparse_point_recv(struct tevent_req *req); + struct tevent_req *cli_symlink_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,