📄 cliconnect.c
字号:
} return True; } /* otherwise do a NT1 style session setup */ return cli_session_setup_nt1(cli, user, pass, passlen, ntpass, ntpasslen, workgroup); }/**************************************************************************** Send a uloggoff.*****************************************************************************/BOOL cli_ulogoff(struct cli_state *cli){ memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBulogoffX); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ cli_send_smb(cli); if (!cli_receive_smb(cli)) return False; if (cli_is_error(cli)) { return False; } cli->cnum = -1; return True;}/**************************************************************************** Send a tconX.****************************************************************************/BOOL cli_send_tconX(struct cli_state *cli, const char *share, const char *dev, const char *pass, int passlen){ fstring fullshare, pword; char *p; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); fstrcpy(cli->share, share); /* in user level security don't send a password now */ if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { passlen = 1; pass = ""; } if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) { if (!lp_client_lanman_auth()) { DEBUG(1, ("Server requested LANMAN password (share-level security) but 'client use lanman auth'" " is disabled\n")); return False; } /* * Non-encrypted passwords - convert to DOS codepage before encryption. */ passlen = 24; SMBencrypt(pass,cli->secblob.data,(uchar *)pword); } else { if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) { if (!lp_client_plaintext_auth() && (*pass)) { DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" " is disabled\n")); return False; } /* * Non-encrypted passwords - convert to DOS codepage before using. */ passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); } else { memcpy(pword, pass, passlen); } } slprintf(fullshare, sizeof(fullshare)-1, "\\\\%s\\%s", cli->desthost, share); set_message(cli->outbuf,4, 0, True); SCVAL(cli->outbuf,smb_com,SMBtconX); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv3,passlen); p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER); p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII); cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) return False; if (cli_is_error(cli)) return False; clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII); if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { /* almost certainly win95 - enable bug fixes */ cli->win95 = True; } /* Make sure that we have the optional support 16-bit field. WCT > 2 */ /* Avoids issues when connecting to Win9x boxes sharing files */ cli->dfsroot = False; if ( (CVAL(cli->inbuf, smb_wct))>2 && cli->protocol >= PROTOCOL_LANMAN2 ) cli->dfsroot = (SVAL( cli->inbuf, smb_vwv2 ) & SMB_SHARE_IN_DFS) ? True : False; cli->cnum = SVAL(cli->inbuf,smb_tid); return True;}/**************************************************************************** Send a tree disconnect.****************************************************************************/BOOL cli_tdis(struct cli_state *cli){ memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBtdis); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); cli_send_smb(cli); if (!cli_receive_smb(cli)) return False; if (cli_is_error(cli)) { return False; } cli->cnum = -1; return True;}/**************************************************************************** Send a negprot command.****************************************************************************/void cli_negprot_send(struct cli_state *cli){ char *p; int numprots; if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ set_message(cli->outbuf,0,0,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_TERMINATE); } SCVAL(cli->outbuf,smb_com,SMBnegprot); cli_setup_bcc(cli, p); cli_setup_packet(cli); SCVAL(smb_buf(cli->outbuf),0,2); cli_send_smb(cli);}/**************************************************************************** Send a negprot command.****************************************************************************/BOOL cli_negprot(struct cli_state *cli){ char *p; int numprots; int plength; if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; 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_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) && cli->sign_info.mandatory_signing) { DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); return False; } 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); cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); 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 (!(cli->capabilities & CAP_EXTENDED_SECURITY) && 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); } /* * As signing is slow we only turn it on if either the client or * the server require it. JRA. */ if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { /* Fail if server says signing is mandatory and we don't want to support it. */ if (!cli->sign_info.allow_smb_signing) { DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); return False; } cli->sign_info.negotiated_smb_signing = True; cli->sign_info.mandatory_signing = True; } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) { /* Fail if client says signing is mandatory and the server doesn't support it. */ if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) { DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n")); return False; } cli->sign_info.negotiated_smb_signing = True; cli->sign_info.mandatory_signing = True; } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) { cli->sign_info.negotiated_smb_signing = True; } if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) { SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); cli->outbuf = (char *)SMB_MALLOC(CLI_MAX_LARGE_READX_SIZE+SAFETY_MARGIN); cli->inbuf = (char *)SMB_MALLOC(CLI_MAX_LARGE_READX_SIZE+SAFETY_MARGIN); cli->bufsize = CLI_MAX_LARGE_READX_SIZE; } } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); cli->max_mux = SVAL(cli->inbuf, smb_vwv3); 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 = cli_make_unix_date(cli,cli->inbuf+smb_vwv8); cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); } else { /* the old core protocol */ cli->use_spnego = False; cli->sec_mode = 0; cli->serverzone = get_time_zone(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;}/**************************************************************************** Send a session request. See rfc1002.txt 4.3 and 4.3.2.****************************************************************************/BOOL cli_session_request(struct cli_state *cli, struct nmb_name *calling, struct nmb_name *called){ char *p; int len = 4; 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); /* 445 doesn't have session request */ if (cli->port == 445) return True; /* send a session request (RFC 1002) */ /* 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); 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 */ 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);}/**************************************************************************** Open the client sockets.****************************************************************************/BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip){ int name_type = 0x20; char *p; /* reasonable default hostname */ if (!host) host = "*SMBSERVER"; fstrcpy(cli->desthost, host);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -