⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pvfs_resolve.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	  '.' components are not allowed, but the rules for what error	  code to give don't seem to make sense. This is a close	  approximation.	*/	for (err_count=i=0;components[i];i++) {		if (strcmp(components[i], "") == 0) {			continue;		}		if (ISDOT(components[i]) || err_count) {			err_count++;		}	}	if (err_count) {		if (flags & PVFS_RESOLVE_WILDCARD) err_count--;		if (err_count==1) {			return NT_STATUS_OBJECT_NAME_INVALID;		} else {			return NT_STATUS_OBJECT_PATH_NOT_FOUND;		}	}	/* remove any null components */	for (i=0;components[i];i++) {		if (strcmp(components[i], "") == 0) {			memmove(&components[i], &components[i+1], 				sizeof(char *)*(num_components-i));			i--;			continue;		}		if (ISDOTDOT(components[i])) {			if (i < 1) return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;			memmove(&components[i-1], &components[i+1], 				sizeof(char *)*(num_components-i));			i -= 2;			continue;		}	}	if (components[0] == NULL) {		talloc_free(s);		*fname = talloc_strdup(mem_ctx, "\\");		return NT_STATUS_OK;	}	for (len=i=0;components[i];i++) {		len += strlen(components[i]) + 1;	}	/* rebuild the name */	ret = talloc_size(mem_ctx, len+1);	if (ret == NULL) {		talloc_free(s);		return NT_STATUS_NO_MEMORY;	}	for (len=0,i=0;components[i];i++) {		size_t len1 = strlen(components[i]);		ret[len] = '\\';		memcpy(ret+len+1, components[i], len1);		len += len1 + 1;	}		ret[len] = 0;	talloc_free(s);	*fname = ret;		return NT_STATUS_OK;}/*  resolve a name from relative client format to a struct pvfs_filename  the memory for the filename is made as a talloc child of 'name'  flags include:     PVFS_RESOLVE_NO_WILDCARD = wildcards are considered illegal characters     PVFS_RESOLVE_STREAMS     = stream names are allowed     TODO: ../ collapsing, and outside share checking*/NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,			   const char *cifs_name,			   uint_t flags, struct pvfs_filename **name){	NTSTATUS status;	*name = talloc(mem_ctx, struct pvfs_filename);	if (*name == NULL) {		return NT_STATUS_NO_MEMORY;	}	(*name)->exists = false;	(*name)->stream_exists = false;	if (!(pvfs->fs_attribs & FS_ATTR_NAMED_STREAMS)) {		flags &= ~PVFS_RESOLVE_STREAMS;	}	/* do the basic conversion to a unix formatted path,	   also checking for allowable characters */	status = pvfs_unix_path(pvfs, cifs_name, flags, *name);	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) {		/* it might contain .. components which need to be reduced */		status = pvfs_reduce_name(*name, lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx), &cifs_name, flags);		if (!NT_STATUS_IS_OK(status)) {			return status;		}		status = pvfs_unix_path(pvfs, cifs_name, flags, *name);	}	if (!NT_STATUS_IS_OK(status)) {		return status;	}	/* if it has a wildcard then no point doing a stat() of the	   full name. Instead We need check if the directory exists 	 */	if ((*name)->has_wildcard) {		const char *p;		char *dir_name, *saved_name;		p = strrchr((*name)->full_name, '/');		if (p == NULL) {			/* root directory wildcard is OK */			return NT_STATUS_OK;		}		dir_name = talloc_strndup(*name, (*name)->full_name, (p-(*name)->full_name));		if (stat(dir_name, &(*name)->st) == 0) {			talloc_free(dir_name);			return NT_STATUS_OK;		}		/* we need to search for a matching name */		saved_name = (*name)->full_name;		(*name)->full_name = dir_name;		status = pvfs_case_search(pvfs, *name);		if (!NT_STATUS_IS_OK(status)) {			/* the directory doesn't exist */			(*name)->full_name = saved_name;			return status;		}		/* it does exist, but might need a case change */		if (dir_name != (*name)->full_name) {			(*name)->full_name = talloc_asprintf(*name, "%s%s",							     (*name)->full_name, p);			NT_STATUS_HAVE_NO_MEMORY((*name)->full_name);		} else {			(*name)->full_name = saved_name;			talloc_free(dir_name);		}		return NT_STATUS_OK;	}	/* if we can stat() the full name now then we are done */	if (stat((*name)->full_name, &(*name)->st) == 0) {		(*name)->exists = true;		return pvfs_fill_dos_info(pvfs, *name, -1);	}	/* search for a matching filename */	status = pvfs_case_search(pvfs, *name);	return status;}/*  do a partial resolve, returning a pvfs_filename structure given a  base path and a relative component. It is an error if the file does  not exist. No case-insensitive matching is done.  this is used in places like directory searching where we need a pvfs_filename  to pass to a function, but already know the unix base directory and component*/NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,			      const char *unix_dir, const char *fname,			      struct pvfs_filename **name){	NTSTATUS status;	*name = talloc(mem_ctx, struct pvfs_filename);	if (*name == NULL) {		return NT_STATUS_NO_MEMORY;	}	(*name)->full_name = talloc_asprintf(*name, "%s/%s", unix_dir, fname);	if ((*name)->full_name == NULL) {		return NT_STATUS_NO_MEMORY;	}	if (stat((*name)->full_name, &(*name)->st) == -1) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	(*name)->exists = true;	(*name)->stream_exists = true;	(*name)->has_wildcard = false;	(*name)->original_name = talloc_strdup(*name, fname);	(*name)->stream_name = NULL;	(*name)->stream_id = 0;	status = pvfs_fill_dos_info(pvfs, *name, -1);	return status;}/*  fill in the pvfs_filename info for an open file, given the current  info for a (possibly) non-open file. This is used by places that need  to update the pvfs_filename stat information, and by pvfs_open()*/NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd,			      struct pvfs_filename *name){	dev_t device = (dev_t)0;	ino_t inode = 0;	if (name->exists) {		device = name->st.st_dev;		inode = name->st.st_ino;	}	if (fd == -1) {		if (stat(name->full_name, &name->st) == -1) {			return NT_STATUS_INVALID_HANDLE;		}	} else {		if (fstat(fd, &name->st) == -1) {			return NT_STATUS_INVALID_HANDLE;		}	}	if (name->exists &&	    (device != name->st.st_dev || inode != name->st.st_ino)) {		/* the file we are looking at has changed! this could		 be someone trying to exploit a race		 condition. Certainly we don't want to continue		 operating on this file */		DEBUG(0,("pvfs: WARNING: file '%s' changed during resolve - failing\n",			 name->full_name));		return NT_STATUS_UNEXPECTED_IO_ERROR;	}	name->exists = true;		return pvfs_fill_dos_info(pvfs, name, fd);}/*  fill in the pvfs_filename info for an open file, given the current  info for a (possibly) non-open file. This is used by places that need  to update the pvfs_filename stat information, and the path  after a possible rename on a different handle.*/NTSTATUS pvfs_resolve_name_handle(struct pvfs_state *pvfs,				  struct pvfs_file_handle *h){	NTSTATUS status;	if (h->have_opendb_entry) {		struct odb_lock *lck;		const char *name = NULL;		lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key);		if (lck == NULL) {			DEBUG(0,("%s: failed to lock file '%s' in opendb\n",				 __FUNCTION__, h->name->full_name));			/* we were supposed to do a blocking lock, so something			   is badly wrong! */			return NT_STATUS_INTERNAL_DB_CORRUPTION;		}		status = odb_get_path(lck, &name);		if (NT_STATUS_IS_OK(status)) {			/*			 * This relies an the fact that			 * renames of open files are only			 * allowed by setpathinfo() and setfileinfo()			 * and there're only renames within the same			 * directory supported			 */			if (strcmp(h->name->full_name, name) != 0) {				const char *orig_dir;				const char *new_file;				const char *new_orig;				char *delim;				delim = strrchr(name, '/');				if (!delim) {					talloc_free(lck);					return NT_STATUS_INTERNAL_ERROR;				}				new_file = delim + 1;				delim = strrchr(h->name->original_name, '\\');				if (delim) {					delim[0] = '\0';					orig_dir = h->name->original_name;					new_orig = talloc_asprintf(h->name, "%s\\%s",								   orig_dir, new_file);					if (!new_orig) {						talloc_free(lck);						return NT_STATUS_NO_MEMORY;					}				} else {					new_orig = talloc_strdup(h->name, new_file);					if (!new_orig) {						talloc_free(lck);						return NT_STATUS_NO_MEMORY;					}				}				talloc_free(h->name->original_name);				talloc_free(h->name->full_name);				h->name->full_name = talloc_steal(h->name, name);				h->name->original_name = new_orig;			}		}		talloc_free(lck);	}	status = pvfs_resolve_name_fd(pvfs, h->fd, h->name);	NT_STATUS_NOT_OK_RETURN(status);	return NT_STATUS_OK;}/*  resolve the parent of a given name*/NTSTATUS pvfs_resolve_parent(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,			     const struct pvfs_filename *child,			     struct pvfs_filename **name){	NTSTATUS status;	char *p;	*name = talloc(mem_ctx, struct pvfs_filename);	if (*name == NULL) {		return NT_STATUS_NO_MEMORY;	}	(*name)->full_name = talloc_strdup(*name, child->full_name);	if ((*name)->full_name == NULL) {		return NT_STATUS_NO_MEMORY;	}	p = strrchr_m((*name)->full_name, '/');	if (p == NULL) {		return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;	}	/* this handles the root directory */	if (p == (*name)->full_name) {		p[1] = 0;	} else {		p[0] = 0;	}	if (stat((*name)->full_name, &(*name)->st) == -1) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	(*name)->exists = true;	(*name)->stream_exists = true;	(*name)->has_wildcard = false;	/* we can't get the correct 'original_name', but for the purposes	   of this call this is close enough */	(*name)->original_name = talloc_reference(*name, child->original_name);	(*name)->stream_name = NULL;	(*name)->stream_id = 0;	status = pvfs_fill_dos_info(pvfs, *name, -1);	return status;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -