Example #1
0
/*
 * Returns false on error
 *         true  on OK, with full_path set to where config file should be 
 */
static bool
find_config_file(const char *config_file, char *full_path, int max_path)
{
   int file_length = strlen(config_file) + 1;

   /* If a full path specified, use it */
   if (first_path_separator(config_file) != NULL) {
      if (file_length > max_path) {
         return false;
      }
      bstrncpy(full_path, config_file, file_length);
      return true;
   }

   /* config_file is default file name, now find default dir */
   const char *config_dir = get_default_configdir();
   int dir_length = strlen(config_dir);

   if ((dir_length + 1 + file_length) > max_path) {
      return false;
   }

   memcpy(full_path, config_dir, dir_length + 1);

   if (!IsPathSeparator(full_path[dir_length - 1])) {
      full_path[dir_length++] = '/';
   }

   memcpy(&full_path[dir_length], config_file, file_length);

   return true;
}
Example #2
0
File: tree.c Project: AlD/bareos
/*
 * Do a relative cwd -- i.e. relative to current node rather than root node
 */
TREE_NODE *tree_relcwd(char *path, TREE_ROOT *root, TREE_NODE *node)
{
   char *p;
   int len;
   TREE_NODE *cd;
   char save_char;
   int match;

   if (*path == 0) {
      return node;
   }

   /*
    * Check the current segment only
    */
   if ((p = first_path_separator(path)) != NULL) {
      len = p - path;
   } else {
      len = strlen(path);
   }

   Dmsg2(100, "tree_relcwd: len=%d path=%s\n", len, path);

   foreach_child(cd, node) {
      Dmsg1(100, "tree_relcwd: test cd=%s\n", cd->fname);
      if (cd->fname[0] == path[0] && len == (int)strlen(cd->fname)
          && bstrncmp(cd->fname, path, len)) {
         break;
      }

      /*
       * fnmatch has no len in call so we truncate the string
       */
      save_char = path[len];
      path[len] = 0;
      match = fnmatch(path, cd->fname, 0) == 0;
      path[len] = save_char;

      if (match) {
         break;
      }
   }
Example #3
0
/*
 * find_my_exec -- find an absolute path to a valid executable
 *
 *	argv0 is the name passed on the command line
 *	retpath is the output area (must be of size MAXPGPATH)
 *	Returns 0 if OK, -1 if error.
 *
 * The reason we have to work so hard to find an absolute path is that
 * on some platforms we can't do dynamic loading unless we know the
 * executable's location.  Also, we need a full path not a relative
 * path because we will later change working directory.  Finally, we want
 * a true path not a symlink location, so that we can locate other files
 * that are part of our installation relative to the executable.
 *
 * This function is not thread-safe because it calls validate_exec(),
 * which calls getgrgid().	This function should be used only in
 * non-threaded binaries, not in library routines.
 */
int
find_my_exec(const char *argv0, char *retpath)
{
	char		cwd[MAXPGPATH],
				test_path[MAXPGPATH];
	char	   *path;

	if (!getcwd(cwd, MAXPGPATH))
	{
		log_error(_("could not identify current directory: %s"),
				  strerror(errno));
		return -1;
	}

	/*
	 * If argv0 contains a separator, then PATH wasn't used.
	 */
	if (first_dir_separator(argv0) != NULL)
	{
		if (is_absolute_path(argv0))
			StrNCpy(retpath, argv0, MAXPGPATH);
		else
			join_path_components(retpath, cwd, argv0);
		canonicalize_path(retpath);

		if (validate_exec(retpath) == 0)
			return resolve_symlinks(retpath);

		log_error(_("invalid binary \"%s\""), retpath);
		return -1;
	}

#ifdef WIN32
	/* Win32 checks the current directory first for names without slashes */
	join_path_components(retpath, cwd, argv0);
	if (validate_exec(retpath) == 0)
		return resolve_symlinks(retpath);
#endif

	/*
	 * Since no explicit path was supplied, the user must have been relying on
	 * PATH.  We'll search the same PATH.
	 */
	if ((path = getenv("PATH")) && *path)
	{
		char	   *startp = NULL,
				   *endp = NULL;

		do
		{
			if (!startp)
				startp = path;
			else
				startp = endp + 1;

			endp = first_path_separator(startp);
			if (!endp)
				endp = startp + strlen(startp); /* point to end */

			StrNCpy(test_path, startp, Min(endp - startp + 1, MAXPGPATH));

			if (is_absolute_path(test_path))
				join_path_components(retpath, test_path, argv0);
			else
			{
				join_path_components(retpath, cwd, test_path);
				join_path_components(retpath, retpath, argv0);
			}
			canonicalize_path(retpath);

			switch (validate_exec(retpath))
			{
				case 0: /* found ok */
					return resolve_symlinks(retpath);
				case -1:		/* wasn't even a candidate, keep looking */
					break;
				case -2:		/* found but disqualified */
					log_error(_("could not read binary \"%s\""),
							  retpath);
					break;
			}
		} while (*endp);
	}

	log_error(_("could not find a \"%s\" to execute"), argv0);
	return -1;
}
Example #4
0
/*
 * mode is the mode bits to use in creating a new directory
 *
 * parent_mode are the parent's modes if we need to create parent
 *    directories.
 *
 * owner and group are to set on any created dirs
 *
 * keep_dir_modes if set means don't change mode bits if dir exists
 */
bool makepath(ATTR *attr, const char *apath, mode_t mode, mode_t parent_mode,
            uid_t owner, gid_t group, int keep_dir_modes)
{
   struct stat statp;
   mode_t omask, tmode;
   char *path = (char *)apath;
   char *p;
   int len;
   bool ok = false;
   int created;
   char new_dir[5000];
   int ndir = 0;
   int i = 0;
   int max_dirs = (int)sizeof(new_dir);
   JCR *jcr = attr->jcr;

   if (stat(path, &statp) == 0) {     /* Does dir exist? */
      if (!S_ISDIR(statp.st_mode)) {
         Jmsg1(jcr, M_ERROR, 0, _("%s exists but is not a directory.\n"), path);
         return false;
      }
      /* Full path exists */
      if (keep_dir_modes) {
         return true;
      }
      set_own_mod(attr, path, owner, group, mode);
      return true;
   }
   omask = umask(0);
   umask(omask);
   len = strlen(apath);
   path = (char *)alloca(len+1);
   bstrncpy(path, apath, len+1);
   strip_trailing_slashes(path);
   /*
    * Now for one of the complexities. If we are not running as root,
    *  then if the parent_mode does not have wx user perms, or we are
    *  setting the userid or group, and the parent_mode has setuid, setgid,
    *  or sticky bits, we must create the dir with open permissions, then
    *  go back and patch all the dirs up with the correct perms.
    * Solution, set everything to 0777, then go back and reset them at the
    *  end.
    */
   tmode = 0777;

#if defined(HAVE_WIN32)
   /* Validate drive letter */
   if (path[1] == ':') {
      char drive[4] = "X:\\";

      drive[0] = path[0];

      UINT drive_type = GetDriveType(drive);

      if (drive_type == DRIVE_UNKNOWN || drive_type == DRIVE_NO_ROOT_DIR) {
         Jmsg1(jcr, M_ERROR, 0, _("%c: is not a valid drive.\n"), path[0]);
         goto bail_out;
      }

      if (path[2] == '\0') {          /* attempt to create a drive */
         ok = true;
         goto bail_out;               /* OK, it is already there */
      }

      p = &path[3];
   } else {
      p = path;
   }
#else
   p = path;
#endif

   /* Skip leading slash(es) */
   while (IsPathSeparator(*p)) {
      p++;
   }
   while ((p = first_path_separator(p))) {
      char save_p;
      save_p = *p;
      *p = 0;
      if (!makedir(jcr, path, tmode, &created)) {
         goto bail_out;
      }
      if (ndir < max_dirs) {
         new_dir[ndir++] = created;
      }
      *p = save_p;
      while (IsPathSeparator(*p)) {
         p++;
      }
   }
   /* Create final component */
   if (!makedir(jcr, path, tmode, &created)) {
      goto bail_out;
   }
   if (ndir < max_dirs) {
      new_dir[ndir++] = created;
   }
   if (ndir >= max_dirs) {
      Jmsg0(jcr, M_WARNING, 0, _("Too many subdirectories. Some permissions not reset.\n"));
   }

   /* Now set the proper owner and modes */
#if defined(HAVE_WIN32)

   /* Don't propagate the hidden or encrypted attributes to parent directories */
   parent_mode &= ~S_ISVTX;
   parent_mode &= ~S_ISGID;

   if (path[1] == ':') {
      p = &path[3];
   } else {
      p = path;
   }
#else
   p = path;
#endif
   /* Skip leading slash(es) */
   while (IsPathSeparator(*p)) {
      p++;
   }
   while ((p = first_path_separator(p))) {
      char save_p;
      save_p = *p;
      *p = 0;
      if (i < ndir && new_dir[i++] && !keep_dir_modes) {
         set_own_mod(attr, path, owner, group, parent_mode);
      }
      *p = save_p;
      while (IsPathSeparator(*p)) {
         p++;
      }
   }

   /* Set for final component */
   if (i < ndir && new_dir[i++]) {
      set_own_mod(attr, path, owner, group, mode);
   }

   ok = true;
bail_out:
   umask(omask);
   return ok;
}
Example #5
0
/*
 * Returns false on error
 *         true  on OK, with full_path set to where config file should be
 */
static bool find_config_file(const char *config_file, char *full_path, int max_path)
{
   int dir_length, file_length;
   const char *config_dir;
#if defined(HAVE_SETENV) || defined(HAVE_PUTENV)
   char *bp;
   POOL_MEM env_string(PM_NAME);
#endif

   /*
    * If a full path specified, use it
    */
   file_length = strlen(config_file) + 1;
   if (first_path_separator(config_file) != NULL) {
      if (file_length > max_path) {
         return false;
      }

      bstrncpy(full_path, config_file, file_length);

#ifdef HAVE_SETENV
      pm_strcpy(env_string, config_file);
      bp = (char *)last_path_separator(env_string.c_str());
      *bp = '\0';
      setenv("BAREOS_CFGDIR", env_string.c_str(), 1);
#elif HAVE_PUTENV
      Mmsg(env_string, "BAREOS_CFGDIR=%s", config_file);
      bp = (char *)last_path_separator(env_string.c_str());
      *bp = '\0';
      putenv(bstrdup(env_string.c_str()));
#endif

      return true;
   }

   /*
    * config_file is default file name, now find default dir
    */
   config_dir = get_default_configdir();
   dir_length = strlen(config_dir);

   if ((dir_length + 1 + file_length) > max_path) {
      return false;
   }

#ifdef HAVE_SETENV
   pm_strcpy(env_string, config_dir);
   setenv("BAREOS_CFGDIR", env_string.c_str(), 1);
#elif HAVE_PUTENV
   Mmsg(env_string, "BAREOS_CFGDIR=%s", config_dir);
   putenv(bstrdup(env_string.c_str()));
#endif

   memcpy(full_path, config_dir, dir_length + 1);

   if (!IsPathSeparator(full_path[dir_length - 1])) {
      full_path[dir_length++] = '/';
   }

   memcpy(full_path + dir_length, config_file, file_length);

   return true;
}