X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Flibsmb%2Fcliconnect.c;h=65f6924a688ddcb7f306bc321226ec6525658083;hb=f13404e27b00f826a11684e69cff82ae0023fc91;hp=53d46be58502d0cdee362baeb60d314d01722d58;hpb=036fcafe242363bd290b179c21406dafc0d3a678;p=samba.git diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 53d46be5850..65f6924a688 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -19,10 +19,14 @@ */ #include "includes.h" +#include "popt_common.h" #include "../libcli/auth/libcli_auth.h" #include "../libcli/auth/spnego.h" #include "smb_krb5.h" -#include "ntlmssp.h" +#include "../libcli/auth/ntlmssp.h" +#include "libads/kerberos_proto.h" +#include "krb5_env.h" +#include "async_smb.h" static const struct { int prot; @@ -854,14 +858,14 @@ static struct tevent_req *cli_session_setup_kerberos_send( cli_temp_set_signing(cli); /* - * Ok, this is cheated: spnego_gen_negTokenTarg can block if + * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if * we have to acquire a ticket. To be fixed later :-) */ - rc = spnego_gen_negTokenTarg(principal, 0, &state->negTokenTarg, + rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg, &state->session_key_krb5, 0, NULL); if (rc) { DEBUG(1, ("cli_session_setup_kerberos: " - "spnego_gen_negTokenTarg failed: %s\n", + "spnego_gen_krb5_negTokenInit failed: %s\n", error_message(rc))); state->ads_status = ADS_ERROR_KRB5(rc); tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); @@ -969,7 +973,7 @@ static int cli_session_setup_ntlmssp_state_destructor( struct cli_session_setup_ntlmssp_state *state) { if (state->ntlmssp_state != NULL) { - ntlmssp_end(&state->ntlmssp_state); + TALLOC_FREE(state->ntlmssp_state); } return 0; } @@ -984,6 +988,7 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( struct cli_session_setup_ntlmssp_state *state; NTSTATUS status; DATA_BLOB blob_out; + const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL}; req = tevent_req_create(mem_ctx, &state, struct cli_session_setup_ntlmssp_state); @@ -1000,7 +1005,11 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( cli_temp_set_signing(cli); - status = ntlmssp_client_start(&state->ntlmssp_state); + status = ntlmssp_client_start(state, + global_myname(), + lp_workgroup(), + lp_client_ntlmv2_auth(), + &state->ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { goto fail; } @@ -1028,7 +1037,7 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( goto fail; } - state->blob_out = gen_negTokenInit(OID_NTLMSSP, blob_out); + state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL); data_blob_free(&blob_out); subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out); @@ -1061,7 +1070,7 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) if (NT_STATUS_IS_OK(status)) { if (state->cli->server_domain[0] == '\0') { fstrcpy(state->cli->server_domain, - state->ntlmssp_state->server_domain); + state->ntlmssp_state->server.netbios_domain); } cli_set_session_key( state->cli, state->ntlmssp_state->session_key); @@ -1075,7 +1084,7 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) return; } TALLOC_FREE(subreq); - ntlmssp_end(&state->ntlmssp_state); + TALLOC_FREE(state->ntlmssp_state); tevent_req_done(req); return; } @@ -1093,11 +1102,11 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { DATA_BLOB tmp_blob = data_blob_null; /* the server might give us back two challenges */ - parse_ret = spnego_parse_challenge(blob_in, &msg_in, + parse_ret = spnego_parse_challenge(state, blob_in, &msg_in, &tmp_blob); data_blob_free(&tmp_blob); } else { - parse_ret = spnego_parse_auth_response(blob_in, status, + parse_ret = spnego_parse_auth_response(state, blob_in, status, OID_NTLMSSP, &msg_in); } state->turn += 1; @@ -1118,12 +1127,12 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { TALLOC_FREE(subreq); - ntlmssp_end(&state->ntlmssp_state); + TALLOC_FREE(state->ntlmssp_state); tevent_req_nterror(req, status); return; } - state->blob_out = spnego_gen_auth(blob_out); + state->blob_out = spnego_gen_auth(state, blob_out); TALLOC_FREE(subreq); if (tevent_req_nomem(state->blob_out.data, req)) { return; @@ -1220,7 +1229,8 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, * negprot reply. It is WRONG to depend on the principal sent in the * negprot reply, but right now we do it. If we don't receive one, * we try to best guess, then fall back to NTLM. */ - if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { + if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) || + OIDs[0] == NULL) { data_blob_free(&blob); return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } @@ -1243,6 +1253,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, status = cli_set_username(cli, user); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(principal); return ADS_ERROR_NT(status); } @@ -1268,10 +1279,9 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, } } - /* If we get a bad principal, try to guess it if - we have a valid host NetBIOS name. + /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us */ - if (strequal(principal, ADS_IGNORE_PRINCIPAL)) { + if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) { TALLOC_FREE(principal); } @@ -1280,23 +1290,11 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, !strequal(STAR_SMBSERVER, cli->desthost)) { char *realm = NULL; - char *machine = NULL; char *host = NULL; - DEBUG(3,("cli_session_setup_spnego: got a " - "bad server principal, trying to guess ...\n")); + DEBUG(3,("cli_session_setup_spnego: using target " + "hostname not SPNEGO principal\n")); host = strchr_m(cli->desthost, '.'); - if (host) { - /* We had a '.' in the name. */ - machine = SMB_STRNDUP(cli->desthost, - host - cli->desthost); - } else { - machine = SMB_STRDUP(cli->desthost); - } - if (machine == NULL) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } - if (dest_realm) { realm = SMB_STRDUP(dest_realm); strupper_m(realm); @@ -1311,21 +1309,11 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, } if (realm && *realm) { - if (host) { - /* DNS name. */ - principal = talloc_asprintf(talloc_tos(), - "cifs/%s@%s", - cli->desthost, - realm); - } else { - /* NetBIOS name, use machine account. */ - principal = talloc_asprintf(talloc_tos(), - "%s$@%s", - machine, - realm); - } + principal = talloc_asprintf(talloc_tos(), + "cifs/%s@%s", + cli->desthost, + realm); if (!principal) { - SAFE_FREE(machine); SAFE_FREE(realm); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -1333,7 +1321,6 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, "server principal=%s\n", principal ? principal : "")); } - SAFE_FREE(machine); SAFE_FREE(realm); } @@ -1488,7 +1475,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli, struct cli_ulogoff_state { struct cli_state *cli; - uint16_t vwv[2]; + uint16_t vwv[3]; }; static void cli_ulogoff_done(struct tevent_req *subreq); @@ -1751,21 +1738,24 @@ static void cli_tcon_andx_done(struct tevent_req *subreq) struct cli_tcon_andx_state *state = tevent_req_data( req, struct cli_tcon_andx_state); struct cli_state *cli = state->cli; - char *inbuf = (char *)cli_smb_inbuf(subreq); + uint8_t *in; + char *inbuf; uint8_t wct; uint16_t *vwv; uint32_t num_bytes; uint8_t *bytes; NTSTATUS status; - status = cli_smb_recv(subreq, NULL, NULL, 0, &wct, &vwv, + status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv, &num_bytes, &bytes); + TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(subreq); tevent_req_nterror(req, status); return; } + inbuf = (char *)in; + clistr_pull(inbuf, cli->dev, bytes, sizeof(fstring), num_bytes, STR_TERMINATE|STR_ASCII); @@ -2030,11 +2020,12 @@ static void cli_negprot_done(struct tevent_req *subreq) uint8_t *bytes; NTSTATUS status; uint16_t protnum; + uint8_t *inbuf; - status = cli_smb_recv(subreq, NULL, NULL, 1, &wct, &vwv, + status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv, &num_bytes, &bytes); + TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(subreq); tevent_req_nterror(req, status); return; } @@ -2121,6 +2112,11 @@ static void cli_negprot_done(struct tevent_req *subreq) SAFE_FREE(cli->inbuf); cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN); cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN); + if (!cli->outbuf || !cli->inbuf) { + tevent_req_nterror(req, + NT_STATUS_NO_MEMORY); + return; + } cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE; } @@ -2133,8 +2129,8 @@ static void cli_negprot_done(struct tevent_req *subreq) cli->serverzone = SVALS(vwv + 10, 0); cli->serverzone *= 60; /* this time is converted to GMT by make_unix_date */ - cli->servertime = cli_make_unix_date( - cli, (char *)(vwv + 8)); + cli->servertime = make_unix_date( + (char *)(vwv + 8), cli->serverzone); cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0); cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0); cli->secblob = data_blob(bytes, num_bytes); @@ -2209,6 +2205,7 @@ bool cli_session_request(struct cli_state *cli, { char *p; int len = 4; + int namelen = 0; char *tmp; /* 445 doesn't have session request */ @@ -2227,8 +2224,11 @@ bool cli_session_request(struct cli_state *cli, } p = cli->outbuf+len; - memcpy(p, tmp, name_len(tmp)); - len += name_len(tmp); + namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp)); + if (namelen > 0) { + memcpy(p, tmp, namelen); + len += namelen; + } TALLOC_FREE(tmp); /* and my name */ @@ -2240,8 +2240,11 @@ bool cli_session_request(struct cli_state *cli, } p = cli->outbuf+len; - memcpy(p, tmp, name_len(tmp)); - len += name_len(tmp); + namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp)); + if (namelen > 0) { + memcpy(p, tmp, namelen); + len += namelen; + } TALLOC_FREE(tmp); /* send a session request (RFC 1002) */