/* <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; }
/* * 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); } }
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; }
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); }
/* <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; }
/* <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; }
/* 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); }