Exemple #1
0
/*
  delete a file - the dirtype specifies the file types to include in the search. 
  The name can contain CIFS wildcards, but rarely does (except with OS/2 clients)
*/
NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
		     struct ntvfs_request *req,
		     union smb_unlink *unl)
{
	struct pvfs_state *pvfs = talloc_get_type(ntvfs->private_data,
				  struct pvfs_state);
	struct pvfs_dir *dir;
	NTSTATUS status;
	uint32_t total_deleted=0;
	struct pvfs_filename *name;
	const char *fname;
	off_t ofs;

	/* resolve the cifs name to a posix name */
	status = pvfs_resolve_name(pvfs, req, unl->unlink.in.pattern, 
				   PVFS_RESOLVE_WILDCARD |
				   PVFS_RESOLVE_STREAMS |
				   PVFS_RESOLVE_NO_OPENDB,
				   &name);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	if (!name->exists && !name->has_wildcard) {
		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
	}

	if (name->exists && 
	    (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
		return NT_STATUS_FILE_IS_A_DIRECTORY;
	}

	if (!name->has_wildcard) {
		return pvfs_unlink_one(pvfs, req, unl, name);
	}

	/*
	 * disable async requests in the wildcard case
	 * untill we have proper tests for this
	 */
	req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC;

	/* get list of matching files */
	status = pvfs_list_start(pvfs, name, req, &dir);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	status = NT_STATUS_NO_SUCH_FILE;
	talloc_free(name);

	ofs = 0;

	while ((fname = pvfs_list_next(dir, &ofs))) {
		/* this seems to be a special case */
		if ((unl->unlink.in.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
		    (ISDOT(fname) || ISDOTDOT(fname))) {
			return NT_STATUS_OBJECT_NAME_INVALID;
		}

		/* get a pvfs_filename object */
		status = pvfs_resolve_partial(pvfs, req,
					      pvfs_list_unix_path(dir),
					      fname,
					      PVFS_RESOLVE_NO_OPENDB,
					      &name);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}

		status = pvfs_unlink_one(pvfs, req, unl, name);
		if (NT_STATUS_IS_OK(status)) {
			total_deleted++;
		}

		talloc_free(name);
	}

	if (total_deleted > 0) {
		status = NT_STATUS_OK;
	}

	return status;
}
Exemple #2
0
/*
  fill in a single search result for a given info level
*/
static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
				 enum smb_search_data_level level,
				 const char *unix_path,
				 const char *fname, 
				 struct pvfs_search_state *search,
				 off_t dir_offset,
				 union smb_search_data *file)
{
	struct pvfs_filename *name;
	NTSTATUS status;
	const char *shortname;
	uint32_t dir_index = (uint32_t)dir_offset; /* truncated - see the code 
						      in pvfs_list_seek_ofs() for 
						      how we cope with this */

	status = pvfs_resolve_partial(pvfs, file, unix_path, fname, 0, &name);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	status = pvfs_match_attrib(pvfs, name, search->search_attrib, search->must_attrib);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	switch (level) {
	case RAW_SEARCH_DATA_SEARCH:
		shortname = pvfs_short_name(pvfs, name, name);
		file->search.attrib           = name->dos.attrib;
		file->search.write_time       = nt_time_to_unix(name->dos.write_time);
		file->search.size             = name->st.st_size;
		file->search.name             = shortname;
		file->search.id.reserved      = search->handle >> 8;
		memset(file->search.id.name, ' ', sizeof(file->search.id.name));
		memcpy(file->search.id.name, shortname, 
		       MIN(strlen(shortname)+1, sizeof(file->search.id.name)));
		file->search.id.handle        = search->handle & 0xFF;
		file->search.id.server_cookie = dir_index;
		file->search.id.client_cookie = 0;
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_STANDARD:
		file->standard.resume_key   = dir_index;
		file->standard.create_time  = nt_time_to_unix(name->dos.create_time);
		file->standard.access_time  = nt_time_to_unix(name->dos.access_time);
		file->standard.write_time   = nt_time_to_unix(name->dos.write_time);
		file->standard.size         = name->st.st_size;
		file->standard.alloc_size   = name->dos.alloc_size;
		file->standard.attrib       = name->dos.attrib;
		file->standard.name.s       = fname;
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_EA_SIZE:
		file->ea_size.resume_key   = dir_index;
		file->ea_size.create_time  = nt_time_to_unix(name->dos.create_time);
		file->ea_size.access_time  = nt_time_to_unix(name->dos.access_time);
		file->ea_size.write_time   = nt_time_to_unix(name->dos.write_time);
		file->ea_size.size         = name->st.st_size;
		file->ea_size.alloc_size   = name->dos.alloc_size;
		file->ea_size.attrib       = name->dos.attrib;
		file->ea_size.ea_size      = name->dos.ea_size;
		file->ea_size.name.s       = fname;
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_EA_LIST:
		file->ea_list.resume_key   = dir_index;
		file->ea_list.create_time  = nt_time_to_unix(name->dos.create_time);
		file->ea_list.access_time  = nt_time_to_unix(name->dos.access_time);
		file->ea_list.write_time   = nt_time_to_unix(name->dos.write_time);
		file->ea_list.size         = name->st.st_size;
		file->ea_list.alloc_size   = name->dos.alloc_size;
		file->ea_list.attrib       = name->dos.attrib;
		file->ea_list.name.s       = fname;
		return pvfs_query_ea_list(pvfs, file, name, -1, 
					  search->num_ea_names,
					  search->ea_names,
					  &file->ea_list.eas);

	case RAW_SEARCH_DATA_DIRECTORY_INFO:
		file->directory_info.file_index   = dir_index;
		file->directory_info.create_time  = name->dos.create_time;
		file->directory_info.access_time  = name->dos.access_time;
		file->directory_info.write_time   = name->dos.write_time;
		file->directory_info.change_time  = name->dos.change_time;
		file->directory_info.size         = name->st.st_size;
		file->directory_info.alloc_size   = name->dos.alloc_size;
		file->directory_info.attrib       = name->dos.attrib;
		file->directory_info.name.s       = fname;
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO:
		file->full_directory_info.file_index   = dir_index;
		file->full_directory_info.create_time  = name->dos.create_time;
		file->full_directory_info.access_time  = name->dos.access_time;
		file->full_directory_info.write_time   = name->dos.write_time;
		file->full_directory_info.change_time  = name->dos.change_time;
		file->full_directory_info.size         = name->st.st_size;
		file->full_directory_info.alloc_size   = name->dos.alloc_size;
		file->full_directory_info.attrib       = name->dos.attrib;
		file->full_directory_info.ea_size      = name->dos.ea_size;
		file->full_directory_info.name.s       = fname;
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_NAME_INFO:
		file->name_info.file_index   = dir_index;
		file->name_info.name.s       = fname;
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO:
		file->both_directory_info.file_index   = dir_index;
		file->both_directory_info.create_time  = name->dos.create_time;
		file->both_directory_info.access_time  = name->dos.access_time;
		file->both_directory_info.write_time   = name->dos.write_time;
		file->both_directory_info.change_time  = name->dos.change_time;
		file->both_directory_info.size         = name->st.st_size;
		file->both_directory_info.alloc_size   = name->dos.alloc_size;
		file->both_directory_info.attrib       = name->dos.attrib;
		file->both_directory_info.ea_size      = name->dos.ea_size;
		file->both_directory_info.short_name.s = pvfs_short_name(pvfs, file, name);
		file->both_directory_info.name.s       = fname;
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO:
		file->id_full_directory_info.file_index   = dir_index;
		file->id_full_directory_info.create_time  = name->dos.create_time;
		file->id_full_directory_info.access_time  = name->dos.access_time;
		file->id_full_directory_info.write_time   = name->dos.write_time;
		file->id_full_directory_info.change_time  = name->dos.change_time;
		file->id_full_directory_info.size         = name->st.st_size;
		file->id_full_directory_info.alloc_size   = name->dos.alloc_size;
		file->id_full_directory_info.attrib       = name->dos.attrib;
		file->id_full_directory_info.ea_size      = name->dos.ea_size;
		file->id_full_directory_info.file_id      = name->dos.file_id;
		file->id_full_directory_info.name.s       = fname;
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO:
		file->id_both_directory_info.file_index   = dir_index;
		file->id_both_directory_info.create_time  = name->dos.create_time;
		file->id_both_directory_info.access_time  = name->dos.access_time;
		file->id_both_directory_info.write_time   = name->dos.write_time;
		file->id_both_directory_info.change_time  = name->dos.change_time;
		file->id_both_directory_info.size         = name->st.st_size;
		file->id_both_directory_info.alloc_size   = name->dos.alloc_size;
		file->id_both_directory_info.attrib       = name->dos.attrib;
		file->id_both_directory_info.ea_size      = name->dos.ea_size;
		file->id_both_directory_info.file_id      = name->dos.file_id;
		file->id_both_directory_info.short_name.s = pvfs_short_name(pvfs, file, name);
		file->id_both_directory_info.name.s       = fname;
		return NT_STATUS_OK;

	case RAW_SEARCH_DATA_GENERIC:
		break;
	}

	return NT_STATUS_INVALID_LEVEL;
}