CHECK_FUNCTION_EXISTS_GLIBC(futimens HAVE_FUTIMENS)
CHECK_FUNCTION_EXISTS_GLIBC(futimes HAVE_FUTIMES)
CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT)
+CHECK_FUNCTION_EXISTS_GLIBC(getegid HAVE_GETEGID)
CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
CHECK_FUNCTION_EXISTS_GLIBC(getline HAVE_GETLINE)
+CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
-CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
+CHECK_FUNCTION_EXISTS_GLIBC(getresgid HAVE_GETRESGID)
+CHECK_FUNCTION_EXISTS_GLIBC(getresuid HAVE_GETRESUID)
CHECK_FUNCTION_EXISTS_GLIBC(getvfsbyname HAVE_GETVFSBYNAME)
CHECK_FUNCTION_EXISTS_GLIBC(gmtime_r HAVE_GMTIME_R)
+CHECK_FUNCTION_EXISTS_GLIBC(issetugid HAVE_ISSETUGID)
CHECK_FUNCTION_EXISTS_GLIBC(lchflags HAVE_LCHFLAGS)
CHECK_FUNCTION_EXISTS_GLIBC(lchmod HAVE_LCHMOD)
CHECK_FUNCTION_EXISTS_GLIBC(lchown HAVE_LCHOWN)
AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fnmatch fork])
AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate])
AC_CHECK_FUNCS([futimens futimes futimesat])
-AC_CHECK_FUNCS([geteuid getline getpid getgrgid_r getgrnam_r])
-AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r])
+AC_CHECK_FUNCS([getegid geteuid getline getpid getresgid getresuid])
+AC_CHECK_FUNCS([getgrgid_r getgrnam_r getpwnam_r getpwuid_r])
+AC_CHECK_FUNCS([getvfsbyname gmtime_r])
+AC_CHECK_FUNCS([issetugid])
AC_CHECK_FUNCS([lchflags lchmod lchown link linkat localtime_r lstat lutimes])
AC_CHECK_FUNCS([mbrtowc memmove memset])
AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp])
__LA_NORETURN void __archive_errx(int retvalue, const char *msg);
void __archive_ensure_cloexec_flag(int fd);
+int __archive_get_tempdir(struct archive_string *);
int __archive_mktemp(const char *tmpdir);
#if defined(_WIN32) && !defined(__CYGWIN__)
int __archive_mkstemp(wchar_t *templates);
int ret = ARCHIVE_OK;
void *buff = NULL;
int have_attrs;
- const char *name, *tempdir;
+ const char *name;
struct archive_string tempfile;
(void)fd; /* UNUSED */
if (have_attrs == 0)
return (ARCHIVE_OK);
- tempdir = NULL;
- if (issetugid() == 0)
- tempdir = getenv("TMPDIR");
- if (tempdir == NULL)
- tempdir = _PATH_TMP;
archive_string_init(&tempfile);
- archive_strcpy(&tempfile, tempdir);
- archive_strcat(&tempfile, "/tar.md.XXXXXX");
+ if (__archive_get_tempdir(&tempfile) != ARCHIVE_OK) {
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
+ archive_strcat(&tempfile, "tar.md.XXXXXX");
tempfd = mkstemp(tempfile.s);
if (tempfd < 0) {
archive_set_error(&a->archive, errno,
#else
static int
-get_tempdir(struct archive_string *temppath)
+__archive_issetugid(void)
{
- const char *tmp;
+#ifdef HAVE_ISSETUGID
+ return (issetugid());
+#elif HAVE_GETRESUID
+ uid_t ruid, euid, suid;
+ gid_t rgid, egid, sgid;
+ if (getresuid(&ruid, &euid, &suid) != 0)
+ return (-1);
+ if (ruid != euid || ruid != suid)
+ return (1);
+ if (getresgid(&ruid, &egid, &sgid) != 0)
+ return (-1);
+ if (rgid != egid || rgid != sgid)
+ return (1);
+#elif HAVE_GETEUID
+ if (geteuid() != getuid())
+ return (1);
+#if HAVE_GETEGID
+ if (getegid() != getgid())
+ return (1);
+#endif
+#endif
+ return (0);
+}
+
+int
+__archive_get_tempdir(struct archive_string *temppath)
+{
+ const char *tmp = NULL;
- tmp = getenv("TMPDIR");
+ if (__archive_issetugid() == 0)
+ tmp = getenv("TMPDIR");
if (tmp == NULL)
#ifdef _PATH_TMP
tmp = _PATH_TMP;
archive_string_init(&temp_name);
if (tmpdir == NULL) {
- if (get_tempdir(&temp_name) != ARCHIVE_OK)
+ if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK)
goto exit_tmpfile;
} else {
archive_strcpy(&temp_name, tmpdir);
if (template == NULL) {
archive_string_init(&temp_name);
if (tmpdir == NULL) {
- if (get_tempdir(&temp_name) != ARCHIVE_OK)
+ if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK)
goto exit_tmpfile;
} else
archive_strcpy(&temp_name, tmpdir);