Exemple #1
0
 int buffer_add_int16(xrtp_buffer_t * buf, int16 word)
 {
    if(buf->len_data + sizeof(int16) > buf->len)
    {
       return OS_EREFUSE;
    }

    if(buf->byte_order == BIGEND_ORDER)
    {
       buffer_log(("buffer_add_int16: Add BE(%d) to buf[%d]@%d\n", word, buf->pos, (int)buf->data));
       RSSVALS(buf->data, buf->len_data, word);
    }
    else
    {
       buffer_log(("buffer_add_int16: Add LE(%d) to buf[%d]@%d\n", word, buf->pos, (int)buf->data));
       SSVALS(buf->data, buf->len_data, word);
    }

    buf->len_data += sizeof(int16);
    buf->pos += sizeof(int16);

    return OS_OK;
 }
Exemple #2
0
static int reply_nt1(char *inbuf, char *outbuf)
{
	/* dual names + lock_and_read + nt SMBs + remote API calls */
	int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
		CAP_LEVEL_II_OPLOCKS;

	int secword=0;
	char *p, *q;
	BOOL negotiate_spnego = False;
	time_t t = time(NULL);

	global_encrypted_passwords_negotiated = lp_encrypted_passwords();

	/* Check the flags field to see if this is Vista.
	   WinXP sets it and Vista does not. But we have to 
	   distinguish from NT which doesn't set it either. */

	if ( (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY) &&
		((SVAL(inbuf, smb_flg2) & FLAGS2_UNKNOWN_BIT4) == 0) ) 
	{
	    	/* Don't override the SAMBA or CIFSFS arch */
		if ((get_remote_arch() != RA_SAMBA) && (get_remote_arch() != RA_CIFSFS)) {
			set_remote_arch( RA_VISTA );
		}
	}

	/* do spnego in user level security if the client
	   supports it and we can do encrypted passwords */
	
	if (global_encrypted_passwords_negotiated && 
	    (lp_security() != SEC_SHARE) &&
	    lp_use_spnego() &&
	    (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
		negotiate_spnego = True;
		capabilities |= CAP_EXTENDED_SECURITY;
		add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
		/* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already
			partially constructed. */
		SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY);
	}
	
	capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;

	if (lp_unix_extensions()) {
		capabilities |= CAP_UNIX;
	}
	
	if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
		capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
	
	if (SMB_OFF_T_BITS == 64)
		capabilities |= CAP_LARGE_FILES;

	if (lp_readraw() && lp_writeraw())
		capabilities |= CAP_RAW_MODE;
	
	if (lp_nt_status_support())
		capabilities |= CAP_STATUS32;
	
	if (lp_host_msdfs())
		capabilities |= CAP_DFS;
	
	if (lp_security() >= SEC_USER)
		secword |= NEGOTIATE_SECURITY_USER_LEVEL;
	if (global_encrypted_passwords_negotiated)
		secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
	
	if (lp_server_signing()) {
	       	if (lp_security() >= SEC_USER) {
			secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
			/* No raw mode with smb signing. */
			capabilities &= ~CAP_RAW_MODE;
			if (lp_server_signing() == Required)
				secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
			srv_set_signing_negotiated();
		} else {
			DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
			if (lp_server_signing() == Required) {
				exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
			}
		}
	}

	set_message(outbuf,17,0,True);
	
	SCVAL(outbuf,smb_vwv1,secword);
	
	Protocol = PROTOCOL_NT1;
	
	SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
	SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
	SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
	SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
	SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
	SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
	put_long_date(outbuf+smb_vwv11+1,t);
	SSVALS(outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
	
	p = q = smb_buf(outbuf);
	if (!negotiate_spnego) {
		/* Create a token value and add it to the outgoing packet. */
		if (global_encrypted_passwords_negotiated) {
			/* note that we do not send a challenge at all if
			   we are using plaintext */
			get_challenge(p);
			SCVAL(outbuf,smb_vwv16+1,8);
			p += 8;
		}
		p += srvstr_push(outbuf, p, lp_workgroup(), BUFFER_SIZE - (p-outbuf), 
				 STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
		DEBUG(3,("not using SPNEGO\n"));
	} else {
		DATA_BLOB spnego_blob = negprot_spnego();

		if (spnego_blob.data == NULL) {
			return ERROR_NT(NT_STATUS_NO_MEMORY);
		}

		memcpy(p, spnego_blob.data, spnego_blob.length);
		p += spnego_blob.length;
		data_blob_free(&spnego_blob);

		SCVAL(outbuf,smb_vwv16+1, 0);
		DEBUG(3,("using SPNEGO\n"));
	}
	
	SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
	set_message_end(outbuf, p);
	
	return (smb_len(outbuf)+4);
}
Exemple #3
0
static void reply_nt1(struct smb_request *req, uint16 choice)
{
	/* dual names + lock_and_read + nt SMBs + remote API calls */
	int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
		CAP_LEVEL_II_OPLOCKS;

	int secword=0;
	bool negotiate_spnego = False;
	struct timespec ts;
	ssize_t ret;
	struct smbd_server_connection *sconn = req->sconn;
	bool signing_enabled = false;
	bool signing_required = false;

	sconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();

	/* Check the flags field to see if this is Vista.
	   WinXP sets it and Vista does not. But we have to 
	   distinguish from NT which doesn't set it either. */

	if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
		((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) )
	{
		if (get_remote_arch() != RA_SAMBA) {
			set_remote_arch( RA_VISTA );
		}
	}

	reply_outbuf(req,17,0);

	/* do spnego in user level security if the client
	   supports it and we can do encrypted passwords */

	if (sconn->smb1.negprot.encrypted_passwords &&
	    lp_use_spnego() &&
	    (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
		negotiate_spnego = True;
		capabilities |= CAP_EXTENDED_SECURITY;
		add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
		/* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
		   (already partially constructed. */
		SSVAL(req->outbuf, smb_flg2,
		      req->flags2 | FLAGS2_EXTENDED_SECURITY);
	}

	capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;

	if (lp_unicode()) {
		capabilities |= CAP_UNICODE;
	}

	if (lp_unix_extensions()) {
		capabilities |= CAP_UNIX;
	}

	if (lp_large_readwrite())
		capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;

	capabilities |= CAP_LARGE_FILES;

	if (!lp_async_smb_echo_handler() && lp_read_raw() && lp_write_raw())
		capabilities |= CAP_RAW_MODE;

	if (lp_nt_status_support())
		capabilities |= CAP_STATUS32;

	if (lp_host_msdfs())
		capabilities |= CAP_DFS;

	secword |= NEGOTIATE_SECURITY_USER_LEVEL;
	if (sconn->smb1.negprot.encrypted_passwords) {
		secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
	}

	signing_enabled = smb_signing_is_allowed(req->sconn->smb1.signing_state);
	signing_required = smb_signing_is_mandatory(req->sconn->smb1.signing_state);

	if (signing_enabled) {
		secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
		/* No raw mode with smb signing. */
		capabilities &= ~CAP_RAW_MODE;
		if (signing_required) {
			secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
		}
	}

	SSVAL(req->outbuf,smb_vwv0,choice);
	SCVAL(req->outbuf,smb_vwv1,secword);

	smbXsrv_connection_init_tables(req->sconn->conn, PROTOCOL_NT1);

	SSVAL(req->outbuf,smb_vwv1+1, lp_max_mux()); /* maxmpx */
	SSVAL(req->outbuf,smb_vwv2+1, 1); /* num vcs */
	SIVAL(req->outbuf,smb_vwv3+1,
	      sconn->smb1.negprot.max_recv); /* max buffer. LOTS! */
	SIVAL(req->outbuf,smb_vwv5+1, 0x10000); /* raw size. full 64k */
	SIVAL(req->outbuf,smb_vwv7+1, getpid()); /* session key */
	SIVAL(req->outbuf,smb_vwv9+1, capabilities); /* capabilities */
	clock_gettime(CLOCK_REALTIME,&ts);
	put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,ts);
	SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60);

	if (!negotiate_spnego) {
		/* Create a token value and add it to the outgoing packet. */
		if (sconn->smb1.negprot.encrypted_passwords) {
			uint8 chal[8];
			/* note that we do not send a challenge at all if
			   we are using plaintext */
			get_challenge(sconn, chal);
			ret = message_push_blob(
				&req->outbuf, data_blob_const(chal, sizeof(chal)));
			if (ret == -1) {
				DEBUG(0, ("Could not push challenge\n"));
				reply_nterror(req, NT_STATUS_NO_MEMORY);
				return;
			}
			SCVAL(req->outbuf, smb_vwv16+1, ret);
		}
		ret = message_push_string(&req->outbuf, lp_workgroup(),
					  STR_UNICODE|STR_TERMINATE
					  |STR_NOALIGN);
		if (ret == -1) {
			DEBUG(0, ("Could not push workgroup string\n"));
			reply_nterror(req, NT_STATUS_NO_MEMORY);
			return;
		}
		ret = message_push_string(&req->outbuf, lp_netbios_name(),
					  STR_UNICODE|STR_TERMINATE
					  |STR_NOALIGN);
		if (ret == -1) {
			DEBUG(0, ("Could not push netbios name string\n"));
			reply_nterror(req, NT_STATUS_NO_MEMORY);
			return;
		}
		DEBUG(3,("not using SPNEGO\n"));
	} else {
		DATA_BLOB spnego_blob = negprot_spnego(req, req->sconn);

		if (spnego_blob.data == NULL) {
			reply_nterror(req, NT_STATUS_NO_MEMORY);
			return;
		}

		ret = message_push_blob(&req->outbuf, spnego_blob);
		if (ret == -1) {
			DEBUG(0, ("Could not push spnego blob\n"));
			reply_nterror(req, NT_STATUS_NO_MEMORY);
			return;
		}
		data_blob_free(&spnego_blob);

		SCVAL(req->outbuf,smb_vwv16+1, 0);
		DEBUG(3,("using SPNEGO\n"));
	}

	return;
}
Exemple #4
0
bool cli_send_trans(struct cli_state *cli, int trans,
		    const char *pipe_name,
		    int fid, int flags,
		    uint16 *setup, unsigned int lsetup, unsigned int msetup,
		    const char *param, unsigned int lparam, unsigned int mparam,
		    const char *data, unsigned int ldata, unsigned int mdata)
{
	unsigned int i;
	unsigned int this_ldata,this_lparam;
	unsigned int tot_data=0,tot_param=0;
	char *outdata,*outparam;
	char *p;
	int pipe_name_len=0;
	uint16 mid;

	this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
	this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam));

	memset(cli->outbuf,'\0',smb_size);
	cli_set_message(cli->outbuf,14+lsetup,0,True);
	SCVAL(cli->outbuf,smb_com,trans);
	SSVAL(cli->outbuf,smb_tid, cli->cnum);
	cli_setup_packet(cli);

	/*
	 * Save the mid we're using. We need this for finding
	 * signing replies.
	 */

	mid = cli->mid;

	if (pipe_name) {
		pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE);
	}

	outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len : 3);
	outdata = outparam+this_lparam;

	/* primary request */
	SSVAL(cli->outbuf,smb_tpscnt,lparam);	/* tpscnt */
	SSVAL(cli->outbuf,smb_tdscnt,ldata);	/* tdscnt */
	SSVAL(cli->outbuf,smb_mprcnt,mparam);	/* mprcnt */
	SSVAL(cli->outbuf,smb_mdrcnt,mdata);	/* mdrcnt */
	SCVAL(cli->outbuf,smb_msrcnt,msetup);	/* msrcnt */
	SSVAL(cli->outbuf,smb_flags,flags);	/* flags */
	SIVAL(cli->outbuf,smb_timeout,0);		/* timeout */
	SSVAL(cli->outbuf,smb_pscnt,this_lparam);	/* pscnt */
	SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */
	SSVAL(cli->outbuf,smb_dscnt,this_ldata);	/* dscnt */
	SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */
	SCVAL(cli->outbuf,smb_suwcnt,lsetup);	/* suwcnt */
	for (i=0;i<lsetup;i++)		/* setup[] */
		SSVAL(cli->outbuf,smb_setup+i*2,setup[i]);
	p = smb_buf(cli->outbuf);
	if (trans != SMBtrans) {
		*p++ = 0;  /* put in a null smb_name */
		*p++ = 'D'; *p++ = ' ';	/* observed in OS/2 */
	}
	if (this_lparam)			/* param[] */
		memcpy(outparam,param,this_lparam);
	if (this_ldata)			/* data[] */
		memcpy(outdata,data,this_ldata);
	cli_setup_bcc(cli, outdata+this_ldata);

	show_msg(cli->outbuf);

	if (!cli_send_smb(cli)) {
		return False;
	}

	cli_state_seqnum_persistent(cli, mid);

	if (this_ldata < ldata || this_lparam < lparam) {
		/* receive interim response */
		if (!cli_receive_smb(cli) || cli_is_error(cli)) {
			cli_state_seqnum_remove(cli, mid);
			return(False);
		}

		tot_data = this_ldata;
		tot_param = this_lparam;

		while (tot_data < ldata || tot_param < lparam)  {
			this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */
			this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam));

			cli_set_message(cli->outbuf,trans==SMBtrans?8:9,0,True);
			SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2));

			outparam = smb_buf(cli->outbuf);
			outdata = outparam+this_lparam;

			/* secondary request */
			SSVAL(cli->outbuf,smb_tpscnt,lparam);	/* tpscnt */
			SSVAL(cli->outbuf,smb_tdscnt,ldata);	/* tdscnt */
			SSVAL(cli->outbuf,smb_spscnt,this_lparam);	/* pscnt */
			SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */
			SSVAL(cli->outbuf,smb_spsdisp,tot_param);	/* psdisp */
			SSVAL(cli->outbuf,smb_sdscnt,this_ldata);	/* dscnt */
			SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */
			SSVAL(cli->outbuf,smb_sdsdisp,tot_data);	/* dsdisp */
			if (trans==SMBtrans2)
				SSVALS(cli->outbuf,smb_sfid,fid);		/* fid */
			if (this_lparam)			/* param[] */
				memcpy(outparam,param+tot_param,this_lparam);
			if (this_ldata)			/* data[] */
				memcpy(outdata,data+tot_data,this_ldata);
			cli_setup_bcc(cli, outdata+this_ldata);

			show_msg(cli->outbuf);

			cli->mid = mid;
			if (!cli_send_smb(cli)) {
				cli_state_seqnum_remove(cli, mid);
				return False;
			}

			tot_data += this_ldata;
			tot_param += this_lparam;
		}
	}

	return(True);
}