Ejemplo n.º 1
0
/****************************************************************************
check for existance of a dir
****************************************************************************/
static BOOL chkpath(char *path,BOOL report)
{
  pstring path2;
  pstring inbuf,outbuf;
  char *p;

  pstrcpy(path2,path);
  trim_string(path2,NULL,"\\");
  if (!*path2) *path2 = '\\';

  bzero(outbuf,smb_size);
  set_message(outbuf,0,4 + strlen(path2),True);
  SCVAL(outbuf,smb_com,SMBchkpth);
  SSVAL(outbuf,smb_tid,cnum);
  cli_setup_pkt(outbuf);

  p = smb_buf(outbuf);
  *p++ = 4;
  pstrcpy(p,path2);

#if 0
  {
	  /* this little bit of code can be used to extract NT error codes.
	     Just feed a bunch of "cd foo" commands to smbclient then watch
	     in netmon (tridge) */
	  static int code=0;
	  SIVAL(outbuf, smb_rcls, code | 0xC0000000);
	  SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | (1<<14));
	  code++;
  }
#endif

  send_smb(Client,outbuf);
  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);

  if (report && CVAL(inbuf,smb_rcls) != 0)
    DEBUG(2,("chkpath: %s\n",smb_errstr(inbuf)));

  return(CVAL(inbuf,smb_rcls) == 0);
}
Ejemplo n.º 2
0
BOOL cli_receive_smb(struct cli_state *cli)
{
	extern int smb_read_error;
	BOOL ret;

	/* fd == -1 causes segfaults -- Tom ([email protected]) */
	if (cli->fd == -1)
		return False; 

 again:
	ret = client_receive_smb(cli->fd,cli->inbuf,abs(cli->timeout));
	
	if (ret) {
		/* it might be an oplock break request */
		if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) &&
		    CVAL(cli->inbuf,smb_com) == SMBlockingX &&
		    SVAL(cli->inbuf,smb_vwv6) == 0 &&
		    SVAL(cli->inbuf,smb_vwv7) == 0) {
			if (cli->oplock_handler) {
				int fnum = SVAL(cli->inbuf,smb_vwv2);
				unsigned char level = CVAL(cli->inbuf,smb_vwv3+1);
				if (!cli->oplock_handler(cli, fnum, level)) return False;
			}
			/* try to prevent loops */
			SCVAL(cli->inbuf,smb_com,0xFF);
			goto again;
		}
	}

        /* If the server is not responding, note that now */
	if (!ret) {
		cli->smb_rw_error = smb_read_error;
		close(cli->fd);
		cli->fd = -1;
	}

	return ret;
}
Ejemplo n.º 3
0
bool cli_receive_smb(struct cli_state *cli)
{
	ssize_t len;
	uint16_t mid;
	uint32_t seqnum;

	/* fd == -1 causes segfaults -- Tom ([email protected]) */
	if (cli->fd == -1)
		return false; 

 again:
	len = client_receive_smb(cli, 0);
	
	if (len > 0) {
		/* it might be an oplock break request */
		if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) &&
		    CVAL(cli->inbuf,smb_com) == SMBlockingX &&
		    SVAL(cli->inbuf,smb_vwv6) == 0 &&
		    SVAL(cli->inbuf,smb_vwv7) == 0) {
			if (cli->oplock_handler) {
				int fnum = SVAL(cli->inbuf,smb_vwv2);
				unsigned char level = CVAL(cli->inbuf,smb_vwv3+1);
				if (!NT_STATUS_IS_OK(cli->oplock_handler(cli, fnum, level))) {
					return false;
				}
			}
			/* try to prevent loops */
			SCVAL(cli->inbuf,smb_com,0xFF);
			goto again;
		}
	}

	/* If the server is not responding, note that now */
	if (len < 0) {
                DEBUG(0, ("Receiving SMB: Server stopped responding\n"));
		close(cli->fd);
		cli->fd = -1;
		return false;
	}

	mid = SVAL(cli->inbuf,smb_mid);
	seqnum = cli_state_get_seqnum(cli, mid);

	if (!cli_check_sign_mac(cli, cli->inbuf, seqnum+1)) {
		/*
		 * If we get a signature failure in sessionsetup, then
		 * the server sometimes just reflects the sent signature
		 * back to us. Detect this and allow the upper layer to
		 * retrieve the correct Windows error message.
		 */
		if (CVAL(cli->outbuf,smb_com) == SMBsesssetupX &&
			(smb_len(cli->inbuf) > (smb_ss_field + 8 - 4)) &&
			(SVAL(cli->inbuf,smb_flg2) & FLAGS2_SMB_SECURITY_SIGNATURES) &&
			memcmp(&cli->outbuf[smb_ss_field],&cli->inbuf[smb_ss_field],8) == 0 &&
			cli_is_error(cli)) {

			/*
			 * Reflected signature on login error. 
			 * Set bad sig but don't close fd.
			 */
			cli->smb_rw_error = SMB_READ_BAD_SIG;
			return true;
		}

		DEBUG(0, ("SMB Signature verification failed on incoming packet!\n"));
		cli->smb_rw_error = SMB_READ_BAD_SIG;
		close(cli->fd);
		cli->fd = -1;
		return false;
	};
	return true;
}