
Allow the cluster to be optionally init'd with read access for the group. This means a relatively non-privileged user can perform a backup of the cluster without requiring write privileges, which enhances security. The mode of PGDATA is used to determine whether group permissions are enabled for directory and file creates. This method was chosen as it's simple and works well for the various utilities that write into PGDATA. Changing the mode of PGDATA manually will not automatically change the mode of all the files contained therein. If the user would like to enable group access on an existing cluster then changing the mode of all the existing files will be required. Note that pg_upgrade will automatically change the mode of all migrated files if the new cluster is init'd with the -g option. Tests are included for the backend and all the utilities which operate on the PG data directory to ensure that the correct mode is set based on the data directory permissions. Author: David Steele <david@pgmasters.net> Reviewed-By: Michael Paquier, with discussion amongst many others. Discussion: https://postgr.es/m/ad346fe6-b23e-59f1-ecb7-0e08390ad629%40pgmasters.net
88 lines
2.5 KiB
C
88 lines
2.5 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* File and directory permission routines
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/common/file_perm.c
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#include <sys/stat.h>
|
|
|
|
#include "c.h"
|
|
#include "common/file_perm.h"
|
|
|
|
/* Modes for creating directories and files in the data directory */
|
|
int pg_dir_create_mode = PG_DIR_MODE_OWNER;
|
|
int pg_file_create_mode = PG_FILE_MODE_OWNER;
|
|
|
|
/*
|
|
* Mode mask to pass to umask(). This is more of a preventative measure since
|
|
* all file/directory creates should be performed using the create modes above.
|
|
*/
|
|
int pg_mode_mask = PG_MODE_MASK_OWNER;
|
|
|
|
/*
|
|
* Set create modes and mask to use when writing to PGDATA based on the data
|
|
* directory mode passed. If group read/execute are present in the mode, then
|
|
* create modes and mask will be relaxed to allow group read/execute on all
|
|
* newly created files and directories.
|
|
*/
|
|
void
|
|
SetDataDirectoryCreatePerm(int dataDirMode)
|
|
{
|
|
/* If the data directory mode has group access */
|
|
if ((PG_DIR_MODE_GROUP & dataDirMode) == PG_DIR_MODE_GROUP)
|
|
{
|
|
pg_dir_create_mode = PG_DIR_MODE_GROUP;
|
|
pg_file_create_mode = PG_FILE_MODE_GROUP;
|
|
pg_mode_mask = PG_MODE_MASK_GROUP;
|
|
}
|
|
/* Else use default permissions */
|
|
else
|
|
{
|
|
pg_dir_create_mode = PG_DIR_MODE_OWNER;
|
|
pg_file_create_mode = PG_FILE_MODE_OWNER;
|
|
pg_mode_mask = PG_MODE_MASK_OWNER;
|
|
}
|
|
}
|
|
|
|
#ifdef FRONTEND
|
|
|
|
/*
|
|
* Get the create modes and mask to use when writing to PGDATA by examining the
|
|
* mode of the PGDATA directory and calling SetDataDirectoryCreatePerm().
|
|
*
|
|
* Errors are not handled here and should be reported by the application when
|
|
* false is returned.
|
|
*
|
|
* Suppress when on Windows, because there may not be proper support for Unix-y
|
|
* file permissions.
|
|
*/
|
|
bool
|
|
GetDataDirectoryCreatePerm(const char *dataDir)
|
|
{
|
|
#if !defined(WIN32) && !defined(__CYGWIN__)
|
|
struct stat statBuf;
|
|
|
|
/*
|
|
* If an error occurs getting the mode then return false. The caller is
|
|
* responsible for generating an error, if appropriate, indicating that we
|
|
* were unable to access the data directory.
|
|
*/
|
|
if (stat(dataDir, &statBuf) == -1)
|
|
return false;
|
|
|
|
/* Set permissions */
|
|
SetDataDirectoryCreatePerm(statBuf.st_mode);
|
|
|
|
return true;
|
|
#endif /* !defined(WIN32) && !defined(__CYGWIN__) */
|
|
}
|
|
|
|
|
|
#endif /* FRONTEND */
|