예제 #1
0
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;
}
예제 #2
0
/*
  fill a single entry in a trans2 find reply 
*/
static NTSTATUS find_fill_info(struct find_state *state,
			       const union smb_search_data *file)
{
	struct smbsrv_request *req = state->op->req;
	struct smb_trans2 *trans = state->op->trans;
	uint8_t *data;
	unsigned int ofs = trans->out.data.length;
	uint32_t ea_size;

	switch (state->data_level) {
	case RAW_SEARCH_DATA_GENERIC:
	case RAW_SEARCH_DATA_SEARCH:
		/* handled elsewhere */
		return NT_STATUS_INVALID_LEVEL;

	case RAW_SEARCH_DATA_STANDARD:
		if (state->flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 27));
			SIVAL(trans->out.data.data, ofs, file->standard.resume_key);
			ofs += 4;
		} else {
			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 23));
		}
		data = trans->out.data.data + ofs;
		srv_push_dos_date2(req->smb_conn, data, 0, file->standard.create_time);
		srv_push_dos_date2(req->smb_conn, data, 4, file->standard.access_time);
		srv_push_dos_date2(req->smb_conn, data, 8, file->standard.write_time);
		SIVAL(data, 12, file->standard.size);
		SIVAL(data, 16, file->standard.alloc_size);
		SSVAL(data, 20, file->standard.attrib);
		TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->standard.name.s, 
						       ofs + 22, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
						       STR_LEN8BIT | STR_TERMINATE | STR_LEN_NOTERM));
		break;

	case RAW_SEARCH_DATA_EA_SIZE:
		if (state->flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 31));
			SIVAL(trans->out.data.data, ofs, file->ea_size.resume_key);
			ofs += 4;
		} else {
			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 27));
		}
		data = trans->out.data.data + ofs;
		srv_push_dos_date2(req->smb_conn, data, 0, file->ea_size.create_time);
		srv_push_dos_date2(req->smb_conn, data, 4, file->ea_size.access_time);
		srv_push_dos_date2(req->smb_conn, data, 8, file->ea_size.write_time);
		SIVAL(data, 12, file->ea_size.size);
		SIVAL(data, 16, file->ea_size.alloc_size);
		SSVAL(data, 20, file->ea_size.attrib);
		SIVAL(data, 22, file->ea_size.ea_size);
		TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->ea_size.name.s, 
						       ofs + 26, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
						       STR_LEN8BIT | STR_NOALIGN));
		TRANS2_CHECK(smbsrv_blob_fill_data(trans, &trans->out.data, trans->out.data.length + 1));
		break;

	case RAW_SEARCH_DATA_EA_LIST:
		ea_size = ea_list_size(file->ea_list.eas.num_eas, file->ea_list.eas.eas);
		if (state->flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 27 + ea_size));
			SIVAL(trans->out.data.data, ofs, file->ea_list.resume_key);
			ofs += 4;
		} else {
			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 23 + ea_size));
		}
		data = trans->out.data.data + ofs;
		srv_push_dos_date2(req->smb_conn, data, 0, file->ea_list.create_time);
		srv_push_dos_date2(req->smb_conn, data, 4, file->ea_list.access_time);
		srv_push_dos_date2(req->smb_conn, data, 8, file->ea_list.write_time);
		SIVAL(data, 12, file->ea_list.size);
		SIVAL(data, 16, file->ea_list.alloc_size);
		SSVAL(data, 20, file->ea_list.attrib);
		ea_put_list(data+22, file->ea_list.eas.num_eas, file->ea_list.eas.eas);
		TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->ea_list.name.s, 
						       ofs + 22 + ea_size, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
						       STR_LEN8BIT | STR_NOALIGN));
		TRANS2_CHECK(smbsrv_blob_fill_data(trans, &trans->out.data, trans->out.data.length + 1));
		break;

	case RAW_SEARCH_DATA_DIRECTORY_INFO:
	case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO:
	case RAW_SEARCH_DATA_NAME_INFO:
	case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO:
	case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO:
	case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO:
		return smbsrv_push_passthru_search(trans, &trans->out.data, state->data_level, file,
						   SMBSRV_REQ_DEFAULT_STR_FLAGS(req));

	case RAW_SEARCH_DATA_UNIX_INFO:
	case RAW_SEARCH_DATA_UNIX_INFO2:
		return NT_STATUS_INVALID_LEVEL;
	}

	return NT_STATUS_OK;
}