Esempio n. 1
0
/* <string1> <string2> renamefile - */
static int
zrenamefile(i_ctx_t *i_ctx_p)
{
    int code;
    os_ptr op = osp;
    gs_parsed_file_name_t pname1, pname2;

    code = parse_real_file_name(op, &pname2, imemory, "renamefile(to)");
    if (code < 0)
        return code;

    pname1.fname = 0;
    code = parse_real_file_name(op - 1, &pname1, imemory, "renamefile(from)");
    if (code >= 0) {
        gx_io_device *iodev_dflt = iodev_default(imemory);
        if (pname1.iodev != pname2.iodev ) {
            if (pname1.iodev == iodev_dflt)
                pname1.iodev = pname2.iodev;
            if (pname2.iodev == iodev_dflt)
                pname2.iodev = pname1.iodev;
        }
        if (pname1.iodev != pname2.iodev ||
            (pname1.iodev == iodev_dflt &&
                /*
                 * We require FileControl permissions on the source path
                 * unless it is a temporary file. Also, we require FileControl
                 * and FileWriting permissions to the destination file/path.
                 */
              ((check_file_permissions(i_ctx_p, pname1.fname, pname1.len,
                                        "PermitFileControl") < 0 &&
                  !file_is_tempfile(i_ctx_p, op[-1].value.bytes, r_size(op - 1))) ||
              (check_file_permissions(i_ctx_p, pname2.fname, pname2.len,
                                        "PermitFileControl") < 0 ||
              check_file_permissions(i_ctx_p, pname2.fname, pname2.len,
                                        "PermitFileWriting") < 0 )))) {
            code = gs_note_error(e_invalidfileaccess);
        } else {
            code = (*pname1.iodev->procs.rename_file)(pname1.iodev,
                            pname1.fname, pname2.fname);
        }
    }
    gs_free_file_name(&pname2, "renamefile(to)");
    gs_free_file_name(&pname1, "renamefile(from)");
    if (code < 0)
        return code;
    pop(2);
    return 0;
}
Esempio n. 2
0
/*
 * Open a file specified by a parsed file name (which may be only a
 * device).
 */
int
zopen_file(i_ctx_t *i_ctx_p, const gs_parsed_file_name_t *pfn,
	   const char *file_access, stream **ps, gs_memory_t *mem)
{
    gx_io_device *const iodev = pfn->iodev;

    if (pfn->fname == NULL)	/* just a device */
	return iodev->procs.open_device(iodev, file_access, ps, mem);
    else {			/* file */
	iodev_proc_open_file((*open_file)) = iodev->procs.open_file;

	if (open_file == 0)
	    open_file = iodev_os_open_file;
	/* Check OS files to make sure we allow the type of access */
	if (open_file == iodev_os_open_file) {
	    int code = check_file_permissions(i_ctx_p, pfn->fname, pfn->len,
		file_access[0] == 'r' ? "PermitFileReading" : "PermitFileWriting");

	    if (code < 0 && !file_is_tempfile(i_ctx_p,
                                          (const uchar *)pfn->fname, pfn->len))
		return code;
	}
	return open_file(iodev, pfn->fname, pfn->len, file_access, ps, mem);
    }
}
Esempio n. 3
0
int
mu_locker_unlock (mu_locker_t lock)
{
  int rc = 0;
  unsigned type;
  
  if (!lock)
    return MU_ERR_LOCKER_NULL;

  if (lock->refcnt == 0)
    return MU_ERR_LOCK_NOT_HELD;

  if ((rc = check_file_permissions (lock->file)))
    return rc;

  if (--lock->refcnt > 0)
    return 0;

  type = MU_LOCKER_TYPE (lock);
  if (locker_tab[type].unlock)
    rc = locker_tab[type].unlock (lock);
  else
    rc = 0;
  
  return rc;
}
Esempio n. 4
0
static int
prelock_common (mu_locker_t locker)
{
  /* Check if we are trying to lock a regular file, with a link count
     of 1, that we have permission to read, etc., or don't lock it. */
  return check_file_permissions (locker->file);
}
Esempio n. 5
0
/* <string> deletefile - */
static int
zdeletefile(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_parsed_file_name_t pname;
    int code = parse_real_file_name(op, &pname, imemory, "deletefile");

    if (code < 0)
	return code;
    if (pname.iodev == iodev_default) {
	if ((code = check_file_permissions(i_ctx_p, pname.fname, pname.len,
		"PermitFileControl")) < 0 &&
		 !file_is_tempfile(i_ctx_p, op->value.bytes, r_size(op))) {
	    return code;
	}
    }
    code = (*pname.iodev->procs.delete_file)(pname.iodev, pname.fname);
    gs_free_file_name(&pname, "deletefile");
    if (code < 0)
	return code;
    pop(1);
    return 0;
}
Esempio n. 6
0
/* <prefix|null> <access_string> .tempfile <name_string> <file> */
static int
ztempfile(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    const char *pstr;
    char fmode[4];
    int code = parse_file_access_string(op, fmode);
    char prefix[gp_file_name_sizeof];
    char fname[gp_file_name_sizeof];
    uint fnlen;
    FILE *sfile;
    stream *s;
    byte *buf;

    if (code < 0)
	return code;
    strcat(fmode, gp_fmode_binary_suffix);
    if (r_has_type(op - 1, t_null))
	pstr = gp_scratch_file_name_prefix;
    else {
	uint psize;

	check_read_type(op[-1], t_string);
	psize = r_size(op - 1);
	if (psize >= gp_file_name_sizeof)
	    return_error(e_rangecheck);
	memcpy(prefix, op[-1].value.const_bytes, psize);
	prefix[psize] = 0;
	pstr = prefix;
    }

    if (gp_file_name_is_absolute(pstr, strlen(pstr))) {
	if (check_file_permissions(i_ctx_p, pstr, strlen(pstr),
				   "PermitFileWriting") < 0) {
	    return_error(e_invalidfileaccess);
	}
    } else if (!prefix_is_simple(pstr)) {
	return_error(e_invalidfileaccess);
    }

    s = file_alloc_stream(imemory, "ztempfile(stream)");
    if (s == 0)
	return_error(e_VMerror);
    buf = gs_alloc_bytes(imemory, file_default_buffer_size,
			 "ztempfile(buffer)");
    if (buf == 0)
	return_error(e_VMerror);
    sfile = gp_open_scratch_file(pstr, fname, fmode);
    if (sfile == 0) {
	gs_free_object(imemory, buf, "ztempfile(buffer)");
	return_error(e_invalidfileaccess);
    }
    fnlen = strlen(fname);
    file_init_stream(s, sfile, fmode, buf, file_default_buffer_size);
    code = ssetfilename(s, (const unsigned char*) fname, fnlen);
    if (code < 0) {
	sclose(s);
	iodev_default->procs.delete_file(iodev_default, fname);
	return_error(e_VMerror);
    }
    make_const_string(op - 1, a_readonly | icurrent_space, fnlen,
		      s->file_name.data);
    make_stream_file(op, s, fmode);
    return code;
}
Esempio n. 7
0
/* Loop though files in a package and perform full file property checking. */
int check_pkg_full(alpm_pkg_t *pkg)
{
	const char *root, *pkgname;
	size_t errors = 0;
	size_t rootlen;
	char filepath[PATH_MAX];
	struct archive *mtree;
	struct archive_entry *entry = NULL;
	size_t file_count = 0;
	const alpm_list_t *lp;

	root = alpm_option_get_root(config->handle);
	rootlen = strlen(root);
	if(rootlen + 1 > PATH_MAX) {
		/* we are in trouble here */
		pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, "");
		return 1;
	}
	strcpy(filepath, root);

	pkgname = alpm_pkg_get_name(pkg);
	mtree = alpm_pkg_mtree_open(pkg);
	if(mtree == NULL) {
		/* TODO: check error to confirm failure due to no mtree file */
		if(!config->quiet) {
			printf(_("%s: no mtree file\n"), pkgname);
		}
		return 0;
	}

	while(alpm_pkg_mtree_next(pkg, mtree, &entry) == ARCHIVE_OK) {
		struct stat st;
		const char *path = archive_entry_pathname(entry);
		mode_t type;
		size_t file_errors = 0;
		int backup = 0;

		/* strip leading "./" from path entries */
		if(path[0] == '.' && path[1] == '/') {
			path += 2;
		}

		if(strcmp(path, ".INSTALL") == 0) {
			char filename[PATH_MAX];
			snprintf(filename, PATH_MAX, "%slocal/%s-%s/install",
					alpm_option_get_dbpath(config->handle) + 1,
					pkgname, alpm_pkg_get_version(pkg));
			archive_entry_set_pathname(entry, filename);
			path = archive_entry_pathname(entry);
		} else if(strcmp(path, ".CHANGELOG") == 0) {
			char filename[PATH_MAX];
			snprintf(filename, PATH_MAX, "%slocal/%s-%s/changelog",
					alpm_option_get_dbpath(config->handle) + 1,
					pkgname, alpm_pkg_get_version(pkg));
			archive_entry_set_pathname(entry, filename);
			path = archive_entry_pathname(entry);
		} else if(*path == '.') {
			continue;
		}

		file_count++;

		if(rootlen + 1 + strlen(path) > PATH_MAX) {
			pm_printf(ALPM_LOG_WARNING, _("path too long: %s%s\n"), root, path);
			continue;
		}
		strcpy(filepath + rootlen, path);

		if(check_file_exists(pkgname, filepath, &st) == 1) {
			errors++;
			continue;
		}

		type = archive_entry_filetype(entry);

		if(type != AE_IFDIR && type != AE_IFREG && type != AE_IFLNK) {
			pm_printf(ALPM_LOG_WARNING, _("file type not recognized: %s%s\n"), root, path);
			continue;
		}

		if(check_file_type(pkgname, filepath, &st, entry) == 1) {
			errors++;
			continue;
		}

		file_errors += check_file_permissions(pkgname, filepath, &st, entry);

		if(type == AE_IFLNK) {
			file_errors += check_file_link(pkgname, filepath, &st, entry);
		}

		/* the following checks are expected to fail if a backup file has been
		   modified */
		for(lp = alpm_pkg_get_backup(pkg); lp; lp = lp->next) {
			alpm_backup_t *bl = lp->data;

			if(strcmp(path, bl->name) == 0) {
				backup = 1;
				break;
			}
		}

		if(type != AE_IFDIR) {
			/* file or symbolic link */
			file_errors += check_file_time(pkgname, filepath, &st, entry, backup);
		}

		if(type == AE_IFREG) {
			/* TODO: these are expected to be changed with backup files */
			file_errors += check_file_size(pkgname, filepath, &st, entry, backup);
			/* file_errors += check_file_md5sum(pkgname, filepath, &st, entry, backup); */
		}

		if(config->quiet && file_errors) {
			printf("%s %s\n", pkgname, filepath);
		}

		errors += (file_errors != 0 ? 1 : 0);
	}

	alpm_pkg_mtree_close(pkg, mtree);

	if(!config->quiet) {
		printf(_n("%s: %jd total file, ", "%s: %jd total files, ",
					(unsigned long)file_count), pkgname, (intmax_t)file_count);
		printf(_n("%jd altered file\n", "%jd altered files\n",
					(unsigned long)errors), (intmax_t)errors);
	}

	return (errors != 0 ? 1 : 0);
}