int buffer_next_int16(xrtp_buffer_t * buf, int16 * ret){ if(buf->pos + sizeof(int16) > buf->len){ return 0; } if(HOST_BYTEORDER == BIGEND_ORDER) *ret = RSVALS(&(buf->data), buf->pos); else *ret = SVALS(&(buf->data), buf->pos); buffer_log(("buffer_next_int16: (%d) at buf[%d]@%d\n", *ret, buf->pos, (int)buf->data)); buf->pos += sizeof(int16); return sizeof(int16); }
/* Send a negprot command. */ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req) { struct smbcli_transport *transport = req->transport; int protocol; if (!smbcli_request_receive(req) || smbcli_request_is_error(req)) { return smbcli_request_destroy(req); } SMBCLI_CHECK_MIN_WCT(req, 1); protocol = SVALS(req->in.vwv, VWV(0)); if (protocol >= ARRAY_SIZE(prots) || protocol < 0) { req->status = NT_STATUS_UNSUCCESSFUL; return smbcli_request_destroy(req); } transport->negotiate.protocol = prots[protocol].prot; if (transport->negotiate.protocol >= PROTOCOL_NT1) { NTTIME ntt; /* NT protocol */ SMBCLI_CHECK_WCT(req, 17); transport->negotiate.sec_mode = CVAL(req->in.vwv,VWV(1)); transport->negotiate.max_mux = SVAL(req->in.vwv,VWV(1)+1); transport->negotiate.max_xmit = IVAL(req->in.vwv,VWV(3)+1); transport->negotiate.sesskey = IVAL(req->in.vwv,VWV(7)+1); transport->negotiate.capabilities = IVAL(req->in.vwv,VWV(9)+1); /* this time arrives in real GMT */ ntt = smbcli_pull_nttime(req->in.vwv, VWV(11)+1); transport->negotiate.server_time = nt_time_to_unix(ntt); transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(15)+1) * 60; transport->negotiate.key_len = CVAL(req->in.vwv,VWV(16)+1); if (transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) { if (req->in.data_size < 16) { goto failed; } transport->negotiate.server_guid = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, 16); transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data + 16, req->in.data_size - 16); } else { if (req->in.data_size < (transport->negotiate.key_len)) { goto failed; } transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, transport->negotiate.key_len); smbcli_req_pull_string(&req->in.bufinfo, transport, &transport->negotiate.server_domain, req->in.data+transport->negotiate.key_len, req->in.data_size-transport->negotiate.key_len, STR_UNICODE|STR_NOALIGN); /* here comes the server name */ } if (transport->negotiate.capabilities & CAP_RAW_MODE) { transport->negotiate.readbraw_supported = true; transport->negotiate.writebraw_supported = true; } if (transport->negotiate.capabilities & CAP_LOCK_AND_READ) transport->negotiate.lockread_supported = true; } else if (transport->negotiate.protocol >= PROTOCOL_LANMAN1) { SMBCLI_CHECK_WCT(req, 13); transport->negotiate.sec_mode = SVAL(req->in.vwv,VWV(1)); transport->negotiate.max_xmit = SVAL(req->in.vwv,VWV(2)); transport->negotiate.sesskey = IVAL(req->in.vwv,VWV(6)); transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(10)) * 60; /* this time is converted to GMT by raw_pull_dos_date */ transport->negotiate.server_time = raw_pull_dos_date(transport, req->in.vwv+VWV(8)); if ((SVAL(req->in.vwv,VWV(5)) & 0x1)) { transport->negotiate.readbraw_supported = 1; } if ((SVAL(req->in.vwv,VWV(5)) & 0x2)) { transport->negotiate.writebraw_supported = 1; } transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, req->in.data_size); } else { /* the old core protocol */ transport->negotiate.sec_mode = 0; transport->negotiate.server_time = time(NULL); transport->negotiate.max_xmit = transport->options.max_xmit; transport->negotiate.server_zone = get_time_zone(transport->negotiate.server_time); } /* a way to force ascii SMB */ if (!transport->options.unicode) { transport->negotiate.capabilities &= ~CAP_UNICODE; } if (!transport->options.ntstatus_support) { transport->negotiate.capabilities &= ~CAP_STATUS32; } if (!transport->options.use_level2_oplocks) { transport->negotiate.capabilities &= ~CAP_LEVEL_II_OPLOCKS; } failed: return smbcli_request_destroy(req); }
BOOL cli_negprot(struct cli_state *cli) { char *p; int numprots; int plength; memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ for (plength=0,numprots=0; prots[numprots].name && prots[numprots].prot<=cli->protocol; numprots++) plength += strlen(prots[numprots].name)+2; set_message(cli->outbuf,0,plength,True); p = smb_buf(cli->outbuf); for (numprots=0; prots[numprots].name && prots[numprots].prot<=cli->protocol; numprots++) { *p++ = 2; p += clistr_push(cli, p, prots[numprots].name, -1, STR_CONVERT|STR_TERMINATE); } SCVAL(cli->outbuf,smb_com,SMBnegprot); cli_setup_packet(cli); SCVAL(smb_buf(cli->outbuf),0,2); cli_send_smb(cli); if (!cli_receive_smb(cli)) return False; show_msg(cli->inbuf); if (cli_is_error(cli) || ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { return(False); } cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1); cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1); cli->serverzone *= 60; /* this time arrives in real GMT */ cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); if (cli->capabilities & CAP_RAW_MODE) { cli->readbraw_supported = True; cli->writebraw_supported = True; } /* work out if they sent us a workgroup */ if (smb_buflen(cli->inbuf) > 8) { clistr_pull(cli, cli->server_domain, smb_buf(cli->inbuf)+8, sizeof(cli->server_domain), smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); cli->sesskey = IVAL(cli->inbuf,smb_vwv6); cli->serverzone = SVALS(cli->inbuf,smb_vwv10); cli->serverzone *= 60; /* this time is converted to GMT by make_unix_date */ cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); } else { /* the old core protocol */ cli->sec_mode = 0; cli->serverzone = TimeDiff(time(NULL)); } cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); /* a way to force ascii SMB */ if (getenv("CLI_FORCE_ASCII")) { cli->capabilities &= ~CAP_UNICODE; } return True; }