X-Git-Url: http://ncurses.scripts.mit.edu/?a=blobdiff_plain;f=ncurses%2Ftinfo%2Faccess.c;h=a735db26eee600c5fb218c83224de4324aeb75bf;hb=3d46d7e9d3e210417f34acf3b469378558398d07;hp=6dd1d69befcf6e6624fc69f631ab7b3658b61a4e;hpb=cecf06633520e80b392644f66fe362009583fedb;p=ncurses.git diff --git a/ncurses/tinfo/access.c b/ncurses/tinfo/access.c index 6dd1d69b..a735db26 100644 --- a/ncurses/tinfo/access.c +++ b/ncurses/tinfo/access.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. * + * 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 * * copy of this software and associated documentation files (the * @@ -33,22 +34,27 @@ #include #include + +#ifndef USE_ROOT_ACCESS +#if HAVE_SETFSUID +#include +#else #include +#endif +#endif #include -MODULE_ID("$Id: access.c,v 1.17 2011/05/07 15:02:03 tom Exp $") +MODULE_ID("$Id: access.c,v 1.31 2021/08/29 10:35:17 tom Exp $") -#ifdef __TANDEM -#define ROOT_UID 65535 -#endif +#define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c)) -#ifndef ROOT_UID -#define ROOT_UID 0 +#ifdef _NC_MSC +# define ACCESS(FN, MODE) access((FN), (MODE)&(R_OK|W_OK)) +#else +# define ACCESS access #endif -#define LOWERCASE(c) ((isalpha(UChar(c)) && isupper(UChar(c))) ? tolower(UChar(c)) : (c)) - NCURSES_EXPORT(char *) _nc_rootname(char *path) { @@ -61,7 +67,7 @@ _nc_rootname(char *path) result = temp; #if !MIXEDCASE_FILENAMES for (s = result; *s != '\0'; ++s) { - *s = LOWERCASE(*s); + *s = (char) LOWERCASE(*s); } #endif #if defined(PROG_EXT) @@ -116,24 +122,33 @@ _nc_basename(char *path) NCURSES_EXPORT(int) _nc_access(const char *path, int mode) { - if (access(path, mode) < 0) { + int result; + + if (path == 0) { + result = -1; + } else if (ACCESS(path, mode) < 0) { if ((mode & W_OK) != 0 && errno == ENOENT && strlen(path) < PATH_MAX) { char head[PATH_MAX]; - char *leaf = _nc_basename(strcpy(head, path)); + char *leaf; + _nc_STRCPY(head, path, sizeof(head)); + leaf = _nc_basename(head); if (leaf == 0) leaf = head; *leaf = '\0'; if (head == leaf) - (void) strcpy(head, "."); + _nc_STRCPY(head, ".", sizeof(head)); - return access(head, R_OK | W_OK | X_OK); + result = ACCESS(head, R_OK | W_OK | X_OK); + } else { + result = -1; } - return -1; + } else { + result = 0; } - return 0; + return result; } NCURSES_EXPORT(bool) @@ -143,7 +158,7 @@ _nc_is_dir_path(const char *path) struct stat sb; if (stat(path, &sb) == 0 - && (sb.st_mode & S_IFMT) == S_IFDIR) { + && S_ISDIR(sb.st_mode)) { result = TRUE; } return result; @@ -156,12 +171,38 @@ _nc_is_file_path(const char *path) struct stat sb; if (stat(path, &sb) == 0 - && (sb.st_mode & S_IFMT) == S_IFREG) { + && S_ISREG(sb.st_mode)) { result = TRUE; } 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 @@ -170,15 +211,50 @@ _nc_is_file_path(const char *path) 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 */