Exemple #1
0
int get_real_filename(connection_struct *conn, const char *path,
		      const char *name, TALLOC_CTX *mem_ctx,
		      char **found_name)
{
	struct smb_Dir *cur_dir;
	const char *dname;
	bool mangled;
	char *unmangled_name = NULL;
	long curpos;

	/* open the directory */
	if (!(cur_dir = OpenDir(talloc_tos(), conn, path, NULL, 0))) {
		DEBUG(3,("scan dir didn't open dir [%s]\n",path));
		TALLOC_FREE(unmangled_name);
		return -1;
	}

	/* now scan for matching names */
	curpos = 0;
	while ((dname = ReadDirName(cur_dir, &curpos, NULL))) {

		/* Is it dot or dot dot. */
		if (ISDOT(dname) || ISDOTDOT(dname)) {
			continue;
		}

		/*
		 * At this point dname is the unmangled name.
		 * name is either mangled or not, depending on the state
		 * of the "mangled" variable. JRA.
		 */

		/*
		 * Check mangled name against mangled name, or unmangled name
		 * against unmangled name.
		 */

		if ((mangled && mangled_equal(name,dname,conn->params)) ||
			fname_equal(name, dname, conn->case_sensitive)) {
			/* we've found the file, change it's name and return */
			*found_name = talloc_strdup(mem_ctx, dname);
			TALLOC_FREE(unmangled_name);
			TALLOC_FREE(cur_dir);
			if (!*found_name) {
				errno = ENOMEM;
				return -1;
			}
			return 0;
		}
	}

	TALLOC_FREE(unmangled_name);
	TALLOC_FREE(cur_dir);
	errno = ENOENT;
	return -1;
}
static int findpty(char **slave)
{
  int master;
  static fstring line;
  void *dirp;
  char *dpname;
  
#if defined(HAVE_GRANTPT)
  /* Try to open /dev/ptmx. If that fails, fall through to old method. */
  if ((master = sys_open("/dev/ptmx", O_RDWR, 0)) >= 0) {
    grantpt(master);
    unlockpt(master);
    *slave = (char *)ptsname(master);
    if (*slave == NULL) {
      DEBUG(0,("findpty: Unable to create master/slave pty pair.\n"));
      /* Stop fd leak on error. */
      close(master);
      return -1;
    } else {
      DEBUG(10, ("findpty: Allocated slave pty %s\n", *slave));
      return (master);
    }
  }
#endif /* HAVE_GRANTPT */

  fstrcpy( line, "/dev/ptyXX" );

  dirp = OpenDir(NULL, "/dev", False);
  if (!dirp)
    return(-1);
  while ((dpname = ReadDirName(dirp)) != NULL) {
    if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) {
      DEBUG(3,("pty: try to open %s, line was %s\n", dpname, line ) );
      line[8] = dpname[3];
      line[9] = dpname[4];
      if ((master = sys_open(line, O_RDWR, 0)) >= 0) {
        DEBUG(3,("pty: opened %s\n", line ) );
        line[5] = 't';
        *slave = line;
        CloseDir(dirp);
        return (master);
      }
    }
  }
  CloseDir(dirp);
  return (-1);
}
Exemple #3
0
void FSDrive::find_first_file(char *pattern)
{
#ifndef __riscos__
	DIR *dir;
	struct dirent *de;

	// Open directory for reading and skip '.' and '..'
	if ((dir = opendir(dir_path)) == NULL)
		return;
	de = readdir(dir);
	while (de && (0 == strcmp(".", de->d_name) || 0 == strcmp("..", de->d_name))) 
		de = readdir(dir);

	while (de) {

		// Match found? Then copy real file name
		if (match(pattern, de->d_name)) {
			strncpy(pattern, de->d_name, NAMEBUF_LENGTH);
			closedir(dir);
			return;
		}

		// Get next directory entry
		de = readdir(dir);
	}

	closedir(dir);
#else
	dir_env de;
	char Buffer[NAMEBUF_LENGTH];

	de.offset = 0; de.buffsize = NAMEBUF_LENGTH; de.match = name;
	do {
		de.readno = 1;
		if (ReadDirName(dir_path,Buffer,&de) != NULL)
			de.offset = -1;
		else if (de.offset != -1 && match(name,Buffer)) {
			strncpy(name, Buffer, NAMEBUF_LENGTH);
			return;
		}
	} while (de.readno > 0);
#endif
}
Exemple #4
0
static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
{
	connection_struct *conn = fsp->conn;
	struct smb_filename *smb_dname = fsp->fsp_name;
	int ret;

	SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));

	/* Might be a symlink. */
	if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
		return map_nt_error_from_unix(errno);
	}

	if (S_ISLNK(smb_dname->st.st_ex_mode)) {
		/* Is what it points to a directory ? */
		if(SMB_VFS_STAT(conn, smb_dname) != 0) {
			return map_nt_error_from_unix(errno);
		}
		if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
			return NT_STATUS_NOT_A_DIRECTORY;
		}
		ret = SMB_VFS_UNLINK(conn, smb_dname);
	} else {
		ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
	}
	if (ret == 0) {
		notify_fname(conn, NOTIFY_ACTION_REMOVED,
			     FILE_NOTIFY_CHANGE_DIR_NAME,
			     smb_dname->base_name);
		return NT_STATUS_OK;
	}

	if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(talloc_tos(), SNUM(conn))) {
		/*
		 * Check to see if the only thing in this directory are
		 * vetoed files/directories. If so then delete them and
		 * retry. If we fail to delete any of them (and we *don't*
		 * do a recursive delete) then fail the rmdir.
		 */
		SMB_STRUCT_STAT st;
		const char *dname = NULL;
		char *talloced = NULL;
		long dirpos = 0;
		struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
						  smb_dname->base_name, NULL,
						  0);

		if(dir_hnd == NULL) {
			errno = ENOTEMPTY;
			goto err;
		}

		while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
					    &talloced)) != NULL) {
			if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
				TALLOC_FREE(talloced);
				continue;
			}
			if (!is_visible_file(conn, smb_dname->base_name, dname,
					     &st, false)) {
				TALLOC_FREE(talloced);
				continue;
			}
			if(!IS_VETO_PATH(conn, dname)) {
				TALLOC_FREE(dir_hnd);
				TALLOC_FREE(talloced);
				errno = ENOTEMPTY;
				goto err;
			}
			TALLOC_FREE(talloced);
		}

		/* We only have veto files/directories.
		 * Are we allowed to delete them ? */

		if(!lp_delete_veto_files(SNUM(conn))) {
			TALLOC_FREE(dir_hnd);
			errno = ENOTEMPTY;
			goto err;
		}

		/* Do a recursive delete. */
		RewindDir(dir_hnd,&dirpos);
		while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
					    &talloced)) != NULL) {
			struct smb_filename *smb_dname_full = NULL;
			char *fullname = NULL;
			bool do_break = true;

			if (ISDOT(dname) || ISDOTDOT(dname)) {
				TALLOC_FREE(talloced);
				continue;
			}
			if (!is_visible_file(conn, smb_dname->base_name, dname,
					     &st, false)) {
				TALLOC_FREE(talloced);
				continue;
			}

			fullname = talloc_asprintf(ctx,
					"%s/%s",
					smb_dname->base_name,
					dname);

			if(!fullname) {
				errno = ENOMEM;
				goto err_break;
			}

			smb_dname_full = synthetic_smb_fname(
				talloc_tos(), fullname, NULL, NULL);
			if (smb_dname_full == NULL) {
				errno = ENOMEM;
				goto err_break;
			}

			if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
				goto err_break;
			}
			if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
				if(!recursive_rmdir(ctx, conn,
						    smb_dname_full)) {
					goto err_break;
				}
				if(SMB_VFS_RMDIR(conn,
					smb_dname_full->base_name) != 0) {
					goto err_break;
				}
			} else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
				goto err_break;
			}

			/* Successful iteration. */
			do_break = false;

		 err_break:
			TALLOC_FREE(fullname);
			TALLOC_FREE(smb_dname_full);
			TALLOC_FREE(talloced);
			if (do_break)
				break;
		}
		TALLOC_FREE(dir_hnd);
		/* Retry the rmdir */
		ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
	}

  err:

	if (ret != 0) {
		DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
			 "%s\n", smb_fname_str_dbg(smb_dname),
			 strerror(errno)));
		return map_nt_error_from_unix(errno);
	}

	notify_fname(conn, NOTIFY_ACTION_REMOVED,
		     FILE_NOTIFY_CHANGE_DIR_NAME,
		     smb_dname->base_name);

	return NT_STATUS_OK;
}
Exemple #5
0
bool recursive_rmdir(TALLOC_CTX *ctx,
		     connection_struct *conn,
		     struct smb_filename *smb_dname)
{
	const char *dname = NULL;
	char *talloced = NULL;
	bool ret = True;
	long offset = 0;
	SMB_STRUCT_STAT st;
	struct smb_Dir *dir_hnd;

	SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));

	dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
	if(dir_hnd == NULL)
		return False;

	while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
		struct smb_filename *smb_dname_full = NULL;
		char *fullname = NULL;
		bool do_break = true;

		if (ISDOT(dname) || ISDOTDOT(dname)) {
			TALLOC_FREE(talloced);
			continue;
		}

		if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
				     false)) {
			TALLOC_FREE(talloced);
			continue;
		}

		/* Construct the full name. */
		fullname = talloc_asprintf(ctx,
				"%s/%s",
				smb_dname->base_name,
				dname);
		if (!fullname) {
			errno = ENOMEM;
			goto err_break;
		}

		smb_dname_full = synthetic_smb_fname(talloc_tos(), fullname,
						     NULL, NULL);
		if (smb_dname_full == NULL) {
			errno = ENOMEM;
			goto err_break;
		}

		if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
			goto err_break;
		}

		if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
			if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
				goto err_break;
			}
			if(SMB_VFS_RMDIR(conn,
					 smb_dname_full->base_name) != 0) {
				goto err_break;
			}
		} else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
			goto err_break;
		}

		/* Successful iteration. */
		do_break = false;

	 err_break:
		TALLOC_FREE(smb_dname_full);
		TALLOC_FREE(fullname);
		TALLOC_FREE(talloced);
		if (do_break) {
			ret = false;
			break;
		}
	}
	TALLOC_FREE(dir_hnd);
	return ret;
}
Exemple #6
0
static int get_real_filename_full_scan(connection_struct *conn,
				       const char *path, const char *name,
				       bool mangled,
				       TALLOC_CTX *mem_ctx, char **found_name)
{
	struct smb_Dir *cur_dir;
	const char *dname = NULL;
	char *talloced = NULL;
	char *unmangled_name = NULL;
	long curpos;

	/* handle null paths */
	if ((path == NULL) || (*path == 0)) {
		path = ".";
	}

	/* If we have a case-sensitive filesystem, it doesn't do us any
	 * good to search for a name. If a case variation of the name was
	 * there, then the original stat(2) would have found it.
	 */
	if (!mangled && !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) {
		errno = ENOENT;
		return -1;
	}

	/*
	 * The incoming name can be mangled, and if we de-mangle it
	 * here it will not compare correctly against the filename (name2)
	 * read from the directory and then mangled by the name_to_8_3()
	 * call. We need to mangle both names or neither.
	 * (JRA).
	 *
	 * Fix for bug found by Dina Fine. If in case sensitive mode then
	 * the mangle cache is no good (3 letter extension could be wrong
	 * case - so don't demangle in this case - leave as mangled and
	 * allow the mangling of the directory entry read (which is done
	 * case insensitively) to match instead. This will lead to more
	 * false positive matches but we fail completely without it. JRA.
	 */

	if (mangled && !conn->case_sensitive) {
		mangled = !mangle_lookup_name_from_8_3(talloc_tos(), name,
						       &unmangled_name,
						       conn->params);
		if (!mangled) {
			/* Name is now unmangled. */
			name = unmangled_name;
		}
	}

	/* open the directory */
	if (!(cur_dir = OpenDir(talloc_tos(), conn, path, NULL, 0))) {
		DEBUG(3,("scan dir didn't open dir [%s]\n",path));
		TALLOC_FREE(unmangled_name);
		return -1;
	}

	/* now scan for matching names */
	curpos = 0;
	while ((dname = ReadDirName(cur_dir, &curpos, NULL, &talloced))) {

		/* Is it dot or dot dot. */
		if (ISDOT(dname) || ISDOTDOT(dname)) {
			TALLOC_FREE(talloced);
			continue;
		}

		/*
		 * At this point dname is the unmangled name.
		 * name is either mangled or not, depending on the state
		 * of the "mangled" variable. JRA.
		 */

		/*
		 * Check mangled name against mangled name, or unmangled name
		 * against unmangled name.
		 */

		if ((mangled && mangled_equal(name,dname,conn->params)) ||
			fname_equal(name, dname, conn->case_sensitive)) {
			/* we've found the file, change it's name and return */
			*found_name = talloc_strdup(mem_ctx, dname);
			TALLOC_FREE(unmangled_name);
			TALLOC_FREE(cur_dir);
			if (!*found_name) {
				errno = ENOMEM;
				TALLOC_FREE(talloced);
				return -1;
			}
			TALLOC_FREE(talloced);
			return 0;
		}
		TALLOC_FREE(talloced);
	}

	TALLOC_FREE(unmangled_name);
	TALLOC_FREE(cur_dir);
	errno = ENOENT;
	return -1;
}
Exemple #7
0
static BOOL scan_directory(connection_struct *conn, const char *path, char *name, size_t maxlength)
{
	struct smb_Dir *cur_dir;
	const char *dname;
	BOOL mangled;
	long curpos;

	mangled = mangle_is_mangled(name, conn->params);

	/* handle null paths */
	if (*path == 0)
		path = ".";

	/* If we have a case-sensitive filesystem, it doesn't do us any
	 * good to search for a name. If a case variation of the name was
	 * there, then the original stat(2) would have found it.
	 */
	if (!(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) {
		errno = ENOENT;
		return False;
	}

	/*
	 * The incoming name can be mangled, and if we de-mangle it
	 * here it will not compare correctly against the filename (name2)
	 * read from the directory and then mangled by the mangle_map()
	 * call. We need to mangle both names or neither.
	 * (JRA).
	 *
	 * Fix for bug found by Dina Fine. If in case sensitive mode then
	 * the mangle cache is no good (3 letter extension could be wrong
	 * case - so don't demangle in this case - leave as mangled and
	 * allow the mangling of the directory entry read (which is done
	 * case insensitively) to match instead. This will lead to more
	 * false positive matches but we fail completely without it. JRA.
	 */

	if (mangled && !conn->case_sensitive) {
		mangled = !mangle_check_cache( name, maxlength, conn->params);
	}

	/* open the directory */
	if (!(cur_dir = OpenDir(conn, path, NULL, 0))) {
		DEBUG(3,("scan dir didn't open dir [%s]\n",path));
		return(False);
	}

	/* now scan for matching names */
	curpos = 0;
	while ((dname = ReadDirName(cur_dir, &curpos))) {

		/* Is it dot or dot dot. */
		if ((dname[0] == '.') && (!dname[1] || (dname[1] == '.' && !dname[2]))) {
			continue;
		}

		/*
		 * At this point dname is the unmangled name.
		 * name is either mangled or not, depending on the state of the "mangled"
		 * variable. JRA.
		 */

		/*
		 * Check mangled name against mangled name, or unmangled name
		 * against unmangled name.
		 */

		if ((mangled && mangled_equal(name,dname,conn->params)) || fname_equal(name, dname, conn->case_sensitive)) {
			/* we've found the file, change it's name and return */
			safe_strcpy(name, dname, maxlength);
			CloseDir(cur_dir);
			return(True);
		}
	}

	CloseDir(cur_dir);
	errno = ENOENT;
	return(False);
}
Exemple #8
0
static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags, 
			struct change_data *data, struct change_data *old_data)
{
	SMB_STRUCT_STAT st;
	pstring full_name;
	char *p;
	char *fname;
	size_t remaining_len;
	size_t fullname_len;
	void *dp;

	ZERO_STRUCTP(data);

	if(vfs_stat(conn,path, &st) == -1)
		return False;

	data->modify_time = st.st_mtime;
	data->status_time = st.st_ctime;

	if (old_data) {
		/*
		 * Shortcut to avoid directory scan if the time
		 * has changed - we always must return true then.
		 */
		if (old_data->modify_time != data->modify_time ||
			old_data->status_time != data->status_time ) {
				return True;
		}
	}
 
	/*
	 * If we are to watch for changes that are only stored
	 * in inodes of files, not in the directory inode, we must
	 * scan the directory and produce a unique identifier with
	 * which we can determine if anything changed. We use the
	 * modify and change times from all the files in the
	 * directory, added together (ignoring wrapping if it's
	 * larger than the max time_t value).
	 */

	dp = OpenDir(conn, path, True);
	if (dp == NULL)
		return False;

	data->num_entries = 0;
	
	pstrcpy(full_name, path);
	pstrcat(full_name, "/");
	
	fullname_len = strlen(full_name);
	remaining_len = sizeof(full_name) - fullname_len - 1;
	p = &full_name[fullname_len];
	
	while ((fname = ReadDirName(dp))) {
		if(strequal(fname, ".") || strequal(fname, ".."))
			continue;		

		data->num_entries++;
		safe_strcpy(p, fname, remaining_len);

		ZERO_STRUCT(st);

		/*
		 * Do the stat - but ignore errors.
		 */		
		vfs_stat(conn,full_name, &st);

		/*
		 * Always sum the times.
		 */

		data->total_time += (st.st_mtime + st.st_ctime);

		/*
		 * If requested hash the names.
		 */

		if (flags & (FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_FILE)) {
			int i;
			unsigned char tmp_hash[16];
			mdfour(tmp_hash, (unsigned char *)fname, strlen(fname));
			for (i=0;i<16;i++)
				data->name_hash[i] ^= tmp_hash[i];
		}

		/*
		 * If requested sum the mode_t's.
		 */

		if (flags & (FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_SECURITY))
			data->mode_sum = st.st_mode;
	}
	
	CloseDir(dp);
	
	return True;
}