/* send a message */ bool smbcli_request_send(struct smbcli_request *req) { if (IVAL(req->out.buffer, 0) == 0) { _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE); } smbcli_request_calculate_sign_mac(req); smbcli_transport_send(req); return true; }
/* send a session request */ struct smbcli_request *smbcli_transport_connect_send(struct smbcli_transport *transport, struct nbt_name *calling, struct nbt_name *called) { uint8_t *p; struct smbcli_request *req; DATA_BLOB calling_blob, called_blob; TALLOC_CTX *tmp_ctx = talloc_new(transport); NTSTATUS status; status = nbt_name_dup(transport, called, &transport->called); if (!NT_STATUS_IS_OK(status)) goto failed; status = nbt_name_to_blob(tmp_ctx, &calling_blob, calling); if (!NT_STATUS_IS_OK(status)) goto failed; status = nbt_name_to_blob(tmp_ctx, &called_blob, called); if (!NT_STATUS_IS_OK(status)) goto failed; /* allocate output buffer */ req = smbcli_request_setup_nonsmb(transport, NBT_HDR_SIZE + calling_blob.length + called_blob.length); if (req == NULL) goto failed; /* put in the destination name */ p = req->out.buffer + NBT_HDR_SIZE; memcpy(p, called_blob.data, called_blob.length); p += called_blob.length; memcpy(p, calling_blob.data, calling_blob.length); p += calling_blob.length; _smb_setlen(req->out.buffer, PTR_DIFF(p, req->out.buffer) - NBT_HDR_SIZE); SCVAL(req->out.buffer,0,0x81); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); goto failed; } talloc_free(tmp_ctx); return req; failed: talloc_free(tmp_ctx); return NULL; }
BOOL cli_session_request(struct cli_state *cli, struct nmb_name *calling, struct nmb_name *called) { char *p; int len = 4; extern pstring user_socket_options; /* 445 doesn't have session request */ if (cli->port == 445) return True; /* send a session request (RFC 1002) */ memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); /* put in the destination name */ p = cli->outbuf+len; name_mangle(cli->called .name, p, cli->called .name_type); len += name_len(p); /* and my name */ p = cli->outbuf+len; name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); /* setup the packet length * Remove four bytes from the length count, since the length * field in the NBT Session Service header counts the number * of bytes which follow. The cli_send_smb() function knows * about this and accounts for those four bytes. * CRH. */ len -= 4; _smb_setlen(cli->outbuf,len); SCVAL(cli->outbuf,0,0x81); #ifdef WITH_SSL retry: #endif /* WITH_SSL */ cli_send_smb(cli); DEBUG(5,("Sent session request\n")); if (!cli_receive_smb(cli)) return False; if (CVAL(cli->inbuf,0) == 0x84) { /* C. Hoch 9/14/95 Start */ /* For information, here is the response structure. * We do the byte-twiddling to for portability. struct RetargetResponse{ unsigned char type; unsigned char flags; int16 length; int32 ip_addr; int16 port; }; */ int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); /* SESSION RETARGET */ putip((char *)&cli->dest_ip,cli->inbuf+4); cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); if (cli->fd == -1) return False; DEBUG(3,("Retargeted\n")); set_socket_options(cli->fd,user_socket_options); /* Try again */ { static int depth; BOOL ret; if (depth > 4) { DEBUG(0,("Retarget recursion - failing\n")); return False; } depth++; ret = cli_session_request(cli, calling, called); depth--; return ret; } } /* C. Hoch 9/14/95 End */ #ifdef WITH_SSL if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ if (!sslutil_fd_is_ssl(cli->fd)){ if (sslutil_connect(cli->fd) == 0) goto retry; } } #endif /* WITH_SSL */ if (CVAL(cli->inbuf,0) != 0x82) { /* This is the wrong place to put the error... JRA. */ cli->rap_error = CVAL(cli->inbuf,4); return False; } return(True); }