/****************************************************************************
- * Copyright 2019,2020 Thomas E. Dickey *
+ * Copyright 2019-2020,2021 Thomas E. Dickey *
* Copyright 1998-2011,2012 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
#include <ctype.h>
+#ifndef USE_ROOT_ACCESS
+#if HAVE_SETFSUID
+#include <sys/fsuid.h>
+#else
+#include <sys/stat.h>
+#endif
+#endif
+
#include <tic.h>
-MODULE_ID("$Id: access.c,v 1.27 2020/08/29 16:22:03 juergen Exp $")
+MODULE_ID("$Id: access.c,v 1.31 2021/08/29 10:35:17 tom Exp $")
#define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c))
return result;
}
+#if HAVE_ISSETUGID
+#define is_elevated() issetugid()
+#elif HAVE_GETEUID && HAVE_GETEGID
+#define is_elevated() \
+ (getuid() != geteuid() \
+ || getgid() != getegid())
+#else
+#define is_elevated() FALSE
+#endif
+
+#if HAVE_SETFSUID
+#define lower_privileges() \
+ int save_err = errno; \
+ setfsuid(getuid()); \
+ setfsgid(getgid()); \
+ errno = save_err
+#define resume_elevation() \
+ save_err = errno; \
+ setfsuid(geteuid()); \
+ setfsgid(getegid()); \
+ errno = save_err
+#else
+#define lower_privileges() /* nothing */
+#define resume_elevation() /* nothing */
+#endif
+
#ifndef USE_ROOT_ENVIRON
/*
* Returns true if we allow application to use environment variables that are
NCURSES_EXPORT(int)
_nc_env_access(void)
{
-#if HAVE_ISSETUGID
- if (issetugid())
- return FALSE;
-#elif HAVE_GETEUID && HAVE_GETEGID
- if (getuid() != geteuid()
- || getgid() != getegid())
- return FALSE;
+ int result = TRUE;
+
+ if (is_elevated()) {
+ result = FALSE;
+ } else if ((getuid() == ROOT_UID) || (geteuid() == ROOT_UID)) {
+ result = FALSE;
+ }
+ return result;
+}
+#endif /* USE_ROOT_ENVIRON */
+
+#ifndef USE_ROOT_ACCESS
+/*
+ * Limit privileges if possible; otherwise disallow access for updating files.
+ */
+NCURSES_EXPORT(FILE *)
+_nc_safe_fopen(const char *path, const char *mode)
+{
+ FILE *result = NULL;
+#if HAVE_SETFSUID
+ lower_privileges();
+ result = fopen(path, mode);
+ resume_elevation();
+#else
+ if (!is_elevated() || *mode == 'r') {
+ result = fopen(path, mode);
+ }
#endif
- /* ...finally, disallow root */
- return (getuid() != ROOT_UID) && (geteuid() != ROOT_UID);
+ return result;
}
+
+NCURSES_EXPORT(int)
+_nc_safe_open3(const char *path, int flags, mode_t mode)
+{
+ int result = -1;
+#if HAVE_SETFSUID
+ lower_privileges();
+ result = open(path, flags, mode);
+ resume_elevation();
+#else
+ if (!is_elevated() || (flags & O_RDONLY)) {
+ result = open(path, flags, mode);
+ }
#endif
+ return result;
+}
+#endif /* USE_ROOT_ENVIRON */