Beispiel #1
0
/*
  trans2 mkdir implementation
*/
static NTSTATUS trans2_mkdir(struct smbsrv_request *req, struct trans_op *op)
{
	struct smb_trans2 *trans = op->trans;
	union smb_mkdir *io;

	/* make sure we got enough parameters */
	if (trans->in.params.length < 5) {
		return NT_STATUS_FOOBAR;
	}

	io = talloc(op, union smb_mkdir);
	NT_STATUS_HAVE_NO_MEMORY(io);

	io->t2mkdir.level = RAW_MKDIR_T2MKDIR;
	smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 4, &io->t2mkdir.in.path, 0);
	if (io->t2mkdir.in.path == NULL) {
		return NT_STATUS_FOOBAR;
	}

	TRANS2_CHECK(ea_pull_list(&trans->in.data, io, 
				  &io->t2mkdir.in.num_eas, 
				  &io->t2mkdir.in.eas));

	op->op_info = io;
	op->send_fn = trans2_simple_send;

	return ntvfs_mkdir(req->ntvfs, io);
}
Beispiel #2
0
/*
  trans2 open implementation
*/
static NTSTATUS trans2_open(struct smbsrv_request *req, struct trans_op *op)
{
	struct smb_trans2 *trans = op->trans;
	union smb_open *io;

	/* make sure we got enough parameters */
	if (trans->in.params.length < 29) {
		return NT_STATUS_FOOBAR;
	}

	io = talloc(op, union smb_open);
	NT_STATUS_HAVE_NO_MEMORY(io);

	io->t2open.level           = RAW_OPEN_T2OPEN;
	io->t2open.in.flags        = SVAL(trans->in.params.data, VWV(0));
	io->t2open.in.open_mode    = SVAL(trans->in.params.data, VWV(1));
	io->t2open.in.search_attrs = SVAL(trans->in.params.data, VWV(2));
	io->t2open.in.file_attrs   = SVAL(trans->in.params.data, VWV(3));
	io->t2open.in.write_time   = srv_pull_dos_date(req->smb_conn, 
						    trans->in.params.data + VWV(4));
	io->t2open.in.open_func    = SVAL(trans->in.params.data, VWV(6));
	io->t2open.in.size         = IVAL(trans->in.params.data, VWV(7));
	io->t2open.in.timeout      = IVAL(trans->in.params.data, VWV(9));
	io->t2open.in.num_eas      = 0;
	io->t2open.in.eas          = NULL;

	smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 28, &io->t2open.in.fname, 0);
	if (io->t2open.in.fname == NULL) {
		return NT_STATUS_FOOBAR;
	}

	TRANS2_CHECK(ea_pull_list(&trans->in.data, io, &io->t2open.in.num_eas, &io->t2open.in.eas));

	op->op_info = io;
	op->send_fn = trans2_open_send;

	return ntvfs_open(req->ntvfs, io);
}
Beispiel #3
0
/*
  parse a trans2 search response. 
  Return the number of bytes consumed
  return 0 for success with end of list
  return -1 for a parse error
*/
static int parse_trans2_search(struct smbcli_tree *tree,
			       TALLOC_CTX *mem_ctx, 
			       enum smb_search_data_level level,
			       uint16_t flags,
			       DATA_BLOB *blob,
			       union smb_search_data *data)
{
	unsigned int len, ofs;
	uint32_t ea_size;
	DATA_BLOB eablob;
	NTSTATUS status;

	switch (level) {
	case RAW_SEARCH_DATA_GENERIC:
	case RAW_SEARCH_DATA_SEARCH:
		/* handled elsewhere */
		return -1;

	case RAW_SEARCH_DATA_STANDARD:
		if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
			if (blob->length < 4) return -1;
			data->standard.resume_key = IVAL(blob->data, 0);
			blob->data += 4;
			blob->length -= 4;
		}
		if (blob->length < 24) return -1;
		data->standard.create_time = raw_pull_dos_date2(tree->session->transport,
								blob->data + 0);
		data->standard.access_time = raw_pull_dos_date2(tree->session->transport,
								blob->data + 4);
		data->standard.write_time  = raw_pull_dos_date2(tree->session->transport,
								blob->data + 8);
		data->standard.size        = IVAL(blob->data, 12);
		data->standard.alloc_size  = IVAL(blob->data, 16);
		data->standard.attrib      = SVAL(blob->data, 20);
		len = smbcli_blob_pull_string(tree->session, mem_ctx, blob,
					   &data->standard.name,
					   22, 23, STR_LEN8BIT | STR_TERMINATE | STR_LEN_NOTERM);
		return len + 23;

	case RAW_SEARCH_DATA_EA_SIZE:
		if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
			if (blob->length < 4) return -1;
			data->ea_size.resume_key = IVAL(blob->data, 0);
			blob->data += 4;
			blob->length -= 4;
		}
		if (blob->length < 28) return -1;
		data->ea_size.create_time = raw_pull_dos_date2(tree->session->transport,
							       blob->data + 0);
		data->ea_size.access_time = raw_pull_dos_date2(tree->session->transport,
							       blob->data + 4);
		data->ea_size.write_time  = raw_pull_dos_date2(tree->session->transport,
							       blob->data + 8);
		data->ea_size.size        = IVAL(blob->data, 12);
		data->ea_size.alloc_size  = IVAL(blob->data, 16);
		data->ea_size.attrib      = SVAL(blob->data, 20);
		data->ea_size.ea_size     = IVAL(blob->data, 22);
		len = smbcli_blob_pull_string(tree->session, mem_ctx, blob,
					   &data->ea_size.name,
					   26, 27, STR_LEN8BIT | STR_TERMINATE | STR_NOALIGN);
		return len + 27 + 1;

	case RAW_SEARCH_DATA_EA_LIST:
		if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
			if (blob->length < 4) return -1;
			data->ea_list.resume_key = IVAL(blob->data, 0);
			blob->data += 4;
			blob->length -= 4;
		}
		if (blob->length < 28) return -1;
		data->ea_list.create_time = raw_pull_dos_date2(tree->session->transport,
							       blob->data + 0);
		data->ea_list.access_time = raw_pull_dos_date2(tree->session->transport,
							       blob->data + 4);
		data->ea_list.write_time  = raw_pull_dos_date2(tree->session->transport,
							       blob->data + 8);
		data->ea_list.size        = IVAL(blob->data, 12);
		data->ea_list.alloc_size  = IVAL(blob->data, 16);
		data->ea_list.attrib      = SVAL(blob->data, 20);
		ea_size                   = IVAL(blob->data, 22);
		if (ea_size > 0xFFFF) {
			return -1;
		}
		eablob.data = blob->data + 22;
		eablob.length = ea_size;
		if (eablob.length > blob->length - 24) {
			return -1;
		}
		status = ea_pull_list(&eablob, mem_ctx, 
				      &data->ea_list.eas.num_eas,
				      &data->ea_list.eas.eas);
		if (!NT_STATUS_IS_OK(status)) {
			return -1;
		}
		len = smbcli_blob_pull_string(tree->session, mem_ctx, blob,
					      &data->ea_list.name,
					      22+ea_size, 23+ea_size, 
					      STR_LEN8BIT | STR_NOALIGN);
		return len + ea_size + 23 + 1;

	case RAW_SEARCH_DATA_UNIX_INFO:
		if (blob->length < 109) return -1;
		ofs                                  = IVAL(blob->data,             0);
		data->unix_info.file_index           = IVAL(blob->data,             4);
		data->unix_info.size                 = BVAL(blob->data,             8);
		data->unix_info.alloc_size           = BVAL(blob->data,            16);
		data->unix_info.status_change_time   = smbcli_pull_nttime(blob->data, 24);
		data->unix_info.access_time          = smbcli_pull_nttime(blob->data, 32);
		data->unix_info.change_time          = smbcli_pull_nttime(blob->data, 40);
		data->unix_info.uid                  = IVAL(blob->data,            48);
		data->unix_info.gid                  = IVAL(blob->data,            56);
		data->unix_info.file_type            = IVAL(blob->data,            64);
		data->unix_info.dev_major            = BVAL(blob->data,            68);
		data->unix_info.dev_minor            = BVAL(blob->data,            76);
		data->unix_info.unique_id            = BVAL(blob->data,            84);
		data->unix_info.permissions          = IVAL(blob->data,            92);
		data->unix_info.nlink                = IVAL(blob->data,           100);
		/* There is no length field for this name but we know it's null terminated. */
		len = smbcli_blob_pull_unix_string(tree->session, mem_ctx, blob,
					   &data->unix_info.name, 108, 0);
		if (ofs != 0 && ofs < 108+len) {
			return -1;
		}
		return ofs;

	case RAW_SEARCH_DATA_UNIX_INFO2:
		/*   8 - size of ofs + file_index
		 * 116 - size of unix_info2
		 *   4 - size of name length
		 *   2 - "." is the shortest name
		 */
		if (blob->length < (116 + 8 + 4 + 2)) {
			return -1;
		}

		ofs                                 = IVAL(blob->data,   0);
		data->unix_info2.file_index         = IVAL(blob->data,   4);
		data->unix_info2.end_of_file        = BVAL(blob->data,   8);
		data->unix_info2.num_bytes          = BVAL(blob->data,  16);
		data->unix_info2.status_change_time = smbcli_pull_nttime(blob->data, 24);
		data->unix_info2.access_time        = smbcli_pull_nttime(blob->data, 32);
		data->unix_info2.change_time        = smbcli_pull_nttime(blob->data, 40);
		data->unix_info2.uid                = IVAL(blob->data,  48);
		data->unix_info2.gid                = IVAL(blob->data,  56);
		data->unix_info2.file_type          = IVAL(blob->data,  64);
		data->unix_info2.dev_major          = BVAL(blob->data,  68);
		data->unix_info2.dev_minor          = BVAL(blob->data,  76);
		data->unix_info2.unique_id          = BVAL(blob->data,  84);
		data->unix_info2.permissions        = IVAL(blob->data,  92);
		data->unix_info2.nlink              = IVAL(blob->data, 100);
		data->unix_info2.create_time	    = smbcli_pull_nttime(blob->data, 108);
		data->unix_info2.file_flags	    = IVAL(blob->data, 116);
		data->unix_info2.flags_mask	    = IVAL(blob->data, 120);

		/* There is a 4 byte length field for this name. The length
		 * does not include the NULL terminator.
		 */
		len = smbcli_blob_pull_string(tree->session, mem_ctx, blob,
				       &data->unix_info2.name,
				       8 + 116, /* offset to length */
				       8 + 116 + 4, /* offset to string */
				       0);

		if (ofs != 0 && ofs < (8 + 116 + 4 + len)) {
			return -1;
		}

		return ofs;

		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: {
			unsigned int str_flags = STR_UNICODE;
			if (!(tree->session->transport->negotiate.capabilities & CAP_UNICODE)) {
				str_flags = STR_ASCII;
			}
			
		status = smb_raw_search_common(mem_ctx, level, blob, data, &ofs, str_flags);
		if (!NT_STATUS_IS_OK(status)) {
			return -1;
		}
		return ofs;
	}
	}

	/* invalid level */
	return -1;
}
Beispiel #4
0
/*
  parse a trans2 setfileinfo/setpathinfo data blob
*/
static NTSTATUS trans2_parse_sfileinfo(struct smbsrv_request *req,
				       union smb_setfileinfo *st,
				       const DATA_BLOB *blob)
{
	enum smb_setfileinfo_level passthru_level;

	switch (st->generic.level) {
	case RAW_SFILEINFO_GENERIC:
	case RAW_SFILEINFO_SETATTR:
	case RAW_SFILEINFO_SETATTRE:
	case RAW_SFILEINFO_SEC_DESC:
		/* handled elsewhere */
		return NT_STATUS_INVALID_LEVEL;

	case RAW_SFILEINFO_STANDARD:
		CHECK_MIN_BLOB_SIZE(blob, 12);

		st->standard.in.create_time = srv_pull_dos_date2(req->smb_conn, blob->data + 0);
		st->standard.in.access_time = srv_pull_dos_date2(req->smb_conn, blob->data + 4);
		st->standard.in.write_time  = srv_pull_dos_date2(req->smb_conn, blob->data + 8);

		return NT_STATUS_OK;

	case RAW_SFILEINFO_EA_SET:
		return ea_pull_list(blob, req, 
				    &st->ea_set.in.num_eas, 
				    &st->ea_set.in.eas);

	case SMB_SFILEINFO_BASIC_INFO:
	case SMB_SFILEINFO_BASIC_INFORMATION:
		passthru_level = SMB_SFILEINFO_BASIC_INFORMATION;
		break;

	case SMB_SFILEINFO_DISPOSITION_INFO:
	case SMB_SFILEINFO_DISPOSITION_INFORMATION:
		passthru_level = SMB_SFILEINFO_DISPOSITION_INFORMATION;
		break;

	case SMB_SFILEINFO_ALLOCATION_INFO:
	case SMB_SFILEINFO_ALLOCATION_INFORMATION:
		passthru_level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
		break;

	case RAW_SFILEINFO_END_OF_FILE_INFO:
	case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
		passthru_level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
		break;

	case RAW_SFILEINFO_RENAME_INFORMATION:
	case RAW_SFILEINFO_POSITION_INFORMATION:
	case RAW_SFILEINFO_MODE_INFORMATION:
		passthru_level = st->generic.level;
		break;

	case RAW_SFILEINFO_UNIX_BASIC:
	case RAW_SFILEINFO_UNIX_LINK:
	case RAW_SFILEINFO_UNIX_HLINK:
	case RAW_SFILEINFO_PIPE_INFORMATION:
	case RAW_SFILEINFO_VALID_DATA_INFORMATION:
	case RAW_SFILEINFO_SHORT_NAME_INFORMATION:
	case RAW_SFILEINFO_1025:
	case RAW_SFILEINFO_1027:
	case RAW_SFILEINFO_1029:
	case RAW_SFILEINFO_1030:
	case RAW_SFILEINFO_1031:
	case RAW_SFILEINFO_1032:
	case RAW_SFILEINFO_1036:
	case RAW_SFILEINFO_1041:
	case RAW_SFILEINFO_1042:
	case RAW_SFILEINFO_1043:
	case RAW_SFILEINFO_1044:
		return NT_STATUS_INVALID_LEVEL;

	default:
		/* we need a default here to cope with invalid values on the wire */
		return NT_STATUS_INVALID_LEVEL;
	}

	return smbsrv_pull_passthru_sfileinfo(st, passthru_level, st,
					      blob, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
					      &req->in.bufinfo);
}