Example #1
0
/****************************************************************************
  reply to a read and X

  This code is basically stolen from reply_read_and_X with some
  wrinkles to handle pipes.
****************************************************************************/
int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
	pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
	int smb_maxcnt = SVAL(inbuf,smb_vwv5);
	int smb_mincnt = SVAL(inbuf,smb_vwv6);
	int nread = -1;
	char *data;
	/* we don't use the offset given to use for pipe reads. This
           is deliberate, instead we always return the next lump of
           data on the pipe */
#if 0
	uint32 smb_offs = IVAL(inbuf,smb_vwv3);
#endif

	if (!p)
		return(ERROR(ERRDOS,ERRbadfid));

	set_message(outbuf,12,0,True);
	data = smb_buf(outbuf);

	nread = (int)read_from_pipe(p, data, (size_t)smb_maxcnt);

	if (nread < 0)
		return(UNIXERROR(ERRDOS,ERRnoaccess));
  
	SSVAL(outbuf,smb_vwv5,nread);
	SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
	SSVAL(smb_buf(outbuf),-2,nread);
  
	DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
		 p->pnum, smb_mincnt, smb_maxcnt, nread));

	return chain_reply(inbuf,outbuf,length,bufsize);
}
Example #2
0
int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
	smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
	uint16 vuid = SVAL(inbuf,smb_uid);
	size_t numtowrite = SVAL(inbuf,smb_vwv10);
	int nwritten = -1;
	int smb_doff = SVAL(inbuf, smb_vwv11);
	BOOL pipe_start_message_raw = ((SVAL(inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) ==
								(PIPE_START_MESSAGE|PIPE_RAW_MODE));
	char *data;

	if (!p) {
		return(ERROR_DOS(ERRDOS,ERRbadfid));
	}

	if (p->vuid != vuid) {
		return ERROR_NT(NT_STATUS_INVALID_HANDLE);
	}

	data = smb_base(inbuf) + smb_doff;

	if (numtowrite == 0) {
		nwritten = 0;
	} else {
		if(pipe_start_message_raw) {
			/*
			 * For the start of a message in named pipe byte mode,
			 * the first two bytes are a length-of-pdu field. Ignore
			 * them (we don't trust the client). JRA.
			 */
	 	       if(numtowrite < 2) {
				DEBUG(0,("reply_pipe_write_and_X: start of message set and not enough data sent.(%u)\n",
					(unsigned int)numtowrite ));
				return (UNIXERROR(ERRDOS,ERRnoaccess));
			}

			data += 2;
			numtowrite -= 2;
		}                        
		nwritten = write_to_pipe(p, data, numtowrite);
	}

	if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) {
		return (UNIXERROR(ERRDOS,ERRnoaccess));
	}
  
	set_message(outbuf,6,0,True);

	nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten);
	SSVAL(outbuf,smb_vwv2,nwritten);
  
	DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));

	return chain_reply(inbuf,outbuf,length,bufsize);
}
//#if 0
int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize, int ProcSockID, int threadid)
{
	pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2, threadid);
	uint32 numtowrite = SVAL(inbuf,smb_vwv10);
	int nwritten = -1;
	int smb_doff = SVAL(inbuf, smb_vwv11);
	int pipe_start_message_raw = ((SVAL(inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) ==
									(PIPE_START_MESSAGE|PIPE_RAW_MODE));
	char *data;

	if (!p)
		return(ERROR(ERRDOS,ERRbadfid));

	data = smb_base(inbuf) + smb_doff;

	if (numtowrite == 0)
		nwritten = 0;
	else {
		if(pipe_start_message_raw) {
			/*
			 * For the start of a message in named pipe byte mode,
			 * the first two bytes are a length-of-pdu field. Ignore
			 * them (we don't trust the client. JRA.
			 */
		if(numtowrite < 2) {
//0507				DEBUG(0,("reply_pipe_write_and_X: start of message set and not enough data sent.(%u)\n",
//0507					(unsigned int)numtowrite ));
//0507				return (UNIXERROR(ERRDOS,ERRnoaccess));
				return 0;
			}

			data += 2;
			numtowrite -= 2;
	}                        
		nwritten = write_to_pipe(p, data, numtowrite);
	}

	if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
//0507		return (UNIXERROR(ERRDOS,ERRnoaccess));
			return 0;	
	set_message(outbuf,6,0,True);

	nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten);
	SSVAL(outbuf,smb_vwv2,nwritten);
  
//0507	DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n",
//0507		 p->pnum, nwritten));

	return chain_reply(inbuf,outbuf,length,bufsize, ProcSockID, threadid);
}
Example #4
0
static void reply_lockingX_success(struct blocking_lock_record *blr)
{
	reply_outbuf(blr->req, 2, 0);

	/*
	 * As this message is a lockingX call we must handle
	 * any following chained message correctly.
	 * This is normally handled in construct_reply(),
	 * but as that calls switch_message, we can't use
	 * that here and must set up the chain info manually.
	 */

	chain_reply(blr->req);
	TALLOC_FREE(blr->req->outbuf);
}
Example #5
0
void reply_pipe_read_and_X(struct smb_request *req)
{
	smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv2));
	int smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
	int smb_mincnt = SVAL(req->inbuf,smb_vwv6);
	int nread = -1;
	char *data;
	bool unused;

	/* we don't use the offset given to use for pipe reads. This
           is deliberate, instead we always return the next lump of
           data on the pipe */
#if 0
	uint32 smb_offs = IVAL(req->inbuf,smb_vwv3);
#endif

	if (!p) {
		reply_doserror(req, ERRDOS, ERRbadfid);
		return;
	}

	reply_outbuf(req, 12, smb_maxcnt);

	data = smb_buf(req->outbuf);

	nread = read_from_pipe(p, data, smb_maxcnt, &unused);

	if (nread < 0) {
		reply_doserror(req, ERRDOS, ERRnoaccess);
		return;
	}

	srv_set_message((char *)req->outbuf, 12, nread, False);
  
	SSVAL(req->outbuf,smb_vwv5,nread);
	SSVAL(req->outbuf,smb_vwv6,smb_offset(data,req->outbuf));
	SSVAL(smb_buf(req->outbuf),-2,nread);
  
	DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
		 p->pnum, smb_mincnt, smb_maxcnt, nread));

	chain_reply(req);
}
Example #6
0
static void reply_lockingX_success(blocking_lock_record *blr)
{
	char *outbuf = OutBuffer;
	int bufsize = BUFFER_SIZE;
	char *inbuf = blr->inbuf;
	int outsize = 0;

	construct_reply_common(inbuf, outbuf);
	set_message(outbuf,2,0,True);

	/*
	 * As this message is a lockingX call we must handle
	 * any following chained message correctly.
	 * This is normally handled in construct_reply(),
	 * but as that calls switch_message, we can't use
	 * that here and must set up the chain info manually.
	 */

	outsize = chain_reply(inbuf,outbuf,blr->length,bufsize);

	outsize += chain_size;

	send_blocking_reply(outbuf,outsize);
}
Example #7
0
void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)
{
	const char *fname = NULL;
	char *pipe_name = NULL;
	files_struct *fsp;
	TALLOC_CTX *ctx = talloc_tos();
	NTSTATUS status;

	/* XXXX we need to handle passed times, sattr and flags */
	srvstr_pull_req_talloc(ctx, req, &pipe_name, req->buf, STR_TERMINATE);
	if (!pipe_name) {
		reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
				ERRDOS, ERRbadpipe);
		return;
	}

	/* If the name doesn't start \PIPE\ then this is directed */
	/* at a mailslot or something we really, really don't understand, */
	/* not just something we really don't understand. */
	if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) {
		reply_doserror(req, ERRSRV, ERRaccess);
		return;
	}

	DEBUG(4,("Opening pipe %s.\n", pipe_name));

	/* Strip \PIPE\ off the name. */
	fname = pipe_name + PIPELEN;

#if 0
	/*
	 * Hack for NT printers... JRA.
	 */
	if(should_fail_next_srvsvc_open(fname)) {
		reply_doserror(req, ERRSRV, ERRaccess);
		return;
	}
#endif

	status = open_np_file(req, fname, &fsp);
	if (!NT_STATUS_IS_OK(status)) {
		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
			reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
					ERRDOS, ERRbadpipe);
			return;
		}
		reply_nterror(req, status);
		return;
	}

	/* Prepare the reply */
	reply_outbuf(req, 15, 0);

	/* Mark the opened file as an existing named pipe in message mode. */
	SSVAL(req->outbuf,smb_vwv9,2);
	SSVAL(req->outbuf,smb_vwv10,0xc700);

	SSVAL(req->outbuf, smb_vwv2, fsp->fnum);
	SSVAL(req->outbuf, smb_vwv3, 0);	/* fmode */
	srv_put_dos_date3((char *)req->outbuf, smb_vwv4, 0);	/* mtime */
	SIVAL(req->outbuf, smb_vwv6, 0);	/* size */
	SSVAL(req->outbuf, smb_vwv8, 0);	/* rmode */
	SSVAL(req->outbuf, smb_vwv11, 0x0001);

	chain_reply(req);
	return;
}
int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
	pstring fname;
	uint16 vuid = SVAL(inbuf, smb_uid);
	pipes_struct *p;
	int smb_ofun = SVAL(inbuf,smb_vwv8);
	int size=0,fmode=0,mtime=0,rmode=0;
	int i;

	/* XXXX we need to handle passed times, sattr and flags */
	pstrcpy(fname,smb_buf(inbuf));

	/* If the name doesn't start \PIPE\ then this is directed */
	/* at a mailslot or something we really, really don't understand, */
	/* not just something we really don't understand. */
	if ( strncmp(fname,PIPE,PIPELEN) != 0 )
		return(ERROR(ERRSRV,ERRaccess));

//0507	DEBUG(4,("Opening pipe %s.\n", fname));

	/* See if it is one we want to handle. */
	for( i = 0; pipe_names[i].client_pipe ; i++ )
//0507		if( strequal(fname,pipe_names[i].client_pipe) )
		if( !strcmp(fname,pipe_names[i].client_pipe) )
			break;

	if (pipe_names[i].client_pipe == NULL)
		return(ERROR(ERRSRV,ERRaccess));
	/* Strip \PIPE\ off the name. */
	pstrcpy(fname,smb_buf(inbuf) + PIPELEN);

	/*
	 * Hack for NT printers... JRA.
	 */
//0611    if(should_fail_next_srvsvc_open(fname))
//      return(ERROR(ERRSRV,ERRaccess));
//0507	  	return 0;
	/* Known pipes arrive with DIR attribs. Remove it so a regular file */
	/* can be opened and add it in after the open. */
//0507	DEBUG(3,("Known pipe %s opening.\n",fname));
	smb_ofun |= FILE_CREATE_IF_NOT_EXIST;

	p = open_rpc_pipe_p(fname, vuid, threadid);

	if (!p) return(ERROR(ERRSRV,ERRnofids));

	/* Prepare the reply */
	set_message(outbuf,15,0,True);

	/* Mark the opened file as an existing named pipe in message mode. */
	SSVAL(outbuf,smb_vwv9,2);
	SSVAL(outbuf,smb_vwv10,0xc700);

	if (rmode == 2) {
//0507		DEBUG(4,("Resetting open result to open from create.\n"));
		rmode = 1;
	}

	SSVAL(outbuf,smb_vwv2, p->pnum);
	SSVAL(outbuf,smb_vwv3,fmode);
//0507	put_dos_date3(outbuf,smb_vwv4,mtime);
	SIVAL(outbuf,smb_vwv6,size);
	SSVAL(outbuf,smb_vwv8,rmode);
	SSVAL(outbuf,smb_vwv11,0x0001);

	return chain_reply(inbuf,outbuf,length,bufsize);
}
Example #9
0
int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
			  int length,int bufsize)
{
	int sess_vuid;
	int   smb_bufsize;    
	DATA_BLOB lm_resp;
	DATA_BLOB nt_resp;
	DATA_BLOB plaintext_password;
	fstring user;
	fstring sub_user; /* Sainitised username for substituion */
	fstring domain;
	fstring native_os;
	fstring native_lanman;
	fstring primary_domain;
	static BOOL done_sesssetup = False;
	auth_usersupplied_info *user_info = NULL;
	auth_serversupplied_info *server_info = NULL;

	NTSTATUS nt_status;

	BOOL doencrypt = global_encrypted_passwords_negotiated;

	DATA_BLOB session_key;
	
	START_PROFILE(SMBsesssetupX);

	ZERO_STRUCT(lm_resp);
	ZERO_STRUCT(nt_resp);
	ZERO_STRUCT(plaintext_password);

	DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2)));

	/* a SPNEGO session setup has 12 command words, whereas a normal
	   NT1 session setup has 13. See the cifs spec. */
	if (CVAL(inbuf, smb_wct) == 12 &&
	    (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
		if (!global_spnego_negotiated) {
			DEBUG(0,("reply_sesssetup_and_X:  Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n"));
			return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
		}

		if (SVAL(inbuf,smb_vwv4) == 0) {
			setup_new_vc_session();
		}
		return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize);
	}

	smb_bufsize = SVAL(inbuf,smb_vwv2);

	if (Protocol < PROTOCOL_NT1) {
		uint16 passlen1 = SVAL(inbuf,smb_vwv7);

		/* Never do NT status codes with protocols before NT1 as we don't get client caps. */
		remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);

		if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) {
			return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
		}

		if (doencrypt) {
			lm_resp = data_blob(smb_buf(inbuf), passlen1);
		} else {
			plaintext_password = data_blob(smb_buf(inbuf), passlen1+1);
			/* Ensure null termination */
			plaintext_password.data[passlen1] = 0;
		}

		srvstr_pull_buf(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), STR_TERMINATE);
		*domain = 0;

	} else {
		uint16 passlen1 = SVAL(inbuf,smb_vwv7);
		uint16 passlen2 = SVAL(inbuf,smb_vwv8);
		enum remote_arch_types ra_type = get_remote_arch();
		char *p = smb_buf(inbuf);    
		char *save_p = smb_buf(inbuf);
		uint16 byte_count;
			

		if(global_client_caps == 0) {
			global_client_caps = IVAL(inbuf,smb_vwv11);
		
			if (!(global_client_caps & CAP_STATUS32)) {
				remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
			}

			/* client_caps is used as final determination if client is NT or Win95. 
			   This is needed to return the correct error codes in some
			   circumstances.
			*/
		
			if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) {
				if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) {
					set_remote_arch( RA_WIN95);
				}
			}
		}

		if (!doencrypt) {
			/* both Win95 and WinNT stuff up the password lengths for
			   non-encrypting systems. Uggh. 
			   
			   if passlen1==24 its a win95 system, and its setting the
			   password length incorrectly. Luckily it still works with the
			   default code because Win95 will null terminate the password
			   anyway 
			   
			   if passlen1>0 and passlen2>0 then maybe its a NT box and its
			   setting passlen2 to some random value which really stuffs
			   things up. we need to fix that one.  */
			
			if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1)
				passlen2 = 0;
		}
		
		/* check for nasty tricks */
		if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(inbuf, p)) {
			return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
		}

		if (passlen2 > MAX_PASS_LEN || passlen2 > smb_bufrem(inbuf, p+passlen1)) {
			return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
		}

		/* Save the lanman2 password and the NT md4 password. */
		
		if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
			doencrypt = False;
		}

		if (doencrypt) {
			lm_resp = data_blob(p, passlen1);
			nt_resp = data_blob(p+passlen1, passlen2);
		} else {
			pstring pass;
			BOOL unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS;

#if 0
			/* This was the previous fix. Not sure if it's still valid. JRA. */
			if ((ra_type == RA_WINNT) && (passlen2 == 0) && unic && passlen1) {
				/* NT4.0 stuffs up plaintext unicode password lengths... */
				srvstr_pull(inbuf, pass, smb_buf(inbuf) + 1,
					sizeof(pass), passlen1, STR_TERMINATE);
#endif

			if (unic && (passlen2 == 0) && passlen1) {
				/* Only a ascii plaintext password was sent. */
				srvstr_pull(inbuf, pass, smb_buf(inbuf), sizeof(pass),
					passlen1, STR_TERMINATE|STR_ASCII);
			} else {
				srvstr_pull(inbuf, pass, smb_buf(inbuf), 
					sizeof(pass),  unic ? passlen2 : passlen1, 
					STR_TERMINATE);
			}
			plaintext_password = data_blob(pass, strlen(pass)+1);
		}
		
		p += passlen1 + passlen2;
		p += srvstr_pull_buf(inbuf, user, p, sizeof(user), STR_TERMINATE);
		p += srvstr_pull_buf(inbuf, domain, p, sizeof(domain), STR_TERMINATE);
		p += srvstr_pull_buf(inbuf, native_os, p, sizeof(native_os), STR_TERMINATE);
		p += srvstr_pull_buf(inbuf, native_lanman, p, sizeof(native_lanman), STR_TERMINATE);

		/* not documented or decoded by Ethereal but there is one more string 
		   in the extra bytes which is the same as the PrimaryDomain when using 
		   extended security.  Windows NT 4 and 2003 use this string to store 
		   the native lanman string. Windows 9x does not include a string here 
		   at all so we have to check if we have any extra bytes left */
		
		byte_count = SVAL(inbuf, smb_vwv13);
		if ( PTR_DIFF(p, save_p) < byte_count)
			p += srvstr_pull_buf(inbuf, primary_domain, p, sizeof(primary_domain), STR_TERMINATE);
		else 
			fstrcpy( primary_domain, "null" );

		DEBUG(3,("Domain=[%s]  NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
			 domain, native_os, native_lanman, primary_domain));

		if ( ra_type == RA_WIN2K ) {
			if ( strlen(native_lanman) == 0 )
				ra_lanman_string( primary_domain );
			else
				ra_lanman_string( native_lanman );
		}

	}

	if (SVAL(inbuf,smb_vwv4) == 0) {
		setup_new_vc_session();
	}

	DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name()));

	if (*user) {
		if (global_spnego_negotiated) {
			
			/* This has to be here, because this is a perfectly valid behaviour for guest logons :-( */
			
			DEBUG(0,("reply_sesssetup_and_X:  Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
			return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
		}
		fstrcpy(sub_user, user);
	} else {
		fstrcpy(sub_user, lp_guestaccount());
	}

	sub_set_smb_name(sub_user);

	reload_services(True);
	
	if (lp_security() == SEC_SHARE) {
		/* in share level we should ignore any passwords */

		data_blob_free(&lm_resp);
		data_blob_free(&nt_resp);
		data_blob_clear_free(&plaintext_password);

		map_username(sub_user);
		add_session_user(sub_user);
		add_session_workgroup(domain);
		/* Then force it to null for the benfit of the code below */
		*user = 0;
	}
	
	if (!*user) {

		nt_status = check_guest_password(&server_info);

	} else if (doencrypt) {
		if (!negprot_global_auth_context) {
			DEBUG(0, ("reply_sesssetup_and_X:  Attempted encrypted session setup without negprot denied!\n"));
			return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
		}
		nt_status = make_user_info_for_reply_enc(&user_info, user, domain,
		                                         lm_resp, nt_resp);
		if (NT_STATUS_IS_OK(nt_status)) {
			nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context, 
										     user_info, 
										     &server_info);
		}
	} else {
		struct auth_context *plaintext_auth_context = NULL;
		const uint8 *chal;

		nt_status = make_auth_context_subsystem(&plaintext_auth_context);

		if (NT_STATUS_IS_OK(nt_status)) {
			chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
			
			if (!make_user_info_for_reply(&user_info, 
						      user, domain, chal,
						      plaintext_password)) {
				nt_status = NT_STATUS_NO_MEMORY;
			}
		
			if (NT_STATUS_IS_OK(nt_status)) {
				nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context, 
											user_info, 
											&server_info); 
				
				(plaintext_auth_context->free)(&plaintext_auth_context);
			}
		}
	}

	free_user_info(&user_info);
	
	if (!NT_STATUS_IS_OK(nt_status)) {
		nt_status = do_map_to_guest(nt_status, &server_info, user, domain);
	}
	
	if (!NT_STATUS_IS_OK(nt_status)) {
		data_blob_free(&nt_resp);
		data_blob_free(&lm_resp);
		data_blob_clear_free(&plaintext_password);
		return ERROR_NT(nt_status_squash(nt_status));
	}

	/* Ensure we can't possible take a code path leading to a null defref. */
	if (!server_info) {
		return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
	}

	nt_status = create_local_token(server_info);
	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(10, ("create_local_token failed: %s\n",
			   nt_errstr(nt_status)));
		data_blob_free(&nt_resp);
		data_blob_free(&lm_resp);
		data_blob_clear_free(&plaintext_password);
		return ERROR_NT(nt_status_squash(nt_status));
	}

	if (server_info->user_session_key.data) {
		session_key = data_blob(server_info->user_session_key.data, server_info->user_session_key.length);
	} else {
		session_key = data_blob(NULL, 0);
	}

	data_blob_clear_free(&plaintext_password);
	
	/* it's ok - setup a reply */
	set_message(outbuf,3,0,True);
	if (Protocol >= PROTOCOL_NT1) {
		char *p = smb_buf( outbuf );
		p += add_signature( outbuf, p );
		set_message_end( outbuf, p );
		/* perhaps grab OS version here?? */
	}
	
	if (server_info->guest) {
		SSVAL(outbuf,smb_vwv2,1);
	}

	/* register the name and uid as being validated, so further connections
	   to a uid can get through without a password, on the same VC */

	if (lp_security() == SEC_SHARE) {
		sess_vuid = UID_FIELD_INVALID;
		data_blob_free(&session_key);
		TALLOC_FREE(server_info);
	} else {
		/* register_vuid keeps the server info */
		sess_vuid = register_vuid(server_info, session_key,
					  nt_resp.data ? nt_resp : lm_resp,
					  sub_user);
		if (sess_vuid == UID_FIELD_INVALID) {
			data_blob_free(&nt_resp);
			data_blob_free(&lm_resp);
			return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
		}

		/* current_user_info is changed on new vuid */
		reload_services( True );

		sessionsetup_start_signing_engine(server_info, inbuf);
	}

	data_blob_free(&nt_resp);
	data_blob_free(&lm_resp);
	
	SSVAL(outbuf,smb_uid,sess_vuid);
	SSVAL(inbuf,smb_uid,sess_vuid);
	
	if (!done_sesssetup)
		max_send = MIN(max_send,smb_bufsize);
	
	done_sesssetup = True;
	
	END_PROFILE(SMBsesssetupX);
	return chain_reply(inbuf,outbuf,length,bufsize);
}
Example #10
0
void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)
{
	const char *fname = NULL;
	char *pipe_name = NULL;
	smb_np_struct *p;
	int size=0,fmode=0,mtime=0,rmode=0;
	int i;
	TALLOC_CTX *ctx = talloc_tos();

	/* XXXX we need to handle passed times, sattr and flags */
	srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &pipe_name,
			smb_buf(req->inbuf), STR_TERMINATE);
	if (!pipe_name) {
		reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
				ERRDOS, ERRbadpipe);
		return;
	}

	/* If the name doesn't start \PIPE\ then this is directed */
	/* at a mailslot or something we really, really don't understand, */
	/* not just something we really don't understand. */
	if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) {
		reply_doserror(req, ERRSRV, ERRaccess);
		return;
	}

	DEBUG(4,("Opening pipe %s.\n", pipe_name));

	/* See if it is one we want to handle. */
	for( i = 0; pipe_names[i].client_pipe ; i++ ) {
		if( strequal(pipe_name,pipe_names[i].client_pipe)) {
			break;
		}
	}

	if (pipe_names[i].client_pipe == NULL) {
		reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
				ERRDOS, ERRbadpipe);
		return;
	}

	/* Strip \PIPE\ off the name. */
	fname = pipe_name + PIPELEN;

#if 0
	/*
	 * Hack for NT printers... JRA.
	 */
	if(should_fail_next_srvsvc_open(fname)) {
		reply_doserror(req, ERRSRV, ERRaccess);
		return;
	}
#endif

	/* Known pipes arrive with DIR attribs. Remove it so a regular file */
	/* can be opened and add it in after the open. */
	DEBUG(3,("Known pipe %s opening.\n",fname));

	p = open_rpc_pipe_p(fname, conn, req->vuid);
	if (!p) {
		reply_doserror(req, ERRSRV, ERRnofids);
		return;
	}

	/* Prepare the reply */
	reply_outbuf(req, 15, 0);

	/* Mark the opened file as an existing named pipe in message mode. */
	SSVAL(req->outbuf,smb_vwv9,2);
	SSVAL(req->outbuf,smb_vwv10,0xc700);

	if (rmode == 2) {
		DEBUG(4,("Resetting open result to open from create.\n"));
		rmode = 1;
	}

	SSVAL(req->outbuf,smb_vwv2, p->pnum);
	SSVAL(req->outbuf,smb_vwv3,fmode);
	srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
	SIVAL(req->outbuf,smb_vwv6,size);
	SSVAL(req->outbuf,smb_vwv8,rmode);
	SSVAL(req->outbuf,smb_vwv11,0x0001);

	chain_reply(req);
	return;
}
Example #11
0
void reply_pipe_write_and_X(struct smb_request *req)
{
	smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv2));
	size_t numtowrite = SVAL(req->inbuf,smb_vwv10);
	int nwritten = -1;
	int smb_doff = SVAL(req->inbuf, smb_vwv11);
	bool pipe_start_message_raw =
		((SVAL(req->inbuf, smb_vwv7)
		  & (PIPE_START_MESSAGE|PIPE_RAW_MODE))
		 == (PIPE_START_MESSAGE|PIPE_RAW_MODE));
	char *data;

	if (!p) {
		reply_doserror(req, ERRDOS, ERRbadfid);
		return;
	}

	if (p->vuid != req->vuid) {
		reply_nterror(req, NT_STATUS_INVALID_HANDLE);
		return;
	}

	data = smb_base(req->inbuf) + smb_doff;

	if (numtowrite == 0) {
		nwritten = 0;
	} else {
		if(pipe_start_message_raw) {
			/*
			 * For the start of a message in named pipe byte mode,
			 * the first two bytes are a length-of-pdu field. Ignore
			 * them (we don't trust the client). JRA.
			 */
	 	       if(numtowrite < 2) {
				DEBUG(0,("reply_pipe_write_and_X: start of "
					 "message set and not enough data "
					 "sent.(%u)\n",
					 (unsigned int)numtowrite ));
				reply_unixerror(req, ERRDOS, ERRnoaccess);
				return;
			}

			data += 2;
			numtowrite -= 2;
		}                        
		nwritten = write_to_pipe(p, data, numtowrite);
	}

	if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) {
		reply_unixerror(req, ERRDOS,ERRnoaccess);
		return;
	}

	reply_outbuf(req, 6, 0);

	nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten);
	SSVAL(req->outbuf,smb_vwv2,nwritten);
  
	DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));

	chain_reply(req);
}
Example #12
0
int reply_open_pipe_and_X(connection_struct *conn,
			  char *inbuf,char *outbuf,int length,int bufsize)
{
	pstring fname;
	pstring pipe_name;
	uint16 vuid = SVAL(inbuf, smb_uid);
	smb_np_struct *p;
	int size=0,fmode=0,mtime=0,rmode=0;
	int i;

	/* XXXX we need to handle passed times, sattr and flags */
	srvstr_pull_buf(inbuf, pipe_name, smb_buf(inbuf), sizeof(pipe_name), STR_TERMINATE);

	/* If the name doesn't start \PIPE\ then this is directed */
	/* at a mailslot or something we really, really don't understand, */
	/* not just something we really don't understand. */
	if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) {
		return(ERROR_DOS(ERRSRV,ERRaccess));
	}

	DEBUG(4,("Opening pipe %s.\n", pipe_name));

	/* See if it is one we want to handle. */
	for( i = 0; pipe_names[i].client_pipe ; i++ ) {
		if( strequal(pipe_name,pipe_names[i].client_pipe)) {
			break;
		}
	}

	if (pipe_names[i].client_pipe == NULL) {
		return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
	}

	/* Strip \PIPE\ off the name. */
	pstrcpy(fname, pipe_name + PIPELEN);

#if 0
	/*
	 * Hack for NT printers... JRA.
	 */
    if(should_fail_next_srvsvc_open(fname))
      return(ERROR(ERRSRV,ERRaccess));
#endif

	/* Known pipes arrive with DIR attribs. Remove it so a regular file */
	/* can be opened and add it in after the open. */
	DEBUG(3,("Known pipe %s opening.\n",fname));

	p = open_rpc_pipe_p(fname, conn, vuid);
	if (!p) {
		return(ERROR_DOS(ERRSRV,ERRnofids));
	}

	/* Prepare the reply */
	set_message(outbuf,15,0,True);

	/* Mark the opened file as an existing named pipe in message mode. */
	SSVAL(outbuf,smb_vwv9,2);
	SSVAL(outbuf,smb_vwv10,0xc700);

	if (rmode == 2) {
		DEBUG(4,("Resetting open result to open from create.\n"));
		rmode = 1;
	}

	SSVAL(outbuf,smb_vwv2, p->pnum);
	SSVAL(outbuf,smb_vwv3,fmode);
	srv_put_dos_date3(outbuf,smb_vwv4,mtime);
	SIVAL(outbuf,smb_vwv6,size);
	SSVAL(outbuf,smb_vwv8,rmode);
	SSVAL(outbuf,smb_vwv11,0x0001);

	return chain_reply(inbuf,outbuf,length,bufsize);
}