Exemple #1
0
/*
  recv a create reply
*/
NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_create *io)
{
	NTSTATUS status;

	if (!smb2_request_receive(req) || 
	    !smb2_request_is_ok(req)) {
		return smb2_request_destroy(req);
	}

	SMB2_CHECK_PACKET_RECV(req, 0x58, True);

	io->out.oplock_flags   = SVAL(req->in.body, 0x02);
	io->out.create_action  = IVAL(req->in.body, 0x04);
	io->out.create_time    = smbcli_pull_nttime(req->in.body, 0x08);
	io->out.access_time    = smbcli_pull_nttime(req->in.body, 0x10);
	io->out.write_time     = smbcli_pull_nttime(req->in.body, 0x18);
	io->out.change_time    = smbcli_pull_nttime(req->in.body, 0x20);
	io->out.alloc_size     = BVAL(req->in.body, 0x28);
	io->out.size           = BVAL(req->in.body, 0x30);
	io->out.file_attr      = IVAL(req->in.body, 0x38);
	io->out._pad           = IVAL(req->in.body, 0x3C);
	smb2_pull_handle(req->in.body+0x40, &io->out.file.handle);
	status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob);
	if (!NT_STATUS_IS_OK(status)) {
		smb2_request_destroy(req);
		return status;
	}

	return smb2_request_destroy(req);
}
Exemple #2
0
/*
  recv a keepalive reply
*/
NTSTATUS smb2_keepalive_recv(struct smb2_request *req)
{
	if (!smb2_request_receive(req) || 
	    !smb2_request_is_ok(req)) {
		return smb2_request_destroy(req);
	}

	SMB2_CHECK_PACKET_RECV(req, 0x04, False);
	return smb2_request_destroy(req);
}
Exemple #3
0
/*
  recv a write reply
*/
NTSTATUS smb2_write_recv(struct smb2_request *req, struct smb2_write *io)
{
	if (!smb2_request_receive(req) || 
	    !smb2_request_is_ok(req)) {
		return smb2_request_destroy(req);
	}

	SMB2_CHECK_PACKET_RECV(req, 0x10, true);

	io->out._pad     = SVAL(req->in.body, 0x02);
	io->out.nwritten = IVAL(req->in.body, 0x04);
	io->out.unknown1 = BVAL(req->in.body, 0x08);

	return smb2_request_destroy(req);
}
Exemple #4
0
/*
  Receive a Lease Break Response
*/
NTSTATUS smb2_lease_break_ack_recv(struct smb2_request *req,
                                   struct smb2_lease_break_ack *io)
{
	if (!smb2_request_receive(req) ||
	    !smb2_request_is_ok(req)) {
		return smb2_request_destroy(req);
	}

	SMB2_CHECK_PACKET_RECV(req, 0x24, false);

	io->out.reserved		= IVAL(req->in.body, 0x02);
	io->out.lease.lease_flags	= IVAL(req->in.body, 0x04);
	memcpy(&io->out.lease.lease_key, req->in.body+0x8,
	    sizeof(struct smb2_lease_key));
	io->out.lease.lease_state	= IVAL(req->in.body, 0x18);
	io->out.lease.lease_duration	= IVAL(req->in.body, 0x1C);

	return smb2_request_destroy(req);
}
Exemple #5
0
/*
  recv a find reply
*/
NTSTATUS smb2_find_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
                        struct smb2_find *io)
{
    NTSTATUS status;

    if (!smb2_request_receive(req) ||
            smb2_request_is_error(req)) {
        return smb2_request_destroy(req);
    }

    SMB2_CHECK_PACKET_RECV(req, 0x08, true);

    status = smb2_pull_o16s32_blob(&req->in, mem_ctx,
                                   req->in.body+0x02, &io->out.blob);
    if (!NT_STATUS_IS_OK(status)) {
        return status;
    }

    return smb2_request_destroy(req);
}
Exemple #6
0
/*
  recv a read reply
*/
NTSTATUS smb2_read_recv(struct smb2_request *req, 
			TALLOC_CTX *mem_ctx, struct smb2_read *io)
{
	NTSTATUS status;

	if (!smb2_request_receive(req) || 
	    !smb2_request_is_ok(req)) {
		return smb2_request_destroy(req);
	}

	SMB2_CHECK_PACKET_RECV(req, 0x10, true);

	status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.data);
	if (!NT_STATUS_IS_OK(status)) {
		smb2_request_destroy(req);
		return status;
	}

	io->out.remaining = IVAL(req->in.body, 0x08);
	io->out.reserved  = IVAL(req->in.body, 0x0C);

	return smb2_request_destroy(req);
}
Exemple #7
0
/**
  recv a session setup reply
*/
NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, 
				 struct smb2_session_setup *io)
{
	NTSTATUS status;

	if (!smb2_request_receive(req) || 
	    (smb2_request_is_error(req) && 
	     !NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED))) {
		return smb2_request_destroy(req);
	}

	SMB2_CHECK_PACKET_RECV(req, 0x08, true);

	io->out.session_flags = SVAL(req->in.body, 0x02);
	io->out.uid           = BVAL(req->in.hdr,  SMB2_HDR_SESSION_ID);
	
	status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x04, &io->out.secblob);
	if (!NT_STATUS_IS_OK(status)) {
		smb2_request_destroy(req);
		return status;
	}

	return smb2_request_destroy(req);
}
Exemple #8
0
/*
  recv a create reply
*/
NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_create *io)
{
	NTSTATUS status;
	DATA_BLOB blob;
	int i;

	if (!smb2_request_receive(req) || 
	    !smb2_request_is_ok(req)) {
		return smb2_request_destroy(req);
	}

	SMB2_CHECK_PACKET_RECV(req, 0x58, true);
	ZERO_STRUCT(io->out);
	io->out.oplock_level   = CVAL(req->in.body, 0x02);
	io->out.reserved       = CVAL(req->in.body, 0x03);
	io->out.create_action  = IVAL(req->in.body, 0x04);
	io->out.create_time    = smbcli_pull_nttime(req->in.body, 0x08);
	io->out.access_time    = smbcli_pull_nttime(req->in.body, 0x10);
	io->out.write_time     = smbcli_pull_nttime(req->in.body, 0x18);
	io->out.change_time    = smbcli_pull_nttime(req->in.body, 0x20);
	io->out.alloc_size     = BVAL(req->in.body, 0x28);
	io->out.size           = BVAL(req->in.body, 0x30);
	io->out.file_attr      = IVAL(req->in.body, 0x38);
	io->out.reserved2      = IVAL(req->in.body, 0x3C);
	smb2_pull_handle(req->in.body+0x40, &io->out.file.handle);
	status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &blob);
	if (!NT_STATUS_IS_OK(status)) {
		smb2_request_destroy(req);
		return status;
	}

	status = smb2_create_blob_parse(mem_ctx, blob, &io->out.blobs);
	if (!NT_STATUS_IS_OK(status)) {
		smb2_request_destroy(req);
		return status;
	}

	/* pull out the parsed blobs */
	for (i=0;i<io->out.blobs.num_blobs;i++) {
		if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_MXAC) == 0) {
			/* TODO: this also contains a status field in
			   first 4 bytes */
			if (io->out.blobs.blobs[i].data.length != 8) {
				smb2_request_destroy(req);
				return NT_STATUS_INVALID_NETWORK_RESPONSE;
			}
			io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 4);
		}
		if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_QFID) == 0) {
			if (io->out.blobs.blobs[i].data.length != 32) {
				smb2_request_destroy(req);
				return NT_STATUS_INVALID_NETWORK_RESPONSE;
			}
			memcpy(io->out.on_disk_id, io->out.blobs.blobs[i].data.data, 32);
		}
		if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_RQLS) == 0) {
			uint8_t *data;
			if (io->out.blobs.blobs[i].data.length != 32) {
				smb2_request_destroy(req);
				return NT_STATUS_INVALID_NETWORK_RESPONSE;
			}

			data = io->out.blobs.blobs[i].data.data;
			memcpy(&io->out.lease_response.lease_key, data, 16);
			io->out.lease_response.lease_state = IVAL(data, 16);
			io->out.lease_response.lease_flags = IVAL(data, 20);
			io->out.lease_response.lease_duration = BVAL(data, 24);
		}
	}

	data_blob_free(&blob);

	return smb2_request_destroy(req);
}