From: Volker Lendecke Date: Thu, 4 Jun 2020 06:38:31 +0000 (+0200) Subject: libsmb: Use SMBgetattrE in cli_qfileinfo_basic_send() if necessary X-Git-Tag: ldb-2.2.0~188 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1a14d8cf7ecac2ff335339739092fa85d654ad41;p=thirdparty%2Fsamba.git libsmb: Use SMBgetattrE in cli_qfileinfo_basic_send() if necessary This is a behaviour change: Before this patch, independent of the actual protocol we tried to do the trans2 getinfo call. All the remaining callers just do a direct fallback to SMBgetattrE when that fails without even looking at the error code. Here we deterministically decide after the negotiated protocol which flavour to use without a fallback. It *might* be relevant for very old embedded systems that we don't know, but if we break something we can easily fix it. Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index ad1f4fe618d..98ddfd67209 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -1309,6 +1309,7 @@ struct cli_qfileinfo_basic_state { }; static void cli_qfileinfo_basic_done(struct tevent_req *subreq); +static void cli_qfileinfo_basic_doneE(struct tevent_req *subreq); struct tevent_req *cli_qfileinfo_basic_send( TALLOC_CTX *mem_ctx, @@ -1325,11 +1326,29 @@ struct tevent_req *cli_qfileinfo_basic_send( return NULL; } - /* if its a win95 server then fail this - win95 totally screws it - up */ - if (cli->win95) { - tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); - return tevent_req_post(req, ev); + if ((smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN2) || + cli->win95) { + /* + * According to + * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/3d9d8f3e-dc70-410d-a3fc-6f4a881e8cab + * SMB_COM_TRANSACTION2 used in cli_qfileinfo_send() + * further down was introduced with the LAN Manager + * 1.2 dialect, which we encode as PROTOCOL_LANMAN2. + * + * The "win95" check was introduced with commit + * 27e5850fd3e1c8 in 1998. Hard to check these days, + * but leave it in. + * + * Use a lowerlevel fallback in both cases. + */ + + subreq = cli_getattrE_send(state, ev, cli, fnum); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback( + subreq, cli_qfileinfo_basic_doneE, req); + return req; } subreq = cli_qfileinfo_send( @@ -1376,6 +1395,28 @@ static void cli_qfileinfo_basic_done(struct tevent_req *subreq) tevent_req_done(req); } +static void cli_qfileinfo_basic_doneE(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_qfileinfo_basic_state *state = tevent_req_data( + req, struct cli_qfileinfo_basic_state); + NTSTATUS status; + + status = cli_getattrE_recv( + subreq, + &state->attr, + &state->size, + &state->change_time.tv_sec, + &state->access_time.tv_sec, + &state->write_time.tv_sec); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + tevent_req_done(req); +} + NTSTATUS cli_qfileinfo_basic_recv( struct tevent_req *req, uint32_t *attr,