コード例 #1
0
ファイル: smb2_notify.c プロジェクト: samnazarko/samba-osmc
static void smbd_smb2_request_notify_done(struct tevent_req *subreq)
{
	struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
					struct smbd_smb2_request);
	int i = req->current_idx;
	uint8_t *outhdr;
	DATA_BLOB outbody;
	DATA_BLOB outdyn;
	uint16_t out_output_buffer_offset;
	DATA_BLOB out_output_buffer = data_blob_null;
	NTSTATUS status;
	NTSTATUS error; /* transport error */

	if (req->cancelled) {
		struct smbd_smb2_notify_state *state = tevent_req_data(subreq,
					       struct smbd_smb2_notify_state);
		const uint8_t *inhdr = (const uint8_t *)req->in.vector[i].iov_base;
		uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);

		DEBUG(10,("smbd_smb2_request_notify_done: cancelled mid %llu\n",
			(unsigned long long)mid ));
		error = smbd_smb2_request_error(req, NT_STATUS_CANCELLED);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(req->sconn,
				nt_errstr(error));
			return;
		}
		TALLOC_FREE(state->im);
		return;
	}

	status = smbd_smb2_notify_recv(subreq,
				       req,
				       &out_output_buffer);
	TALLOC_FREE(subreq);
	if (!NT_STATUS_IS_OK(status)) {
		error = smbd_smb2_request_error(req, status);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(req->sconn,
							 nt_errstr(error));
			return;
		}
		return;
	}

	out_output_buffer_offset = SMB2_HDR_BODY + 0x08;

	outhdr = (uint8_t *)req->out.vector[i].iov_base;

	outbody = data_blob_talloc(req->out.vector, NULL, 0x08);
	if (outbody.data == NULL) {
		error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(req->sconn,
							 nt_errstr(error));
			return;
		}
		return;
	}

	SSVAL(outbody.data, 0x00, 0x08 + 1);	/* struct size */
	SSVAL(outbody.data, 0x02,
	      out_output_buffer_offset);	/* output buffer offset */
	SIVAL(outbody.data, 0x04,
	      out_output_buffer.length);	/* output buffer length */

	outdyn = out_output_buffer;

	error = smbd_smb2_request_done(req, outbody, &outdyn);
	if (!NT_STATUS_IS_OK(error)) {
		smbd_server_connection_terminate(req->sconn,
						 nt_errstr(error));
		return;
	}
}
コード例 #2
0
ファイル: smb2_negprot.c プロジェクト: 0x24bin/winexe-1
NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
{
	const uint8_t *inbody;
	const uint8_t *indyn = NULL;
	int i = req->current_idx;
	DATA_BLOB outbody;
	DATA_BLOB outdyn;
	DATA_BLOB negprot_spnego_blob;
	uint16_t security_offset;
	DATA_BLOB security_buffer;
	size_t expected_body_size = 0x24;
	size_t body_size;
	size_t expected_dyn_size = 0;
	size_t c;
	uint16_t security_mode;
	uint16_t dialect_count;
	uint16_t dialect = 0;
	uint32_t capabilities;

/* TODO: drop the connection with INVALI_PARAMETER */

	if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}

	inbody = (const uint8_t *)req->in.vector[i+1].iov_base;

	body_size = SVAL(inbody, 0x00);
	if (body_size != expected_body_size) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}

	dialect_count = SVAL(inbody, 0x02);
	if (dialect_count == 0) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}

	expected_dyn_size = dialect_count * 2;
	if (req->in.vector[i+2].iov_len < expected_dyn_size) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}
	indyn = (const uint8_t *)req->in.vector[i+2].iov_base;

	for (c=0; c < dialect_count; c++) {
		dialect = SVAL(indyn, c*2);
		if (dialect == SMB2_DIALECT_REVISION_202) {
			break;
		}
	}

	if (dialect != SMB2_DIALECT_REVISION_202) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}

	set_Protocol(PROTOCOL_SMB2);

	if (get_remote_arch() != RA_SAMBA) {
		set_remote_arch(RA_VISTA);
	}

	/* negprot_spnego() returns a the server guid in the first 16 bytes */
	negprot_spnego_blob = negprot_spnego();
	if (negprot_spnego_blob.data == NULL) {
		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
	}
	talloc_steal(req, negprot_spnego_blob.data);

	if (negprot_spnego_blob.length < 16) {
		return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
	}

	security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
	if (lp_server_signing() == Required) {
		security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
	}

	capabilities = 0;
	if (lp_host_msdfs()) {
		capabilities |= SMB2_CAP_DFS;
	}

	security_offset = SMB2_HDR_BODY + 0x40;

#if 1
	/* Try SPNEGO auth... */
	security_buffer = data_blob_const(negprot_spnego_blob.data + 16,
					  negprot_spnego_blob.length - 16);
#else
	/* for now we want raw NTLMSSP */
	security_buffer = data_blob_const(NULL, 0);
#endif

	outbody = data_blob_talloc(req->out.vector, NULL, 0x40);
	if (outbody.data == NULL) {
		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
	}

	SSVAL(outbody.data, 0x00, 0x40 + 1);	/* struct size */
	SSVAL(outbody.data, 0x02,
	      security_mode);			/* security mode */
	SSVAL(outbody.data, 0x04, dialect);	/* dialect revision */
	SSVAL(outbody.data, 0x06, 0);		/* reserved */
	memcpy(outbody.data + 0x08,
	       negprot_spnego_blob.data, 16);	/* server guid */
	SIVAL(outbody.data, 0x18,
	      capabilities);			/* capabilities */
	SIVAL(outbody.data, 0x1C, 0x00010000);	/* max transact size */
	SIVAL(outbody.data, 0x20, 0x00010000);	/* max read size */
	SIVAL(outbody.data, 0x24, 0x00010000);	/* max write size */
	SBVAL(outbody.data, 0x28, 0);		/* system time */
	SBVAL(outbody.data, 0x30, 0);		/* server start time */
	SSVAL(outbody.data, 0x38,
	      security_offset);			/* security buffer offset */
	SSVAL(outbody.data, 0x3A,
	      security_buffer.length);		/* security buffer length */
	SIVAL(outbody.data, 0x3C, 0);		/* reserved */

	outdyn = security_buffer;

	return smbd_smb2_request_done(req, outbody, &outdyn);
}
コード例 #3
0
ファイル: smb2_getinfo.c プロジェクト: rchicoli/samba
static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq)
{
	struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
					struct smbd_smb2_request);
	DATA_BLOB outbody;
	DATA_BLOB outdyn;
	uint16_t out_output_buffer_offset;
	DATA_BLOB out_output_buffer = data_blob_null;
	NTSTATUS status;
	NTSTATUS call_status = NT_STATUS_OK;
	NTSTATUS error; /* transport error */

	status = smbd_smb2_getinfo_recv(subreq,
					req,
					&out_output_buffer,
					&call_status);
	TALLOC_FREE(subreq);
	if (!NT_STATUS_IS_OK(status)) {
		error = smbd_smb2_request_error(req, status);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(req->sconn,
							 nt_errstr(error));
			return;
		}
		return;
	}

	/* some GetInfo responses set STATUS_BUFFER_OVERFLOW and return partial,
	   but valid data */
	if (!(NT_STATUS_IS_OK(call_status) ||
	      NT_STATUS_EQUAL(call_status, STATUS_BUFFER_OVERFLOW))) {
		/* Return a specific error with data. */
		error = smbd_smb2_request_error_ex(req,
						call_status,
						&out_output_buffer,
						__location__);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(req->sconn,
							 nt_errstr(error));
			return;
		}
		return;
	}

	out_output_buffer_offset = SMB2_HDR_BODY + 0x08;

	outbody = data_blob_talloc(req->out.vector, NULL, 0x08);
	if (outbody.data == NULL) {
		error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(req->sconn,
							 nt_errstr(error));
			return;
		}
		return;
	}

	SSVAL(outbody.data, 0x00, 0x08 + 1);	/* struct size */
	SSVAL(outbody.data, 0x02,
	      out_output_buffer_offset);	/* output buffer offset */
	SIVAL(outbody.data, 0x04,
	      out_output_buffer.length);	/* output buffer length */

	outdyn = out_output_buffer;

	error = smbd_smb2_request_done_ex(req, call_status, outbody, &outdyn, __location__);
	if (!NT_STATUS_IS_OK(error)) {
		smbd_server_connection_terminate(req->sconn,
						 nt_errstr(error));
		return;
	}
}
コード例 #4
0
ファイル: vfs_vxfs.c プロジェクト: DanilKorotenko/samba
/*
 * Sort aces so that comparing 2 ACLs will be straight forward.
 * This function will fill buffer as follows:
 * For each ace:
 * 	1. ace->a_type will be filled as first 2 bytes in buf.
 * 	2. ace->a_perm will be filled as next 2 bytes.
 * 	3. ace->xid will be filled as next 4 bytes.
 * Thus each ace entry in buf is equal to 8 bytes.
 * Also a_type is mapped to VXFS_ACL_* so that ordering aces
 * becomes easy.
 */
static char * vxfs_sort_acl(SMB_ACL_T theacl, TALLOC_CTX *mem_ctx,
			    uint32_t o_uid,
			    uint32_t o_gid) {

	struct smb_acl_entry *smb_ace;
	int i, count;
	uint16_t type, perm;
	uint32_t id;
	int offset = 0;
	char *buf = NULL;

	count = theacl->count;

	buf = talloc_zero_size(mem_ctx, count * 8);
	if (!buf) {
		return NULL;
	}

	smb_ace = theacl->acl;

	for (i = 0; i < count; i++) {
		/* Calculate type */
		/* Map type to SMB_ACL_* to VXFS_ACL_* */
		switch(smb_ace->a_type) {
		case SMB_ACL_USER:
			type = VXFS_ACL_USER;
			break;
		case SMB_ACL_USER_OBJ:
			type = VXFS_ACL_USER_OBJ;
			break;
		case SMB_ACL_GROUP:
			type = VXFS_ACL_GROUP;
			break;
		case SMB_ACL_GROUP_OBJ:
			type = VXFS_ACL_GROUP_OBJ;
			break;
		case SMB_ACL_OTHER:
			type = VXFS_ACL_OTHER;
			break;
		case SMB_ACL_MASK:
			type = VXFS_ACL_MASK;
			break;
		default:
			type = -1;
			talloc_free(buf);
			return NULL;
		}

		type = type & 0xff;

		/* Calculate id:
		 * We get owner uid and owner group gid in o_uid and o_gid
		 * Put these ids instead of -1
		 */
		switch(smb_ace->a_type) {
		case SMB_ACL_USER:
			id = smb_ace->info.user.uid;
			break;
		case SMB_ACL_GROUP:
			id = smb_ace->info.group.gid;
			break;
		case SMB_ACL_USER_OBJ:
			id = o_uid;
			break;
		case SMB_ACL_GROUP_OBJ:
			id = o_gid;
			break;
		case SMB_ACL_MASK:
		case SMB_ACL_OTHER:
			id = -1;
			break;
		default:
			/* Can't happen.. */
			id = -1;
			break;
		}

		/* Calculate perm */
		perm = smb_ace->a_perm & 0xff;

		/* TYPE is the first 2 bytes of an entry */
		SSVAL(buf, offset, type);
		offset += 2;

		/* PERM is the next 2 bytes of an entry */
		SSVAL(buf, offset, perm);
		offset += 2;

		/* ID is the last 4 bytes of an entry */
		SIVAL(buf, offset, id);
		offset += 4;

		smb_ace++;
	}

	qsort(buf, count, 8, vxfs_ace_cmp);

	DEBUG(10, ("vfs_vxfs: Print sorted aces:\n"));
	vxfs_print_ace_buf(buf, count);

	return buf;
}
コード例 #5
0
ファイル: pipes.c プロジェクト: 0x24bin/winexe-1
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;
}
コード例 #6
0
static void smbd_smb2_request_read_done(struct tevent_req *subreq)
{
	struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
					struct smbd_smb2_request);
	int i = req->current_idx;
	uint8_t *outhdr;
	DATA_BLOB outbody;
	DATA_BLOB outdyn;
	uint8_t out_data_offset;
	DATA_BLOB out_data_buffer = data_blob_null;
	uint32_t out_data_remaining = 0;
	NTSTATUS status;
	NTSTATUS error; /* transport error */

	status = smbd_smb2_read_recv(subreq,
				     req,
				     &out_data_buffer,
				     &out_data_remaining);
	TALLOC_FREE(subreq);
	if (!NT_STATUS_IS_OK(status)) {
		error = smbd_smb2_request_error(req, status);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(req->sconn,
							 nt_errstr(error));
			return;
		}
		return;
	}

	out_data_offset = SMB2_HDR_BODY + 0x10;

	outhdr = (uint8_t *)req->out.vector[i].iov_base;

	outbody = data_blob_talloc(req->out.vector, NULL, 0x10);
	if (outbody.data == NULL) {
		error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
		if (!NT_STATUS_IS_OK(error)) {
			smbd_server_connection_terminate(req->sconn,
							 nt_errstr(error));
			return;
		}
		return;
	}

	SSVAL(outbody.data, 0x00, 0x10 + 1);	/* struct size */
	SCVAL(outbody.data, 0x02,
	      out_data_offset);			/* data offset */
	SCVAL(outbody.data, 0x03, 0);		/* reserved */
	SIVAL(outbody.data, 0x04,
	      out_data_buffer.length);		/* data length */
	SIVAL(outbody.data, 0x08,
	      out_data_remaining);		/* data remaining */
	SIVAL(outbody.data, 0x0C, 0);		/* reserved */

	outdyn = out_data_buffer;

	error = smbd_smb2_request_done(req, outbody, &outdyn);
	if (!NT_STATUS_IS_OK(error)) {
		smbd_server_connection_terminate(req->sconn,
						 nt_errstr(error));
		return;
	}
}
コード例 #7
0
ファイル: cliquota.c プロジェクト: AllardJ/Tomato
bool cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST **pqt_list)
{
	bool ret = False;
	uint16 setup;
	char params[16];
	char *rparam=NULL, *rdata=NULL;
	unsigned int rparam_count=0, rdata_count=0;
	unsigned int offset;
	const char *curdata = NULL;
	unsigned int curdata_count = 0;
	TALLOC_CTX *mem_ctx = NULL;
	SMB_NTQUOTA_STRUCT qt;
	SMB_NTQUOTA_LIST *tmp_list_ent;

	if (!cli||!pqt_list) {
		smb_panic("cli_list_user_quota() called with NULL Pointer!");
	}

	setup = NT_TRANSACT_GET_USER_QUOTA;

	SSVAL(params, 0,quota_fnum);
	SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_START);
	SIVAL(params, 4,0x00000000);
	SIVAL(params, 8,0x00000000);
	SIVAL(params,12,0x00000000);

	if (!cli_send_nt_trans(cli, 
			       NT_TRANSACT_GET_USER_QUOTA, 
			       0, 
			       &setup, 1, 0,
			       params, 16, 4,
			       NULL, 0, 2048)) {
		DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
		goto cleanup;
	}


	if (!cli_receive_nt_trans(cli,
				  &rparam, &rparam_count,
				  &rdata, &rdata_count)) {
		DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
		goto cleanup;
	}

	if (cli_is_error(cli)) {
		ret = False;
		goto cleanup;
	} else {
		ret = True;
	}

	if (rdata_count == 0) {
		*pqt_list = NULL;
		return True;
	}

	if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) {
		DEBUG(0,("talloc_init() failed\n"));
		return (-1);
	}

	offset = 1;
	for (curdata=rdata,curdata_count=rdata_count;
		((curdata)&&(curdata_count>=8)&&(offset>0));
		curdata +=offset,curdata_count -= offset) {
		ZERO_STRUCT(qt);
		if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) {
			DEBUG(1,("Failed to parse the quota record\n"));
			goto cleanup;
		}

		if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
			DEBUG(0,("TALLOC_ZERO() failed\n"));
			talloc_destroy(mem_ctx);
			return (-1);
		}

		if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
			DEBUG(0,("TALLOC_ZERO() failed\n"));
			talloc_destroy(mem_ctx);
			return (-1);
		}

		memcpy(tmp_list_ent->quotas,&qt,sizeof(qt));
		tmp_list_ent->mem_ctx = mem_ctx;		

		DLIST_ADD((*pqt_list),tmp_list_ent);
	}

	SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_CONTINUE);	
	while(1) {
		if (!cli_send_nt_trans(cli, 
				       NT_TRANSACT_GET_USER_QUOTA, 
				       0, 
				       &setup, 1, 0,
				       params, 16, 4,
				       NULL, 0, 2048)) {
			DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
			goto cleanup;
		}

		SAFE_FREE(rparam);
		SAFE_FREE(rdata);
		if (!cli_receive_nt_trans(cli,
					  &rparam, &rparam_count,
					  &rdata, &rdata_count)) {
			DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
			goto cleanup;
		}

		if (cli_is_error(cli)) {
			ret = False;
			goto cleanup;
		} else {
			ret = True;
		}

		if (rdata_count == 0) {
			break;	
		}

		offset = 1;
		for (curdata=rdata,curdata_count=rdata_count;
			((curdata)&&(curdata_count>=8)&&(offset>0));
			curdata +=offset,curdata_count -= offset) {
			ZERO_STRUCT(qt);
			if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) {
				DEBUG(1,("Failed to parse the quota record\n"));
				goto cleanup;
			}

			if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
				DEBUG(0,("TALLOC_ZERO() failed\n"));
				talloc_destroy(mem_ctx);
				goto cleanup;
			}

			if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
				DEBUG(0,("TALLOC_ZERO() failed\n"));
				talloc_destroy(mem_ctx);
				goto cleanup;
			}

			memcpy(tmp_list_ent->quotas,&qt,sizeof(qt));
			tmp_list_ent->mem_ctx = mem_ctx;		

			DLIST_ADD((*pqt_list),tmp_list_ent);
		}
	}


	ret = True;
 cleanup:
	SAFE_FREE(rparam);
	SAFE_FREE(rdata);

	return ret;
}
コード例 #8
0
ファイル: blob.c プロジェクト: Marvin-Lee/libwmiclient
/*
  fill a single entry in a trans2 find reply 
*/
NTSTATUS smbsrv_push_passthru_search(TALLOC_CTX *mem_ctx,
				     DATA_BLOB *blob,
				     enum smb_search_data_level level,
				     union smb_search_data *file,
				     int default_str_flags)
{
	uint8_t *data;
	uint_t ofs = blob->length;

	switch (level) {
	case RAW_SEARCH_DATA_DIRECTORY_INFO:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 64));
		data = blob->data + ofs;
		SIVAL(data,          4, file->directory_info.file_index);
		push_nttime(data,    8, file->directory_info.create_time);
		push_nttime(data,   16, file->directory_info.access_time);
		push_nttime(data,   24, file->directory_info.write_time);
		push_nttime(data,   32, file->directory_info.change_time);
		SBVAL(data,         40, file->directory_info.size);
		SBVAL(data,         48, file->directory_info.alloc_size);
		SIVAL(data,         56, file->directory_info.attrib);
		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->directory_info.name.s,
						     ofs + 60, default_str_flags,
						     STR_TERMINATE_ASCII));
		BLOB_ALIGN(blob, 8);
		data = blob->data + ofs;
		SIVAL(data,          0, blob->length - ofs);
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 68));
		data = blob->data + ofs;
		SIVAL(data,          4, file->full_directory_info.file_index);
		push_nttime(data,    8, file->full_directory_info.create_time);
		push_nttime(data,   16, file->full_directory_info.access_time);
		push_nttime(data,   24, file->full_directory_info.write_time);
		push_nttime(data,   32, file->full_directory_info.change_time);
		SBVAL(data,         40, file->full_directory_info.size);
		SBVAL(data,         48, file->full_directory_info.alloc_size);
		SIVAL(data,         56, file->full_directory_info.attrib);
		SIVAL(data,         64, file->full_directory_info.ea_size);
		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->full_directory_info.name.s, 
						     ofs + 60, default_str_flags,
						     STR_TERMINATE_ASCII));
		BLOB_ALIGN(blob, 8);
		data = blob->data + ofs;
		SIVAL(data,          0, blob->length - ofs);
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_NAME_INFO:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 12));
		data = blob->data + ofs;
		SIVAL(data,          4, file->name_info.file_index);
		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->name_info.name.s, 
						     ofs + 8, default_str_flags,
						     STR_TERMINATE_ASCII));
		BLOB_ALIGN(blob, 8);
		data = blob->data + ofs;
		SIVAL(data,          0, blob->length - ofs);
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 94));
		data = blob->data + ofs;
		SIVAL(data,          4, file->both_directory_info.file_index);
		push_nttime(data,    8, file->both_directory_info.create_time);
		push_nttime(data,   16, file->both_directory_info.access_time);
		push_nttime(data,   24, file->both_directory_info.write_time);
		push_nttime(data,   32, file->both_directory_info.change_time);
		SBVAL(data,         40, file->both_directory_info.size);
		SBVAL(data,         48, file->both_directory_info.alloc_size);
		SIVAL(data,         56, file->both_directory_info.attrib);
		SIVAL(data,         64, file->both_directory_info.ea_size);
		SCVAL(data,         69, 0); /* reserved */
		memset(data+70,0,24);
		smbsrv_blob_push_string(mem_ctx, blob, 
					68 + ofs, 70 + ofs, 
					file->both_directory_info.short_name.s, 
					24, default_str_flags,
					STR_UNICODE | STR_LEN8BIT);
		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->both_directory_info.name.s, 
						     ofs + 60, default_str_flags,
						     STR_TERMINATE_ASCII));
		BLOB_ALIGN(blob, 8);
		data = blob->data + ofs;
		SIVAL(data,          0, blob->length - ofs);
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 80));
		data = blob->data + ofs;
		SIVAL(data,          4, file->id_full_directory_info.file_index);
		push_nttime(data,    8, file->id_full_directory_info.create_time);
		push_nttime(data,   16, file->id_full_directory_info.access_time);
		push_nttime(data,   24, file->id_full_directory_info.write_time);
		push_nttime(data,   32, file->id_full_directory_info.change_time);
		SBVAL(data,         40, file->id_full_directory_info.size);
		SBVAL(data,         48, file->id_full_directory_info.alloc_size);
		SIVAL(data,         56, file->id_full_directory_info.attrib);
		SIVAL(data,         64, file->id_full_directory_info.ea_size);
		SIVAL(data,         68, 0); /* padding */
		SBVAL(data,         72, file->id_full_directory_info.file_id);
		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->id_full_directory_info.name.s, 
						     ofs + 60, default_str_flags,
						     STR_TERMINATE_ASCII));
		BLOB_ALIGN(blob, 8);
		data = blob->data + ofs;
		SIVAL(data,          0, blob->length - ofs);
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 104));
		data = blob->data + ofs;
		SIVAL(data,          4, file->id_both_directory_info.file_index);
		push_nttime(data,    8, file->id_both_directory_info.create_time);
		push_nttime(data,   16, file->id_both_directory_info.access_time);
		push_nttime(data,   24, file->id_both_directory_info.write_time);
		push_nttime(data,   32, file->id_both_directory_info.change_time);
		SBVAL(data,         40, file->id_both_directory_info.size);
		SBVAL(data,         48, file->id_both_directory_info.alloc_size);
		SIVAL(data,         56, file->id_both_directory_info.attrib);
		SIVAL(data,         64, file->id_both_directory_info.ea_size);
		SCVAL(data,         69, 0); /* reserved */
		memset(data+70,0,26);
		smbsrv_blob_push_string(mem_ctx, blob, 
					68 + ofs, 70 + ofs, 
					file->id_both_directory_info.short_name.s, 
					24, default_str_flags,
					STR_UNICODE | STR_LEN8BIT);
		SBVAL(data,         96, file->id_both_directory_info.file_id);
		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->id_both_directory_info.name.s, 
						     ofs + 60, default_str_flags,
						     STR_TERMINATE_ASCII));
		BLOB_ALIGN(blob, 8);
		data = blob->data + ofs;
		SIVAL(data,          0, blob->length - ofs);
		return NT_STATUS_OK;

	default:
		return NT_STATUS_INVALID_LEVEL;
	}

	return NT_STATUS_INVALID_LEVEL;
}
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);
}
コード例 #10
0
ファイル: blob.c プロジェクト: Marvin-Lee/libwmiclient
NTSTATUS smbsrv_push_passthru_fsinfo(TALLOC_CTX *mem_ctx,
				     DATA_BLOB *blob,
				     enum smb_fsinfo_level level,
				     union smb_fsinfo *fsinfo,
				     int default_str_flags)
{
	uint_t i;
	DATA_BLOB guid_blob;

	switch (level) {
	case RAW_QFS_VOLUME_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 18));

		push_nttime(blob->data, 0, fsinfo->volume_info.out.create_time);
		SIVAL(blob->data,       8, fsinfo->volume_info.out.serial_number);
		SSVAL(blob->data,      16, 0); /* padding */
		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob,
						     fsinfo->volume_info.out.volume_name.s,
						     12, default_str_flags,
						     STR_UNICODE));

		return NT_STATUS_OK;

	case RAW_QFS_SIZE_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 24));

		SBVAL(blob->data,  0, fsinfo->size_info.out.total_alloc_units);
		SBVAL(blob->data,  8, fsinfo->size_info.out.avail_alloc_units);
		SIVAL(blob->data, 16, fsinfo->size_info.out.sectors_per_unit);
		SIVAL(blob->data, 20, fsinfo->size_info.out.bytes_per_sector);

		return NT_STATUS_OK;

	case RAW_QFS_DEVICE_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 8));

		SIVAL(blob->data,      0, fsinfo->device_info.out.device_type);
		SIVAL(blob->data,      4, fsinfo->device_info.out.characteristics);

		return NT_STATUS_OK;

	case RAW_QFS_ATTRIBUTE_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 12));

		SIVAL(blob->data, 0, fsinfo->attribute_info.out.fs_attr);
		SIVAL(blob->data, 4, fsinfo->attribute_info.out.max_file_component_length);
		/* this must not be null terminated or win98 gets
		   confused!  also note that w2k3 returns this as
		   unicode even when ascii is negotiated */
		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob,
						     fsinfo->attribute_info.out.fs_type.s,
						     8, default_str_flags,
						     STR_UNICODE));
		return NT_STATUS_OK;


	case RAW_QFS_QUOTA_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 48));

		SBVAL(blob->data,   0, fsinfo->quota_information.out.unknown[0]);
		SBVAL(blob->data,   8, fsinfo->quota_information.out.unknown[1]);
		SBVAL(blob->data,  16, fsinfo->quota_information.out.unknown[2]);
		SBVAL(blob->data,  24, fsinfo->quota_information.out.quota_soft);
		SBVAL(blob->data,  32, fsinfo->quota_information.out.quota_hard);
		SBVAL(blob->data,  40, fsinfo->quota_information.out.quota_flags);

		return NT_STATUS_OK;


	case RAW_QFS_FULL_SIZE_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 32));

		SBVAL(blob->data,  0, fsinfo->full_size_information.out.total_alloc_units);
		SBVAL(blob->data,  8, fsinfo->full_size_information.out.call_avail_alloc_units);
		SBVAL(blob->data, 16, fsinfo->full_size_information.out.actual_avail_alloc_units);
		SIVAL(blob->data, 24, fsinfo->full_size_information.out.sectors_per_unit);
		SIVAL(blob->data, 28, fsinfo->full_size_information.out.bytes_per_sector);

		return NT_STATUS_OK;

	case RAW_QFS_OBJECTID_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 64));

		BLOB_CHECK(ndr_push_struct_blob(&guid_blob, mem_ctx, 
						&fsinfo->objectid_information.out.guid,
						(ndr_push_flags_fn_t)ndr_push_GUID));
		memcpy(blob->data, guid_blob.data, guid_blob.length);

		for (i=0;i<6;i++) {
			SBVAL(blob->data, 16 + 8*i, fsinfo->objectid_information.out.unknown[i]);
		}

		return NT_STATUS_OK;

	default:
		return NT_STATUS_INVALID_LEVEL;
	}

	return NT_STATUS_INVALID_LEVEL;
}
コード例 #11
0
ファイル: blob.c プロジェクト: Marvin-Lee/libwmiclient
NTSTATUS smbsrv_push_passthru_fileinfo(TALLOC_CTX *mem_ctx,
				       DATA_BLOB *blob,
				       enum smb_fileinfo_level level,
				       union smb_fileinfo *st,
				       int default_str_flags)
{
	uint_t i;
	size_t list_size;

	switch (level) {
	case RAW_FILEINFO_BASIC_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 40));

		push_nttime(blob->data,  0, st->basic_info.out.create_time);
		push_nttime(blob->data,  8, st->basic_info.out.access_time);
		push_nttime(blob->data, 16, st->basic_info.out.write_time);
		push_nttime(blob->data, 24, st->basic_info.out.change_time);
		SIVAL(blob->data,       32, st->basic_info.out.attrib);
		SIVAL(blob->data,       36, 0); /* padding */
		return NT_STATUS_OK;

	case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 56));

		push_nttime(blob->data,  0, st->network_open_information.out.create_time);
		push_nttime(blob->data,  8, st->network_open_information.out.access_time);
		push_nttime(blob->data, 16, st->network_open_information.out.write_time);
		push_nttime(blob->data, 24, st->network_open_information.out.change_time);
		SBVAL(blob->data,       32, st->network_open_information.out.alloc_size);
		SBVAL(blob->data,       40, st->network_open_information.out.size);
		SIVAL(blob->data,       48, st->network_open_information.out.attrib);
		SIVAL(blob->data,       52, 0); /* padding */
		return NT_STATUS_OK;

	case RAW_FILEINFO_STANDARD_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 24));

		SBVAL(blob->data,  0, st->standard_info.out.alloc_size);
		SBVAL(blob->data,  8, st->standard_info.out.size);
		SIVAL(blob->data, 16, st->standard_info.out.nlink);
		SCVAL(blob->data, 20, st->standard_info.out.delete_pending);
		SCVAL(blob->data, 21, st->standard_info.out.directory);
		SSVAL(blob->data, 22, 0); /* padding */
		return NT_STATUS_OK;

	case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 8));

		SIVAL(blob->data,  0, st->attribute_tag_information.out.attrib);
		SIVAL(blob->data,  4, st->attribute_tag_information.out.reparse_tag);
		return NT_STATUS_OK;

	case RAW_FILEINFO_EA_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4));

		SIVAL(blob->data,  0, st->ea_info.out.ea_size);
		return NT_STATUS_OK;

	case RAW_FILEINFO_MODE_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4));

		SIVAL(blob->data,  0, st->mode_information.out.mode);
		return NT_STATUS_OK;

	case RAW_FILEINFO_ALIGNMENT_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4));

		SIVAL(blob->data,  0, 
		      st->alignment_information.out.alignment_requirement);
		return NT_STATUS_OK;

	case RAW_FILEINFO_ACCESS_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4));

		SIVAL(blob->data,  0, st->access_information.out.access_flags);
		return NT_STATUS_OK;

	case RAW_FILEINFO_POSITION_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 8));

		SBVAL(blob->data,  0, st->position_information.out.position);
		return NT_STATUS_OK;

	case RAW_FILEINFO_COMPRESSION_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 16));

		SBVAL(blob->data,  0, st->compression_info.out.compressed_size);
		SSVAL(blob->data,  8, st->compression_info.out.format);
		SCVAL(blob->data, 10, st->compression_info.out.unit_shift);
		SCVAL(blob->data, 11, st->compression_info.out.chunk_shift);
		SCVAL(blob->data, 12, st->compression_info.out.cluster_shift);
		SSVAL(blob->data, 13, 0); /* 3 bytes padding */
		SCVAL(blob->data, 15, 0);
		return NT_STATUS_OK;

	case RAW_FILEINFO_INTERNAL_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 8));

		SBVAL(blob->data,  0, st->internal_information.out.file_id);
		return NT_STATUS_OK;

	case RAW_FILEINFO_ALL_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 72));

		push_nttime(blob->data,  0, st->all_info.out.create_time);
		push_nttime(blob->data,  8, st->all_info.out.access_time);
		push_nttime(blob->data, 16, st->all_info.out.write_time);
		push_nttime(blob->data, 24, st->all_info.out.change_time);
		SIVAL(blob->data,       32, st->all_info.out.attrib);
		SIVAL(blob->data,       36, 0); /* padding */
		SBVAL(blob->data,       40, st->all_info.out.alloc_size);
		SBVAL(blob->data,       48, st->all_info.out.size);
		SIVAL(blob->data,       56, st->all_info.out.nlink);
		SCVAL(blob->data,       60, st->all_info.out.delete_pending);
		SCVAL(blob->data,       61, st->all_info.out.directory);
		SSVAL(blob->data,       62, 0); /* padding */
		SIVAL(blob->data,       64, st->all_info.out.ea_size);
		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob,
						     st->all_info.out.fname.s,
						     68, default_str_flags,
						     STR_UNICODE));
		return NT_STATUS_OK;

	case RAW_FILEINFO_NAME_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4));

		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob,
						     st->name_info.out.fname.s,
						     0, default_str_flags,
						     STR_UNICODE));
		return NT_STATUS_OK;

	case RAW_FILEINFO_ALT_NAME_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4));

		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, 
						     st->alt_name_info.out.fname.s,
						     0, default_str_flags,
						     STR_UNICODE));
		return NT_STATUS_OK;

	case RAW_FILEINFO_STREAM_INFORMATION:
		for (i=0;i<st->stream_info.out.num_streams;i++) {
			uint32_t data_size = blob->length;
			uint8_t *data;

			BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, data_size + 24));
			data = blob->data + data_size;
			SBVAL(data,  8, st->stream_info.out.streams[i].size);
			SBVAL(data, 16, st->stream_info.out.streams[i].alloc_size);
			BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob,
							     st->stream_info.out.streams[i].stream_name.s,
							     data_size + 4, default_str_flags,
							     STR_UNICODE));
			if (i == st->stream_info.out.num_streams - 1) {
				SIVAL(blob->data, data_size, 0);
			} else {
				BLOB_CHECK(smbsrv_blob_fill_data(mem_ctx, blob, (blob->length+7)&~7));
				SIVAL(blob->data, data_size, 
				      blob->length - data_size);
			}
		}
		return NT_STATUS_OK;

	case RAW_FILEINFO_SMB2_ALL_EAS:
		/* if no eas are returned the backend should
		 * have returned NO_EAS_ON_FILE or NO_MORE_EAS
		 *
		 * so it's a programmer error if num_eas == 0
		 */
		if (st->all_eas.out.num_eas == 0) {
			smb_panic("0 eas for SMB2_ALL_EAS - programmer error in ntvfs backend");
		}

		list_size = ea_list_size_chained(st->all_eas.out.num_eas,
						 st->all_eas.out.eas);
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, list_size));

		ea_put_list_chained(blob->data,
				    st->all_eas.out.num_eas,
				    st->all_eas.out.eas);
		return NT_STATUS_OK;

	case RAW_FILEINFO_SMB2_ALL_INFORMATION:
		BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 0x64));

		push_nttime(blob->data, 0x00, st->all_info2.out.create_time);
		push_nttime(blob->data, 0x08, st->all_info2.out.access_time);
		push_nttime(blob->data, 0x10, st->all_info2.out.write_time);
		push_nttime(blob->data, 0x18, st->all_info2.out.change_time);
		SIVAL(blob->data,       0x20, st->all_info2.out.attrib);
		SIVAL(blob->data,       0x24, st->all_info2.out.unknown1);
		SBVAL(blob->data,       0x28, st->all_info2.out.alloc_size);
		SBVAL(blob->data,       0x30, st->all_info2.out.size);
		SIVAL(blob->data,       0x38, st->all_info2.out.nlink);
		SCVAL(blob->data,       0x3C, st->all_info2.out.delete_pending);
		SCVAL(blob->data,       0x3D, st->all_info2.out.directory);
		SSVAL(blob->data,       0x3E, 0); /* padding */
		SBVAL(blob->data,	0x40, st->all_info2.out.file_id);
		SIVAL(blob->data,       0x48, st->all_info2.out.ea_size);
		SIVAL(blob->data,	0x4C, st->all_info2.out.access_mask);
		SBVAL(blob->data,	0x50, st->all_info2.out.position);
		SBVAL(blob->data,	0x58, st->all_info2.out.mode);
		BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob,
						     st->all_info2.out.fname.s,
						     0x60, default_str_flags,
						     STR_UNICODE));
		return NT_STATUS_OK;

	default:
		return NT_STATUS_INVALID_LEVEL;
	}

	return NT_STATUS_INVALID_LEVEL;
}
コード例 #12
0
ファイル: blob.c プロジェクト: Marvin-Lee/libwmiclient
/*
  push a string into the data section of a trans2 request
  return the number of bytes consumed in the output
*/
size_t smbsrv_blob_push_string(TALLOC_CTX *mem_ctx,
			       DATA_BLOB *blob,
			       uint32_t len_offset,
			       uint32_t offset,
			       const char *str,
			       int dest_len,
			       int default_flags,
			       int flags)
{
	int alignment = 0, ret = 0, pkt_len;

	/* we use STR_NO_RANGE_CHECK because the params are allocated
	   separately in a DATA_BLOB, so we need to do our own range
	   checking */
	if (!str || offset >= blob->length) {
		if (flags & STR_LEN8BIT) {
			SCVAL(blob->data, len_offset, 0);
		} else {
			SIVAL(blob->data, len_offset, 0);
		}
		return 0;
	}

	flags |= STR_NO_RANGE_CHECK;

	if (dest_len == -1 || (dest_len > blob->length - offset)) {
		dest_len = blob->length - offset;
	}

	if (!(flags & (STR_ASCII|STR_UNICODE))) {
		flags |= default_flags;
	}

	if ((offset&1) && (flags & STR_UNICODE) && !(flags & STR_NOALIGN)) {
		alignment = 1;
		if (dest_len > 0) {
			SCVAL(blob->data + offset, 0, 0);
			ret = push_string(blob->data + offset + 1, str, dest_len-1, flags);
		}
	} else {
		ret = push_string(blob->data + offset, str, dest_len, flags);
	}

	/* sometimes the string needs to be terminated, but the length
	   on the wire must not include the termination! */
	pkt_len = ret;

	if ((flags & STR_LEN_NOTERM) && (flags & STR_TERMINATE)) {
		if ((flags & STR_UNICODE) && ret >= 2) {
			pkt_len = ret-2;
		}
		if ((flags & STR_ASCII) && ret >= 1) {
			pkt_len = ret-1;
		}
	}

	if (flags & STR_LEN8BIT) {
		SCVAL(blob->data, len_offset, pkt_len);
	} else {
		SIVAL(blob->data, len_offset, pkt_len);
	}

	return ret + alignment;
}
コード例 #13
0
ファイル: afs.c プロジェクト: hajuuk/R7000
static BOOL afs_createtoken(const char *username, const char *cell,
			    DATA_BLOB *ticket, struct ClearToken *ct)
{
	fstring clear_ticket;
	char *p = clear_ticket;
	uint32 len;
	uint32 now;

	struct afs_key key;
	des_key_schedule key_schedule;

	if (!secrets_init()) 
		return False;

	if (!secrets_fetch_afs_key(cell, &key)) {
		DEBUG(1, ("Could not fetch AFS service key\n"));
		return False;
	}

	ct->AuthHandle = key.kvno;

	/* Build the ticket. This is going to be encrypted, so in our
           way we fill in ct while we still have the unencrypted
           form. */

	p = clear_ticket;

	/* The byte-order */
	*p = 1;
	p += 1;

	/* "Alice", the client username */
	strncpy(p, username, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
	p += strlen(p)+1;
	strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
	p += strlen(p)+1;
	strncpy(p, cell, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
	p += strlen(p)+1;

	/* Alice's network layer address. At least Openafs-1.2.10
           ignores this, so we fill in a dummy value here. */
	SIVAL(p, 0, 0);
	p += 4;

	/* We need to create a session key */
	generate_random_buffer(p, 8);

	/* Our client code needs the the key in the clear, it does not
           know the server-key ... */
	memcpy(ct->HandShakeKey, p, 8);

	p += 8;

	/* This is a kerberos 4 life time. The life time is expressed
	 * in units of 5 minute intervals up to 38400 seconds, after
	 * that a table is used up to lifetime 0xBF. Values between
	 * 0xC0 and 0xFF is undefined. 0xFF is defined to be the
	 * infinite time that never expire.
	 *
	 * So here we cheat and use the infinite time */
	*p = 255;
	p += 1;

	/* Ticket creation time */
	now = time(NULL);
	SIVAL(p, 0, now);
	ct->BeginTimestamp = now;

	if(lp_afs_token_lifetime() == 0)
		ct->EndTimestamp = NEVERDATE;
	else
		ct->EndTimestamp = now + lp_afs_token_lifetime();

	if (((ct->EndTimestamp - ct->BeginTimestamp) & 1) == 1) {
		ct->BeginTimestamp += 1; /* Lifetime must be even */
	}
	p += 4;

	/* And here comes Bob's name and instance, in this case the
           AFS server. */
	strncpy(p, "afs", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
	p += strlen(p)+1;
	strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
	p += strlen(p)+1;

	/* And zero-pad to a multiple of 8 bytes */
	len = PTR_DIFF(p, clear_ticket);
	if (len & 7) {
		uint32 extra_space = 8-(len & 7);
		memset(p, 0, extra_space);
		p+=extra_space;
	}
	len = PTR_DIFF(p, clear_ticket);

	des_key_sched((const_des_cblock *)key.key, key_schedule);
	des_pcbc_encrypt(clear_ticket, clear_ticket,
			 len, key_schedule, (C_Block *)key.key, 1);

	ZERO_STRUCT(key);

	*ticket = data_blob(clear_ticket, len);

	return True;
}
コード例 #14
0
ファイル: smb2_negprot.c プロジェクト: aixoss/samba
NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
{
	struct smbXsrv_connection *xconn = req->xconn;
	NTSTATUS status;
	const uint8_t *inbody;
	const uint8_t *indyn = NULL;
	DATA_BLOB outbody;
	DATA_BLOB outdyn;
	DATA_BLOB negprot_spnego_blob;
	uint16_t security_offset;
	DATA_BLOB security_buffer;
	size_t expected_dyn_size = 0;
	size_t c;
	uint16_t security_mode;
	uint16_t dialect_count;
	uint16_t in_security_mode;
	uint32_t in_capabilities;
	DATA_BLOB in_guid_blob;
	struct GUID in_guid;
	struct smb2_negotiate_contexts in_c = { .num_contexts = 0, };
	struct smb2_negotiate_context *in_preauth = NULL;
	struct smb2_negotiate_context *in_cipher = NULL;
	struct smb2_negotiate_contexts out_c = { .num_contexts = 0, };
	DATA_BLOB out_negotiate_context_blob = data_blob_null;
	uint32_t out_negotiate_context_offset = 0;
	uint16_t out_negotiate_context_count = 0;
	uint16_t dialect = 0;
	uint32_t capabilities;
	DATA_BLOB out_guid_blob;
	struct GUID out_guid;
	enum protocol_types protocol = PROTOCOL_NONE;
	uint32_t max_limit;
	uint32_t max_trans = lp_smb2_max_trans();
	uint32_t max_read = lp_smb2_max_read();
	uint32_t max_write = lp_smb2_max_write();
	NTTIME now = timeval_to_nttime(&req->request_time);
	bool signing_required = true;
	bool ok;

	status = smbd_smb2_request_verify_sizes(req, 0x24);
	if (!NT_STATUS_IS_OK(status)) {
		return smbd_smb2_request_error(req, status);
	}
	inbody = SMBD_SMB2_IN_BODY_PTR(req);

	dialect_count = SVAL(inbody, 0x02);

	in_security_mode = SVAL(inbody, 0x04);
	in_capabilities = IVAL(inbody, 0x08);
	in_guid_blob = data_blob_const(inbody + 0x0C, 16);

	if (dialect_count == 0) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}

	status = GUID_from_ndr_blob(&in_guid_blob, &in_guid);
	if (!NT_STATUS_IS_OK(status)) {
		return smbd_smb2_request_error(req, status);
	}

	expected_dyn_size = dialect_count * 2;
	if (SMBD_SMB2_IN_DYN_LEN(req) < expected_dyn_size) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}
	indyn = SMBD_SMB2_IN_DYN_PTR(req);

	protocol = smbd_smb2_protocol_dialect_match(indyn,
					dialect_count,
					&dialect);

	for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
		if (lp_server_max_protocol() < PROTOCOL_SMB2_10) {
			break;
		}

		dialect = SVAL(indyn, c*2);
		if (dialect == SMB2_DIALECT_REVISION_2FF) {
			if (xconn->smb2.allow_2ff) {
				xconn->smb2.allow_2ff = false;
				protocol = PROTOCOL_SMB2_10;
				break;
			}
		}
	}

	if (protocol == PROTOCOL_NONE) {
		return smbd_smb2_request_error(req, NT_STATUS_NOT_SUPPORTED);
	}

	if (protocol >= PROTOCOL_SMB3_10) {
		uint32_t in_negotiate_context_offset = 0;
		uint16_t in_negotiate_context_count = 0;
		DATA_BLOB in_negotiate_context_blob = data_blob_null;
		size_t ofs;

		in_negotiate_context_offset = IVAL(inbody, 0x1C);
		in_negotiate_context_count = SVAL(inbody, 0x20);

		ofs = SMB2_HDR_BODY;
		ofs += SMBD_SMB2_IN_BODY_LEN(req);
		ofs += expected_dyn_size;
		if ((ofs % 8) != 0) {
			ofs += 8 - (ofs % 8);
		}

		if (in_negotiate_context_offset != ofs) {
			return smbd_smb2_request_error(req,
					NT_STATUS_INVALID_PARAMETER);
		}

		ofs -= SMB2_HDR_BODY;
		ofs -= SMBD_SMB2_IN_BODY_LEN(req);

		if (SMBD_SMB2_IN_DYN_LEN(req) < ofs) {
			return smbd_smb2_request_error(req,
					NT_STATUS_INVALID_PARAMETER);
		}

		in_negotiate_context_blob = data_blob_const(indyn,
						SMBD_SMB2_IN_DYN_LEN(req));

		in_negotiate_context_blob.data += ofs;
		in_negotiate_context_blob.length -= ofs;

		status = smb2_negotiate_context_parse(req,
					in_negotiate_context_blob, &in_c);
		if (!NT_STATUS_IS_OK(status)) {
			return smbd_smb2_request_error(req, status);
		}

		if (in_negotiate_context_count != in_c.num_contexts) {
			return smbd_smb2_request_error(req,
					NT_STATUS_INVALID_PARAMETER);
		}
	}

	if ((dialect != SMB2_DIALECT_REVISION_2FF) &&
	    (protocol >= PROTOCOL_SMB2_10) &&
	    !GUID_all_zero(&in_guid))
	{
		ok = remote_arch_cache_update(&in_guid);
		if (!ok) {
			return smbd_smb2_request_error(
				req, NT_STATUS_UNSUCCESSFUL);
		}
	}

	switch (get_remote_arch()) {
	case RA_VISTA:
	case RA_SAMBA:
	case RA_CIFSFS:
	case RA_OSX:
		break;
	default:
		set_remote_arch(RA_VISTA);
		break;
	}

	fstr_sprintf(remote_proto, "SMB%X_%02X",
		     (dialect >> 8) & 0xFF, dialect & 0xFF);

	reload_services(req->sconn, conn_snum_used, true);
	DEBUG(3,("Selected protocol %s\n", remote_proto));

	in_preauth = smb2_negotiate_context_find(&in_c,
					SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
	if (protocol >= PROTOCOL_SMB3_10 && in_preauth == NULL) {
		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
	}
	in_cipher = smb2_negotiate_context_find(&in_c,
					SMB2_ENCRYPTION_CAPABILITIES);

	/* negprot_spnego() returns a the server guid in the first 16 bytes */
	negprot_spnego_blob = negprot_spnego(req, xconn);
	if (negprot_spnego_blob.data == NULL) {
		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
	}

	if (negprot_spnego_blob.length < 16) {
		return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
	}

	security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
	/*
	 * We use xconn->smb1.signing_state as that's already present
	 * and used lpcfg_server_signing_allowed() to get the correct
	 * defaults, e.g. signing_required for an ad_dc.
	 */
	signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state);
	if (signing_required) {
		security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
	}

	capabilities = 0;
	if (lp_host_msdfs()) {
		capabilities |= SMB2_CAP_DFS;
	}

	if (protocol >= PROTOCOL_SMB2_10 &&
	    lp_smb2_leases() &&
	    lp_oplocks(GLOBAL_SECTION_SNUM) &&
	    !lp_kernel_oplocks(GLOBAL_SECTION_SNUM))
	{
		capabilities |= SMB2_CAP_LEASING;
	}

	if ((protocol >= PROTOCOL_SMB2_24) &&
	    (lp_smb_encrypt(-1) != SMB_SIGNING_OFF) &&
	    (in_capabilities & SMB2_CAP_ENCRYPTION)) {
		capabilities |= SMB2_CAP_ENCRYPTION;
	}

	/*
	 * 0x10000 (65536) is the maximum allowed message size
	 * for SMB 2.0
	 */
	max_limit = 0x10000;

	if (protocol >= PROTOCOL_SMB2_10) {
		int p = 0;

		if (tsocket_address_is_inet(req->sconn->local_address, "ip")) {
			p = tsocket_address_inet_port(req->sconn->local_address);
		}

		/* largeMTU is not supported over NBT (tcp port 139) */
		if (p != NBT_SMB_PORT) {
			capabilities |= SMB2_CAP_LARGE_MTU;
			xconn->smb2.credits.multicredit = true;

			/*
			 * We allow up to almost 16MB.
			 *
			 * The maximum PDU size is 0xFFFFFF (16776960)
			 * and we need some space for the header.
			 */
			max_limit = 0xFFFF00;
		}
	}

	/*
	 * the defaults are 8MB, but we'll limit this to max_limit based on
	 * the dialect (64kb for SMB 2.0, 8MB for SMB >= 2.1 with LargeMTU)
	 *
	 * user configured values exceeding the limits will be overwritten,
	 * only smaller values will be accepted
	 */

	max_trans = MIN(max_limit, lp_smb2_max_trans());
	max_read = MIN(max_limit, lp_smb2_max_read());
	max_write = MIN(max_limit, lp_smb2_max_write());

	if (in_preauth != NULL) {
		size_t needed = 4;
		uint16_t hash_count;
		uint16_t salt_length;
		uint16_t selected_preauth = 0;
		const uint8_t *p;
		uint8_t buf[38];
		DATA_BLOB b;
		size_t i;

		if (in_preauth->data.length < needed) {
			return smbd_smb2_request_error(req,
					NT_STATUS_INVALID_PARAMETER);
		}

		hash_count = SVAL(in_preauth->data.data, 0);
		salt_length = SVAL(in_preauth->data.data, 2);

		if (hash_count == 0) {
			return smbd_smb2_request_error(req,
					NT_STATUS_INVALID_PARAMETER);
		}

		p = in_preauth->data.data + needed;
		needed += hash_count * 2;
		needed += salt_length;

		if (in_preauth->data.length < needed) {
			return smbd_smb2_request_error(req,
					NT_STATUS_INVALID_PARAMETER);
		}

		for (i=0; i < hash_count; i++) {
			uint16_t v;

			v = SVAL(p, 0);
			p += 2;

			if (v == SMB2_PREAUTH_INTEGRITY_SHA512) {
				selected_preauth = v;
				break;
			}
		}

		if (selected_preauth == 0) {
			return smbd_smb2_request_error(req,
				NT_STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP);
		}

		SSVAL(buf, 0,  1); /* HashAlgorithmCount */
		SSVAL(buf, 2, 32); /* SaltLength */
		SSVAL(buf, 4, selected_preauth);
		generate_random_buffer(buf + 6, 32);

		b = data_blob_const(buf, sizeof(buf));
		status = smb2_negotiate_context_add(req, &out_c,
					SMB2_PREAUTH_INTEGRITY_CAPABILITIES, b);
		if (!NT_STATUS_IS_OK(status)) {
			return smbd_smb2_request_error(req, status);
		}

		req->preauth = &req->xconn->smb2.preauth;
	}

	if (in_cipher != NULL) {
		size_t needed = 2;
		uint16_t cipher_count;
		const uint8_t *p;
		uint8_t buf[4];
		DATA_BLOB b;
		size_t i;
		bool aes_128_ccm_supported = false;
		bool aes_128_gcm_supported = false;

		capabilities &= ~SMB2_CAP_ENCRYPTION;

		if (in_cipher->data.length < needed) {
			return smbd_smb2_request_error(req,
					NT_STATUS_INVALID_PARAMETER);
		}

		cipher_count = SVAL(in_cipher->data.data, 0);

		if (cipher_count == 0) {
			return smbd_smb2_request_error(req,
					NT_STATUS_INVALID_PARAMETER);
		}

		p = in_cipher->data.data + needed;
		needed += cipher_count * 2;

		if (in_cipher->data.length < needed) {
			return smbd_smb2_request_error(req,
					NT_STATUS_INVALID_PARAMETER);
		}

		for (i=0; i < cipher_count; i++) {
			uint16_t v;

			v = SVAL(p, 0);
			p += 2;

			if (v == SMB2_ENCRYPTION_AES128_GCM) {
				aes_128_gcm_supported = true;
			}
			if (v == SMB2_ENCRYPTION_AES128_CCM) {
				aes_128_ccm_supported = true;
			}
		}

		/*
		 * For now we preferr CCM because our implementation
		 * is faster than GCM, see bug #11451.
		 */
		if (aes_128_ccm_supported) {
			xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
		} else if (aes_128_gcm_supported) {
			xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_GCM;
		}

		SSVAL(buf, 0, 1); /* ChiperCount */
		SSVAL(buf, 2, xconn->smb2.server.cipher);

		b = data_blob_const(buf, sizeof(buf));
		status = smb2_negotiate_context_add(req, &out_c,
					SMB2_ENCRYPTION_CAPABILITIES, b);
		if (!NT_STATUS_IS_OK(status)) {
			return smbd_smb2_request_error(req, status);
		}
	}

	if (capabilities & SMB2_CAP_ENCRYPTION) {
		xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
	}

	if (protocol >= PROTOCOL_SMB2_22 &&
	    xconn->client->server_multi_channel_enabled)
	{
		if (in_capabilities & SMB2_CAP_MULTI_CHANNEL) {
			capabilities |= SMB2_CAP_MULTI_CHANNEL;
		}
	}

	security_offset = SMB2_HDR_BODY + 0x40;

#if 1
	/* Try SPNEGO auth... */
	security_buffer = data_blob_const(negprot_spnego_blob.data + 16,
					  negprot_spnego_blob.length - 16);
#else
	/* for now we want raw NTLMSSP */
	security_buffer = data_blob_const(NULL, 0);
#endif

	if (out_c.num_contexts != 0) {
		status = smb2_negotiate_context_push(req,
						&out_negotiate_context_blob,
						out_c);
		if (!NT_STATUS_IS_OK(status)) {
			return smbd_smb2_request_error(req, status);
		}
	}

	if (out_negotiate_context_blob.length != 0) {
		static const uint8_t zeros[8];
		size_t pad = 0;
		size_t ofs;

		outdyn = data_blob_dup_talloc(req, security_buffer);
		if (outdyn.length != security_buffer.length) {
			return smbd_smb2_request_error(req,
						NT_STATUS_NO_MEMORY);
		}

		ofs = security_offset + security_buffer.length;
		if ((ofs % 8) != 0) {
			pad = 8 - (ofs % 8);
		}
		ofs += pad;

		ok = data_blob_append(req, &outdyn, zeros, pad);
		if (!ok) {
			return smbd_smb2_request_error(req,
						NT_STATUS_NO_MEMORY);
		}

		ok = data_blob_append(req, &outdyn,
				      out_negotiate_context_blob.data,
				      out_negotiate_context_blob.length);
		if (!ok) {
			return smbd_smb2_request_error(req,
						NT_STATUS_NO_MEMORY);
		}

		out_negotiate_context_offset = ofs;
		out_negotiate_context_count = out_c.num_contexts;
	} else {
		outdyn = security_buffer;
	}

	out_guid_blob = data_blob_const(negprot_spnego_blob.data, 16);
	status = GUID_from_ndr_blob(&out_guid_blob, &out_guid);
	if (!NT_STATUS_IS_OK(status)) {
		return smbd_smb2_request_error(req, status);
	}

	outbody = smbd_smb2_generate_outbody(req, 0x40);
	if (outbody.data == NULL) {
		return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
	}

	SSVAL(outbody.data, 0x00, 0x40 + 1);	/* struct size */
	SSVAL(outbody.data, 0x02,
	      security_mode);			/* security mode */
	SSVAL(outbody.data, 0x04, dialect);	/* dialect revision */
	SSVAL(outbody.data, 0x06,
	      out_negotiate_context_count);	/* reserved/NegotiateContextCount */
	memcpy(outbody.data + 0x08,
	       out_guid_blob.data, 16);	/* server guid */
	SIVAL(outbody.data, 0x18,
	      capabilities);			/* capabilities */
	SIVAL(outbody.data, 0x1C, max_trans);	/* max transact size */
	SIVAL(outbody.data, 0x20, max_read);	/* max read size */
	SIVAL(outbody.data, 0x24, max_write);	/* max write size */
	SBVAL(outbody.data, 0x28, now);		/* system time */
	SBVAL(outbody.data, 0x30, 0);		/* server start time */
	SSVAL(outbody.data, 0x38,
	      security_offset);			/* security buffer offset */
	SSVAL(outbody.data, 0x3A,
	      security_buffer.length);		/* security buffer length */
	SIVAL(outbody.data, 0x3C,
	      out_negotiate_context_offset);	/* reserved/NegotiateContextOffset */

	req->sconn->using_smb2 = true;

	if (dialect != SMB2_DIALECT_REVISION_2FF) {
		struct smbXsrv_client_global0 *global0 = NULL;

		status = smbXsrv_connection_init_tables(xconn, protocol);
		if (!NT_STATUS_IS_OK(status)) {
			return smbd_smb2_request_error(req, status);
		}

		xconn->smb2.client.capabilities = in_capabilities;
		xconn->smb2.client.security_mode = in_security_mode;
		xconn->smb2.client.guid = in_guid;
		xconn->smb2.client.num_dialects = dialect_count;
		xconn->smb2.client.dialects = talloc_array(xconn,
							   uint16_t,
							   dialect_count);
		if (xconn->smb2.client.dialects == NULL) {
			return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
		}
		for (c=0; c < dialect_count; c++) {
			xconn->smb2.client.dialects[c] = SVAL(indyn, c*2);
		}

		xconn->smb2.server.capabilities = capabilities;
		xconn->smb2.server.security_mode = security_mode;
		xconn->smb2.server.guid = out_guid;
		xconn->smb2.server.dialect = dialect;
		xconn->smb2.server.max_trans = max_trans;
		xconn->smb2.server.max_read  = max_read;
		xconn->smb2.server.max_write = max_write;

		if (xconn->protocol < PROTOCOL_SMB2_10) {
			/*
			 * SMB2_02 doesn't support client guids
			 */
			return smbd_smb2_request_done(req, outbody, &outdyn);
		}

		if (!xconn->client->server_multi_channel_enabled) {
			/*
			 * Only deal with the client guid database
			 * if multi-channel is enabled.
			 */
			return smbd_smb2_request_done(req, outbody, &outdyn);
		}

		if (xconn->smb2.client.guid_verified) {
			/*
			 * The connection was passed from another
			 * smbd process.
			 */
			return smbd_smb2_request_done(req, outbody, &outdyn);
		}

		status = smb2srv_client_lookup_global(xconn->client,
						xconn->smb2.client.guid,
						req, &global0);
		/*
		 * TODO: check for races...
		 */
		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECTID_NOT_FOUND)) {
			/*
			 * This stores the new client information in
			 * smbXsrv_client_global.tdb
			 */
			xconn->client->global->client_guid =
						xconn->smb2.client.guid;
			status = smbXsrv_client_update(xconn->client);
			if (!NT_STATUS_IS_OK(status)) {
				return status;
			}

			xconn->smb2.client.guid_verified = true;
		} else if (NT_STATUS_IS_OK(status)) {
			status = smb2srv_client_connection_pass(req,
								global0);
			if (!NT_STATUS_IS_OK(status)) {
				return smbd_smb2_request_error(req, status);
			}

			smbd_server_connection_terminate(xconn,
							 "passed connection");
			return NT_STATUS_OBJECTID_EXISTS;
		} else {
			return smbd_smb2_request_error(req, status);
		}
	}

	return smbd_smb2_request_done(req, outbody, &outdyn);
}
コード例 #15
0
ファイル: clirap.c プロジェクト: DanilKorotenko/samba
bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32_t stype,
		       void (*fn)(const char *, uint32_t, const char *, void *),
		       void *state)
{
	char *rparam = NULL;
	char *rdata = NULL;
	char *rdata_end = NULL;
	unsigned int rdrcnt,rprcnt;
	char *p;
	char param[1024];
	int uLevel = 1;
	size_t len;
	uint32_t func = RAP_NetServerEnum2;
	char *last_entry = NULL;
	int total_cnt = 0;
	int return_cnt = 0;
	int res;

	errno = 0; /* reset */

	/*
	 * This may take more than one transaction, so we should loop until
	 * we no longer get a more data to process or we have all of the
	 * items.
	 */
	do {
		/* send a SMBtrans command with api NetServerEnum */
	        p = param;
		SIVAL(p,0,func); /* api number */
	        p += 2;

		if (func == RAP_NetServerEnum3) {
			strlcpy(p,"WrLehDzz", sizeof(param)-PTR_DIFF(p,param));
		} else {
			strlcpy(p,"WrLehDz", sizeof(param)-PTR_DIFF(p,param));
		}

		p = skip_string(param, sizeof(param), p);
		strlcpy(p,"B16BBDz", sizeof(param)-PTR_DIFF(p,param));

		p = skip_string(param, sizeof(param), p);
		SSVAL(p,0,uLevel);
		SSVAL(p,2,CLI_BUFFER_SIZE);
		p += 4;
		SIVAL(p,0,stype);
		p += 4;

		/* If we have more data, tell the server where
		 * to continue from.
		 */
		len = push_ascii(p,
				workgroup,
				sizeof(param) - PTR_DIFF(p,param) - 1,
				STR_TERMINATE|STR_UPPER);

		if (len == 0) {
			SAFE_FREE(last_entry);
			return false;
		}
		p += len;

		if (func == RAP_NetServerEnum3) {
			len = push_ascii(p,
					last_entry ? last_entry : "",
					sizeof(param) - PTR_DIFF(p,param) - 1,
					STR_TERMINATE);

			if (len == 0) {
				SAFE_FREE(last_entry);
				return false;
			}
			p += len;
		}

		/* Next time through we need to use the continue api */
		func = RAP_NetServerEnum3;

		if (!cli_api(cli,
			param, PTR_DIFF(p,param), 8, /* params, length, max */
			NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
		            &rparam, &rprcnt, /* return params, return size */
		            &rdata, &rdrcnt)) { /* return data, return size */

			/* break out of the loop on error */
		        res = -1;
		        break;
		}

		rdata_end = rdata + rdrcnt;
		res = rparam ? SVAL(rparam,0) : -1;

		if (res == 0 || res == ERRmoredata ||
                    (res != -1 && cli_errno(cli) == 0)) {
			char *sname = NULL;
			int i, count;
			int converter=SVAL(rparam,2);

			/* Get the number of items returned in this buffer */
			count = SVAL(rparam, 4);

			/* The next field contains the number of items left,
			 * including those returned in this buffer. So the
			 * first time through this should contain all of the
			 * entries.
			 */
			if (total_cnt == 0) {
			        total_cnt = SVAL(rparam, 6);
			}

			/* Keep track of how many we have read */
			return_cnt += count;
			p = rdata;

			/* The last name in the previous NetServerEnum reply is
			 * sent back to server in the NetServerEnum3 request
			 * (last_entry). The next reply should repeat this entry
			 * as the first element. We have no proof that this is
			 * always true, but from traces that seems to be the
			 * behavior from Window Servers. So first lets do a lot
			 * of checking, just being paranoid. If the string
			 * matches then we already saw this entry so skip it.
			 *
			 * NOTE: sv1_name field must be null terminated and has
			 * a max size of 16 (NetBIOS Name).
			 */
			if (last_entry && count && p &&
				(strncmp(last_entry, p, 16) == 0)) {
			    count -= 1; /* Skip this entry */
			    return_cnt = -1; /* Not part of total, so don't count. */
			    p = rdata + 26; /* Skip the whole record */
			}

			for (i = 0; i < count; i++, p += 26) {
				int comment_offset;
				const char *cmnt;
				const char *p1;
				char *s1, *s2;
				TALLOC_CTX *frame = talloc_stackframe();
				uint32_t entry_stype;

				if (p + 26 > rdata_end) {
					TALLOC_FREE(frame);
					break;
				}

				sname = p;
				comment_offset = (IVAL(p,22) & 0xFFFF)-converter;
				cmnt = comment_offset?(rdata+comment_offset):"";

				if (comment_offset < 0 || comment_offset >= (int)rdrcnt) {
					TALLOC_FREE(frame);
					continue;
				}

				/* Work out the comment length. */
				for (p1 = cmnt, len = 0; *p1 &&
						p1 < rdata_end; len++)
					p1++;
				if (!*p1) {
					len++;
				}

				entry_stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;

				pull_string_talloc(frame,rdata,0,
					&s1,sname,16,STR_ASCII);
				pull_string_talloc(frame,rdata,0,
					&s2,cmnt,len,STR_ASCII);

				if (!s1 || !s2) {
					TALLOC_FREE(frame);
					continue;
				}

				fn(s1, entry_stype, s2, state);
				TALLOC_FREE(frame);
			}

			/* We are done with the old last entry, so now we can free it */
			if (last_entry) {
			        SAFE_FREE(last_entry); /* This will set it to null */
			}

			/* We always make a copy of  the last entry if we have one */
			if (sname) {
			        last_entry = smb_xstrdup(sname);
			}

			/* If we have more data, but no last entry then error out */
			if (!last_entry && (res == ERRmoredata)) {
			        errno = EINVAL;
			        res = 0;
			}

		}

		SAFE_FREE(rparam);
		SAFE_FREE(rdata);
	} while ((res == ERRmoredata) && (total_cnt > return_cnt));

	SAFE_FREE(rparam);
	SAFE_FREE(rdata);
	SAFE_FREE(last_entry);

	if (res == -1) {
		errno = cli_errno(cli);
	} else {
		if (!return_cnt) {
			/* this is a very special case, when the domain master for the
			   work group isn't part of the work group itself, there is something
			   wild going on */
			errno = ENOENT;
		}
	    }

	return(return_cnt > 0);
}
コード例 #16
0
ファイル: ntlmssp_sign.c プロジェクト: hynnet/ralink_sdk
NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
                             uchar *data, size_t length,
                             DATA_BLOB *sig)
{
    if (!ntlmssp_state->session_key.length) {
        DEBUG(3, ("NO session key, cannot seal packet\n"));
        return NT_STATUS_NO_USER_SESSION_KEY;
    }

    DEBUG(10,("ntlmssp_seal_data: seal\n"));
    dump_data_pw("ntlmssp clear data\n", data, length);
    if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
        HMACMD5Context ctx;
        char seq_num[4];
        uchar digest[16];
        SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);

        hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx);
        hmac_md5_update((const unsigned char *)seq_num, 4, &ctx);
        hmac_md5_update(data, length, &ctx);
        hmac_md5_final(digest, &ctx);

        if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */
                       , ntlmssp_state->ntlmssp_seq_num)) {
            return NT_STATUS_NO_MEMORY;
        }

        dump_data_pw("ntlmssp client sealing hash:\n",
                     ntlmssp_state->send_seal_hash,
                     sizeof(ntlmssp_state->send_seal_hash));
        NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length);
        dump_data_pw("ntlmssp client signing hash:\n",
                     ntlmssp_state->send_sign_hash,
                     sizeof(ntlmssp_state->send_sign_hash));
        NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash,  sig->data+4, sig->length-4);
    } else {
        uint32 crc;
        crc = crc32_calc_buffer((const char *)data, length);
        if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
            return NT_STATUS_NO_MEMORY;
        }

        /* The order of these two operations matters - we must first seal the packet,
           then seal the sequence number - this is becouse the ntlmssp_hash is not
           constant, but is is rather updated with each iteration */

        dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
                     sizeof(ntlmssp_state->ntlmssp_hash));
        NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length);

        dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
                     sizeof(ntlmssp_state->ntlmssp_hash));
        NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4);
    }
    dump_data_pw("ntlmssp sealed data\n", data, length);

    /* increment counter on send */
    ntlmssp_state->ntlmssp_seq_num++;

    return NT_STATUS_OK;
}
コード例 #17
0
ファイル: clisecdesc.c プロジェクト: Nymphetaminer/dsl-n55u
/****************************************************************************
  set the security descriptor for a open file
 ****************************************************************************/
BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd)
{
	char param[8];
	char *rparam=NULL, *rdata=NULL;
	unsigned int rparam_count=0, rdata_count=0;
	uint32 sec_info = 0;
	TALLOC_CTX *mem_ctx;
	prs_struct pd;
	BOOL ret = False;

	if ((mem_ctx = talloc_init("cli_set_secdesc")) == NULL) {
		DEBUG(0,("talloc_init failed.\n"));
		goto cleanup;
	}

	prs_init(&pd, 0, mem_ctx, MARSHALL);
	prs_give_memory(&pd, NULL, 0, True);

	if (!sec_io_desc("sd data", &sd, &pd, 1)) {
		DEBUG(1,("Failed to marshall secdesc\n"));
		goto cleanup;
	}

	SIVAL(param, 0, fnum);

	if (sd->off_dacl)
		sec_info |= DACL_SECURITY_INFORMATION;
	if (sd->off_owner_sid)
		sec_info |= OWNER_SECURITY_INFORMATION;
	if (sd->off_grp_sid)
		sec_info |= GROUP_SECURITY_INFORMATION;
	SSVAL(param, 4, sec_info);

	if (!cli_send_nt_trans(cli, 
			       NT_TRANSACT_SET_SECURITY_DESC, 
			       0, 
			       NULL, 0, 0,
			       param, 8, 0,
			       prs_data_p(&pd), prs_offset(&pd), 0)) {
		DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n"));
		goto cleanup;
	}


	if (!cli_receive_nt_trans(cli, 
				  &rparam, &rparam_count,
				  &rdata, &rdata_count)) {
		DEBUG(1,("NT_TRANSACT_SET_SECURITY_DESC failed\n"));
		goto cleanup;
	}

	ret = True;

  cleanup:

	SAFE_FREE(rparam);
	SAFE_FREE(rdata);

	talloc_destroy(mem_ctx);

	prs_mem_free(&pd);
	return ret;
}
コード例 #18
0
ファイル: rawfile.c プロジェクト: AIdrifter/samba
/*
 Open a file using NTTRANS CREATE - async send 
*/
static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tree, 
							  union smb_open *parms)
{
	struct smb_nttrans nt;
	uint8_t *params;
	TALLOC_CTX *mem_ctx = talloc_new(tree);
	uint16_t fname_len;
	DATA_BLOB sd_blob, ea_blob;
	struct smbcli_request *req;

	nt.in.max_setup = 0;
	nt.in.max_param = 101;
	nt.in.max_data  = 0;
	nt.in.setup_count = 0;
	nt.in.function = NT_TRANSACT_CREATE;
	nt.in.setup = NULL;

	sd_blob = data_blob(NULL, 0);
	ea_blob = data_blob(NULL, 0);

	if (parms->ntcreatex.in.sec_desc) {
		enum ndr_err_code ndr_err;
		ndr_err = ndr_push_struct_blob(&sd_blob, mem_ctx, 
					       parms->ntcreatex.in.sec_desc,
					       (ndr_push_flags_fn_t)ndr_push_security_descriptor);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			talloc_free(mem_ctx);
			return NULL;
		}
	}

	if (parms->ntcreatex.in.ea_list) {
		uint32_t ea_size = ea_list_size_chained(parms->ntcreatex.in.ea_list->num_eas,
							parms->ntcreatex.in.ea_list->eas, 4);
		ea_blob = data_blob_talloc(mem_ctx, NULL, ea_size);
		if (ea_blob.data == NULL) {
			return NULL;
		}
		ea_put_list_chained(ea_blob.data, 
				    parms->ntcreatex.in.ea_list->num_eas,
				    parms->ntcreatex.in.ea_list->eas, 4);
	}

	nt.in.params = data_blob_talloc(mem_ctx, NULL, 53);
	if (nt.in.params.data == NULL) {
		talloc_free(mem_ctx);
		return NULL;
	}

	/* build the parameter section */
	params = nt.in.params.data;

	SIVAL(params,  0, parms->ntcreatex.in.flags);
	SIVAL(params,  4, parms->ntcreatex.in.root_fid.fnum);
	SIVAL(params,  8, parms->ntcreatex.in.access_mask);
	SBVAL(params, 12, parms->ntcreatex.in.alloc_size);
	SIVAL(params, 20, parms->ntcreatex.in.file_attr);
	SIVAL(params, 24, parms->ntcreatex.in.share_access);
	SIVAL(params, 28, parms->ntcreatex.in.open_disposition);
	SIVAL(params, 32, parms->ntcreatex.in.create_options);
	SIVAL(params, 36, sd_blob.length);
	SIVAL(params, 40, ea_blob.length);
	SIVAL(params, 48, parms->ntcreatex.in.impersonation);
	SCVAL(params, 52, parms->ntcreatex.in.security_flags);

	/* the empty string first forces the correct alignment */
	smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,"", 0);
	fname_len = smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,
					      parms->ntcreatex.in.fname, STR_TERMINATE);

	SIVAL(nt.in.params.data, 44, fname_len);

	/* build the data section */
	nt.in.data = data_blob_talloc(mem_ctx, NULL, sd_blob.length + ea_blob.length);
	memcpy(nt.in.data.data, sd_blob.data, sd_blob.length);
	memcpy(nt.in.data.data+sd_blob.length, ea_blob.data, ea_blob.length);

	/* send the request on its way */
	req = smb_raw_nttrans_send(tree, &nt);

	talloc_free(mem_ctx);
	
	return req;
}
コード例 #19
0
ファイル: cliquota.c プロジェクト: AllardJ/Tomato
bool cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt)
{
	bool ret = False;
	uint16 setup;
	char params[16];
	unsigned int data_len;
	char data[SID_MAX_SIZE+8];
	char *rparam=NULL, *rdata=NULL;
	unsigned int rparam_count=0, rdata_count=0;
	unsigned int sid_len;
	unsigned int offset;

	if (!cli||!pqt) {
		smb_panic("cli_get_user_quota() called with NULL Pointer!");
	}

	setup = NT_TRANSACT_GET_USER_QUOTA;

	SSVAL(params, 0,quota_fnum);
	SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_FOR_SID);
	SIVAL(params, 4,0x00000024);
	SIVAL(params, 8,0x00000000);
	SIVAL(params,12,0x00000024);

	sid_len = ndr_size_dom_sid(&pqt->sid, NULL, 0);
	data_len = sid_len+8;
	SIVAL(data, 0, 0x00000000);
	SIVAL(data, 4, sid_len);
	sid_linearize(data+8, sid_len, &pqt->sid);

	if (!cli_send_nt_trans(cli, 
			       NT_TRANSACT_GET_USER_QUOTA, 
			       0, 
			       &setup, 1, 0,
			       params, 16, 4,
			       data, data_len, 112)) {
		DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n"));
		goto cleanup;
	}


	if (!cli_receive_nt_trans(cli,
				  &rparam, &rparam_count,
				  &rdata, &rdata_count)) {
		DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));
		goto cleanup;
	}

	if (cli_is_error(cli)) {
		ret = False;
		goto cleanup;
	} else {
		ret = True;
	}

	if ((rparam&&rdata)&&(rparam_count>=4&&rdata_count>=8)) {
		ret = parse_user_quota_record(rdata, rdata_count, &offset, pqt);
	} else {
		DEBUG(0,("Got INVALID NT_TRANSACT_GET_USER_QUOTA reply.\n"));
		ret = False; 
	}

 cleanup:
	SAFE_FREE(rparam);
	SAFE_FREE(rdata); 
	return ret;
}
コード例 #20
0
ファイル: rawfile.c プロジェクト: AIdrifter/samba
/****************************************************************************
 Open a file - async send
****************************************************************************/
_PUBLIC_ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_open *parms)
{
	int len;
	struct smbcli_request *req = NULL; 
	bool bigoffset = false;

	switch (parms->generic.level) {
	case RAW_OPEN_T2OPEN:
		return smb_raw_t2open_send(tree, parms);

	case RAW_OPEN_OPEN:
		SETUP_REQUEST(SMBopen, 2, 0);
		SSVAL(req->out.vwv, VWV(0), parms->openold.in.open_mode);
		SSVAL(req->out.vwv, VWV(1), parms->openold.in.search_attrs);
		smbcli_req_append_ascii4(req, parms->openold.in.fname, STR_TERMINATE);
		break;
		
	case RAW_OPEN_OPENX:
		SETUP_REQUEST(SMBopenX, 15, 0);
		SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1), 0);
		SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags);
		SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode);
		SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs);
		SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs);
		raw_push_dos_date3(tree->session->transport, 
				  req->out.vwv, VWV(6), parms->openx.in.write_time);
		SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func);
		SIVAL(req->out.vwv, VWV(9), parms->openx.in.size);
		SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout);
		SIVAL(req->out.vwv, VWV(13),0); /* reserved */
		smbcli_req_append_string(req, parms->openx.in.fname, STR_TERMINATE);
		break;
		
	case RAW_OPEN_MKNEW:
		SETUP_REQUEST(SMBmknew, 3, 0);
		SSVAL(req->out.vwv, VWV(0), parms->mknew.in.attrib);
		raw_push_dos_date3(tree->session->transport, 
				  req->out.vwv, VWV(1), parms->mknew.in.write_time);
		smbcli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE);
		break;

	case RAW_OPEN_CREATE:
		SETUP_REQUEST(SMBcreate, 3, 0);
		SSVAL(req->out.vwv, VWV(0), parms->create.in.attrib);
		raw_push_dos_date3(tree->session->transport, 
				  req->out.vwv, VWV(1), parms->create.in.write_time);
		smbcli_req_append_ascii4(req, parms->create.in.fname, STR_TERMINATE);
		break;
		
	case RAW_OPEN_CTEMP:
		SETUP_REQUEST(SMBctemp, 3, 0);
		SSVAL(req->out.vwv, VWV(0), parms->ctemp.in.attrib);
		raw_push_dos_date3(tree->session->transport, 
				  req->out.vwv, VWV(1), parms->ctemp.in.write_time);
		smbcli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE);
		break;
		
	case RAW_OPEN_SPLOPEN:
		SETUP_REQUEST(SMBsplopen, 2, 0);
		SSVAL(req->out.vwv, VWV(0), parms->splopen.in.setup_length);
		SSVAL(req->out.vwv, VWV(1), parms->splopen.in.mode);
		break;
		
	case RAW_OPEN_NTCREATEX:
		SETUP_REQUEST(SMBntcreateX, 24, 0);
		SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1),0);
		SCVAL(req->out.vwv, VWV(2),0); /* padding */
		SIVAL(req->out.vwv,  7, parms->ntcreatex.in.flags);
		SIVAL(req->out.vwv, 11, parms->ntcreatex.in.root_fid.fnum);
		SIVAL(req->out.vwv, 15, parms->ntcreatex.in.access_mask);
		SBVAL(req->out.vwv, 19, parms->ntcreatex.in.alloc_size);
		SIVAL(req->out.vwv, 27, parms->ntcreatex.in.file_attr);
		SIVAL(req->out.vwv, 31, parms->ntcreatex.in.share_access);
		SIVAL(req->out.vwv, 35, parms->ntcreatex.in.open_disposition);
		SIVAL(req->out.vwv, 39, parms->ntcreatex.in.create_options);
		SIVAL(req->out.vwv, 43, parms->ntcreatex.in.impersonation);
		SCVAL(req->out.vwv, 47, parms->ntcreatex.in.security_flags);
		
		smbcli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len);
		SSVAL(req->out.vwv, 5, len);
		break;

	case RAW_OPEN_NTTRANS_CREATE:
		return smb_raw_nttrans_create_send(tree, parms);


	case RAW_OPEN_OPENX_READX:
		SETUP_REQUEST(SMBopenX, 15, 0);
		SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1), 0);
		SSVAL(req->out.vwv, VWV(2), parms->openxreadx.in.flags);
		SSVAL(req->out.vwv, VWV(3), parms->openxreadx.in.open_mode);
		SSVAL(req->out.vwv, VWV(4), parms->openxreadx.in.search_attrs);
		SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.file_attrs);
		raw_push_dos_date3(tree->session->transport, 
				  req->out.vwv, VWV(6), parms->openxreadx.in.write_time);
		SSVAL(req->out.vwv, VWV(8), parms->openxreadx.in.open_func);
		SIVAL(req->out.vwv, VWV(9), parms->openxreadx.in.size);
		SIVAL(req->out.vwv, VWV(11),parms->openxreadx.in.timeout);
		SIVAL(req->out.vwv, VWV(13),0);
		smbcli_req_append_string(req, parms->openxreadx.in.fname, STR_TERMINATE);

		if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) {
			bigoffset = true;
		}

		smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0);

		SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1), 0);
		SSVAL(req->out.vwv, VWV(2), 0);
		SIVAL(req->out.vwv, VWV(3), parms->openxreadx.in.offset);
		SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.maxcnt & 0xFFFF);
		SSVAL(req->out.vwv, VWV(6), parms->openxreadx.in.mincnt);
		SIVAL(req->out.vwv, VWV(7), parms->openxreadx.in.maxcnt >> 16);
		SSVAL(req->out.vwv, VWV(9), parms->openxreadx.in.remaining);
		if (bigoffset) {
			SIVAL(req->out.vwv, VWV(10),parms->openxreadx.in.offset>>32);
		}
		break;

	case RAW_OPEN_NTCREATEX_READX:
		SETUP_REQUEST(SMBntcreateX, 24, 0);
		SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1),0);
		SCVAL(req->out.vwv, VWV(2),0); /* padding */
		SIVAL(req->out.vwv,  7, parms->ntcreatexreadx.in.flags);
		SIVAL(req->out.vwv, 11, parms->ntcreatexreadx.in.root_fid.fnum);
		SIVAL(req->out.vwv, 15, parms->ntcreatexreadx.in.access_mask);
		SBVAL(req->out.vwv, 19, parms->ntcreatexreadx.in.alloc_size);
		SIVAL(req->out.vwv, 27, parms->ntcreatexreadx.in.file_attr);
		SIVAL(req->out.vwv, 31, parms->ntcreatexreadx.in.share_access);
		SIVAL(req->out.vwv, 35, parms->ntcreatexreadx.in.open_disposition);
		SIVAL(req->out.vwv, 39, parms->ntcreatexreadx.in.create_options);
		SIVAL(req->out.vwv, 43, parms->ntcreatexreadx.in.impersonation);
		SCVAL(req->out.vwv, 47, parms->ntcreatexreadx.in.security_flags);

		smbcli_req_append_string_len(req, parms->ntcreatexreadx.in.fname, STR_TERMINATE, &len);
		SSVAL(req->out.vwv, 5, len);

		if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) {
			bigoffset = true;
		}

		smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0);

		SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
		SSVAL(req->out.vwv, VWV(1), 0);
		SSVAL(req->out.vwv, VWV(2), 0);
		SIVAL(req->out.vwv, VWV(3), parms->ntcreatexreadx.in.offset);
		SSVAL(req->out.vwv, VWV(5), parms->ntcreatexreadx.in.maxcnt & 0xFFFF);
		SSVAL(req->out.vwv, VWV(6), parms->ntcreatexreadx.in.mincnt);
		SIVAL(req->out.vwv, VWV(7), parms->ntcreatexreadx.in.maxcnt >> 16);
		SSVAL(req->out.vwv, VWV(9), parms->ntcreatexreadx.in.remaining);
		if (bigoffset) {
			SIVAL(req->out.vwv, VWV(10),parms->ntcreatexreadx.in.offset>>32);
		}
		break;

	case RAW_OPEN_SMB2:
		return NULL;
	}

	if (!smbcli_request_send(req)) {
		smbcli_request_destroy(req);
		return NULL;
	}

	return req;
}
コード例 #21
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;
}
コード例 #22
0
static void filter_request(char *buf, size_t buf_len)
{
	int msg_type = CVAL(buf,0);
	int type = CVAL(buf,smb_com);
	unsigned x;
	fstring name1,name2;
	int name_len1, name_len2;
	int name_type1, name_type2;

	if (msg_type) {
		/* it's a netbios special */
		switch (msg_type)
		case 0x81:
			/* session request */
			/* inbuf_size is guaranteed to be at least 4. */
			name_len1 = name_len((unsigned char *)(buf+4),
					buf_len - 4);
			if (name_len1 <= 0 || name_len1 > buf_len - 4) {
				DEBUG(0,("Invalid name length in session request\n"));
				return;
			}
			name_len2 = name_len((unsigned char *)(buf+4+name_len1),
					buf_len - 4 - name_len1);
			if (name_len2 <= 0 || name_len2 > buf_len - 4 - name_len1) {
				DEBUG(0,("Invalid name length in session request\n"));
				return;
			}

			name_type1 = name_extract((unsigned char *)buf,
					buf_len,(unsigned int)4,name1);
			name_type2 = name_extract((unsigned char *)buf,
					buf_len,(unsigned int)(4 + name_len1),name2);

			if (name_type1 == -1 || name_type2 == -1) {
				DEBUG(0,("Invalid name type in session request\n"));
				return;
			}

			d_printf("sesion_request: %s -> %s\n",
				 name1, name2);
			if (netbiosname) {
				char *mangled = name_mangle(
					talloc_tos(), netbiosname, 0x20);
				if (mangled != NULL) {
					/* replace the destination netbios
					 * name */
					memcpy(buf+4, mangled,
					       name_len((unsigned char *)mangled,
							talloc_get_size(mangled)));
					TALLOC_FREE(mangled);
				}
			}
		return;
	}

	/* it's an ordinary SMB request */
	switch (type) {
	case SMBsesssetupX:
		/* force the client capabilities */
		x = IVAL(buf,smb_vwv11);
		d_printf("SMBsesssetupX cap=0x%08x\n", x);
		d_printf("pwlen=%d/%d\n", SVAL(buf, smb_vwv7), SVAL(buf, smb_vwv8));
		system("mv sessionsetup.dat sessionsetup1.dat");
		save_file("sessionsetup.dat", smb_buf(buf), SVAL(buf, smb_vwv7));
		x = (x | CLI_CAPABILITY_SET) & ~CLI_CAPABILITY_MASK;
		SIVAL(buf, smb_vwv11, x);
		break;
	}
}
コード例 #23
0
ファイル: vfs_vxfs.c プロジェクト: DanilKorotenko/samba
static char * vxfs_compact_buf(char *e_buf, int *new_count, int count,
			       TALLOC_CTX *mem_ctx)
{
	int i, e_offset = 0, c_offset = 0;
	uint16_t type, perm, o_perm;
	uint32_t id, owner_id, group_id;
	char *c_buf = NULL;


	if (count < 2) {
		return NULL;
	}

	c_buf = talloc_zero_size(mem_ctx, count * 8);
	if (!c_buf) {
		return NULL;
	}

	/*Copy first two enries from e_buf to c_buf
	 *These are USER_OBJ and GROUP_OBJ
	 */

	memcpy(c_buf, e_buf, 16);

	(*new_count) = 2;

	owner_id = IVAL(e_buf, 4);
	group_id = IVAL(e_buf, 12);

	c_offset = e_offset = 16;

	/* Start comparing other entries */
	for (i = 2; i < count; i++) {

		type = SVAL(e_buf, e_offset);
		e_offset += 2;
		perm = SVAL(e_buf, e_offset);
		e_offset += 2;
		id = IVAL(e_buf, e_offset);
		e_offset += 4;

		switch(type) {
		case VXFS_ACL_USER:
			if (id == owner_id) {
				o_perm = SVAL(c_buf, 2);
				o_perm |= perm;
				SSVAL(c_buf, 2, o_perm);
				DEBUG(10, ("vfs_vxfs: merging with owner"
					  "e_type = %u,"
					  "e_perm = %u,"
					  "e_id = %u\n", (unsigned int)type,
					  (unsigned int)perm,
					  (unsigned int)id));
				continue;
			}
			break;
		case VXFS_ACL_GROUP:
			if (id == group_id) {
				o_perm = SVAL(c_buf, 10);
				o_perm |= perm;
				SSVAL(c_buf, 10, o_perm);
				DEBUG(10, ("vfs_vxfs: merging with owner group"
					  "e_type = %u,"
					  "e_perm = %u,"
					  "e_id = %u\n", (unsigned int)type,
					  (unsigned int)perm,
					  (unsigned int)id));
				continue;
			}
			break;
		}

		SSVAL(c_buf, c_offset, type);
		c_offset += 2;

		SSVAL(c_buf, c_offset, perm);
		c_offset += 2;

		SIVAL(c_buf, c_offset, id);
		c_offset += 4;

		(*new_count)++;
	}
	DEBUG(10, ("vfs_vxfs: new_count is %d\n", *new_count));
	return c_buf;
}
コード例 #24
0
ファイル: cldap.c プロジェクト: jameshilliard/WECB-BH-GPL
/*
  do a cldap netlogon query
*/
static int send_cldap_netlogon(int sock, const char *domain, 
			       const char *hostname, unsigned ntversion)
{
	ASN1_DATA data;
	char ntver[4];
#ifdef CLDAP_USER_QUERY
	char aac[4];

	SIVAL(aac, 0, 0x00000180);
#endif
	SIVAL(ntver, 0, ntversion);

	memset(&data, 0, sizeof(data));

	asn1_push_tag(&data,ASN1_SEQUENCE(0));
	asn1_write_Integer(&data, 4);
	asn1_push_tag(&data, ASN1_APPLICATION(3));
	asn1_write_OctetString(&data, NULL, 0);
	asn1_write_enumerated(&data, 0);
	asn1_write_enumerated(&data, 0);
	asn1_write_Integer(&data, 0);
	asn1_write_Integer(&data, 0);
	asn1_write_BOOLEAN2(&data, False);
	asn1_push_tag(&data, ASN1_CONTEXT(0));

	if (domain) {
		asn1_push_tag(&data, ASN1_CONTEXT(3));
		asn1_write_OctetString(&data, "DnsDomain", 9);
		asn1_write_OctetString(&data, domain, strlen(domain));
		asn1_pop_tag(&data);
	}

	asn1_push_tag(&data, ASN1_CONTEXT(3));
	asn1_write_OctetString(&data, "Host", 4);
	asn1_write_OctetString(&data, hostname, strlen(hostname));
	asn1_pop_tag(&data);

#ifdef CLDAP_USER_QUERY
	asn1_push_tag(&data, ASN1_CONTEXT(3));
	asn1_write_OctetString(&data, "User", 4);
	asn1_write_OctetString(&data, "SAMBA$", 6);
	asn1_pop_tag(&data);

	asn1_push_tag(&data, ASN1_CONTEXT(3));
	asn1_write_OctetString(&data, "AAC", 4);
	asn1_write_OctetString(&data, aac, 4);
	asn1_pop_tag(&data);
#endif

	asn1_push_tag(&data, ASN1_CONTEXT(3));
	asn1_write_OctetString(&data, "NtVer", 5);
	asn1_write_OctetString(&data, ntver, 4);
	asn1_pop_tag(&data);

	asn1_pop_tag(&data);

	asn1_push_tag(&data,ASN1_SEQUENCE(0));
	asn1_write_OctetString(&data, "NetLogon", 8);
	asn1_pop_tag(&data);
	asn1_pop_tag(&data);
	asn1_pop_tag(&data);

	if (data.has_error) {
		DEBUG(2,("Failed to build cldap netlogon at offset %d\n", (int)data.ofs));
		asn1_free(&data);
		return -1;
	}

	if (write(sock, data.data, data.length) != (ssize_t)data.length) {
		DEBUG(2,("failed to send cldap query (%s)\n", strerror(errno)));
		asn1_free(&data);
		return -1;
	}

	asn1_free(&data);

	return 0;
}
コード例 #25
0
int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName,
		     char *PassWord)

{
  struct RFCNB_Pkt *pkt;
  int param_len, pkt_len, pass_len;
  char *p, pword[256];

  /* First we need a packet etc ... but we need to know what protocol has  */
  /* been negotiated to figure out if we can do it and what SMB format to  */
  /* use ...                                                               */

  if (Con_Handle -> protocol < SMB_P_LanMan1) {

    SMBlib_errno = SMBlibE_ProtLow;
    return(SMBlibE_BAD);

  }

  strcpy(pword, PassWord);
  if (Con_Handle -> encrypt_passwords)
  {
    pass_len=24;
    SMBencrypt((uchar *) PassWord, (uchar *)Con_Handle -> Encrypt_Key,(uchar *)pword);
  }
  else
	pass_len=strlen(pword);


  /* Now build the correct structure */

  if (Con_Handle -> protocol < SMB_P_NT1) {

    param_len = strlen(UserName) + 1 + pass_len + 1 +
                strlen(Con_Handle -> PDomain) + 1 +
	        strlen(Con_Handle -> OSName) + 1;

    pkt_len = SMB_ssetpLM_len + param_len;

    pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);

    if (pkt == NULL) {

      SMBlib_errno = SMBlibE_NoSpace;
      return(SMBlibE_BAD); /* Should handle the error */

    }

    bzero(SMB_Hdr(pkt), SMB_ssetpLM_len);
    SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
    *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
    SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
    *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10;
    *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF;    /* No extra command */
    SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);

    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid);
    SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, pass_len + 1);
    SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len);

    /* Now copy the param strings in with the right stuff */

    p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset);

    /* Copy  in password, then the rest. Password has a null at end */

    memcpy(p, pword, pass_len);

    p = p + pass_len + 1;

    strcpy(p, UserName);
    p = p + strlen(UserName);
    *p = 0;

    p = p + 1;

    strcpy(p, Con_Handle -> PDomain);
    p = p + strlen(Con_Handle -> PDomain);
    *p = 0;
    p = p + 1;

    strcpy(p, Con_Handle -> OSName);
    p = p + strlen(Con_Handle -> OSName);
    *p = 0;

  }
  else {

    /* We don't admit to UNICODE support ... */

    param_len = strlen(UserName) + 1 + pass_len +
                strlen(Con_Handle -> PDomain) + 1 +
	        strlen(Con_Handle -> OSName) + 1 +
		strlen(Con_Handle -> LMType) + 1;

    pkt_len = SMB_ssetpNTLM_len + param_len;

    pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);

    if (pkt == NULL) {

      SMBlib_errno = SMBlibE_NoSpace;
      return(-1); /* Should handle the error */

    }

    bzero(SMB_Hdr(pkt), SMB_ssetpNTLM_len);
    SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);  /* Plunk in IDF */
    *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
    SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid);
    SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid);
    *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13;
    *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF;    /* No extra command */
    SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);

    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0);
    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, pass_len);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0);
    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0);
    SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0);
    SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len);

    /* Now copy the param strings in with the right stuff */

    p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset);

    /* Copy  in password, then the rest. Password has no null at end */

    memcpy(p, pword, pass_len);

    p = p + pass_len;

    strcpy(p, UserName);
    p = p + strlen(UserName);
    *p = 0;

    p = p + 1;

    strcpy(p, Con_Handle -> PDomain);
    p = p + strlen(Con_Handle -> PDomain);
  *p = 0;
    p = p + 1;

    strcpy(p, Con_Handle -> OSName);
    p = p + strlen(Con_Handle -> OSName);
    *p = 0;
    p = p + 1;

    strcpy(p, Con_Handle -> LMType);
    p = p + strlen(Con_Handle -> LMType);
    *p = 0;

  }

  /* Now send it and get a response */

  if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0){

#ifdef DEBUG
    fprintf(stderr, "Error sending SessSetupX request\n");
#endif

    RFCNB_Free_Pkt(pkt);
    SMBlib_errno = SMBlibE_SendFailed;
    return(SMBlibE_BAD);

  }

  /* Now get the response ... */

  if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) {

#ifdef DEBUG
    fprintf(stderr, "Error receiving response to SessSetupAndX\n");
#endif

    RFCNB_Free_Pkt(pkt);
    SMBlib_errno = SMBlibE_RecvFailed;
    return(SMBlibE_BAD);

  }

  /* Check out the response type ... */

  if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {  /* Process error */

#ifdef DEBUG
    fprintf(stderr, "SMB_SessSetupAndX failed with errorclass = %i, Error Code = %i\n",
	    CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
	    SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
#endif

    SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
    RFCNB_Free_Pkt(pkt);
    SMBlib_errno = SMBlibE_Remote;
    return(SMBlibE_BAD);

  }
/** @@@ mdz: check for guest login { **/
       if (SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset) & 0x1)
       {
               /* do we allow guest login? NO! */
               return(SMBlibE_BAD);

       }
 /** @@@ mdz: } **/


#ifdef DEBUG
  fprintf(stderr, "SessSetupAndX response. Action = %i\n",
          SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset));
#endif

  /* Now pick up the UID for future reference ... */

  Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset);
  RFCNB_Free_Pkt(pkt);

  return(0);

}
コード例 #26
0
ファイル: smbcontrol.c プロジェクト: srimalik/samba
static bool do_winbind_offline(struct tevent_context *ev_ctx,
			       struct messaging_context *msg_ctx,
			       const struct server_id pid,
			       const int argc, const char **argv)
{
	TDB_CONTEXT *tdb;
	bool ret = False;
	int retry = 0;

	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol winbindd offline\n");
		return False;
	}

	/* Create an entry in the winbindd_cache tdb to tell a later
	   starting winbindd that we're offline. We may actually create
	   it here... */

	tdb = tdb_open_log(state_path("winbindd_cache.tdb"),
				WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
				TDB_DEFAULT|TDB_INCOMPATIBLE_HASH /* TDB_CLEAR_IF_FIRST */,
				O_RDWR|O_CREAT, 0600);

	if (!tdb) {
		fprintf(stderr, "Cannot open the tdb %s for writing.\n",
			state_path("winbindd_cache.tdb"));
		return False;
	}

	/* There's a potential race condition that if a child
	   winbindd detects a domain is online at the same time
	   we're trying to tell it to go offline that it might 
	   delete the record we add between us adding it and
	   sending the message. Minimize this by retrying up to
	   5 times. */

	for (retry = 0; retry < 5; retry++) {
		TDB_DATA d;
		uint8 buf[4];

		ZERO_STRUCT(d);

		SIVAL(buf, 0, time(NULL));
		d.dptr = buf;
		d.dsize = 4;

		tdb_store_bystring(tdb, "WINBINDD_OFFLINE", d, TDB_INSERT);

		ret = send_message(msg_ctx, pid, MSG_WINBIND_OFFLINE,
				   NULL, 0);

		/* Check that the entry "WINBINDD_OFFLINE" still exists. */
		d = tdb_fetch_bystring( tdb, "WINBINDD_OFFLINE" );

		if (!d.dptr || d.dsize != 4) {
			SAFE_FREE(d.dptr);
			DEBUG(10,("do_winbind_offline: offline state not set - retrying.\n"));
		} else {
			SAFE_FREE(d.dptr);
			break;
		}
	}

	tdb_close(tdb);
	return ret;
}
コード例 #27
0
ファイル: rawrequest.c プロジェクト: srimalik/samba
/*
  setup a chained reply in req->out with the given word count and
  initial data buffer size.
*/
NTSTATUS smbcli_chained_request_setup(struct smbcli_request *req,
				      uint8_t command, 
				      unsigned int wct, size_t buflen)
{
	size_t wct_ofs;
	size_t size;

	/*
	 * here we only support one chained command
	 * If someone needs longer chains, the low
	 * level code should be used directly.
	 */
	if (req->subreqs[0] != NULL) {
		return NT_STATUS_INVALID_PARAMETER_MIX;
	}
	if (req->subreqs[1] != NULL) {
		return NT_STATUS_INVALID_PARAMETER_MIX;
	}

	req->subreqs[0] = smbcli_transport_setup_subreq(req);
	if (req->subreqs[0] == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	wct_ofs = smb1cli_req_wct_ofs(req->subreqs, 1);

	size = NBT_HDR_SIZE + wct_ofs + 1 + VWV(wct) + 2 + buflen;

	req->out.size = size;

	/* over allocate by a small amount */
	req->out.allocated = req->out.size + REQ_OVER_ALLOCATION;

	req->out.buffer = talloc_zero_array(req, uint8_t, req->out.allocated);
	if (!req->out.buffer) {
		return NT_STATUS_NO_MEMORY;
	}

	req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
	req->out.vwv = req->out.hdr + wct_ofs;
	req->out.wct = wct;
	req->out.data = req->out.vwv + VWV(wct) + 2;
	req->out.data_size = buflen;
	req->out.ptr = req->out.data;

	SCVAL(req->out.hdr, HDR_WCT, wct);
	SSVAL(req->out.vwv, VWV(wct), buflen);

	memcpy(req->out.hdr, "\377SMB", 4);
	SCVAL(req->out.hdr,HDR_COM,command);

	SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES);
	SSVAL(req->out.hdr,HDR_FLG2, 0);

	/* copy the pid, uid and mid to the request */
	SSVAL(req->out.hdr, HDR_PID, 0);
	SSVAL(req->out.hdr, HDR_UID, 0);
	SSVAL(req->out.hdr, HDR_MID, 0);
	SSVAL(req->out.hdr, HDR_TID,0);
	SSVAL(req->out.hdr, HDR_PIDHIGH,0);
	SIVAL(req->out.hdr, HDR_RCLS, 0);
	memset(req->out.hdr+HDR_SS_FIELD, 0, 10);

	if (req->session != NULL) {
		SSVAL(req->out.hdr, HDR_FLG2, req->session->flags2);
		SSVAL(req->out.hdr, HDR_PID, req->session->pid & 0xFFFF);
		SSVAL(req->out.hdr, HDR_PIDHIGH, req->session->pid >> 16);
		SSVAL(req->out.hdr, HDR_UID, req->session->vuid);
	}
コード例 #28
0
ファイル: clilist.c プロジェクト: AllardJ/Tomato
int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, 
		 void (*fn)(const char *, file_info *, const char *, void *), void *state)
{
#if 1
	int max_matches = 1366; /* Match W2k - was 512. */
#else
	int max_matches = 512;
#endif
	int info_level;
	char *p, *p2;
	pstring mask;
	file_info finfo;
	int i;
	char *dirlist = NULL;
	int dirlist_len = 0;
	int total_received = -1;
	BOOL First = True;
	int ff_searchcount=0;
	int ff_eos=0;
	int ff_dir_handle=0;
	int loop_count = 0;
	char *rparam=NULL, *rdata=NULL;
	unsigned int param_len, data_len;	
	uint16 setup;
	pstring param;
	const char *mnt;
	uint32 resume_key = 0;
	uint32 last_name_raw_len = 0;
	DATA_BLOB last_name_raw = data_blob(NULL, 2*sizeof(pstring));

	/* NT uses 260, OS/2 uses 2. Both accept 1. */
	info_level = (cli->capabilities&CAP_NT_SMBS)?260:1;
	
	pstrcpy(mask,Mask);
	
	while (ff_eos == 0) {
		loop_count++;
		if (loop_count > 200) {
			DEBUG(0,("Error: Looping in FIND_NEXT??\n"));
			break;
		}

		if (First) {
			setup = TRANSACT2_FINDFIRST;
			SSVAL(param,0,attribute); /* attribute */
			SSVAL(param,2,max_matches); /* max count */
			SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END));	/* resume required + close on end */
			SSVAL(param,6,info_level); 
			SIVAL(param,8,0);
			p = param+12;
			p += clistr_push(cli, param+12, mask, sizeof(param)-12, 
					 STR_TERMINATE);
		} else {
			setup = TRANSACT2_FINDNEXT;
			SSVAL(param,0,ff_dir_handle);
			SSVAL(param,2,max_matches); /* max count */
			SSVAL(param,4,info_level); 
			/* For W2K servers serving out FAT filesystems we *must* set the
			   resume key. If it's not FAT then it's returned as zero. */
			SIVAL(param,6,resume_key); /* ff_resume_key */
			/* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren
			   can miss filenames. Use last filename continue instead. JRA */
			SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END));	/* resume required + close on end */
			p = param+12;
			if (last_name_raw_len && (last_name_raw_len < (sizeof(param)-12))) {
				memcpy(p, last_name_raw.data, last_name_raw_len);
				p += last_name_raw_len;
			} else {
				p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE);
			}
		}

		param_len = PTR_DIFF(p, param);

		if (!cli_send_trans(cli, SMBtrans2, 
				    NULL,                   /* Name */
				    -1, 0,                  /* fid, flags */
				    &setup, 1, 0,           /* setup, length, max */
				    param, param_len, 10,   /* param, length, max */
				    NULL, 0, 
#if 0
				    /* w2k value. */
				    MIN(16384,cli->max_xmit) /* data, length, max. */
#else
				    cli->max_xmit	    /* data, length, max. */
#endif
				    )) {
			break;
		}

		if (!cli_receive_trans(cli, SMBtrans2, 
				       &rparam, &param_len,
				       &rdata, &data_len) &&
                    cli_is_dos_error(cli)) {
			/* We need to work around a Win95 bug - sometimes
			   it gives ERRSRV/ERRerror temprarily */
			uint8 eclass;
			uint32 ecode;

			SAFE_FREE(rdata);
			SAFE_FREE(rparam);

			cli_dos_error(cli, &eclass, &ecode);

			/*
			 * OS/2 might return "no more files",
			 * which just tells us, that searchcount is zero
			 * in this search.
			 * Guenter Kukkukk <*****@*****.**>
			 */

			if (eclass == ERRDOS && ecode == ERRnofiles) {
				ff_searchcount = 0;
				cli_reset_error(cli);
				break;
			}

			if (eclass != ERRSRV || ecode != ERRerror)
				break;
			smb_msleep(100);
			continue;
		}

                if (cli_is_error(cli) || !rdata || !rparam) {
			SAFE_FREE(rdata);
			SAFE_FREE(rparam);
			break;
		}

		if (total_received == -1)
			total_received = 0;

		/* parse out some important return info */
		p = rparam;
		if (First) {
			ff_dir_handle = SVAL(p,0);
			ff_searchcount = SVAL(p,2);
			ff_eos = SVAL(p,4);
		} else {
			ff_searchcount = SVAL(p,0);
			ff_eos = SVAL(p,2);
		}

		if (ff_searchcount == 0) {
			SAFE_FREE(rdata);
			SAFE_FREE(rparam);
			break;
		}

		/* point to the data bytes */
		p = rdata;

		/* we might need the lastname for continuations */
		for (p2=p,i=0;i<ff_searchcount;i++) {
			if ((info_level == 260) && (i == ff_searchcount-1)) {
				/* Last entry - fixup the last offset length. */
				SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2));
			}
			p2 += interpret_long_filename(cli,info_level,p2,&finfo,
							&resume_key,&last_name_raw,&last_name_raw_len);

			if (!First && *mask && strcsequal(finfo.name, mask)) {
				DEBUG(0,("Error: Looping in FIND_NEXT as name %s has already been seen?\n",
					finfo.name));
				ff_eos = 1;
				break;
			}
		}

		if (ff_searchcount > 0) {
			pstrcpy(mask, finfo.name);
		} else {
			pstrcpy(mask,"");
		}

		/* grab the data for later use */
		/* and add them to the dirlist pool */
		dirlist = (char *)SMB_REALLOC(dirlist,dirlist_len + data_len);

		if (!dirlist) {
			DEBUG(0,("cli_list_new: Failed to expand dirlist\n"));
			SAFE_FREE(rdata);
			SAFE_FREE(rparam);
			break;
		}

		memcpy(dirlist+dirlist_len,p,data_len);
		dirlist_len += data_len;

		total_received += ff_searchcount;

		SAFE_FREE(rdata);
		SAFE_FREE(rparam);

		DEBUG(3,("received %d entries (eos=%d)\n",
			 ff_searchcount,ff_eos));

		if (ff_searchcount > 0)
			loop_count = 0;

		First = False;
	}

	mnt = cli_cm_get_mntpoint( cli );

        /* see if the server disconnected or the connection otherwise failed */
        if (cli_is_error(cli)) {
                total_received = -1;
        } else {
                /* no connection problem.  let user function add each entry */
                for (p=dirlist,i=0;i<total_received;i++) {
                        p += interpret_long_filename(cli, info_level, p,
                                                     &finfo,NULL,NULL,NULL);
                        fn( mnt,&finfo, Mask, state );
                }
        }

	/* free up the dirlist buffer and last name raw blob */
	SAFE_FREE(dirlist);
	data_blob_free(&last_name_raw);
	return(total_received);
}
コード例 #29
0
ファイル: smb2_getinfo.c プロジェクト: rchicoli/samba
static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
						 struct tevent_context *ev,
						 struct smbd_smb2_request *smb2req,
						 struct files_struct *fsp,
						 uint8_t in_info_type,
						 uint8_t in_file_info_class,
						 uint32_t in_output_buffer_length,
						 DATA_BLOB in_input_buffer,
						 uint32_t in_additional_information,
						 uint32_t in_flags)
{
	struct tevent_req *req;
	struct smbd_smb2_getinfo_state *state;
	struct smb_request *smbreq;
	connection_struct *conn = smb2req->tcon->compat;
	NTSTATUS status;

	req = tevent_req_create(mem_ctx, &state,
				struct smbd_smb2_getinfo_state);
	if (req == NULL) {
		return NULL;
	}
	state->smb2req = smb2req;
	state->status = NT_STATUS_OK;
	state->out_output_buffer = data_blob_null;

	DEBUG(10,("smbd_smb2_getinfo_send: %s - %s\n",
		  fsp_str_dbg(fsp), fsp_fnum_dbg(fsp)));

	smbreq = smbd_smb2_fake_smb_request(smb2req);
	if (tevent_req_nomem(smbreq, req)) {
		return tevent_req_post(req, ev);
	}

	if (IS_IPC(conn)) {
		smb2_ipc_getinfo(req, state, ev,
			in_info_type, in_file_info_class);
		return tevent_req_post(req, ev);
	}

	switch (in_info_type) {
	case SMB2_GETINFO_FILE:
	{
		uint16_t file_info_level;
		char *data = NULL;
		unsigned int data_size = 0;
		bool delete_pending = false;
		struct timespec write_time_ts;
		struct file_id fileid;
		struct ea_list *ea_list = NULL;
		int lock_data_count = 0;
		char *lock_data = NULL;
		size_t fixed_portion;

		ZERO_STRUCT(write_time_ts);

		switch (in_file_info_class) {
		case 0x0F:/* RAW_FILEINFO_SMB2_ALL_EAS */
			file_info_level = 0xFF00 | in_file_info_class;
			break;

		case 0x12:/* RAW_FILEINFO_SMB2_ALL_INFORMATION */
			file_info_level = 0xFF00 | in_file_info_class;
			break;

		default:
			/* the levels directly map to the passthru levels */
			file_info_level = in_file_info_class + 1000;
			break;
		}

		if (fsp->fake_file_handle) {
			/*
			 * This is actually for the QUOTA_FAKE_FILE --metze
			 */

			/* We know this name is ok, it's already passed the checks. */

		} else if (fsp->fh->fd == -1) {
			/*
			 * This is actually a QFILEINFO on a directory
			 * handle (returned from an NT SMB). NT5.0 seems
			 * to do this call. JRA.
			 */

			if (INFO_LEVEL_IS_UNIX(file_info_level)) {
				/* Always do lstat for UNIX calls. */
				if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) {
					DEBUG(3,("smbd_smb2_getinfo_send: "
						 "SMB_VFS_LSTAT of %s failed "
						 "(%s)\n", fsp_str_dbg(fsp),
						 strerror(errno)));
					status = map_nt_error_from_unix(errno);
					tevent_req_nterror(req, status);
					return tevent_req_post(req, ev);
				}
			} else if (SMB_VFS_STAT(conn, fsp->fsp_name)) {
				DEBUG(3,("smbd_smb2_getinfo_send: "
					 "SMB_VFS_STAT of %s failed (%s)\n",
					 fsp_str_dbg(fsp),
					 strerror(errno)));
				status = map_nt_error_from_unix(errno);
				tevent_req_nterror(req, status);
				return tevent_req_post(req, ev);
			}

			fileid = vfs_file_id_from_sbuf(conn,
						       &fsp->fsp_name->st);
			get_file_infos(fileid, fsp->name_hash,
				&delete_pending, &write_time_ts);
		} else {
			/*
			 * Original code - this is an open file.
			 */

			if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
				DEBUG(3, ("smbd_smb2_getinfo_send: "
					  "fstat of %s failed (%s)\n",
					  fsp_fnum_dbg(fsp), strerror(errno)));
				status = map_nt_error_from_unix(errno);
				tevent_req_nterror(req, status);
				return tevent_req_post(req, ev);
			}
			fileid = vfs_file_id_from_sbuf(conn,
						       &fsp->fsp_name->st);
			get_file_infos(fileid, fsp->name_hash,
				&delete_pending, &write_time_ts);
		}

		status = smbd_do_qfilepathinfo(conn, state,
					       file_info_level,
					       fsp,
					       fsp->fsp_name,
					       delete_pending,
					       write_time_ts,
					       ea_list,
					       lock_data_count,
					       lock_data,
					       STR_UNICODE,
					       in_output_buffer_length,
					       &fixed_portion,
					       &data,
					       &data_size);
		if (!NT_STATUS_IS_OK(status)) {
			SAFE_FREE(data);
			if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
				status = NT_STATUS_INVALID_INFO_CLASS;
			}
			tevent_req_nterror(req, status);
			return tevent_req_post(req, ev);
		}
		if (in_output_buffer_length < fixed_portion) {
			SAFE_FREE(data);
			tevent_req_nterror(
				req, NT_STATUS_INFO_LENGTH_MISMATCH);
			return tevent_req_post(req, ev);
		}
		if (data_size > 0) {
			state->out_output_buffer = data_blob_talloc(state,
								    data,
								    data_size);
			SAFE_FREE(data);
			if (tevent_req_nomem(state->out_output_buffer.data, req)) {
				return tevent_req_post(req, ev);
			}
			if (data_size > in_output_buffer_length) {
				state->out_output_buffer.length =
					in_output_buffer_length;
				status = STATUS_BUFFER_OVERFLOW;
			}
		}
		SAFE_FREE(data);
		break;
	}

	case SMB2_GETINFO_FS:
	{
		uint16_t file_info_level;
		char *data = NULL;
		int data_size = 0;
		size_t fixed_portion;

		/* the levels directly map to the passthru levels */
		file_info_level = in_file_info_class + 1000;

		status = smbd_do_qfsinfo(conn, state,
					 file_info_level,
					 STR_UNICODE,
					 in_output_buffer_length,
					 &fixed_portion,
					 fsp->fsp_name,
					 &data,
					 &data_size);
		/* some responses set STATUS_BUFFER_OVERFLOW and return
		   partial, but valid data */
		if (!(NT_STATUS_IS_OK(status) ||
		      NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW))) {
			SAFE_FREE(data);
			if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
				status = NT_STATUS_INVALID_INFO_CLASS;
			}
			tevent_req_nterror(req, status);
			return tevent_req_post(req, ev);
		}
		if (in_output_buffer_length < fixed_portion) {
			SAFE_FREE(data);
			tevent_req_nterror(
				req, NT_STATUS_INFO_LENGTH_MISMATCH);
			return tevent_req_post(req, ev);
		}
		if (data_size > 0) {
			state->out_output_buffer = data_blob_talloc(state,
								    data,
								    data_size);
			SAFE_FREE(data);
			if (tevent_req_nomem(state->out_output_buffer.data, req)) {
				return tevent_req_post(req, ev);
			}
			if (data_size > in_output_buffer_length) {
				state->out_output_buffer.length =
					in_output_buffer_length;
				status = STATUS_BUFFER_OVERFLOW;
			}
		}
		SAFE_FREE(data);
		break;
	}

	case SMB2_GETINFO_SECURITY:
	{
		uint8_t *p_marshalled_sd = NULL;
		size_t sd_size = 0;

		status = smbd_do_query_security_desc(conn,
				state,
				fsp,
				/* Security info wanted. */
				in_additional_information &
				SMB_SUPPORTED_SECINFO_FLAGS,
				in_output_buffer_length,
				&p_marshalled_sd,
				&sd_size);

		if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
			/* Return needed size. */
			state->out_output_buffer = data_blob_talloc(state,
								    NULL,
								    4);
			if (tevent_req_nomem(state->out_output_buffer.data, req)) {
				return tevent_req_post(req, ev);
			}
			SIVAL(state->out_output_buffer.data,0,(uint32_t)sd_size);
			state->status = NT_STATUS_BUFFER_TOO_SMALL;
			break;
		}
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(10,("smbd_smb2_getinfo_send: "
				 "smbd_do_query_security_desc of %s failed "
				 "(%s)\n", fsp_str_dbg(fsp),
				 nt_errstr(status)));
			tevent_req_nterror(req, status);
			return tevent_req_post(req, ev);
		}

		if (sd_size > 0) {
			state->out_output_buffer = data_blob_talloc(state,
								    p_marshalled_sd,
								    sd_size);
			if (tevent_req_nomem(state->out_output_buffer.data, req)) {
				return tevent_req_post(req, ev);
			}
		}
		break;
	}

	case SMB2_GETINFO_QUOTA:
		tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
		return tevent_req_post(req, ev);

	default:
		DEBUG(10,("smbd_smb2_getinfo_send: "
			"unknown in_info_type of %u "
			" for file %s\n",
			(unsigned int)in_info_type,
			fsp_str_dbg(fsp) ));

		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
		return tevent_req_post(req, ev);
	}

	state->status = status;
	tevent_req_done(req);
	return tevent_req_post(req, ev);
}
コード例 #30
0
ファイル: clirap.c プロジェクト: aosm/samba
BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, 
                     time_t create_time,
                     time_t access_time,
                     time_t write_time,
                     time_t change_time,
                     uint16 mode)
{
	unsigned int data_len = 0;
	unsigned int param_len = 0;
	unsigned int rparam_len, rdata_len;
	uint16 setup = TRANSACT2_SETPATHINFO;
	pstring param;
        pstring data;
	char *rparam=NULL, *rdata=NULL;
	int count=8;
	BOOL ret;
	char *p;

	memset(param, 0, sizeof(param));
	memset(data, 0, sizeof(data));

        p = param;

        /* Add the information level */
	SSVAL(p, 0, SMB_FILE_BASIC_INFORMATION);

        /* Skip reserved */
	p += 6;

        /* Add the file name */
	p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE);

	param_len = PTR_DIFF(p, param);

        p = data;

        /*
         * Add the create, last access, modification, and status change times
         */
        
        put_long_date(p, create_time);
        p += 8;

        put_long_date(p, access_time);
        p += 8;
        
        put_long_date(p, write_time);
        p += 8;
        
        put_long_date(p, change_time);
        p += 8;

        /* Add attributes */
        SIVAL(p, 0, mode);
        p += 4;

        /* Add padding */
        SIVAL(p, 0, 0);
        p += 4;

        data_len = PTR_DIFF(p, data);

	do {
		ret = (cli_send_trans(cli, SMBtrans2, 
				      NULL,           /* Name */
				      -1, 0,          /* fid, flags */
				      &setup, 1, 0,   /* setup, length, max */
				      param, param_len, 10, /* param, length, max */
				      data, data_len, cli->max_xmit /* data, length, max */
				      ) &&
		       cli_receive_trans(cli, SMBtrans2, 
					 &rparam, &rparam_len,
					 &rdata, &rdata_len));
		if (!cli_is_dos_error(cli)) break;
		if (!ret) {
			/* we need to work around a Win95 bug - sometimes
			   it gives ERRSRV/ERRerror temprarily */
			uint8 eclass;
			uint32 ecode;
			cli_dos_error(cli, &eclass, &ecode);
			if (eclass != ERRSRV || ecode != ERRerror) break;
			smb_msleep(100);
		}
	} while (count-- && ret==False);

	if (!ret) {
		return False;
	}

	SAFE_FREE(rdata);
	SAFE_FREE(rparam);
	return True;
}