1 /*-------------------------------------------------------------------------
2  *
3  * File and directory permission routines
4  *
5  *
6  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * src/common/file_perm.c
10  *
11  *-------------------------------------------------------------------------
12  */
13 #include "c.h"
14 
15 #include "common/file_perm.h"
16 
17 /* Modes for creating directories and files in the data directory */
18 int			pg_dir_create_mode = PG_DIR_MODE_OWNER;
19 int			pg_file_create_mode = PG_FILE_MODE_OWNER;
20 
21 /*
22  * Mode mask to pass to umask().  This is more of a preventative measure since
23  * all file/directory creates should be performed using the create modes above.
24  */
25 int			pg_mode_mask = PG_MODE_MASK_OWNER;
26 
27 /*
28  * Set create modes and mask to use when writing to PGDATA based on the data
29  * directory mode passed.  If group read/execute are present in the mode, then
30  * create modes and mask will be relaxed to allow group read/execute on all
31  * newly created files and directories.
32  */
33 void
SetDataDirectoryCreatePerm(int dataDirMode)34 SetDataDirectoryCreatePerm(int dataDirMode)
35 {
36 	/* If the data directory mode has group access */
37 	if ((PG_DIR_MODE_GROUP & dataDirMode) == PG_DIR_MODE_GROUP)
38 	{
39 		pg_dir_create_mode = PG_DIR_MODE_GROUP;
40 		pg_file_create_mode = PG_FILE_MODE_GROUP;
41 		pg_mode_mask = PG_MODE_MASK_GROUP;
42 	}
43 	/* Else use default permissions */
44 	else
45 	{
46 		pg_dir_create_mode = PG_DIR_MODE_OWNER;
47 		pg_file_create_mode = PG_FILE_MODE_OWNER;
48 		pg_mode_mask = PG_MODE_MASK_OWNER;
49 	}
50 }
51 
52 #ifdef FRONTEND
53 
54 /*
55  * Get the create modes and mask to use when writing to PGDATA by examining the
56  * mode of the PGDATA directory and calling SetDataDirectoryCreatePerm().
57  *
58  * Errors are not handled here and should be reported by the application when
59  * false is returned.
60  *
61  * Suppress when on Windows, because there may not be proper support for Unix-y
62  * file permissions.
63  */
64 bool
GetDataDirectoryCreatePerm(const char * dataDir)65 GetDataDirectoryCreatePerm(const char *dataDir)
66 {
67 #if !defined(WIN32) && !defined(__CYGWIN__)
68 	struct stat statBuf;
69 
70 	/*
71 	 * If an error occurs getting the mode then return false.  The caller is
72 	 * responsible for generating an error, if appropriate, indicating that we
73 	 * were unable to access the data directory.
74 	 */
75 	if (stat(dataDir, &statBuf) == -1)
76 		return false;
77 
78 	/* Set permissions */
79 	SetDataDirectoryCreatePerm(statBuf.st_mode);
80 	return true;
81 #else							/* !defined(WIN32) && !defined(__CYGWIN__) */
82 	/*
83 	 * On Windows, we don't have anything to do here since they don't have
84 	 * Unix-y permissions.
85 	 */
86 	return true;
87 #endif
88 }
89 
90 
91 #endif							/* FRONTEND */
92