Thread: [HACKERS] PATCH: Configurable file mode mask

[HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
PostgreSQL currently requires the file mode mask (umask) to be 0077.
However, this precludes the possibility of a user in the postgres group
performing a backup (or whatever).  Now that
pg_start_backup()/pg_stop_backup() privileges can be delegated to an
unprivileged user, it makes sense to also allow a (relatively)
unprivileged user to perform the backup at the file system level as well.

This patch introduces a new initdb param, -u/-file-mode-mask, and a new
GUC, file_mode_mask, to allow the default mode of files and directories
in the $PGDATA directory to be modified.

This obviously required mode changes in a number of places, so at the
same time the BasicOpenFile(), OpenTransientFile(), and
PathNameOpenFile() have been split into versions that either use the
default permissions or allow custom permissions.  In the end there was
only one call to the custom permission version (be-fsstubs.c:505) for
all three variants.

The following three calls (at the least) need to be reviewed:

bin/pg_dump/pg_backup_directory.c:194
src/port/mkdtemp.c:190
bin/pg_basebackup.c:599:655:1399

And this call needs serious consideration:

bin/pg_rewind/file_ops.c:214

Besides that there should be tests to make sure the masks are working as
expected and these could be added to the initdb TAP tests, though no
mask tests exist at this time.  Making sure all file operations produce
the correct modes would need to be placed in a new module, perhaps the
new backup tests proposed in [1].

Adam Brightwell developed the patch based on an initial concept by me
and Stephen Frost.  I added the refactoring in fd.c and some additional
documentation.

This patch applies cleanly on 016c990 but may fare badly over time due
to the number of files modified.

-- 
-David
david@pgmasters.net

[1]
https://www.postgresql.org/message-id/758e3fd1-45b4-5e28-75cd-e9e7f93a4c02@pgmasters.net

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Attachment

Re: [HACKERS] PATCH: Configurable file mode mask

From
Simon Riggs
Date:
On 1 March 2017 at 01:58, David Steele <david@pgmasters.net> wrote:
> PostgreSQL currently requires the file mode mask (umask) to be 0077.
> However, this precludes the possibility of a user in the postgres group
> performing a backup (or whatever).  Now that
> pg_start_backup()/pg_stop_backup() privileges can be delegated to an
> unprivileged user, it makes sense to also allow a (relatively)
> unprivileged user to perform the backup at the file system level as well.

+1

> This patch introduces a new initdb param, -u/-file-mode-mask, and a new
> GUC, file_mode_mask,

Why both initdb and at server start? Seems like initdb is OK, or in pg_control.

> to allow the default mode of files and directories
> in the $PGDATA directory to be modified.

Are you saying if this is changed all files/directories will be
changed to the new mode?

It seems like it would be annoying to have some files in one mode,
some in another.

-- 
Simon Riggs                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services



Re: [HACKERS] PATCH: Configurable file mode mask

From
Tom Lane
Date:
Simon Riggs <simon@2ndquadrant.com> writes:
> On 1 March 2017 at 01:58, David Steele <david@pgmasters.net> wrote:
>> PostgreSQL currently requires the file mode mask (umask) to be 0077.
>> However, this precludes the possibility of a user in the postgres group
>> performing a backup (or whatever).  Now that
>> pg_start_backup()/pg_stop_backup() privileges can be delegated to an
>> unprivileged user, it makes sense to also allow a (relatively)
>> unprivileged user to perform the backup at the file system level as well.

> +1

I'd ask what is the point, considering that we don't view "cp -a" as a
supported backup technique in the first place.
        regards, tom lane



Re: [HACKERS] PATCH: Configurable file mode mask

From
Robert Haas
Date:
On Mon, Mar 6, 2017 at 7:38 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Simon Riggs <simon@2ndquadrant.com> writes:
>> On 1 March 2017 at 01:58, David Steele <david@pgmasters.net> wrote:
>>> PostgreSQL currently requires the file mode mask (umask) to be 0077.
>>> However, this precludes the possibility of a user in the postgres group
>>> performing a backup (or whatever).  Now that
>>> pg_start_backup()/pg_stop_backup() privileges can be delegated to an
>>> unprivileged user, it makes sense to also allow a (relatively)
>>> unprivileged user to perform the backup at the file system level as well.
>
>> +1
>
> I'd ask what is the point, considering that we don't view "cp -a" as a
> supported backup technique in the first place.

/me is confused.

Surely the idea is that you'd like an unprivileged database user to
run pg_start_backup(), an operating system user that can read but not
write the database files to copy them, and then the unprivileged to
then run pg_stop_backup().  I have no opinion on the patch, but I
support the goal.  As I said on the surprisingly-controversial thread
about ripping out hard-coded superuser checks, reducing the level of
privilege which someone must have in order to perform a necessary
operation leads to better security.  An exclusive backup taken via the
filesystem (probably not via cp, but say via tar or cpio) inevitably
requires the backup user to be able to read the entire cluster
directory, but it doesn't inherently require the backup user to be
able to write the cluster directory.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: [HACKERS] PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Greetings,

* Simon Riggs (simon@2ndquadrant.com) wrote:
> On 1 March 2017 at 01:58, David Steele <david@pgmasters.net> wrote:
> > PostgreSQL currently requires the file mode mask (umask) to be 0077.
> > However, this precludes the possibility of a user in the postgres group
> > performing a backup (or whatever).  Now that
> > pg_start_backup()/pg_stop_backup() privileges can be delegated to an
> > unprivileged user, it makes sense to also allow a (relatively)
> > unprivileged user to perform the backup at the file system level as well.
>
> +1
>
> > This patch introduces a new initdb param, -u/-file-mode-mask, and a new
> > GUC, file_mode_mask,
>
> Why both initdb and at server start? Seems like initdb is OK, or in pg_control.

One could imagine someone wishing to change their mind regarding the
permissions after initdb, and for existing systems who may wish to move
to allowing group-read in an environment where that can be safely done
but don't wish to re-initdb.

> > to allow the default mode of files and directories
> > in the $PGDATA directory to be modified.
>
> Are you saying if this is changed all files/directories will be
> changed to the new mode?

No, new files will be created with the new mode and existing files will
be allowed to have the mode set.  Changing all of the existing files
didn't seem like something we should be trying to do at server start.

> It seems like it would be annoying to have some files in one mode,
> some in another.

It's not intended for that to happen, but it is possible for it to.  The
alternative is to try and forcibly change all files at server start time
to match what is configured but that didn't seem like a great idea.

Thanks!

Stephen

Re: [HACKERS] PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Tom,

* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> Simon Riggs <simon@2ndquadrant.com> writes:
> > On 1 March 2017 at 01:58, David Steele <david@pgmasters.net> wrote:
> >> PostgreSQL currently requires the file mode mask (umask) to be 0077.
> >> However, this precludes the possibility of a user in the postgres group
> >> performing a backup (or whatever).  Now that
> >> pg_start_backup()/pg_stop_backup() privileges can be delegated to an
> >> unprivileged user, it makes sense to also allow a (relatively)
> >> unprivileged user to perform the backup at the file system level as well.
>
> > +1
>
> I'd ask what is the point, considering that we don't view "cp -a" as a
> supported backup technique in the first place.

The point is to allow backups to be performed as a user who only has
read-only access to the files and is a non-superuser in the database.
With the changes to allow GRANT'ing of the pg_start/stop_backup and
related functions and these changes to allow the files to be group
readable, that will be possible using a tool such as pgbackrest, not
just with a "cp -a".

Thanks!

Stephen

Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/6/17 8:50 AM, Stephen Frost wrote:

> * Simon Riggs (simon@2ndquadrant.com) wrote:
>>> to allow the default mode of files and directories
>>> in the $PGDATA directory to be modified.
>>
>> Are you saying if this is changed all files/directories will be
>> changed to the new mode?
>
> No, new files will be created with the new mode and existing files will
> be allowed to have the mode set.  Changing all of the existing files
> didn't seem like something we should be trying to do at server start.
>
>> It seems like it would be annoying to have some files in one mode,
>> some in another.
>
> It's not intended for that to happen, but it is possible for it to.  The
> alternative is to try and forcibly change all files at server start time
> to match what is configured but that didn't seem like a great idea.

Agreed.  It would definitely affect server start time, perhaps
significantly.

I have added a note to the docs that a change in file_mode_mask does not
automatically change the mode of existing files on disk.

This patch applies cleanly on 6f3a13f.

--
-David
david@pgmasters.net

Attachment

Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/6/17 8:17 AM, Robert Haas wrote:
> On Mon, Mar 6, 2017 at 7:38 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> Simon Riggs <simon@2ndquadrant.com> writes:
>>> On 1 March 2017 at 01:58, David Steele <david@pgmasters.net> wrote:
>>>> PostgreSQL currently requires the file mode mask (umask) to be 0077.
>>>> However, this precludes the possibility of a user in the postgres group
>>>> performing a backup (or whatever).  Now that
>>>> pg_start_backup()/pg_stop_backup() privileges can be delegated to an
>>>> unprivileged user, it makes sense to also allow a (relatively)
>>>> unprivileged user to perform the backup at the file system level as well.
>>
>>> +1
>>
>> I'd ask what is the point, considering that we don't view "cp -a" as a
>> supported backup technique in the first place.
> 
> /me is confused.
> 
> Surely the idea is that you'd like an unprivileged database user to
> run pg_start_backup(), an operating system user that can read but not
> write the database files to copy them, and then the unprivileged to
> then run pg_stop_backup().  I have no opinion on the patch, but I
> support the goal.  As I said on the surprisingly-controversial thread
> about ripping out hard-coded superuser checks, reducing the level of
> privilege which someone must have in order to perform a necessary
> operation leads to better security.  An exclusive backup taken via the
> filesystem (probably not via cp, but say via tar or cpio) inevitably
> requires the backup user to be able to read the entire cluster
> directory, but it doesn't inherently require the backup user to be
> able to write the cluster directory.

Limiting privileges also serves to guard against any bugs in tools that
run directly against $PGDATA and do not require write privileges.

-- 
-David
david@pgmasters.net



Re: [HACKERS] PATCH: Configurable file mode mask

From
Peter Eisentraut
Date:
On 2/28/17 20:58, David Steele wrote:
> This patch introduces a new initdb param, -u/-file-mode-mask, and a new
> GUC, file_mode_mask, to allow the default mode of files and directories
> in the $PGDATA directory to be modified.

The postmaster.pid file appears not to observe the configured mask.

There ought to be a test, perhaps under src/bin/initdb/, to check for
that kind of thing.

There is no documentation update for initdb.

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services



Re: [HACKERS] PATCH: Configurable file mode mask

From
"Tsunakawa, Takayuki"
Date:
From: pgsql-hackers-owner@postgresql.org
> [mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of David Steele
> PostgreSQL currently requires the file mode mask (umask) to be 0077.
> However, this precludes the possibility of a user in the postgres group
> performing a backup (or whatever).  Now that
> pg_start_backup()/pg_stop_backup() privileges can be delegated to an
> unprivileged user, it makes sense to also allow a (relatively) unprivileged
> user to perform the backup at the file system level as well.

I'd like to help review this.  First, let me give some questions and comments.


1.What's the concrete use case of this feature?  Do you intend to extend the concept of multiple DBAs to the full range
ofadministration of a single database instance, or just multiple OS users for database backup?
 
If you think that multiple OS user support is desirable to reduce the administration burdon on a single person, then
isn'tthe automated backup sufficient (such as with cron)? 
 

2.Backup should always be considered with recovery.  If you allow another OS user to back up the database, can you
allowhim to recover the database as well?
 
For example, assume the PostgreSQL user account (the OS user who does initdb and pg_ctl start/stop) is dba1, and dba2
backsup the database using tar or cpio.
 
When dba2 restores the backup, the owner of the database cluster becomes dba2.  If the file permission only allows one
userto write the file, then dba1 can't start the instance.
 

3.The default location of the SSL key file is $PGDATA, so the permission of the key file is likely to become 0640.  But
thecurrent postgres requires it to be 0600.  See src/backend/libpq/be-secure-openssl.c.
 

4.I've seen a few users to place .pgpass file in $PGDATA and set the environment variable PGPASSFILE to point to it.
Theyexpect it to be back up with other database files.  So I'm afraid the permission of .pgpass file also becomes 0640
sometime.  However, the current code requires it to be 0600.  See src/interface/libpq/fe-connect.c.
 

5.I think some explanation about the concept of multiple OS users is necessary, such as here:

16.1. Short Version
https://www.postgresql.org/docs/devel/static/install-short.html

18.2. Creating a Database Cluster
https://www.postgresql.org/docs/devel/static/creating-cluster.html


[FYI]
Oracle instructs the user, during the software installation, to put "umask 022" in ~/.bashrc or so.
MySQL's files in the data directory appears to be 0640.

Regards
Takayuki Tsunakawa


Re: [HACKERS] PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Peter,

* Peter Eisentraut (peter.eisentraut@2ndquadrant.com) wrote:
> On 2/28/17 20:58, David Steele wrote:
> > This patch introduces a new initdb param, -u/-file-mode-mask, and a new
> > GUC, file_mode_mask, to allow the default mode of files and directories
> > in the $PGDATA directory to be modified.
>
> The postmaster.pid file appears not to observe the configured mask.

Good point, it should.

> There ought to be a test, perhaps under src/bin/initdb/, to check for
> that kind of thing.

Good idea.

> There is no documentation update for initdb.

Right, that needs to be fixed.

Thanks!

Stephen

Re: [HACKERS] PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Greetings,

* Tsunakawa, Takayuki (tsunakawa.takay@jp.fujitsu.com) wrote:
> From: pgsql-hackers-owner@postgresql.org
> > [mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of David Steele
> > PostgreSQL currently requires the file mode mask (umask) to be 0077.
> > However, this precludes the possibility of a user in the postgres group
> > performing a backup (or whatever).  Now that
> > pg_start_backup()/pg_stop_backup() privileges can be delegated to an
> > unprivileged user, it makes sense to also allow a (relatively) unprivileged
> > user to perform the backup at the file system level as well.
>
> I'd like to help review this.  First, let me give some questions and comments.

Great!

> 1.What's the concrete use case of this feature?  Do you intend to extend the concept of multiple DBAs to the full
rangeof administration of a single database instance, or just multiple OS users for database backup? 

This is to allow a non-postgres user to perform a backup of the
database.  Perhaps this could be leveraged for other administration
functions, but it's not clear how off-hand to me and the backup use-case
is the reason for adding this.

> If you think that multiple OS user support is desirable to reduce the administration burdon on a single person, then
isn'tthe automated backup sufficient (such as with cron)?  

I'm not quite sure what the question here is, but it is desirable to
minimize the amount of access any process requires to only that which is
required to perform its duties.  In the case of backup, only read access
to the data directory and access to connect to PG and run certain
functions is required.  The ability to run those functions as a
non-superuser was added in 9.6, this continues the work to minimize what
a backup user needs to perform a backup of the system by allowing a user
to have only read-only access to the data directory.

There are multiple reasons why matching the privileges a process has to
only that which is required is good practice.  Minimizing impact to
ongoing operations from a compromise of the backup user and reducing the
risk that bugs in backup software could disrupt operations are two of
those.

> 2.Backup should always be considered with recovery.  If you allow another OS user to back up the database, can you
allowhim to recover the database as well? 

That would not be our recommended approach, but it would be possible to
do.  Our recommended solution is for the backup user to only be able to
perform the backup.  In this use-case, the restore would be run by the
OS user who owns the database (eg: postgres), who would have read-only
access to the backup repository.

To be clear, this is not hypothetical, pgBackrest supports these
configurations and has been tested with this approach.  As noted, there
are a few additional items that need to be addressed which weren't
covered in the initial testing (on Debian-based systems, the pid file
and SSL key aren't in the data directory, so they didn't pose a problem,
but they should be addressed so that this can work on other
distributions).

> For example, assume the PostgreSQL user account (the OS user who does initdb and pg_ctl start/stop) is dba1, and dba2
backsup the database using tar or cpio. 
> When dba2 restores the backup, the owner of the database cluster becomes dba2.  If the file permission only allows
oneuser to write the file, then dba1 can't start the instance. 

If the uesr chose to configure the system with both dba1 and dba2 having
write access to the data directory, performing a restore as dba2 would
be possible and the backup utility could be sure to remove all existing
files and restore them from the backup, ensuring that all of the files
would be owned by a single user (dba2 in this case).  Of course, one
would then need to adjust the startup process to run as dba2 instead.

With group write access to all of the files and directories, it may be
possible to actually run with the dba1 user even though the files are
owned by dba2, but we would not recommend it as the result would be a
mix of files owned by one dba or the other.  This is not the use-case
this is being developed for.

> 3.The default location of the SSL key file is $PGDATA, so the permission of the key file is likely to become 0640.
Butthe current postgres requires it to be 0600.  See src/backend/libpq/be-secure-openssl.c. 

Yes, that needs to be addressed.  There was discussion on another thread
that it would be useful to support the SSL key file having group read
access, but since this patch is handling the other files it seems like
it would make sense to do that change here also.

> 4.I've seen a few users to place .pgpass file in $PGDATA and set the environment variable PGPASSFILE to point to it.
Theyexpect it to be back up with other database files.  So I'm afraid the permission of .pgpass file also becomes 0640
sometime.  However, the current code requires it to be 0600.  See src/interface/libpq/fe-connect.c. 

This is not a configuration which we would recommend (generally
speaking, it's not really a good idea to drop random files into
$PGDATA).  That said, there was discussion on another thread about
supporting this with an explicit client-side option to allow it.  That
would be independent from this patch, I believe.

> 5.I think some explanation about the concept of multiple OS users is necessary, such as here:
>
> 16.1. Short Version
> https://www.postgresql.org/docs/devel/static/install-short.html
>
> 18.2. Creating a Database Cluster
> https://www.postgresql.org/docs/devel/static/creating-cluster.html

I agree that we should update the documention for this, including those.

> [FYI]
> Oracle instructs the user, during the software installation, to put "umask 022" in ~/.bashrc or so.
> MySQL's files in the data directory appears to be 0640.

When it comes to MySQL, at least, this may be distribution dependent.
In any case, it's good to see that we are not the only ones doing this.

Thanks!

Stephen

Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/10/17 8:12 AM, Stephen Frost wrote:
> Peter,
>
> * Peter Eisentraut (peter.eisentraut@2ndquadrant.com) wrote:
>> On 2/28/17 20:58, David Steele wrote:
>>> This patch introduces a new initdb param, -u/-file-mode-mask, and a new
>>> GUC, file_mode_mask, to allow the default mode of files and directories
>>> in the $PGDATA directory to be modified.
>>
>> The postmaster.pid file appears not to observe the configured mask.
>
> Good point, it should.

Leaving the mask on this file as-is was intentional.  At miscinit.c:829:

/* Think not to make the file protection weaker than 0600.  See comments
below. */

At miscinit.c:893:

/* We can treat the EPERM-error case as okay because that error implies
that the existing process has a different userid than we do, which means
it cannot be a competing postmaster.  A postmaster cannot successfully
attach to a data directory owned by a userid other than its own.  (This
is now checked directly in checkDataDir(), but has been true for a long
time because of the restriction that the data directory isn't group- or
world-accessible.)  Also, since we create the lockfiles mode 600, we'd
have failed above if the lockfile belonged to another userid --- which
means that whatever process kill() is reporting about isn't the one that
made the lockfile.  (NOTE: this last consideration is the only one that
keeps us from blowing away a Unix socket file belonging to an instance
of Postgres being run by someone else, at least on machines where /tmp
hasn't got a stickybit.) */

I can't see why this explanation does not continue to hold even if
permissions for other files are changed.  For the use cases I envision,
I don't think being able to read/manipulate postmaster.pid is important,
only to detect that it is present.

>> There ought to be a test, perhaps under src/bin/initdb/, to check for
>> that kind of thing.
>
> Good idea.

Agreed, will add to next patch.

> >> There is no documentation update for initdb.

The --file-mode-mask option was added to the option list, but you are
probably referring to a paragraph under description.  Will add to the
next patch.

--
-David
david@pgmasters.net


Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/10/17 8:34 AM, Stephen Frost wrote:
> Greetings,
>
> * Tsunakawa, Takayuki (tsunakawa.takay@jp.fujitsu.com) wrote:
>> From: pgsql-hackers-owner@postgresql.org
>>> [mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of David Steele
>>> PostgreSQL currently requires the file mode mask (umask) to be 0077.
>>> However, this precludes the possibility of a user in the postgres group
>>> performing a backup (or whatever).  Now that
>>> pg_start_backup()/pg_stop_backup() privileges can be delegated to an
>>> unprivileged user, it makes sense to also allow a (relatively) unprivileged
>>> user to perform the backup at the file system level as well.
>>
>> I'd like to help review this.  First, let me give some questions and comments.

Much appreciated!

>> 3.The default location of the SSL key file is $PGDATA, so the permission of the key file is likely to become 0640.
Butthe current postgres requires it to be 0600.  See src/backend/libpq/be-secure-openssl.c. 
>
> Yes, that needs to be addressed.  There was discussion on another thread
> that it would be useful to support the SSL key file having group read
> access, but since this patch is handling the other files it seems like
> it would make sense to do that change here also.

Perhaps, but since these files are not setup by initdb I'm not sure if
we should be handling their permissions.  This seems to be a
distro-specific issue.

It seems to me that it would be best to advise in the docs that these
files should be relocated if they won't be readable by the backup user.
In any event, I'm not convinced that backing up server private keys is a
good idea.

>> 5.I think some explanation about the concept of multiple OS users is necessary, such as here:
>>
>> 16.1. Short Version
>> https://www.postgresql.org/docs/devel/static/install-short.html
>>
>> 18.2. Creating a Database Cluster
>> https://www.postgresql.org/docs/devel/static/creating-cluster.html
>
> I agree that we should update the documention for this, including those.

We'll add that to the next patch.

Thanks,
--
-David
david@pgmasters.net


Re: [HACKERS] PATCH: Configurable file mode mask

From
Tom Lane
Date:
David Steele <david@pgmasters.net> writes:
> At miscinit.c:893:

> /* We can treat the EPERM-error case as okay because that error implies
> that the existing process has a different userid than we do, which means
> it cannot be a competing postmaster.  A postmaster cannot successfully
> attach to a data directory owned by a userid other than its own.  (This
> is now checked directly in checkDataDir(), but has been true for a long
> time because of the restriction that the data directory isn't group- or
> world-accessible.)  Also, since we create the lockfiles mode 600, we'd
> have failed above if the lockfile belonged to another userid --- which
> means that whatever process kill() is reporting about isn't the one that
> made the lockfile.  (NOTE: this last consideration is the only one that
> keeps us from blowing away a Unix socket file belonging to an instance
> of Postgres being run by someone else, at least on machines where /tmp
> hasn't got a stickybit.) */

TBH, the fact that we're relying on 0600 mode for considerations such
as these makes me tremendously afraid of this whole patch.  I think that
the claimed advantages are not anywhere near worth the risk that somebody
is going to destroy their database because we weakened some aspect of the
protection against starting multiple postmasters in a database directory.

At the very least, I'd want to see much closer analysis of the safety
issues than I've seen so far in this thread.  And since the proposed
patch falsifies the above-quoted comment (and probably others), why
hasn't it updated it?
        regards, tom lane



Re: [HACKERS] PATCH: Configurable file mode mask

From
Tom Lane
Date:
... oh, and now that I've actually looked at the patch, I think it's
a seriously bad idea to proceed by removing the mode parameter to
PathNameOpenFile et al.  That's basically doubling down on an assumption
that there are NO places in the backend, and never will be any, in which
we want to create files with nondefault permissions.  That assumption
seems broken on its face.  It also makes the patch exceedingly invasive
for extensions.
        regards, tom lane



Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Tom,

On 3/13/17 1:13 PM, Tom Lane wrote:
> ... oh, and now that I've actually looked at the patch, I think it's
> a seriously bad idea to proceed by removing the mode parameter to
> PathNameOpenFile et al.  That's basically doubling down on an assumption
> that there are NO places in the backend, and never will be any, in which
> we want to create files with nondefault permissions.  That assumption
> seems broken on its face.  It also makes the patch exceedingly invasive
> for extensions.

I think it's a bad idea to have the same parameters copied over and over
throughout the code with slight variations (e.g. 0600 vs S_IRUSR |
S_IWUSR) but the same intent.

In all cases there is another version of the function (added by this
patch) that accepts a mode parameter.  In practice this was only needed
in one place, be_lo_export().  I think this makes a pretty good argument
for standardization/simplification in other areas.

Thanks,
-- 
-David
david@pgmasters.net



Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Tom,

On 3/13/17 1:03 PM, Tom Lane wrote:
> David Steele <david@pgmasters.net> writes:
>> At miscinit.c:893:
> 
>> /* We can treat the EPERM-error case as okay because that error implies
>> that the existing process has a different userid than we do, which means
>> it cannot be a competing postmaster.  A postmaster cannot successfully
>> attach to a data directory owned by a userid other than its own.  (This
>> is now checked directly in checkDataDir(), but has been true for a long
>> time because of the restriction that the data directory isn't group- or
>> world-accessible.)  Also, since we create the lockfiles mode 600, we'd
>> have failed above if the lockfile belonged to another userid --- which
>> means that whatever process kill() is reporting about isn't the one that
>> made the lockfile.  (NOTE: this last consideration is the only one that
>> keeps us from blowing away a Unix socket file belonging to an instance
>> of Postgres being run by someone else, at least on machines where /tmp
>> hasn't got a stickybit.) */
> 
> TBH, the fact that we're relying on 0600 mode for considerations such
> as these makes me tremendously afraid of this whole patch.  I think that
> the claimed advantages are not anywhere near worth the risk that somebody
> is going to destroy their database because we weakened some aspect of the
> protection against starting multiple postmasters in a database directory.

I don't see a risk if the user uses umask 0027 which is the example
given in the docs.  I'm happy to change this example to a strong
recommendation.

> At the very least, I'd want to see much closer analysis of the safety
> issues than I've seen so far in this thread.  

I think it's clear that there would be safety risks with unwise umask
choices.  I also think the example/recommended umask is safe.

Running external processes as the postgres user carries serious risks as
well.  Not only with regards to data access but the danger of corruption
due to bugs.  If a process does not require write access to do its job
then why take that risk?

To (hopefully) address your concerns, I'll perform an analysis of
starting multiple postmasters with a variety of umask choices and report
the outcomes here.

> And since the proposed
> patch falsifies the above-quoted comment (and probably others), why
> hasn't it updated it?

That was an oversight on my part.  I'll update it in the next patch.

Thanks,
-- 
-David
david@pgmasters.net



Re: [HACKERS] PATCH: Configurable file mode mask

From
Tom Lane
Date:
David Steele <david@pgmasters.net> writes:
> On 3/13/17 1:03 PM, Tom Lane wrote:
>> TBH, the fact that we're relying on 0600 mode for considerations such
>> as these makes me tremendously afraid of this whole patch.  I think that
>> the claimed advantages are not anywhere near worth the risk that somebody
>> is going to destroy their database because we weakened some aspect of the
>> protection against starting multiple postmasters in a database directory.

> I don't see a risk if the user uses umask 0027 which is the example
> given in the docs.  I'm happy to change this example to a strong
> recommendation.

I do not want a "strong recommendation".  I want "we don't let you
break this".  We don't let you run the postmaster as root either,
even though there have been repeated requests to remove that safety
check.

It might be all right if we forcibly or'd 027 into whatever umask
the user tries to provide; not sure.  The existing safety analysis,
such as the cited comment, has all been based on the assumption of
file mode 600 not mode 640.  I'm not certain that we always attempt
to open-for-writing files that we expect to be exclusively accessible
by the postmaster.

Anyway, given that we do that analysis, I'd rather not expose this
as a "here, set the umask you want" variable.  I think a bool saying
"allow group access" (translating to exactly two supported umasks,
027 and 077) would be simpler from the user's standpoint and much
easier to reason about.  I don't see the value in having to think
about what happens if the user supplies a mask like 037 or 067.

I also don't especially want to have to analyze cases like "what
happens if user initdb'd with mask X but then changes the GUC and
restarts the postmaster?".  Maybe the right thing is to not expose
this as a GUC at all, but drive it off the permissions observed on
the data directory at postmaster start.  Viz:

* $PGDATA has permissions 0700: adopt umask 077

* $PGDATA has permissions 0750: adopt umask 027

* anything else: fail

That way, a "chmod -R" would be the necessary and sufficient procedure
for switching from one case to the other.
        regards, tom lane



Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/13/17 2:16 PM, Tom Lane wrote:
> David Steele <david@pgmasters.net> writes:
>> On 3/13/17 1:03 PM, Tom Lane wrote:
>>> TBH, the fact that we're relying on 0600 mode for considerations such
>>> as these makes me tremendously afraid of this whole patch.  I think that
>>> the claimed advantages are not anywhere near worth the risk that somebody
>>> is going to destroy their database because we weakened some aspect of the
>>> protection against starting multiple postmasters in a database directory.
> 
>> I don't see a risk if the user uses umask 0027 which is the example
>> given in the docs.  I'm happy to change this example to a strong
>> recommendation.

<...>

> Anyway, given that we do that analysis, I'd rather not expose this
> as a "here, set the umask you want" variable.  I think a bool saying
> "allow group access" (translating to exactly two supported umasks,
> 027 and 077) would be simpler from the user's standpoint and much
> easier to reason about.  I don't see the value in having to think
> about what happens if the user supplies a mask like 037 or 067.

We debated a flag vs a umask and came down on the side of flexibility.
I'm perfectly happy with using a flag instead.

> I also don't especially want to have to analyze cases like "what
> happens if user initdb'd with mask X but then changes the GUC and
> restarts the postmaster?".  Maybe the right thing is to not expose
> this as a GUC at all, but drive it off the permissions observed on
> the data directory at postmaster start.  Viz:
> 
> * $PGDATA has permissions 0700: adopt umask 077
> 
> * $PGDATA has permissions 0750: adopt umask 027
> 
> * anything else: fail

How about a GUC, allow_group_access, that when set will enforce
permissions and set the umask accordingly, and when not set will follow
$PGDATA as proposed above?

Not much we can do for Windows, though.  I think it would have to WARN
if the GUC is set and then continue as usual.

> That way, a "chmod -R" would be the necessary and sufficient procedure
> for switching from one case to the other.

I'm OK with that if you think it's the best course, but perhaps the GUC
would be better because it can detect accidental permission changes.

-- 
-David
david@pgmasters.net



Re: [HACKERS] PATCH: Configurable file mode mask

From
Tom Lane
Date:
David Steele <david@pgmasters.net> writes:
> On 3/13/17 2:16 PM, Tom Lane wrote:
>> I also don't especially want to have to analyze cases like "what
>> happens if user initdb'd with mask X but then changes the GUC and
>> restarts the postmaster?".  Maybe the right thing is to not expose
>> this as a GUC at all, but drive it off the permissions observed on
>> the data directory at postmaster start.  Viz:
>> 
>> * $PGDATA has permissions 0700: adopt umask 077
>> 
>> * $PGDATA has permissions 0750: adopt umask 027
>> 
>> * anything else: fail

> How about a GUC, allow_group_access, that when set will enforce
> permissions and set the umask accordingly, and when not set will follow
> $PGDATA as proposed above?

Seems overcomplicated ...

> Not much we can do for Windows, though.  I think it would have to WARN
> if the GUC is set and then continue as usual.

Yeah, the Windows port has been weak in this area all along.  I don't
think it's incumbent on you to make it better.

>> That way, a "chmod -R" would be the necessary and sufficient procedure
>> for switching from one case to the other.

> I'm OK with that if you think it's the best course, but perhaps the GUC
> would be better because it can detect accidental permission changes.

If we're only checking file permissions at postmaster start, I think it's
illusory to suppose that we're offering very much protection against
accidental changes.  A chmod applied while the postmaster is running
could still break things, and we'd not notice till the next restart.

But it might be worth thinking about whether we want to encourage people
to do manual chmod's at all; that's fairly easy to get wrong, particularly
given the difference in X bits that should be applied to files and
directories.  Another approach that could be worth considering is
a PGC_POSTMASTER GUC with just two states (group access or not) and
make it the postmaster's responsibility to do the equivalent of chmod -R
to make the file tree match the GUC.  I think we do a tree scan anyway
for other purposes, so correcting any wrong file permissions might not
be much added work in the normal case.
        regards, tom lane



Re: [HACKERS] PATCH: Configurable file mode mask

From
"Tsunakawa, Takayuki"
Date:
From: David Steele [mailto:david@pgmasters.net]
> >> 3.The default location of the SSL key file is $PGDATA, so the permission
> of the key file is likely to become 0640.  But the current postgres requires
> it to be 0600.  See src/backend/libpq/be-secure-openssl.c.
> >
> > Yes, that needs to be addressed.  There was discussion on another
> > thread that it would be useful to support the SSL key file having
> > group read access, but since this patch is handling the other files it
> > seems like it would make sense to do that change here also.
> 
> Perhaps, but since these files are not setup by initdb I'm not sure if we
> should be handling their permissions.  This seems to be a distro-specific
> issue.
> 
> It seems to me that it would be best to advise in the docs that these files
> should be relocated if they won't be readable by the backup user.
> In any event, I'm not convinced that backing up server private keys is a
> good idea.

Maybe so, but it's convenient to be able to store the key and certificate files in $PGDATA and back them up together.
Ifthe database backup were stolen through the compromised backup OS user, then the malicious person can read the data
anywayregardless of whether the key file is there or not.  That's because the key is not for encrypting data at rest.
 

Related to this, please see:

https://www.postgresql.org/docs/devel/static/ssl-tcp.html

"On Unix systems, the permissions on server.key must disallow any access to world or group; achieve this by the command
chmod0600 server.key. Alternatively, the file can be owned by root and have group read access (that is, 0640
permissions).That setup is intended for installations where certificate and key files are managed by the operating
system.The user under which the PostgreSQL server runs should then be made a member of the group that has access to
thosecertificate and key files."
 

In the latter case, the file owner is root and the permission is 0640.  At first I was a bit confused and misunderstood
thatthe PostgreSQL user account and the backup OS user needs to belong to the same OS group.  But that's not the case.
Thegroup of the key file can be, for example, "ssl_cert", the PostgreSQL user account belongs to the OS group
"ssl_cert"and "dba", and the backup OS user only belongs to "backup."  This can prevent the backup OS user from reading
thekey file.  I think it would be better to have some explanation with examples in the above section.
 


Regards
Takayuki Tsunakawa






Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/14/17 4:23 AM, Tsunakawa, Takayuki wrote:
> From: David Steele [mailto:david@pgmasters.net]
>>>> 3.The default location of the SSL key file is $PGDATA, so the permission
>> of the key file is likely to become 0640.  But the current postgres requires
>> it to be 0600.  See src/backend/libpq/be-secure-openssl.c.
>>>
>>> Yes, that needs to be addressed.  There was discussion on another
>>> thread that it would be useful to support the SSL key file having
>>> group read access, but since this patch is handling the other files it
>>> seems like it would make sense to do that change here also.
>>
>> Perhaps, but since these files are not setup by initdb I'm not sure if we
>> should be handling their permissions.  This seems to be a distro-specific
>> issue.
>>
>> It seems to me that it would be best to advise in the docs that these files
>> should be relocated if they won't be readable by the backup user.
>> In any event, I'm not convinced that backing up server private keys is a
>> good idea.
> 
> Maybe so, but it's convenient to be able to store the key and certificate files in $PGDATA and back them up together.
If the database backup were stolen through the compromised backup OS user, then the malicious person can read the data
anywayregardless of whether the key file is there or not.  That's because the key is not for encrypting data at rest.
 

Sure, but having the private key may allow them to get new data from the
server as well as the data from the backup.

To be clear, the default for this patch is to leave permissions exactly
as they are now.  It also provides alternatives that may or not be
useful in all cases.

> Related to this, please see:
> 
> https://www.postgresql.org/docs/devel/static/ssl-tcp.html
> 
> "On Unix systems, the permissions on server.key must disallow any access to world or group; achieve this by the
commandchmod 0600 server.key. Alternatively, the file can be owned by root and have group read access (that is, 0640
permissions).That setup is intended for installations where certificate and key files are managed by the operating
system.The user under which the PostgreSQL server runs should then be made a member of the group that has access to
thosecertificate and key files."
 
> 
> In the latter case, the file owner is root and the permission is 0640.  At first I was a bit confused and
misunderstoodthat the PostgreSQL user account and the backup OS user needs to belong to the same OS group.  But that's
notthe case.  The group of the key file can be, for example, "ssl_cert", the PostgreSQL user account belongs to the OS
group"ssl_cert" and "dba", and the backup OS user only belongs to "backup."  This can prevent the backup OS user from
readingthe key file.  I think it would be better to have some explanation with examples in the above section.
 

If the backup user is in the same group as the postgres user and in the
ssl_cert group then backups of the certs would be possible using group
reads.  Restores will be a little tricky, though, because of the need to
set ownership to root.  The restore would need to be run as root or the
permissions fixed up after the restore completes.

-- 
-David
david@pgmasters.net



Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/13/17 3:03 PM, Tom Lane wrote:
> David Steele <david@pgmasters.net> writes:
>> On 3/13/17 2:16 PM, Tom Lane wrote:
>>> I also don't especially want to have to analyze cases like "what
>>> happens if user initdb'd with mask X but then changes the GUC and
>>> restarts the postmaster?".  Maybe the right thing is to not expose
>>> this as a GUC at all, but drive it off the permissions observed on
>>> the data directory at postmaster start.  Viz:
>>>
>>> * $PGDATA has permissions 0700: adopt umask 077
>>>
>>> * $PGDATA has permissions 0750: adopt umask 027
>>>
>>> * anything else: fail
> 
>> How about a GUC, allow_group_access, that when set will enforce
>> permissions and set the umask accordingly, and when not set will follow
>> $PGDATA as proposed above?
> 
> Seems overcomplicated ...

Yeah.  It wouldn't be a lot of fun to document, that's for sure.

>>> That way, a "chmod -R" would be the necessary and sufficient procedure
>>> for switching from one case to the other.
> 
>> I'm OK with that if you think it's the best course, but perhaps the GUC
>> would be better because it can detect accidental permission changes.
> 
> If we're only checking file permissions at postmaster start, I think it's
> illusory to suppose that we're offering very much protection against
> accidental changes.  A chmod applied while the postmaster is running
> could still break things, and we'd not notice till the next restart.

Fair enough.

> But it might be worth thinking about whether we want to encourage people
> to do manual chmod's at all; that's fairly easy to get wrong, particularly
> given the difference in X bits that should be applied to files and
> directories.  Another approach that could be worth considering is
> a PGC_POSTMASTER GUC with just two states (group access or not) and
> make it the postmaster's responsibility to do the equivalent of chmod -R
> to make the file tree match the GUC.  I think we do a tree scan anyway
> for other purposes, so correcting any wrong file permissions might not
> be much added work in the normal case.

The majority of scanning is done in recovery (to find and remove
unlogged tables) and I'm not sure we would want to add that overhead to
normal startup.

-- 
-David
david@pgmasters.net



Re: [HACKERS] PATCH: Configurable file mode mask

From
"Tsunakawa, Takayuki"
Date:
From: pgsql-hackers-owner@postgresql.org
> [mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of David Steele
> Sure, but having the private key may allow them to get new data from the
> server as well as the data from the backup.

You are right.  My rough intent was that the data is stolen anyway.  So, I thought it might not be so bad to expect to
beable to back up the SSL key file in $PGDATA together with the database.  If it's bad, then the default value of
ssl_key_file(=$PGDATA/ssl.key) should be disallowed.
 


> > https://www.postgresql.org/docs/devel/static/ssl-tcp.html
> >
> > "On Unix systems, the permissions on server.key must disallow any access
> to world or group; achieve this by the command chmod 0600 server.key.
> Alternatively, the file can be owned by root and have group read access
> (that is, 0640 permissions). That setup is intended for installations where
> certificate and key files are managed by the operating system. The user
> under which the PostgreSQL server runs should then be made a member of the
> group that has access to those certificate and key files."
> >
> > In the latter case, the file owner is root and the permission is 0640.
> At first I was a bit confused and misunderstood that the PostgreSQL user
> account and the backup OS user needs to belong to the same OS group.  But
> that's not the case.  The group of the key file can be, for example,
> "ssl_cert", the PostgreSQL user account belongs to the OS group "ssl_cert"
> and "dba", and the backup OS user only belongs to "backup."  This can prevent
> the backup OS user from reading the key file.  I think it would be better
> to have some explanation with examples in the above section.
> 
> If the backup user is in the same group as the postgres user and in the
> ssl_cert group then backups of the certs would be possible using group reads.
> Restores will be a little tricky, though, because of the need to set
> ownership to root.  The restore would need to be run as root or the
> permissions fixed up after the restore completes.

Yes, but I thought, from the following message,  that you do not recommend that the backup user be able to read the SSL
keyfile.  So, I proposed to describe the example configuration to achieve that -- postgres user in dba and ssl_cert
group,and a separate backup user in only dba group.
 

> >> It seems to me that it would be best to advise in the docs that these
> >> files should be relocated if they won't be readable by the backup user.
> >> In any event, I'm not convinced that backing up server private keys
> >> is a good idea.


> To be clear, the default for this patch is to leave permissions exactly
> as they are now.  It also provides alternatives that may or not be useful
> in all cases.

So you think there are configurations that may be useful or not, don't you?  Adding a new parameter could possibly
complicatewhat users have to consider.  Maximal flexibility could lead to insecure misuse.  So I think it would be
betterto describe secure and practical configuration examples in the SSL section and/or the backup chapter.  The
configurationfactor includes whether the backup user is different from the postgres user, where the SSL key file is
placed,the owner of the SSL key file, whether the backup user can read the SSL key file.
 

Regards
Takayuki Tsunakawa







Re: [HACKERS] PATCH: Configurable file mode mask

From
"Tsunakawa, Takayuki"
Date:
From: pgsql-hackers-owner@postgresql.org
> [mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of David Steele
> > But it might be worth thinking about whether we want to encourage
> > people to do manual chmod's at all; that's fairly easy to get wrong,
> > particularly given the difference in X bits that should be applied to
> > files and directories.  Another approach that could be worth
> > considering is a PGC_POSTMASTER GUC with just two states (group access
> > or not) and make it the postmaster's responsibility to do the
> > equivalent of chmod -R to make the file tree match the GUC.  I think
> > we do a tree scan anyway for other purposes, so correcting any wrong
> > file permissions might not be much added work in the normal case.
> 
> The majority of scanning is done in recovery (to find and remove unlogged
> tables) and I'm not sure we would want to add that overhead to normal startup.

I'm on David's side, too.  I don't postmaster to always scan all files at startup.

On the other hand, just doing "chmod -R $PGDATA" is not enough, because chmod doesn't follow the symbolic links.
Symboliclinks are used for pg_tblspc/* and pg_wal at least.  FYI, MySQL's manual describes the pithole like this:
 

https://dev.mysql.com/doc/refman/8.0/en/changing-mysql-user.html
----------------------------------------
2. Change the database directories and files so that user_name has privileges to read and write files in them (you
mightneed to do this as the Unix root user): 
 
shell> chown -R user_name /path/to/mysql/datadir


If you do not do this, the server will not be able to access databases or tables when it runs as user_name. 

If directories or files within the MySQL data directory are symbolic links, chown -R might not follow symbolic links
foryou. If it does not, you will also need to follow those links and change the directories and files they point to. 
 
----------------------------------------


I think we also need to describe the procedure carefully.  That said, it would be best to make users aware of a
configurationalternative (group access) with enough documentation when they first build the database or upgrade the
databasecluster.  Just describing the alternative only in initdb reference page would result in being unaware of the
betterconfiguration, like --data-checksum.
 

Regards
Takayuki Tsunakawa








Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/15/17 1:56 AM, Tsunakawa, Takayuki wrote:
> From: pgsql-hackers-owner@postgresql.org
>> [mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of David Steele
>> Sure, but having the private key may allow them to get new data from the
>> server as well as the data from the backup.
> 
> You are right.  My rough intent was that the data is stolen anyway.  So, I thought it might not be so bad to expect
tobe able to back up the SSL key file in $PGDATA together with the database.  If it's bad, then the default value of
ssl_key_file(=$PGDATA/ssl.key) should be disallowed.
 

I think it really depends on the situation and the user needs to make an
evaluation of the security risks for themselves.

>> If the backup user is in the same group as the postgres user and in the
>> ssl_cert group then backups of the certs would be possible using group reads.
>> Restores will be a little tricky, though, because of the need to set
>> ownership to root.  The restore would need to be run as root or the
>> permissions fixed up after the restore completes.
> 
> Yes, but I thought, from the following message,  that you do not recommend that the backup user be able to read the
SSLkey file.  So, I proposed to describe the example configuration to achieve that -- postgres user in dba and ssl_cert
group,and a separate backup user in only dba group.
 

That would work as long as the key was not in $PGDATA.  Most database
backup software does not have a --ignore option because of the obvious
dangers.

>>>> It seems to me that it would be best to advise in the docs that these
>>>> files should be relocated if they won't be readable by the backup user.
>>>> In any event, I'm not convinced that backing up server private keys
>>>> is a good idea.
> 
>> To be clear, the default for this patch is to leave permissions exactly
>> as they are now.  It also provides alternatives that may or not be useful
>> in all cases.
> 
> So you think there are configurations that may be useful or not, don't you?  Adding a new parameter could possibly
complicatewhat users have to consider.  Maximal flexibility could lead to insecure misuse.  So I think it would be
betterto describe secure and practical configuration examples in the SSL section and/or the backup chapter.  The
configurationfactor includes whether the backup user is different from the postgres user, where the SSL key file is
placed,the owner of the SSL key file, whether the backup user can read the SSL key file.
 

I think we are more or less on the same page, and you'd like to see
documentation that shows examples of secure configurations when group
access is allow.  I agree and I'm working on documentation for all the
sections you recommended.

Thanks,
-- 
-David
david@pgmasters.net



Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/15/17 3:00 AM, Tsunakawa, Takayuki wrote:
> From: pgsql-hackers-owner@postgresql.org
>> [mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of David Steele
>>> But it might be worth thinking about whether we want to encourage
>>> people to do manual chmod's at all; that's fairly easy to get wrong,
>>> particularly given the difference in X bits that should be applied to
>>> files and directories.  Another approach that could be worth
>>> considering is a PGC_POSTMASTER GUC with just two states (group access
>>> or not) and make it the postmaster's responsibility to do the
>>> equivalent of chmod -R to make the file tree match the GUC.  I think
>>> we do a tree scan anyway for other purposes, so correcting any wrong
>>> file permissions might not be much added work in the normal case.
>>
>> The majority of scanning is done in recovery (to find and remove unlogged
>> tables) and I'm not sure we would want to add that overhead to normal startup.
> 
> I'm on David's side, too.  I don't postmaster to always scan all files at startup.
> 
> On the other hand, just doing "chmod -R $PGDATA" is not enough, because chmod doesn't follow the symbolic links.
Symboliclinks are used for pg_tblspc/* and pg_wal at least.  FYI, MySQL's manual describes the pithole like this:
 

Good point - I think we'll need to add that to the docs as well.

> I think we also need to describe the procedure carefully.  That said, it would be best to make users aware of a
configurationalternative (group access) with enough documentation when they first build the database or upgrade the
databasecluster.  Just describing the alternative only in initdb reference page would result in being unaware of the
betterconfiguration, like --data-checksum.
 

I'm working on a new approach incorporating everybody's suggestions and
enhanced documentation.  It should be ready on Monday.

-- 
-David
david@pgmasters.net



Re: [HACKERS] PATCH: Configurable file mode mask

From
Robert Haas
Date:
On Wed, Mar 15, 2017 at 3:00 AM, Tsunakawa, Takayuki
<tsunakawa.takay@jp.fujitsu.com> wrote:
> I'm on David's side, too.  I don't postmaster to always scan all files at startup.

+1.  Even just doing it during crash recovery, it can take a
regrettably long time on machines with tons of relations and a very
slow disk.  I've been sort of thinking that we should add some logging
there so that users know what's happening when that code goes into the
tank - I've seen that come up 3 or 4 times now, and I'm getting tired
of telling people to run strace to find out.

I think Tom's concerns about people doing insecure stuff are
excessive.  People can do insecure stuff no matter what we do, and
trying to prevent them often leads to them doing even-more-insecure
stuff.  That having been aid, I do wonder whether the idea of allowing
group read privileges specifically might be a better concept than a
umask, though, because (1) it's not obvious that there's a real use
case for anything other than group read privileges, so why not support
exactly that to avoid user confusion and (2) umask is a pretty
specific concept that may not apply on every platform.  For example,
AFS has an ACL list instead of using the traditional UNIX permission
bits, and I'm not sure Windows has the umask concept exactly either.
So wording what we're trying to do a bit more generically might be
smart.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: [HACKERS] PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/18/17 3:57 PM, Robert Haas wrote:
> On Wed, Mar 15, 2017 at 3:00 AM, Tsunakawa, Takayuki
> <tsunakawa.takay@jp.fujitsu.com> wrote:
>> I'm on David's side, too.  I don't postmaster to always scan all files at startup.
>
> +1.  Even just doing it during crash recovery, it can take a
> regrettably long time on machines with tons of relations and a very
> slow disk.  I've been sort of thinking that we should add some logging
> there so that users know what's happening when that code goes into the
> tank - I've seen that come up 3 or 4 times now, and I'm getting tired
> of telling people to run strace to find out.

Most of this time is spent scanning for unlogged tables.  We were 
working on a patch to put unlogged tables (except for the init fork) in 
a pg_unlogged directory created for each tablespace, just like 
pgsql_temp.  This would make cleanup a lot faster and make it easier for 
backup software to skip relations that can't be restored and only take 
up space.

Unfortunately the patch was not ready for the last CF and maybe would 
not have been a good candidate anyway due to complexity.  It's still on 
our radar, though.

> I think Tom's concerns about people doing insecure stuff are
> excessive.  People can do insecure stuff no matter what we do, and
> trying to prevent them often leads to them doing even-more-insecure
> stuff.  That having been aid, I do wonder whether the idea of allowing
> group read privileges specifically might be a better concept than a
> umask, though, because (1) it's not obvious that there's a real use
> case for anything other than group read privileges, so why not support
> exactly that to avoid user confusion and (2) umask is a pretty
> specific concept that may not apply on every platform.  For example,
> AFS has an ACL list instead of using the traditional UNIX permission
> bits, and I'm not sure Windows has the umask concept exactly either.
> So wording what we're trying to do a bit more generically might be
> smart.

We took Tom's advice to heart and this is the direction the patch is 
currently going in.  Even the GUC may be too much as there are number of 
tools that write into PGDATA but don't read postgresql.conf.  It looks 
like using the permissions of PGDATA may be the best way to go.

In any case, the changes required have enlarged the size and scope of 
the patch considerably and we are not confident that it will be done in 
time to commit for v10.

I have marked this submission "Returned with Feedback".

-- 
-David
david@pgmasters.net



Re: Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/21/17 2:02 PM, David Steele wrote:
> On 3/18/17 3:57 PM, Robert Haas wrote:
> 
>> I think Tom's concerns about people doing insecure stuff are
>> excessive.  People can do insecure stuff no matter what we do, and
>> trying to prevent them often leads to them doing even-more-insecure
>> stuff.  That having been aid, I do wonder whether the idea of allowing
>> group read privileges specifically might be a better concept than a
>> umask, though, because (1) it's not obvious that there's a real use
>> case for anything other than group read privileges, so why not support
>> exactly that to avoid user confusion and (2) umask is a pretty
>> specific concept that may not apply on every platform.  For example,
>> AFS has an ACL list instead of using the traditional UNIX permission
>> bits, and I'm not sure Windows has the umask concept exactly either.
>> So wording what we're trying to do a bit more generically might be
>> smart.
> 
> We took Tom's advice to heart and this is the direction the patch is 
> currently going in.  Even the GUC may be too much as there are number of 
> tools that write into PGDATA but don't read postgresql.conf.  It looks 
> like using the permissions of PGDATA may be the best way to go.
> 
> In any case, the changes required have enlarged the size and scope of 
> the patch considerably and we are not confident that it will be done in 
> time to commit for v10.
> 
> I have marked this submission "Returned with Feedback".

Attached is a new patch set that should address various concerns raised 
in this thread.

1) group-access-v3-01-mkdir.patch

Abstracts all mkdir calls in the backend into a MakeDirectory() function 
implemented in fd.c.  This did not get committed in September as part of 
0c5803b450e but I still think it has value.  However, I have kept it 
separate to reduce noise in the second patch.  The mkdir() calls could 
also be modified to use PG_DIR_MODE_DEFAULT with equivalent results.

2) group-access-v3-02-group.patch

This is a "GUC-less" implementation of group read access that depends on 
the mode of the $PGDATA directory to determine which mode to use for 
subsequent writes.  The initdb option is preserved to allow group access 
to be enabled when the cluster is initialized.

Only two modes are allowed (700, 750) and the error message on startup 
is hard-coded to address translation concerns.

I'll add this to the 2018-01 CF.

Thanks!
-- 
-David
david@pgmasters.net

Attachment

Re: Re: PATCH: Configurable file mode mask

From
Robert Haas
Date:
On Thu, Dec 28, 2017 at 2:36 PM, David Steele <david@pgmasters.net> wrote:
> Attached is a new patch set that should address various concerns raised in
> this thread.
>
> 1) group-access-v3-01-mkdir.patch
>
> Abstracts all mkdir calls in the backend into a MakeDirectory() function
> implemented in fd.c.  This did not get committed in September as part of
> 0c5803b450e but I still think it has value.  However, I have kept it
> separate to reduce noise in the second patch.  The mkdir() calls could also
> be modified to use PG_DIR_MODE_DEFAULT with equivalent results.

+/*
+ * Default mode for created directories, unless something else is specified
+ * using the MakeDirectoryPerm() function variant.
+ */
+#define PG_DIR_MODE_DEFAULT            (S_IRWXU)
+#define PG_MODE_MASK_DEFAULT   (S_IRWXG | S_IRWXO)

There's only one comment here, but there are two constants that do
different things.

Also, this hunk gets removed again by 02, which is probably OK, but 02
adds the replacement stuff in a different part of the file, which
seems not as good.

I think MakeDirectory() is a good wrapper, but isn't
MakeDirectoryPerm() sort of silly?

> 2) group-access-v3-02-group.patch
>
> This is a "GUC-less" implementation of group read access that depends on the
> mode of the $PGDATA directory to determine which mode to use for subsequent
> writes.  The initdb option is preserved to allow group access to be enabled
> when the cluster is initialized.
>
> Only two modes are allowed (700, 750) and the error message on startup is
> hard-coded to address translation concerns.

+       umask(~(stat_buf.st_mode & PG_DIR_MODE_DEFAULT));

Hmm, I wonder if this is going to be 100% portable.  Maybe some
obscure platform won't like an argument with all the high bits set.

Also, why should we break what's now one #if into two?  That seems
like it's mildly more complicated for no gain.

+    (These files can confuse <application>pg_ctl</application>.)  If group read
+    access is enabled on the data directory and an unprivileged user in the
+    <productname>PostgreSQL</productname> group is performing the backup, then
+    <filename>postmaster.pid</filename> will not be readable and must be
+    excluded.

Is that actually the behavior we want?

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Robert,

Thanks for looking at the patches.

On 12/31/17 1:27 PM, Robert Haas wrote:
> On Thu, Dec 28, 2017 at 2:36 PM, David Steele <david@pgmasters.net> wrote:
>> Attached is a new patch set that should address various concerns raised in
>> this thread.
>>
>> 1) group-access-v3-01-mkdir.patch
>>
>> Abstracts all mkdir calls in the backend into a MakeDirectory() function
>> implemented in fd.c.  This did not get committed in September as part of
>> 0c5803b450e but I still think it has value.  However, I have kept it
>> separate to reduce noise in the second patch.  The mkdir() calls could also
>> be modified to use PG_DIR_MODE_DEFAULT with equivalent results.
> 
> +/*
> + * Default mode for created directories, unless something else is specified
> + * using the MakeDirectoryPerm() function variant.
> + */
> +#define PG_DIR_MODE_DEFAULT            (S_IRWXU)
> +#define PG_MODE_MASK_DEFAULT   (S_IRWXG | S_IRWXO)
> 
> There's only one comment here, but there are two constants that do
> different things.

Looks like a copy pasto - I didn't mean PG_MODE_MASK_DEFAULT to be in 
patch 01 at all.  Removed.

> Also, this hunk gets removed again by 02, which is probably OK, but 02
> adds the replacement stuff in a different part of the file, which
> seems not as good.

Agreed.  I have moved that.

> > I think MakeDirectory() is a good wrapper, but isn't
> MakeDirectoryPerm() sort of silly?

There's one place in the backend (storage/ipc/ipc.c) that sets 
non-default directory permissions.  This function is intended to support 
that and any extensions that need to set custom perms.

>> 2) group-access-v3-02-group.patch
>>
>> This is a "GUC-less" implementation of group read access that depends on the
>> mode of the $PGDATA directory to determine which mode to use for subsequent
>> writes.  The initdb option is preserved to allow group access to be enabled
>> when the cluster is initialized.
>>
>> Only two modes are allowed (700, 750) and the error message on startup is
>> hard-coded to address translation concerns.
> 
> +       umask(~(stat_buf.st_mode & PG_DIR_MODE_DEFAULT));
> 
> Hmm, I wonder if this is going to be 100% portable.  Maybe some
> obscure platform won't like an argument with all the high bits set.

Sure - I have masked this with 0777 to clear any high bits.  Sound OK?

> Also, why should we break what's now one #if into two?  That seems
> like it's mildly more complicated for no gain.

There were already two #ifdef blocks so I added a third.  I think we 
should leave it as three or combine them all into one.  There are no 
runtime performance implications so I'm agnostic.

> +    (These files can confuse <application>pg_ctl</application>.)  If group read
> +    access is enabled on the data directory and an unprivileged user in the
> +    <productname>PostgreSQL</productname> group is performing the backup, then
> +    <filename>postmaster.pid</filename> will not be readable and must be
> +    excluded.
> 
> Is that actually the behavior we want?

I think it is.  Comments in the code are pretty specific about not 
changing the permissions on postmaster.pid and I don't see any reason to 
mess with it.  Copying postmaster.pid as part of a backup is not a good 
idea anyway.

New patches attached.

Thanks!
-- 
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Robert Haas
Date:
On Tue, Jan 2, 2018 at 11:43 AM, David Steele <david@pgmasters.net> wrote:
>> > I think MakeDirectory() is a good wrapper, but isn't
>> MakeDirectoryPerm() sort of silly?
>
> There's one place in the backend (storage/ipc/ipc.c) that sets non-default
> directory permissions.  This function is intended to support that and any
> extensions that need to set custom perms.

Yeah, but all it does is call mkdir(), which could just as well be
called directly.  I think there's a pointer to a wrapper when it does
something for you -- supply an argument, log something, handle
portability concerns -- but this wrapper does exactly nothing.

>> +       umask(~(stat_buf.st_mode & PG_DIR_MODE_DEFAULT));
>>
>> Hmm, I wonder if this is going to be 100% portable.  Maybe some
>> obscure platform won't like an argument with all the high bits set.
>
> Sure - I have masked this with 0777 to clear any high bits.  Sound OK?

Seems a little strange to spell it that way when we're using constants
everywhere else.  How about writing it like this:

umask(PG_DIR_MODE_DEFAULT & ~stat_buf.st_mode);

I think that reads as "clear all bits from PG_DIR_MODE_DEFAULT that
are not set in stat_buf.st_mode", which sounds like what we want.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Re: PATCH: Configurable file mode mask

From
Peter Eisentraut
Date:
On 1/3/18 08:11, Robert Haas wrote:
> On Tue, Jan 2, 2018 at 11:43 AM, David Steele <david@pgmasters.net> wrote:
>>>> I think MakeDirectory() is a good wrapper, but isn't
>>> MakeDirectoryPerm() sort of silly?
>>
>> There's one place in the backend (storage/ipc/ipc.c) that sets non-default
>> directory permissions.  This function is intended to support that and any
>> extensions that need to set custom perms.
> 
> Yeah, but all it does is call mkdir(), which could just as well be
> called directly.  I think there's a pointer to a wrapper when it does
> something for you -- supply an argument, log something, handle
> portability concerns -- but this wrapper does exactly nothing.

Yeah, I didn't like this aspect when this patch was originally
submitted.  We want to keep the code legible for future new
contributors.  Having these generic-sounding but specific-in-purpose
wrapper functions can be pretty confusing.  Let's use mkdir() when it's
the appropriate function, and let's figure out a different name for
"make a data directory subdirectory in a secure and robust way".

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 1/8/18 8:58 PM, Peter Eisentraut wrote:
> On 1/3/18 08:11, Robert Haas wrote:
>> On Tue, Jan 2, 2018 at 11:43 AM, David Steele <david@pgmasters.net> wrote:
>>>>> I think MakeDirectory() is a good wrapper, but isn't
>>>> MakeDirectoryPerm() sort of silly?
>>>
>>> There's one place in the backend (storage/ipc/ipc.c) that sets non-default
>>> directory permissions.  This function is intended to support that and any
>>> extensions that need to set custom perms.
>>
>> Yeah, but all it does is call mkdir(), which could just as well be
>> called directly.  I think there's a pointer to a wrapper when it does
>> something for you -- supply an argument, log something, handle
>> portability concerns -- but this wrapper does exactly nothing.
> 
> Yeah, I didn't like this aspect when this patch was originally
> submitted.  We want to keep the code legible for future new
> contributors.  Having these generic-sounding but specific-in-purpose
> wrapper functions can be pretty confusing.  Let's use mkdir() when it's
> the appropriate function, and let's figure out a different name for
> "make a data directory subdirectory in a secure and robust way".

I think there is value to keeping the function names symmetric to the
FileOpen()/FileOpenPerm() variants but I'm clearly in the minority so
there's no point in pursuing it.

How about MakeDirectoryDefaultPerm()?  That's what I'll go with if I
don't hear any other ideas.  The single call to MakeDirectoryPerm() will
be reverted to mkdir() and I'll remove the function.

Thanks,
-- 
-David
david@pgmasters.net


Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
David,

* David Steele (david@pgmasters.net) wrote:
> On 1/8/18 8:58 PM, Peter Eisentraut wrote:
> > On 1/3/18 08:11, Robert Haas wrote:
> >> On Tue, Jan 2, 2018 at 11:43 AM, David Steele <david@pgmasters.net> wrote:
> >>>>> I think MakeDirectory() is a good wrapper, but isn't
> >>>> MakeDirectoryPerm() sort of silly?
> >>>
> >>> There's one place in the backend (storage/ipc/ipc.c) that sets non-default
> >>> directory permissions.  This function is intended to support that and any
> >>> extensions that need to set custom perms.
> >>
> >> Yeah, but all it does is call mkdir(), which could just as well be
> >> called directly.  I think there's a pointer to a wrapper when it does
> >> something for you -- supply an argument, log something, handle
> >> portability concerns -- but this wrapper does exactly nothing.
> >
> > Yeah, I didn't like this aspect when this patch was originally
> > submitted.  We want to keep the code legible for future new
> > contributors.  Having these generic-sounding but specific-in-purpose
> > wrapper functions can be pretty confusing.  Let's use mkdir() when it's
> > the appropriate function, and let's figure out a different name for
> > "make a data directory subdirectory in a secure and robust way".
>
> I think there is value to keeping the function names symmetric to the
> FileOpen()/FileOpenPerm() variants but I'm clearly in the minority so
> there's no point in pursuing it.
>
> How about MakeDirectoryDefaultPerm()?  That's what I'll go with if I
> don't hear any other ideas.  The single call to MakeDirectoryPerm() will
> be reverted to mkdir() and I'll remove the function.

I would be sure to include a good comment/explanation about why mkdir()
is being used there and not MakeDirectoryDefaultPerm() (unless one
exists already), just to avoid later hackers thinking that mkdir() is
the way to go in general when, in most cases, MakeDirectoryDefaultPerm()
should be used.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Alvaro Herrera
Date:
David Steele wrote:
> On 1/8/18 8:58 PM, Peter Eisentraut wrote:

> > Yeah, I didn't like this aspect when this patch was originally
> > submitted.  We want to keep the code legible for future new
> > contributors.  Having these generic-sounding but specific-in-purpose
> > wrapper functions can be pretty confusing.  Let's use mkdir() when it's
> > the appropriate function, and let's figure out a different name for
> > "make a data directory subdirectory in a secure and robust way".

> How about MakeDirectoryDefaultPerm()?  That's what I'll go with if I
> don't hear any other ideas.  The single call to MakeDirectoryPerm() will
> be reverted to mkdir() and I'll remove the function.

I'd go with MakeDirectory, documenting exactly what it does and why, and
be done with it.  If your new function satisfies future users, great; if
not, it can be patched (or not) once we know exactly what these callers
need.

You know, YAGNI.

-- 
Álvaro Herrera                https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Re: PATCH: Configurable file mode mask

From
Peter Eisentraut
Date:
On 1/10/18 12:37, David Steele wrote:
> How about MakeDirectoryDefaultPerm()?  That's what I'll go with if I
> don't hear any other ideas.  The single call to MakeDirectoryPerm() will
> be reverted to mkdir() and I'll remove the function.

Works for me.

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Wed, Jan 10, 2018 at 03:19:46PM -0300, Alvaro Herrera wrote:
> David Steele wrote:
> > On 1/8/18 8:58 PM, Peter Eisentraut wrote:
>
> > > Yeah, I didn't like this aspect when this patch was originally
> > > submitted.  We want to keep the code legible for future new
> > > contributors.  Having these generic-sounding but specific-in-purpose
> > > wrapper functions can be pretty confusing.  Let's use mkdir() when it's
> > > the appropriate function, and let's figure out a different name for
> > > "make a data directory subdirectory in a secure and robust way".
>
> > How about MakeDirectoryDefaultPerm()?  That's what I'll go with if I
> > don't hear any other ideas.  The single call to MakeDirectoryPerm() will
> > be reverted to mkdir() and I'll remove the function.
>
> I'd go with MakeDirectory, documenting exactly what it does and why, and
> be done with it.  If your new function satisfies future users, great; if
> not, it can be patched (or not) once we know exactly what these callers
> need.

After going through the thread, I would vote for making things simple by
just using MakeDirectory() and document precisely what it does. Anyway,
there is as well the approach of using MakeDirectoryDefaultPerm(), so
I'll be fine with the decision you make, David. The patchis moved to
"waiting on author".
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 1/19/18 3:08 AM, Michael Paquier wrote:
> On Wed, Jan 10, 2018 at 03:19:46PM -0300, Alvaro Herrera wrote:
>> David Steele wrote:
>>> On 1/8/18 8:58 PM, Peter Eisentraut wrote:
>>
>>>> Yeah, I didn't like this aspect when this patch was originally
>>>> submitted.  We want to keep the code legible for future new
>>>> contributors.  Having these generic-sounding but specific-in-purpose
>>>> wrapper functions can be pretty confusing.  Let's use mkdir() when it's
>>>> the appropriate function, and let's figure out a different name for
>>>> "make a data directory subdirectory in a secure and robust way".
>>
>>> How about MakeDirectoryDefaultPerm()?  That's what I'll go with if I
>>> don't hear any other ideas.  The single call to MakeDirectoryPerm() will
>>> be reverted to mkdir() and I'll remove the function.
>>
>> I'd go with MakeDirectory, documenting exactly what it does and why, and
>> be done with it.  If your new function satisfies future users, great; if
>> not, it can be patched (or not) once we know exactly what these callers
>> need.
>
> After going through the thread, I would vote for making things simple by
> just using MakeDirectory() and document precisely what it does. Anyway,
> there is as well the approach of using MakeDirectoryDefaultPerm(), so
> I'll be fine with the decision you make, David. The patchis moved to
> "waiting on author".

I ended up with MakeDirectoryDefaultPerm(), but I'm flexible.

Attached is a new patch set that also adds the following to patch 02.

1) Move permission constants to a new file in common so they can be
shared with the front end.

2) Update all client programs that write to PGDATA: initdb, pg_ctl,
pg_resetwal, pg_rewind, pg_upgrade.

3) Add tests for initdb, pg_ctl, and pg_rewind.

I have yet to add tests for pg_rewindwal and pg_upgrade.  pg_rewindwal
doesn't *have* any tests as far as I can tell and pg_upgrade has tests
in a shell script -- it's not clear how I would extend it or reuse the
Perl code for perm testing.

Does anyone have suggestions on tests for pg_resetwal and pg_upgrade?
Should I start from scratch?

Thanks,
--
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Peter Eisentraut
Date:
On 1/19/18 14:07, David Steele wrote:
> I have yet to add tests for pg_rewindwal and pg_upgrade.  pg_rewindwal
> doesn't *have* any tests as far as I can tell and pg_upgrade has tests
> in a shell script -- it's not clear how I would extend it or reuse the
> Perl code for perm testing.
> 
> Does anyone have suggestions on tests for pg_resetwal and pg_upgrade?
> Should I start from scratch?

A test suite for pg_resetwal would be nice.

TAP tests for pg_upgrade will create problems with the build farm.
There was a recent thread about that.

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Re: PATCH: Configurable file mode mask

From
Alvaro Herrera
Date:
Peter Eisentraut wrote:
> On 1/19/18 14:07, David Steele wrote:
> > I have yet to add tests for pg_rewindwal and pg_upgrade.  pg_rewindwal
> > doesn't *have* any tests as far as I can tell and pg_upgrade has tests
> > in a shell script -- it's not clear how I would extend it or reuse the
> > Perl code for perm testing.
> > 
> > Does anyone have suggestions on tests for pg_resetwal and pg_upgrade?
> > Should I start from scratch?
> 
> A test suite for pg_resetwal would be nice.
> 
> TAP tests for pg_upgrade will create problems with the build farm.
> There was a recent thread about that.

Is this about this commit?

commit 58ffe141eb37c3f027acd25c1fc6b36513bf9380
Author:     Peter Eisentraut <peter_e@gmx.net>
AuthorDate: Fri Sep 22 16:34:46 2017 -0400
CommitDate: Fri Sep 22 16:46:56 2017 -0400

    Revert "Add basic TAP test setup for pg_upgrade"
    
    This reverts commit f41e56c76e39f02bef7ba002c9de03d62b76de4d.
    
    The build farm client would run the pg_upgrade tests twice, once as part
    of the existing pg_upgrade check run and once as part of picking up all
    TAP tests by looking for "t" directories.  Since the pg_upgrade tests
    are pretty slow, we will need a better solution or possibly a build farm
    client change before we can proceed with this.

If the only problem is that buildfarm would run tests twice, then I
think we should just press forward with this regardless of that: it
seems a chicken-and-egg problem, because buildfarm cannot be upgraded to
use some new test method if the method doesn't exist yet.  As a
solution, let's just live with some run duplication for a period until
the machines are upgraded to a future buildfarm client code.

If there are other problems, let's see what they are so that we can fix
them.

-- 
Álvaro Herrera                https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Fri, Jan 19, 2018 at 06:54:23PM -0300, Alvaro Herrera wrote:
> Peter Eisentraut wrote:
> If the only problem is that buildfarm would run tests twice, then I
> think we should just press forward with this regardless of that: it
> seems a chicken-and-egg problem, because buildfarm cannot be upgraded to
> use some new test method if the method doesn't exist yet.  As a
> solution, let's just live with some run duplication for a period until
> the machines are upgraded to a future buildfarm client code.
>
> If there are other problems, let's see what they are so that we can fix
> them.

The main complain I received about this move of the pg_upgrade tests to
be a TAP one is that they don't support easily cross-major version
upgrades, removing some abilities to what a developer or the builfarm
can actually do. Making this possible would require first some
refactoring of PostgresNode.pm so as a node is aware of the binary paths
it uses to be able to manipulate multiple instances with different
install paths at the same time.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 1/19/18 4:43 PM, Peter Eisentraut wrote:
> On 1/19/18 14:07, David Steele wrote:
>> I have yet to add tests for pg_rewindwal and pg_upgrade.  pg_rewindwal
>> doesn't *have* any tests as far as I can tell and pg_upgrade has tests
>> in a shell script -- it's not clear how I would extend it or reuse the
>> Perl code for perm testing.
>>
>> Does anyone have suggestions on tests for pg_resetwal and pg_upgrade?
>> Should I start from scratch?
> 
> A test suite for pg_resetwal would be nice.

It sure would!  I'll put together a basic test suite then add perms
testing to it.

-- 
-David
david@pgmasters.net


Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 1/20/18 5:47 PM, Michael Paquier wrote:
> On Fri, Jan 19, 2018 at 06:54:23PM -0300, Alvaro Herrera wrote:
>> Peter Eisentraut wrote:
>> If the only problem is that buildfarm would run tests twice, then I
>> think we should just press forward with this regardless of that: it
>> seems a chicken-and-egg problem, because buildfarm cannot be upgraded to
>> use some new test method if the method doesn't exist yet.  As a
>> solution, let's just live with some run duplication for a period until
>> the machines are upgraded to a future buildfarm client code.

It also appears that the TAP tests don't have the infrastructure to be
able to run pg_ugrade properly, per below.

> The main complain I received about this move of the pg_upgrade tests to
> be a TAP one is that they don't support easily cross-major version
> upgrades, removing some abilities to what a developer or the builfarm
> can actually do.

Unless I read it wrong the buildfarm is not doing cross-version
upgrades, but a developer/user can do so manually using the same script?

> Making this possible would require first some
> refactoring of PostgresNode.pm so as a node is aware of the binary paths
> it uses to be able to manipulate multiple instances with different
> install paths at the same time.

Any idea of what the LOE would be for that?

Thanks,
--
-David
david@pgmasters.net


Attachment

Re: PATCH: Configurable file mode mask

From
Tom Lane
Date:
David Steele <david@pgmasters.net> writes:
> Unless I read it wrong the buildfarm is not doing cross-version
> upgrades, but a developer/user can do so manually using the same script?

The buildfarm isn't doing that *by default*, but Andrew has at least
one critter configured to do so (crake I think).  It found a bug just
a couple days ago too, so losing that capability isn't going to sell.

            regards, tom lane


Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 1/23/18 9:26 AM, Tom Lane wrote:
> David Steele <david@pgmasters.net> writes:
>> Unless I read it wrong the buildfarm is not doing cross-version
>> upgrades, but a developer/user can do so manually using the same script?
> 
> The buildfarm isn't doing that *by default*, but Andrew has at least
> one critter configured to do so (crake I think).  It found a bug just
> a couple days ago too, so losing that capability isn't going to sell.
Thanks for the clarification, Tom.

What if I update pg_upgrade/test.sh to optionally allow group
permissions and we configure an animal to test it if it gets committed?

It's not ideal, I know, but it would get the permissions patch over the
line and is consistent with how we currently test pg_upgrade.

Regards,
-- 
-David
david@pgmasters.net


Re: PATCH: Configurable file mode mask

From
Peter Eisentraut
Date:
On 1/19/18 16:54, Alvaro Herrera wrote:
> If the only problem is that buildfarm would run tests twice, then I
> think we should just press forward with this regardless of that: it
> seems a chicken-and-egg problem, because buildfarm cannot be upgraded to
> use some new test method if the method doesn't exist yet.  As a
> solution, let's just live with some run duplication for a period until
> the machines are upgraded to a future buildfarm client code.

Well, people protested against that approach.

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Re: PATCH: Configurable file mode mask

From
Tom Lane
Date:
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
> On 1/19/18 16:54, Alvaro Herrera wrote:
>> If the only problem is that buildfarm would run tests twice, then I
>> think we should just press forward with this regardless of that: it
>> seems a chicken-and-egg problem, because buildfarm cannot be upgraded to
>> use some new test method if the method doesn't exist yet.  As a
>> solution, let's just live with some run duplication for a period until
>> the machines are upgraded to a future buildfarm client code.

> Well, people protested against that approach.

I think I was one of the complainers, but my objection was pretty
straightforward.  I want the buildfarm script update to be available
more or less contemporaneously with the change going into git.
Some owners might not care if their machines are doing lots of
extra work, but for those that do, we shouldn't leave them stuck
until a buildfarm update appears in some indefinite future.

In short: get Dunstan into the loop.  Don't push this till he's
signed off on new buildfarm code.

            regards, tom lane


Re: PATCH: Configurable file mode mask

From
Peter Eisentraut
Date:
On 1/23/18 09:33, David Steele wrote:
> What if I update pg_upgrade/test.sh to optionally allow group
> permissions and we configure an animal to test it if it gets committed?
> 
> It's not ideal, I know, but it would get the permissions patch over the
> line and is consistent with how we currently test pg_upgrade.

Basically, what you'd need is some way to pass some options to the
initdb invocations in the pg_upgrade test script, right?  That would
seem reasonable, and also useful for testing upgrading with other initdb
options.

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Tue, Jan 23, 2018 at 09:18:51AM -0500, David Steele wrote:
> On 1/20/18 5:47 PM, Michael Paquier wrote:
>> Making this possible would require first some
>> refactoring of PostgresNode.pm so as a node is aware of the binary paths
>> it uses to be able to manipulate multiple instances with different
>> install paths at the same time.
>
> Any idea of what the LOE would be for that?

What does LOE means?
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 1/23/18 9:22 PM, Michael Paquier wrote:
> On Tue, Jan 23, 2018 at 09:18:51AM -0500, David Steele wrote:
>> On 1/20/18 5:47 PM, Michael Paquier wrote:
>>> Making this possible would require first some
>>> refactoring of PostgresNode.pm so as a node is aware of the binary paths
>>> it uses to be able to manipulate multiple instances with different
>>> install paths at the same time.
>>
>> Any idea of what the LOE would be for that?
>
> What does LOE means?

Sorry - it means "level of effort".  I was trying to get an idea if it
is something that could be available in the PG11 development cycle, or
if I should be looking at other ways to get the testing for this patch
completed.

--
-David
david@pgmasters.net


Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Tue, Jan 23, 2018 at 10:48:07PM -0500, David Steele wrote:
> Sorry - it means "level of effort".  I was trying to get an idea if it
> is something that could be available in the PG11 development cycle, or
> if I should be looking at other ways to get the testing for this patch
> completed.

I don't think that it would be more than a couple of hours digging
things out, but that may be optimistic. What only needs to be done is
extending get_new_node with an optional argument to define the bin
directory of a PostgresNode and register the path. If the binary
directory is undefined, just rely on PATH and call pg_config --bindir to
get the information, then register it. What we need to be careful at is
that all the binary calls of PostgresNode.pm need to be changed to use
the binary path, which is not really complicated, but it can be easy to
miss some.

There is one small issue with TestLib::check_pg_config but I think that
we can live with the existing version relying on PATH. Once this
refactoring is done, you need the patch set I sent previously here with
some tiny modifications:
https://www.postgresql.org/message-id/CAB7nPqRJXz0sEuUL36eBsF7iZtOQGMJoJPGFWxHLuS6TYPxf5w%40mail.gmail.com

Those modifications involve just looking at the environment variables
specified in pg_upgrade's TESTING and change the node binaries if those
are defined. It is also necessary to tweak probin's paths for the dump
consistency checks, which is something that my last patch set was not
doing.

It is tiring to see this topic come up again and again, so you know
what, let's bite the bullet. I commit myself into coding this thing with
a patch set for the next commit fest. the only thing I want to be sure
about is if folks on this list are fine with the plan of this email.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 1/19/18 4:43 PM, Peter Eisentraut wrote:
> On 1/19/18 14:07, David Steele wrote:
>> I have yet to add tests for pg_rewindwal and pg_upgrade.  pg_rewindwal
>> doesn't *have* any tests as far as I can tell and pg_upgrade has tests
>> in a shell script -- it's not clear how I would extend it or reuse the
>> Perl code for perm testing.
>>
>> Does anyone have suggestions on tests for pg_resetwal and pg_upgrade?
>> Should I start from scratch?
> 
> A test suite for pg_resetwal would be nice.

Agreed.

> TAP tests for pg_upgrade will create problems with the build farm.
> There was a recent thread about that.

OK, that being the case I have piggy-backed on the current pg_upgrade
tests in the same way that --wal-segsize did.

There are now three patches:

1) 01-pgresetwal-test

Adds a *very* basic test suite for pg_resetwal.  I was able to make this
utility core dump (floating point errors) pretty easily with empty or
malformed pg_control files so I focused on WAL reset functionality plus
the basic help/command tests that every utility has.

2) 02-mkdir

Converts mkdir() calls to MakeDirectoryDefaultPerm() if the original
call used default permissions.

3) 03-group

Allow group access on PGDATA.  This includes backend changes, utility
changes (initdb, pg_ctl, pg_upgrade, etc.) and tests for each utility.

Regards,
-- 
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Mon, Jan 29, 2018 at 04:29:08PM -0500, David Steele wrote:
> OK, that being the case I have piggy-backed on the current pg_upgrade
> tests in the same way that --wal-segsize did.
>
> There are now three patches:
>
> 1) 01-pgresetwal-test
>
> Adds a *very* basic test suite for pg_resetwal.  I was able to make this
> utility core dump (floating point errors) pretty easily with empty or
> malformed pg_control files so I focused on WAL reset functionality plus
> the basic help/command tests that every utility has.

A little is better than nothing, so that's an improvement, thanks!

+# Remove WAL from pg_wal and make sure it gets rebuilt
+$node->stop;
+
+unlink("$pgwal/000000010000000000000001") == 1
+   or die("unable to remove 000000010000000000000001");
+
+is_deeply(
+   [sort(slurp_dir($pgwal))], [sort(qw(. .. archive_status))], 'no WAL');
This is_deeply test serves little purpose.  The segment gets removed
directly so I would just remove it.

Another test that could be easily included is with -o, then create a
table and check for its OID value.  Also for -x, then just use
txid_current to check the value consistency.  For -c, with
track_commit_timestamp set to on, you can set a couple of values and
then check for pg_last_committed_xact() which would be NULL if you use
an XID older than the minimum set for example.  All those are simple
enough so they could easily be added in the first version of this test
suite.

You need to update src/bin/pg_resetxlog/.gitignore to include
tmp_check/.

> 2) 02-mkdir
>
> Converts mkdir() calls to MakeDirectoryDefaultPerm() if the original
> call used default permissions.

So the only call not converted to that API is in ipc.c...  OK, this one
is pretty simple so nothing really to say about it, the real meat comes
with patch 3.  I would rather see with a good eye if this patch
introduces file_perm.h which includes both PG_FILE_MODE_DEFAULT and
PG_DIR_MODE_DEFAULT, and have the frontends use those values.  This
would make the switch to 0003 a bit easier if you look at pg_resetwal's
diffs for example.

> 3) 03-group
>
> Allow group access on PGDATA.  This includes backend changes, utility
> changes (initdb, pg_ctl, pg_upgrade, etc.) and tests for each utility.

+++ b/src/include/common/file_perm.h
+ *
+ * This module is located in common so the backend can use the constants.
+ *
This is the case of more or less all the content in src/common/, except
for the things which are frontend-only, so this comment could just be
removed.

+command_ok(
+   ['chmod', "-R", 'g+rX', "$pgdata"],
+   'add group perms to PGDATA');
That would blow up on Windows.  You should replace that by perl's chmod
and look at its return result for sanity checks, likely with ($cnt != 0).
And let's not use icacls please...

+    if ($params{has_group_access})
+    {
+        push(@{$params{extra}}, '-g');
+    }
No need to introduce a new parameter here, please use directly extra =>
[ '-g' ] in the routines calling PostgresNode::init.

The efforts put in the tests are good.

Patch 0003 needs a very careful lookup...  We don't want to introduce any
kind of race conditions here.  I am not familiar enough with the
proposed patch but the patch is giving me some chills.

You may want to run pgindent once on your patch set.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Michael,

Thanks for having a look at the patches.

On 1/30/18 3:01 AM, Michael Paquier wrote:
> On Mon, Jan 29, 2018 at 04:29:08PM -0500, David Steele wrote:
>>
>> Adds a *very* basic test suite for pg_resetwal.  I was able to make this
>> utility core dump (floating point errors) pretty easily with empty or
>> malformed pg_control files so I focused on WAL reset functionality plus
>> the basic help/command tests that every utility has.
>
> A little is better than nothing, so that's an improvement, thanks!
>
> +# Remove WAL from pg_wal and make sure it gets rebuilt
> +$node->stop;
> +
> +unlink("$pgwal/000000010000000000000001") == 1
> +   or die("unable to remove 000000010000000000000001");
> +
> +is_deeply(
> +   [sort(slurp_dir($pgwal))], [sort(qw(. .. archive_status))], 'no WAL');
> This is_deeply test serves little purpose.  The segment gets removed
> directly so I would just remove it.

The purpose of this test to be ensure nothing else is in the directory.
As the tests get more complex I think keeping track of the state will be
important.  In other words, this is really an assertion that the current
test state is correct, not that the prior command succeeded.

> Another test that could be easily included is with -o, then create a
> table and check for its OID value.  Also for -x, then just use
> txid_current to check the value consistency.  For -c, with
> track_commit_timestamp set to on, you can set a couple of values and
> then check for pg_last_committed_xact() which would be NULL if you use
> an XID older than the minimum set for example.  All those are simple
> enough so they could easily be added in the first version of this test
> suite.

I would prefer to leave this for another patch.

> You need to update src/bin/pg_resetxlog/.gitignore to include
> tmp_check/.

Added.

>> 2) 02-mkdir
>>
>> Converts mkdir() calls to MakeDirectoryDefaultPerm() if the original
>> call used default permissions.
>
> So the only call not converted to that API is in ipc.c...  OK, this one
> is pretty simple so nothing really to say about it, the real meat comes
> with patch 3.  I would rather see with a good eye if this patch
> introduces file_perm.h which includes both PG_FILE_MODE_DEFAULT and
> PG_DIR_MODE_DEFAULT, and have the frontends use those values.  This
> would make the switch to 0003 a bit easier if you look at pg_resetwal's
> diffs for example.

Agreed.  I thought about this originally but could not come up with a
good split.  I spent some time on it and came up with something that I
think works (and would make sense to commit separately).

>> 3) 03-group
>>
>> Allow group access on PGDATA.  This includes backend changes, utility
>> changes (initdb, pg_ctl, pg_upgrade, etc.) and tests for each utility.
>
> +++ b/src/include/common/file_perm.h
> + *
> + * This module is located in common so the backend can use the constants.
> + *
> This is the case of more or less all the content in src/common/, except
> for the things which are frontend-only, so this comment could just be
> removed.

Removed.

> +command_ok(
> +   ['chmod', "-R", 'g+rX', "$pgdata"],
> +   'add group perms to PGDATA');
>
> That would blow up on Windows.  You should replace that by perl's chmod
> and look at its return result for sanity checks, likely with ($cnt != 0).
> And let's not use icacls please...

Fixed with a new function, add_pg_data_group_perm().

> +    if ($params{has_group_access})
> +    {
> +        push(@{$params{extra}}, '-g');
> +    }
> No need to introduce a new parameter here, please use directly extra =>
> [ '-g' ] in the routines calling PostgresNode::init.

Other code needs to know if group access is enabled on the node (see
RewindTest.pm) so it's not just a matter of passing the option.

> The efforts put in the tests are good.

Thanks!

New patches are attached.  The end result is almost identical to v6 but
code was moved from 03 to 02 as per Michael's suggestion.

1) 01-pgresetwal-test

Adds a very basic test suite for pg_resetwal.

2) 02-file-perm

Adds a new header (file_perm.h) and makes all front-end utilities use
the new constants for setting umask.  Converts mkdir() calls in the
backend to MakeDirectoryDefaultPerm() if the original
call used default permissions.  Adds tests to make sure permissions in
PGDATA are set correctly by the front-end tools.

3) 03-group

Allow group access on PGDATA.  This includes backend changes, utility
changes (initdb, pg_ctl, pg_upgrade, etc.) and tests for each utility.

Thanks!
--
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Tue, Feb 27, 2018 at 03:52:32PM -0500, David Steele wrote:
> On 1/30/18 3:01 AM, Michael Paquier wrote:
> The purpose of this test to be ensure nothing else is in the directory.
> As the tests get more complex I think keeping track of the state will be
> important.  In other words, this is really an assertion that the current
> test state is correct, not that the prior command succeeded.

Good point.  Objection removed.

>> Another test that could be easily included is with -o, then create a
>> table and check for its OID value.  Also for -x, then just use
>> txid_current to check the value consistency.  For -c, with
>> track_commit_timestamp set to on, you can set a couple of values and
>> then check for pg_last_committed_xact() which would be NULL if you use
>> an XID older than the minimum set for example.  All those are simple
>> enough so they could easily be added in the first version of this test
>> suite.
>
> I would prefer to leave this for another patch.

OK, no problems with that either.

>>> 2) 02-mkdir
>>>
>>> Converts mkdir() calls to MakeDirectoryDefaultPerm() if the original
>>> call used default permissions.
>>
>> So the only call not converted to that API is in ipc.c...  OK, this one
>> is pretty simple so nothing really to say about it, the real meat comes
>> with patch 3.  I would rather see with a good eye if this patch
>> introduces file_perm.h which includes both PG_FILE_MODE_DEFAULT and
>> PG_DIR_MODE_DEFAULT, and have the frontends use those values.  This
>> would make the switch to 0003 a bit easier if you look at pg_resetwal's
>> diffs for example.
>
> Agreed.  I thought about this originally but could not come up with a
> good split.  I spent some time on it and came up with something that I
> think works (and would make sense to commit separately).

OK, thanks.

>> +command_ok(
>> +   ['chmod', "-R", 'g+rX', "$pgdata"],
>> +   'add group perms to PGDATA');
>>
>> That would blow up on Windows.  You should replace that by perl's chmod
>> and look at its return result for sanity checks, likely with ($cnt != 0).
>> And let's not use icacls please...
>
> Fixed with a new function, add_pg_data_group_perm().

That's basically a recursive chmod, so chmod_recursive is more adapted?
I could imagine that this is useful as well for removing group
permissions, so the new mode could be specified as an argument.

>> +    if ($params{has_group_access})
>> +    {
>> +        push(@{$params{extra}}, '-g');
>> +    }
>> No need to introduce a new parameter here, please use directly extra =>
>> [ '-g' ] in the routines calling PostgresNode::init.
>
> Other code needs to know if group access is enabled on the node (see
> RewindTest.pm) so it's not just a matter of passing the option.

I don't quite understand here.  I have no objection into extending
setup_cluster() with a group_access argument so as the tests run both
the group access and without it, but I'd rather keep the low-level API
clean of anything fancy if we can use the facility which already
exists.

> New patches are attached.  The end result is almost identical to v6 but
> code was moved from 03 to 02 as per Michael's suggestion.

Thanks for the updated versions.

> 1) 01-pgresetwal-test
>
> Adds a very basic test suite for pg_resetwal.

Okay.  This one looks fine to me.  It could be passed down to a
committer.

> 2) 02-file-perm
>
> Adds a new header (file_perm.h) and makes all front-end utilities use
> the new constants for setting umask.  Converts mkdir() calls in the
> backend to MakeDirectoryDefaultPerm() if the original
> call used default permissions.  Adds tests to make sure permissions in
> PGDATA are set correctly by the front-end tools.

I had a more simple (complicated?) thing in mind for the split, which
would actually cause this patch to be split into two more:
1) Introduce file_perm.h and replace all the existing values for modes
and masks to what the header introduces.  This allows to check if the
new header is not forgotten anywhere, especially for the frontends.
2) Introduce MakeDirectoryDefaultPerm, which switches the backend calls
of mkdir() to the new API.
3) Add the grouping facilities, which updates the default masks and
modes of file_perm.h.

Grouping 1) and 2) together as you do makes sense as well I guess, as in
my proposal the mkdir calls in the backend would be touched twice, still
things get more incremental.

+/*
+ * Default mode for created files.
+ */
+#define PG_FILE_MODE_DEFAULT       (S_IRUSR | S_IWUSR | S_IRGRP)
+
+/*
+ * Default mode for directories.
+ */
+#define PG_DIR_MODE_DEFAULT            (S_IRWXU | S_IRGRP | S_IXGRP)
For the first cut, this should not use S_IRGRP in the first declaration,
and (S_IXGRP | S_IXGRP) in the second declaration.

-    if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
+    if (script == NULL && (script = fopen(output_path, "w")) == NULL)
Why are those calls in pg_upgrade changed?

TestLib.pm does not need the group-related extensions, right?

check_pg_data_perm() looks useful even without $allow_group even if the
grouping facility is reverted at the end.  S_ISLNK should be considered
as well for tablespaces or symlinks of pg_wal?  We have such cases in
the regression tests.

-    if (chmod(pg_data, S_IRWXU) != 0)
+    if (chmod(pg_data, PG_DIR_MODE_DEFAULT & ~file_mode_mask) != 0)
[...]
-    if (chmod(xlog_dir, S_IRWXU) != 0)
+    if (chmod(xlog_dir, PG_DIR_MODE_DEFAULT & ~file_mode_mask) != 0)
Those seems incorrect, as they consider the default value only.

     snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);

     writefile(path, conflines);
-    if (chmod(path, S_IRUSR | S_IWUSR) != 0)
-    {
-    fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"),
-        progname, path, strerror(errno));
-    exit_nicely();
-    }
Hm.  Why are those removed?

    setup_signals();

-   umask(S_IRWXG | S_IRWXO);
-
    create_data_directory();
This should not be moved around.

> 3) 03-group
>
> Allow group access on PGDATA.  This includes backend changes, utility
> changes (initdb, pg_ctl, pg_upgrade, etc.) and tests for each utility.

I have not looked much in depth into this one, but I spotted two issues
on a quick read:
+ * Errors are not handled here and should be checked by the frontend
+ * application.
+ */
+#ifdef FRONTEND

What you need to do for frontend-only files in src/common/ is to define
that at the top and not bother about FRONTEND cflags at all:
#ifndef FRONTEND
#error "This file is not expected to be compiled for backend code"
#endif

src/tools/msvc/Mkvcbuild.pm also needs to be updated with this new file,
or you will break MSVC build.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
Andres Freund
Date:
Hi,

On 2018-02-27 15:52:32 -0500, David Steele wrote:
> Thanks for having a look at the patches.

I'd personally appreciate if you'd add commit messages to the individual
patches in a series. A brief explanation why something is done is good
enough.  E.g. here it's far from obvious why something is done with
pg_resetwal.

I'd suggest just using git format-patch -v to format series.


Independent of that, I'm not entirely clear on what the status of this
patch is, without rereading the thread. Could you summarize?

- Andres


Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Andres,

On 3/1/18 9:04 PM, Andres Freund wrote:
> On 2018-02-27 15:52:32 -0500, David Steele wrote:
>> Thanks for having a look at the patches.
> 
> I'd personally appreciate if you'd add commit messages to the individual
> patches in a series. A brief explanation why something is done is good
> enough.
> 
> I'd suggest just using git format-patch -v to format series.

Sure, I've been meaning to switch over to this format and just haven't 
gotten around to it yet.  I do recognize the value, however, and will do 
it going forward.

> Independent of that, I'm not entirely clear on what the status of this
> patch is, without rereading the thread. Could you summarize?

Good question.  This patch has been around for a year and has gone 
though a number of iterations.

In summary, we started with a more rigid design that required a GUC to 
enable group privs (actually, at first it was any mode you wanted). 
Through feedback from Tom and others we realized that the front-end 
tools could not read the GUCs and it would probably be best based on the 
perms of PGDATA, as long as they were 700 or 750.

We decided the patch was too big, so broke it up a bit and got some of 
the infrastructure committed in 2017-09 [1].

In 2018-01 we brought in a unified patch set that built on the ideas 
from 2017-03.  During that CF we taught all the front-end tools to check 
PGDATA for permissions and wrote a lot of tests.

The current incarnation is a refinement with input from Michael and a 
different split in the patches.

 > E.g. here it's far from obvious why something is done with
 > pg_resetwal.
[reordered by me for clarity]

Any front-end tool that writes into PGDATA is affected by this patch 
because mode must be set correctly.

pg_resetwal had no tests, so I wrote a basic test suite to base the 
group permissions tests on.  I included the basic test suite as a 
separate patch because I felt it should be committed even if the main 
feature wasn't.  It's far from a comprehensive test suite, but certainly 
better than what we have currently.

Does that clear things up?

-- 
-David
david@pgmasters.net

[1] https://commitfest.postgresql.org/14/1262/


Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Thu, Mar 01, 2018 at 09:32:58PM -0500, David Steele wrote:
> On 3/1/18 9:04 PM, Andres Freund wrote:
>> I'd suggest just using git format-patch -v to format series.
>
> Sure, I've been meaning to switch over to this format and just haven't
> gotten around to it yet.  I do recognize the value, however, and will do it
> going forward.

Simple patches can bypass on that, but once you have at least three
patches this helps a lot with reviews.  Explaining as well in the email
sending the patches what each patch actually does, even roughly helps in
focusing on one element or the other.

>> E.g. here it's far from obvious why something is done with
>> pg_resetwal.
> [reordered by me for clarity]
>
> Any front-end tool that writes into PGDATA is affected by this patch because
> mode must be set correctly.
>
> pg_resetwal had no tests, so I wrote a basic test suite to base the group
> permissions tests on.  I included the basic test suite as a separate patch
> because I felt it should be committed even if the main feature wasn't.  It's
> far from a comprehensive test suite, but certainly better than what we have
> currently.

Based on my recent lookup at code level for this feature, the patch for
pg_resetwal (which could have been discussed on its own thread as well),
would be fine for commit.  The thing could be extended a bit more but
there is nothing opposing even a basic test suite to be in.  Then you
have a set of refactoring patches, which still need some work.  And
finally there is a rather invasive patch on top of the whole thing.  The
refactoring work shows much more value only after the main feature is
in, still I think that unifying the default permissions allowed for
files and directories, as well as mkdir() calls has some value in
itself to think it as an mergeable, independent, change.  I think that
it would be hard to get the whole patch set into the tree by the end of
the CF though, but cutting the refactoring pieces would be doable.  At
least it would provide some base for integration in v12.  And the
refactoring patch has some pieces that would be helpful for TAP tests as
well.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 2/28/18 2:28 AM, Michael Paquier wrote:
> On Tue, Feb 27, 2018 at 03:52:32PM -0500, David Steele wrote:
>> On 1/30/18 3:01 AM, Michael Paquier wrote:
>
>>> +command_ok(
>>> +   ['chmod', "-R", 'g+rX', "$pgdata"],
>>> +   'add group perms to PGDATA');
>>>
>>> That would blow up on Windows.  You should replace that by perl's chmod
>>> and look at its return result for sanity checks, likely with ($cnt != 0).
>>> And let's not use icacls please...
>>
>> Fixed with a new function, add_pg_data_group_perm().
>
> That's basically a recursive chmod, so chmod_recursive is more adapted?
> I could imagine that this is useful as well for removing group
> permissions, so the new mode could be specified as an argument.

The required package (File::chmod::Recursive) for chmod_recursive is not
in use anywhere else and was not installed when I installed build
dependencies.

I'm not sure what the protocol for introducing a new Perl module is?  I
couldn't find packages for the major OSes.  Are we OK with using CPAN?

>>> +    if ($params{has_group_access})
>>> +    {
>>> +        push(@{$params{extra}}, '-g');
>>> +    }
>>> No need to introduce a new parameter here, please use directly extra =>
>>> [ '-g' ] in the routines calling PostgresNode::init.
>>
>> Other code needs to know if group access is enabled on the node (see
>> RewindTest.pm) so it's not just a matter of passing the option.
>
> I don't quite understand here.  I have no objection into extending
> setup_cluster() with a group_access argument so as the tests run both
> the group access and without it, but I'd rather keep the low-level API
> clean of anything fancy if we can use the facility which already
> exists.

I'm not sure what you mean by, "facility that already exists".  I think
I implemented this the same as the allows_streaming and has_archiving
flags.  The only difference is that this option must be set at initdb
time rather than in postgresql.conf.

Could you be more specific?

>> New patches are attached.  The end result is almost identical to v6 but
>> code was moved from 03 to 02 as per Michael's suggestion.
>
> Thanks for the updated versions.
>
>> 1) 01-pgresetwal-test
>>
>> Adds a very basic test suite for pg_resetwal.
>
> Okay.  This one looks fine to me.  It could be passed down to a
> committer.

Agreed.

>> 2) 02-file-perm
>>
>> Adds a new header (file_perm.h) and makes all front-end utilities use
>> the new constants for setting umask.  Converts mkdir() calls in the
>> backend to MakeDirectoryDefaultPerm() if the original
>> call used default permissions.  Adds tests to make sure permissions in
>> PGDATA are set correctly by the front-end tools.
>
> I had a more simple (complicated?) thing in mind for the split, which
> would actually cause this patch to be split into two more:
> 1) Introduce file_perm.h and replace all the existing values for modes
> and masks to what the header introduces.  This allows to check if the
> new header is not forgotten anywhere, especially for the frontends.
> 2) Introduce MakeDirectoryDefaultPerm, which switches the backend calls
> of mkdir() to the new API.
> 3) Add the grouping facilities, which updates the default masks and
> modes of file_perm.h.
>
> Grouping 1) and 2) together as you do makes sense as well I guess, as in
> my proposal the mkdir calls in the backend would be touched twice, still
> things get more incremental.

I think I prefer grouping 1 and 2.  It produces less churn, as you say,
and I don't think MakeDirectoryDefaultPerm really needs its own patch.
Based on comments so far, nobody has an objection to it.

In theory, the first two patches could be applied just for refactoring
without adding group permissions at all.  There are a lot of new tests
to make sure permissions are set correctly so it seems like a win right off.

>
> +/*
> + * Default mode for created files.
> + */
> +#define PG_FILE_MODE_DEFAULT       (S_IRUSR | S_IWUSR | S_IRGRP)
> +
> +/*
> + * Default mode for directories.
> + */
> +#define PG_DIR_MODE_DEFAULT            (S_IRWXU | S_IRGRP | S_IXGRP)
> For the first cut, this should not use S_IRGRP in the first declaration,
> and (S_IXGRP | S_IXGRP) in the second declaration.

Done.

>
> -    if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
> +    if (script == NULL && (script = fopen(output_path, "w")) == NULL)
> Why are those calls in pg_upgrade changed?

Done.

Those should have been removed already.  Originally I had removed
fopen_priv() because it didn't serve a purpose anymore.  In the
meantime, somebody else made it a macro to fopen().  I decided my patch
would be less noisy if I reverted to fopen_priv() but I missed a few places.

> TestLib.pm does not need the group-related extensions, right?

Done.

> check_pg_data_perm() looks useful even without $allow_group even if the
> grouping facility is reverted at the end.  S_ISLNK should be considered
> as well for tablespaces or symlinks of pg_wal?  We have such cases in
> the regression tests.

Hmmm, the link is just pointing to a directory whose permissions have
been changed.  Why do we need to worry about the link?

> -    if (chmod(path, S_IRUSR | S_IWUSR) != 0)
> -    {
> -    fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"),
> -        progname, path, strerror(errno));
> -    exit_nicely();
> -    }
> Hm.  Why are those removed?

When I started working on this, pg_upgrade did not set umask and instead
did chmod for each dir created.  umask() has since been added (even
before my patch) and so these are now noops.  Seemed easier to remove
them than to change them all.

>     setup_signals();
>
> -   umask(S_IRWXG | S_IRWXO);
> -
>     create_data_directory();
> This should not be moved around.

Hmmm - I moved it much earlier in the process which seems like a good
thing.  Consider if there was a option to fixup permissions, like there
is to fsync.  Isn't it best to set the mode as soon as possible to
prevent code from being inserted before it?

> What you need to do for frontend-only files in src/common/ is to define
> that at the top and not bother about FRONTEND cflags at all:
> #ifndef FRONTEND
> #error "This file is not expected to be compiled for backend code"
> #endif

Fixed.

> src/tools/msvc/Mkvcbuild.pm also needs to be updated with this new file,
> or you will break MSVC build.

Fixed.

New patches attached.

--
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/1/18 11:18 PM, Michael Paquier wrote:
>
> Based on my recent lookup at code level for this feature, the patch for
> pg_resetwal (which could have been discussed on its own thread as well),
> would be fine for commit.  The thing could be extended a bit more but
> there is nothing opposing even a basic test suite to be in.

There are no core changes, so it doesn't seem like the tests can hurt
anything.

> Then you
> have a set of refactoring patches, which still need some work.

New patches posted today, hopefully those address most of your concerns.

> And
> finally there is a rather invasive patch on top of the whole thing.

I'm not sure if I would call it invasive since it's an optional feature
that is off by default.  Honestly, I think the refactor in 02 is more
likely to cause problems even if the goal there is *not* to change the
behavior.

> The
> refactoring work shows much more value only after the main feature is
> in, still I think that unifying the default permissions allowed for
> files and directories, as well as mkdir() calls has some value in
> itself to think it as an mergeable, independent, change.

I agree.

> I think that
> it would be hard to get the whole patch set into the tree by the end of
> the CF though

I hope it does make it, it's a pretty big win for security.

> but cutting the refactoring pieces would be doable.  At
> least it would provide some base for integration in v12.  And the
> refactoring patch has some pieces that would be helpful for TAP tests as
> well.

I've gone pretty big on tests in this patch because I recognize it is a
pretty fundamental behavior change.

Thanks,
--
-David
david@pgmasters.net


Attachment

Re: PATCH: Configurable file mode mask

From
Tom Lane
Date:
David Steele <david@pgmasters.net> writes:
> On 2/28/18 2:28 AM, Michael Paquier wrote:
>> That's basically a recursive chmod, so chmod_recursive is more adapted?
>> I could imagine that this is useful as well for removing group
>> permissions, so the new mode could be specified as an argument.

> The required package (File::chmod::Recursive) for chmod_recursive is not
> in use anywhere else and was not installed when I installed build
> dependencies.

> I'm not sure what the protocol for introducing a new Perl module is?  I
> couldn't find packages for the major OSes.  Are we OK with using CPAN?

I don't think that's cool.  Anything that's not part of a standard Perl
installation is a bit of a lift already, and if it's not packaged by
major distros then it's really a problem for many people.  (Yeah, they
may know what CPAN is, but they might have local policy issues about
installing directly from there.)

            regards, tom lane


Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Tom,

On 3/5/18 5:11 PM, Tom Lane wrote:
> David Steele <david@pgmasters.net> writes:
>> On 2/28/18 2:28 AM, Michael Paquier wrote:
>>> That's basically a recursive chmod, so chmod_recursive is more adapted?
>>> I could imagine that this is useful as well for removing group
>>> permissions, so the new mode could be specified as an argument.
> 
>> The required package (File::chmod::Recursive) for chmod_recursive is not
>> in use anywhere else and was not installed when I installed build
>> dependencies.
> 
>> I'm not sure what the protocol for introducing a new Perl module is?  I
>> couldn't find packages for the major OSes.  Are we OK with using CPAN?
> 
> I don't think that's cool.  Anything that's not part of a standard Perl
> installation is a bit of a lift already, and if it's not packaged by
> major distros then it's really a problem for many people.  (Yeah, they
> may know what CPAN is, but they might have local policy issues about
> installing directly from there.)

This is my view as well.  I don't think CPAN should ever be on a
production box, mostly because of all the other tools that need to be
installed to make it work.

It's a little different here, because these packages are only used for
testing/development.

Of course, maybe I have this wrong and Michael will point out my error.
If not, I'm happy to rework the function (about 15 lines) to be more
generic.

-- 
-David
david@pgmasters.net


Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Tom, all,

* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> David Steele <david@pgmasters.net> writes:
> > On 2/28/18 2:28 AM, Michael Paquier wrote:
> >> That's basically a recursive chmod, so chmod_recursive is more adapted?
> >> I could imagine that this is useful as well for removing group
> >> permissions, so the new mode could be specified as an argument.
>
> > The required package (File::chmod::Recursive) for chmod_recursive is not
> > in use anywhere else and was not installed when I installed build
> > dependencies.
>
> > I'm not sure what the protocol for introducing a new Perl module is?  I
> > couldn't find packages for the major OSes.  Are we OK with using CPAN?
>
> I don't think that's cool.  Anything that's not part of a standard Perl
> installation is a bit of a lift already, and if it's not packaged by
> major distros then it's really a problem for many people.  (Yeah, they
> may know what CPAN is, but they might have local policy issues about
> installing directly from there.)

Agreed.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Tom Lane
Date:
David Steele <david@pgmasters.net> writes:
> On 3/5/18 5:11 PM, Tom Lane wrote:
>> David Steele <david@pgmasters.net> writes:
>>> I'm not sure what the protocol for introducing a new Perl module is?  I
>>> couldn't find packages for the major OSes.  Are we OK with using CPAN?

>> I don't think that's cool.  Anything that's not part of a standard Perl
>> installation is a bit of a lift already, and if it's not packaged by
>> major distros then it's really a problem for many people.  (Yeah, they
>> may know what CPAN is, but they might have local policy issues about
>> installing directly from there.)

> It's a little different here, because these packages are only used for
> testing/development.

True, but if we want this test to be part of either check-world or the
buildfarm run, that's still a lot of people we're asking to install
the extra module.  If we're talking about saving just a few dozen
lines of code, it ain't worth it.

            regards, tom lane


Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/5/18 5:51 PM, Tom Lane wrote:
> David Steele <david@pgmasters.net> writes:
>> On 3/5/18 5:11 PM, Tom Lane wrote:
>>> David Steele <david@pgmasters.net> writes:
>>>> I'm not sure what the protocol for introducing a new Perl module is?  I
>>>> couldn't find packages for the major OSes.  Are we OK with using CPAN?
> 
>>> I don't think that's cool.  Anything that's not part of a standard Perl
>>> installation is a bit of a lift already, and if it's not packaged by
>>> major distros then it's really a problem for many people.  (Yeah, they
>>> may know what CPAN is, but they might have local policy issues about
>>> installing directly from there.)
> 
>> It's a little different here, because these packages are only used for
>> testing/development.
> 
> True, but if we want this test to be part of either check-world or the
> buildfarm run, that's still a lot of people we're asking to install
> the extra module.  If we're talking about saving just a few dozen
> lines of code, it ain't worth it.

+1.

-- 
-David
david@pgmasters.net


Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Mon, Mar 05, 2018 at 05:11:29PM -0500, Tom Lane wrote:
> David Steele <david@pgmasters.net> writes:
>> On 2/28/18 2:28 AM, Michael Paquier wrote:
>>> That's basically a recursive chmod, so chmod_recursive is more adapted?
>>> I could imagine that this is useful as well for removing group
>>> permissions, so the new mode could be specified as an argument.
>
>> The required package (File::chmod::Recursive) for chmod_recursive is not
>> in use anywhere else and was not installed when I installed build
>> dependencies.

Woah.  I didn't even know that chmod_recursive existed and was part of a
module.  What I commented about here was to rename to a more generic
name the routine you are implementing so as other tests could use it.

>> I'm not sure what the protocol for introducing a new Perl module is?  I
>> couldn't find packages for the major OSes.  Are we OK with using CPAN?
>
> I don't think that's cool.  Anything that's not part of a standard Perl
> installation is a bit of a lift already, and if it's not packaged by
> major distros then it's really a problem for many people.  (Yeah, they
> may know what CPAN is, but they might have local policy issues about
> installing directly from there.)

Yes, that's not cool.  I am not pushing in this direction.  Sorry for
creating confusion with fuzzy wording.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/5/18 8:03 PM, Michael Paquier wrote:
> On Mon, Mar 05, 2018 at 05:11:29PM -0500, Tom Lane wrote:
>> David Steele <david@pgmasters.net> writes:
>>> On 2/28/18 2:28 AM, Michael Paquier wrote:
>>>> That's basically a recursive chmod, so chmod_recursive is more adapted?
>>>> I could imagine that this is useful as well for removing group
>>>> permissions, so the new mode could be specified as an argument.
>>
>>> The required package (File::chmod::Recursive) for chmod_recursive is not
>>> in use anywhere else and was not installed when I installed build
>>> dependencies.
>
> Woah.  I didn't even know that chmod_recursive existed and was part of a
> module.  What I commented about here was to rename to a more generic
> name the routine you are implementing so as other tests could use it.

OK, that is pretty funny.  I thought you were directing me to a Perl
function I hadn't heard of (but did exist).

>>> I'm not sure what the protocol for introducing a new Perl module is?  I
>>> couldn't find packages for the major OSes.  Are we OK with using CPAN?
>>
>> I don't think that's cool.  Anything that's not part of a standard Perl
>> installation is a bit of a lift already, and if it's not packaged by
>> major distros then it's really a problem for many people.  (Yeah, they
>> may know what CPAN is, but they might have local policy issues about
>> installing directly from there.)
>
> Yes, that's not cool.  I am not pushing in this direction.  Sorry for
> creating confusion with fuzzy wording.
No worries, I'll just make it more generic as suggested.

--
-David
david@pgmasters.net


Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Mon, Mar 05, 2018 at 03:07:20PM -0500, David Steele wrote:
> On 2/28/18 2:28 AM, Michael Paquier wrote:
>> On Tue, Feb 27, 2018 at 03:52:32PM -0500, David Steele wrote:
>> I don't quite understand here.  I have no objection into extending
>> setup_cluster() with a group_access argument so as the tests run both
>> the group access and without it, but I'd rather keep the low-level API
>> clean of anything fancy if we can use the facility which already
>> exists.
>
> I'm not sure what you mean by, "facility that already exists".  I think
> I implemented this the same as the allows_streaming and has_archiving
> flags.  The only difference is that this option must be set at initdb
> time rather than in postgresql.conf.
>
> Could you be more specific?

Let's remove has_group_access from PostgresNode::init and instead use
existing parameter called "extra".  In your patch, this setup:
has_group_access => 1
is equivalent to that:
extra => [ -g ]
You can also guess the value of has_group_access by parsing the
arguments from the array "extra".

> I think I prefer grouping 1 and 2.  It produces less churn, as you say,
> and I don't think MakeDirectoryDefaultPerm really needs its own patch.
> Based on comments so far, nobody has an objection to it.
>
> In theory, the first two patches could be applied just for refactoring
> without adding group permissions at all.  There are a lot of new tests
> to make sure permissions are set correctly so it seems like a win
> right off.

Okay, that's fine for me.

>> check_pg_data_perm() looks useful even without $allow_group even if the
>> grouping facility is reverted at the end.  S_ISLNK should be considered
>> as well for tablespaces or symlinks of pg_wal?  We have such cases in
>> the regression tests.
>
> Hmmm, the link is just pointing to a directory whose permissions have
> been changed.  Why do we need to worry about the link?

Oh, perhaps I misread your code here, but this ignores symlinks, for
example take an instance where pg_wal is symlinked, we'd likely want to
make sure that at least archive_status is using a correct set of
permissions, no?  There is a "follow" option in File::Find which could
help.

>> -    if (chmod(path, S_IRUSR | S_IWUSR) != 0)
>> -    {
>> -    fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"),
>> -        progname, path, strerror(errno));
>> -    exit_nicely();
>> -    }
>> Hm.  Why are those removed?
>
> When I started working on this, pg_upgrade did not set umask and instead
> did chmod for each dir created.  umask() has since been added (even
> before my patch) and so these are now noops.  Seemed easier to remove
> them than to change them all.
>
>>     setup_signals();
>>
>> -   umask(S_IRWXG | S_IRWXO);
>> -
>>     create_data_directory();
>> This should not be moved around.
>
> Hmmm - I moved it much earlier in the process which seems like a good
> thing.  Consider if there was a option to fixup permissions, like there
> is to fsync.  Isn't it best to set the mode as soon as possible to
> prevent code from being inserted before it?

Those two are separate issues.  Could you begin a new thread on the
matter?  This will attract more attention.

The indentation in RewindTest.pm is a bit wrong.

-   if (chmod(location, S_IRWXU) != 0)
+   current_umask = umask(0);
+   umask(current_umask);
[...]
-   if (chmod(pg_data, S_IRWXU) != 0)
+   if (chmod(pg_data, PG_DIR_MODE_DEFAULT & ~file_mode_mask) != 0)
Such modifications should be part of patch 3, not 2, where the group
features really apply.

    my $test_mode = shift;

+   umask(0077);
+
    RewindTest::setup_cluster($test_mode);
What's that for?  A comment would be welcome.

+# make sure all directories and files have group permissions
+if [ $(find ${PGDATA} -type f ! -perm 600 | wc -l) -ne 0 ]; then
+   echo "files in PGDATA with permission != 600";
+   exit 1;
+fi
Perhaps on hold if we are able to move pg_upgrade tests to a TAP
suite...  We'll see what happens.

Perhaps the tests should be cut into a separate patch?  Those are not
directly related to the refactoring done in patch 2.

Patch 2 begins to look fine for me.  I still need to look at patch 3 in
more details.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/5/18 10:46 PM, Michael Paquier wrote:
> On Mon, Mar 05, 2018 at 03:07:20PM -0500, David Steele wrote:
>> On 2/28/18 2:28 AM, Michael Paquier wrote:
>>> On Tue, Feb 27, 2018 at 03:52:32PM -0500, David Steele wrote:
>>> I don't quite understand here.  I have no objection into extending
>>> setup_cluster() with a group_access argument so as the tests run both
>>> the group access and without it, but I'd rather keep the low-level API
>>> clean of anything fancy if we can use the facility which already
>>> exists.
>>
>> I'm not sure what you mean by, "facility that already exists".  I think
>> I implemented this the same as the allows_streaming and has_archiving
>> flags.  The only difference is that this option must be set at initdb
>> time rather than in postgresql.conf.
>>
>> Could you be more specific?
>
> Let's remove has_group_access from PostgresNode::init and instead use
> existing parameter called "extra".  In your patch, this setup:
> has_group_access => 1
> is equivalent to that:
> extra => [ -g ]
> You can also guess the value of has_group_access by parsing the
> arguments from the array "extra".

OK.  extra is used to set -g and the group_access() function checks
pgdata directly since this can change after the cluster is created.

>>> check_pg_data_perm() looks useful even without $allow_group even if the
>>> grouping facility is reverted at the end.  S_ISLNK should be considered
>>> as well for tablespaces or symlinks of pg_wal?  We have such cases in
>>> the regression tests.
>>
>> Hmmm, the link is just pointing to a directory whose permissions have
>> been changed.  Why do we need to worry about the link?
>
> Oh, perhaps I misread your code here, but this ignores symlinks, for
> example take an instance where pg_wal is symlinked, we'd likely want to
> make sure that at least archive_status is using a correct set of
> permissions, no?  There is a "follow" option in File::Find which could
> help.

Ah, I see what you mean now.  Fixed using follow_fast.  This variant
claims to be faster and it doesn't matter if files are occasionally
checked twice.

>>
>>>     setup_signals();
>>>
>>> -   umask(S_IRWXG | S_IRWXO);
>>> -
>>>     create_data_directory();
>>> This should not be moved around.
>>
>> Hmmm - I moved it much earlier in the process which seems like a good
>> thing.  Consider if there was a option to fixup permissions, like there
>> is to fsync.  Isn't it best to set the mode as soon as possible to
>> prevent code from being inserted before it?
>
> Those two are separate issues.  Could you begin a new thread on the
> matter?  This will attract more attention.

OK, I'll move it back for now, and make a note to raise the position as
a separate issue.  I'd rather not do it in this fest, though.

> The indentation in RewindTest.pm is a bit wrong.

Fixed.

> -   if (chmod(location, S_IRWXU) != 0)
> +   current_umask = umask(0);
> +   umask(current_umask);
> [...]
> -   if (chmod(pg_data, S_IRWXU) != 0)
> +   if (chmod(pg_data, PG_DIR_MODE_DEFAULT & ~file_mode_mask) != 0)
> Such modifications should be part of patch 3, not 2, where the group
> features really apply.

The goal of patch 2 is to refactor the way permissions are set by
replacing locally hard-coded values with centralized values, so I think
this makes sense here.

>     my $test_mode = shift;
>
> +   umask(0077);

Added. (Ensure that all files are created with default data dir
permissions).

>     RewindTest::setup_cluster($test_mode);
> What's that for?  A comment would be welcome.

Added. (Used to differentiate clusters).

> Perhaps the tests should be cut into a separate patch?

I prefer tests to be in the same patch as the code they test.

> Those are not
> directly related to the refactoring done in patch 2.

The point of the tests is to be sure there are no regressions in the
refactor so they seem directly related to me.  Also, the tests
themselves were not to good about keeping permissions consistent.

> Patch 2 begins to look fine for me.

I also made chmod_recursive() generic.

New patches are attached.

Thanks!
--
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Tue, Mar 06, 2018 at 01:32:49PM -0500, David Steele wrote:
> On 3/5/18 10:46 PM, Michael Paquier wrote:
> Ah, I see what you mean now.  Fixed using follow_fast.  This variant
> claims to be faster and it doesn't matter if files are occasionally
> checked twice.

Fine for me.  I can see this option present in perl 5.8.8 as well, so we
should be good.

>> Those two are separate issues.  Could you begin a new thread on the
>> matter?  This will attract more attention.
>
> OK, I'll move it back for now, and make a note to raise the position as
> a separate issue.  I'd rather not do it in this fest, though.

Seems like you forgot to re-add the chmod calls in initdb.c.

>> -   if (chmod(location, S_IRWXU) != 0)
>> +   current_umask = umask(0);
>> +   umask(current_umask);
>> [...]
>> -   if (chmod(pg_data, S_IRWXU) != 0)
>> +   if (chmod(pg_data, PG_DIR_MODE_DEFAULT & ~file_mode_mask) != 0)
>> Such modifications should be part of patch 3, not 2, where the group
>> features really apply.
>
> The goal of patch 2 is to refactor the way permissions are set by
> replacing locally hard-coded values with centralized values, so I think
> this makes sense here.

Hm.  I would have left that out in this first version, now I am fine to
defer that to a committer's opinion as well.

>>     my $test_mode = shift;
>>
>> +   umask(0077);
>
> Added. (Ensure that all files are created with default data dir
> permissions).

+   # Ensure that all files are created with default data dir permissions
+   umask(0077);
I have stared at this comment two minutes to finally understand that
this refers to the extra files which are part of this test.  It may be
better to be a bit more precise here.  I thought first that this
referred as well to setup_cluster calls...

>> Patch 2 begins to look fine for me.
>
> I also made chmod_recursive() generic.

Likely this name is not worth worrying with conflicts in CPAN stuff ;)

+# Ensure all permissions in the pg_data directory are
correct. Permissions
+# should be dir = 0700, file = 0600.
+sub check_pg_data_perm
+{
check_permission_recursive() would be a more adapted name.  Stuff in
TestLib.pm is not necessarily linked to data folders.

sub clean_rewind_test
{
+   ok (check_pg_data_perm($node_master->data_dir(), 0));
+
    $node_master->teardown_node  if defined $node_master;
I have also a pending patch for pg_rewind which adds read-only files in
the data folders of a new test, so this would cause this part to blow
up.  Testing that for all the test sets does not bring additional value
as well, and doing it at cleanup phase is also confusing.  So could you
move that check into only one test's script?  You could remove the umask
call in 003_extrafiles.pl as well this way, and reduce the patch diffs.

+     if ($file_mode != 0600)
+     {
+         print(*STDERR, "$File::Find::name mode must be 0600\n");
+
+         $result = 0;
+         return
+     }
0600 should be replaced by $expected_file_perm, and isn't a ';' missing
for each return "clause" (how does this even work..)?

Patch 2 is getting close for a committer lookup I think, still need to
look at patch 3 in details..  And from patch 3:
     # Expected permission
-    my $expected_file_perm = 0600;
-    my $expected_dir_perm = 0700;
+    my $expected_file_perm = $allow_group ? 0640 : 0600;
+    my $expected_dir_perm = $allow_group ? 0750 : 0700;
Or $expected_file_perm and $expected_dir_perm could just be used as
arguments.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/6/18 10:04 PM, Michael Paquier wrote:
> On Tue, Mar 06, 2018 at 01:32:49PM -0500, David Steele wrote:
>> On 3/5/18 10:46 PM, Michael Paquier wrote:
>
>>> Those two are separate issues.  Could you begin a new thread on the
>>> matter?  This will attract more attention.
>>
>> OK, I'll move it back for now, and make a note to raise the position as
>> a separate issue.  I'd rather not do it in this fest, though.
>
> Seems like you forgot to re-add the chmod calls in initdb.c.

Hmmm, I thought we were talking about moving the position of umask().

I don't think the chmod() calls are needed because umask() is being set.
 The tests show that the config files have the proper permissions after
inidb, so this just looks like redundant code to me.

But, I'm not going to argue if you think they should go back.  It would
make the patch less noisy.

>>> -   if (chmod(location, S_IRWXU) != 0)
>>> +   current_umask = umask(0);
>>> +   umask(current_umask);
>>> [...]
>>> -   if (chmod(pg_data, S_IRWXU) != 0)
>>> +   if (chmod(pg_data, PG_DIR_MODE_DEFAULT & ~file_mode_mask) != 0)
>>> Such modifications should be part of patch 3, not 2, where the group
>>> features really apply.
>>
>> The goal of patch 2 is to refactor the way permissions are set by
>> replacing locally hard-coded values with centralized values, so I think
>> this makes sense here.
>
> Hm.  I would have left that out in this first version, now I am fine to
> defer that to a committer's opinion as well.

OK - I really do think it belongs here.  A committer may not agree, of
course.

>>>     my $test_mode = shift;
>>>
>>> +   umask(0077);
>>
>> Added. (Ensure that all files are created with default data dir
>> permissions).
>
> +   # Ensure that all files are created with default data dir permissions
> +   umask(0077);
> I have stared at this comment two minutes to finally understand that
> this refers to the extra files which are part of this test.  It may be
> better to be a bit more precise here.  I thought first that this
> referred as well to setup_cluster calls...

Updated to, "Ensure that all files created in this module for testing
are set with default data dir permissions."

> +# Ensure all permissions in the pg_data directory are
> correct. Permissions
> +# should be dir = 0700, file = 0600.
> +sub check_pg_data_perm
> +{
> check_permission_recursive() would be a more adapted name.  Stuff in
> TestLib.pm is not necessarily linked to data folders.

When we add group permissions we need to have special logic around
postmaster.pid.  This should be 0600 even if the rest of the files are 0640.

I can certainly remove that special logic in 02 and make this function
more generic, but then I think we would still have to add
check_pg_data_perm() in patch 03.

Another way to do this would be to make the function generic and
stipulate that the postmaster must be shut down before running the
function.  We could check postmaster.pid permissions as a separate test.

What do you think?

> sub clean_rewind_test
> {
> +   ok (check_pg_data_perm($node_master->data_dir(), 0));
> +
>     $node_master->teardown_node  if defined $node_master;
> I have also a pending patch for pg_rewind which adds read-only files in
> the data folders of a new test, so this would cause this part to blow
> up.  Testing that for all the test sets does not bring additional value
> as well, and doing it at cleanup phase is also confusing.  So could you
> move that check into only one test's script?  You could remove the umask
> call in 003_extrafiles.pl as well this way, and reduce the patch diffs.

I think I would rather have a way to skip the permission test rather
than disable it for most of the tests.  pg_rewind does more writes into
PGDATA that anything other than a backend.  Good coverage seems like a plus.

> +     if ($file_mode != 0600)
> +     {
> +         print(*STDERR, "$File::Find::name mode must be 0600\n");
> +
> +         $result = 0;
> +         return
> +     }
> 0600 should be replaced by $expected_file_perm, and isn't a ';' missing
> for each return "clause" (how does this even work..)?

Well, 0600 is a special case -- see above.  As for the missing
semi-colon, well that's Perl for you.  Fixed.

> Patch 2 is getting close for a committer lookup I think, still need to
> look at patch 3 in details..  And from patch 3:
>      # Expected permission
> -    my $expected_file_perm = 0600;
> -    my $expected_dir_perm = 0700;
> +    my $expected_file_perm = $allow_group ? 0640 : 0600;
> +    my $expected_dir_perm = $allow_group ? 0750 : 0700;
> Or $expected_file_perm and $expected_dir_perm could just be used as
> arguments.

This gets back to the check_pg_data_perm() discussion above.

I'll hold off on another set of patches until I hear back from you.
There were only trivial changes as noted above.

Thanks,
--
-David
david@pgmasters.net


Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Wed, Mar 07, 2018 at 10:56:32AM -0500, David Steele wrote:
> On 3/6/18 10:04 PM, Michael Paquier wrote:
>> Seems like you forgot to re-add the chmod calls in initdb.c.
>
> Hmmm, I thought we were talking about moving the position of umask().
>
> I don't think the chmod() calls are needed because umask() is being set.
>  The tests show that the config files have the proper permissions after
> inidb, so this just looks like redundant code to me.

Let's discuss that on a separate thread then, there could be something
we are missing, but I agree that those should not be needed.  Looking at
the code history, those calls have been around since the beginning of
PG-times.

> Another way to do this would be to make the function generic and
> stipulate that the postmaster must be shut down before running the
> function.  We could check postmaster.pid permissions as a separate
> test.

Yeah, that looks like a sensitive approach as this could be run
post-initdb or after taking a backup.  This way we would avoid other
similar behaviors in the future...  Still postmaster.pid is an
exception.

>> sub clean_rewind_test
>> {
>> +   ok (check_pg_data_perm($node_master->data_dir(), 0));
>> +
>>     $node_master->teardown_node  if defined $node_master;
>> I have also a pending patch for pg_rewind which adds read-only files in
>> the data folders of a new test, so this would cause this part to blow
>> up.  Testing that for all the test sets does not bring additional value
>> as well, and doing it at cleanup phase is also confusing.  So could you
>> move that check into only one test's script?  You could remove the umask
>> call in 003_extrafiles.pl as well this way, and reduce the patch diffs.
>
> I think I would rather have a way to skip the permission test rather
> than disable it for most of the tests.  pg_rewind does more writes into
> PGDATA that anything other than a backend.  Good coverage seems like a
> plus.

All the tests basically run the same scenario, wiht minimal variations,
so let's do the test once in the test touching the highest amount of
files and call it good.

>> Patch 2 is getting close for a committer lookup I think, still need to
>> look at patch 3 in details..  And from patch 3:
>>      # Expected permission
>> -    my $expected_file_perm = 0600;
>> -    my $expected_dir_perm = 0700;
>> +    my $expected_file_perm = $allow_group ? 0640 : 0600;
>> +    my $expected_dir_perm = $allow_group ? 0750 : 0700;
>> Or $expected_file_perm and $expected_dir_perm could just be used as
>> arguments.
>
> This gets back to the check_pg_data_perm() discussion above.
>
> I'll hold off on another set of patches until I hear back from you.
> There were only trivial changes as noted above.

OK, let's keep things simple here and assume that the grouping extension
is not available yet.  So no extra parameters should be needed.

I have begun to read through patch 3.

-    if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
+    if (stat_buf.st_mode & PG_MODE_MASK_ALLOW_GROUP)
         ereport(FATAL,
             (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
-             errmsg("data directory \"%s\" has group or world access",
+             errmsg("data directory \"%s\" has invalid permissions",
                     DataDir),
-             errdetail("Permissions should be u=rwx (0700).")));
+             errdetail("Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).")));
Hm.  This relaxes the checks and concerns me a lot.  What if users want
to keep strict permission all the time and rely on the existing check to
be sure that this gets never changed post-initdb?  For such users, we
may want to track if cluster has been initialized with group access, in
which case tracking that in the control file would be more adapted.
Then the startup checks should use this configuration.  Another idea
would be a startup option.  So, I cannot believe that all users would
like to see such checks relaxed.  Some of my users would surely complain
about such sanity checks relaxed unconditionally, so making this
configurable would be fine, and the current approach is not acceptable
in my opinion.

Patch 2 introduces some standards regarding file permissions as those
are copied all over the code tree, which is definitely good in my
opinion. I am rather reserved about patch 3 per what I am seeing now.
Looking in-depth at the security-related requirements would take more
time than I have now.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Michael,

On 3/7/18 8:51 PM, Michael Paquier wrote:
> On Wed, Mar 07, 2018 at 10:56:32AM -0500, David Steele wrote:
>> On 3/6/18 10:04 PM, Michael Paquier wrote:
>>> Seems like you forgot to re-add the chmod calls in initdb.c.
>>
>> Hmmm, I thought we were talking about moving the position of umask().
>>
>> I don't think the chmod() calls are needed because umask() is being set.
>>  The tests show that the config files have the proper permissions after
>> inidb, so this just looks like redundant code to me.
>
> Let's discuss that on a separate thread then, there could be something
> we are missing, but I agree that those should not be needed.  Looking at
> the code history, those calls have been around since the beginning of
> PG-times.

Done.

>> Another way to do this would be to make the function generic and
>> stipulate that the postmaster must be shut down before running the
>> function.  We could check postmaster.pid permissions as a separate
>> test.
>
> Yeah, that looks like a sensitive approach as this could be run
> post-initdb or after taking a backup.  This way we would avoid other
> similar behaviors in the future...  Still postmaster.pid is an
> exception.

Done.

>>> sub clean_rewind_test
>>> {
>>> +   ok (check_pg_data_perm($node_master->data_dir(), 0));
>>> +
>>>     $node_master->teardown_node  if defined $node_master;
>>> I have also a pending patch for pg_rewind which adds read-only files in
>>> the data folders of a new test, so this would cause this part to blow
>>> up.  Testing that for all the test sets does not bring additional value
>>> as well, and doing it at cleanup phase is also confusing.  So could you
>>> move that check into only one test's script?  You could remove the umask
>>> call in 003_extrafiles.pl as well this way, and reduce the patch diffs.
>>
>> I think I would rather have a way to skip the permission test rather
>> than disable it for most of the tests.  pg_rewind does more writes into
>> PGDATA that anything other than a backend.  Good coverage seems like a
>> plus.
>
> All the tests basically run the same scenario, with minimal variations,
> so let's do the test once in the test touching the highest amount of
> files and call it good.

OK, test 001 is used to check default mode and 002 is used to check
group mode.  The rest are left as-is.  Does that work for you?

> I have begun to read through patch 3.
>
> -    if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
> +    if (stat_buf.st_mode & PG_MODE_MASK_ALLOW_GROUP)
>          ereport(FATAL,
>              (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
> -             errmsg("data directory \"%s\" has group or world access",
> +             errmsg("data directory \"%s\" has invalid permissions",
>                      DataDir),
> -             errdetail("Permissions should be u=rwx (0700).")));
> +             errdetail("Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).")));
> Hm.  This relaxes the checks and concerns me a lot.  What if users want
> to keep strict permission all the time and rely on the existing check to
> be sure that this gets never changed post-initdb?  For such users, we
> may want to track if cluster has been initialized with group access, in
> which case tracking that in the control file would be more adapted.
> Then the startup checks should use this configuration.  Another idea
> would be a startup option.  So, I cannot believe that all users would
> like to see such checks relaxed.  Some of my users would surely complain
> about such sanity checks relaxed unconditionally, so making this
> configurable would be fine, and the current approach is not acceptable
> in my opinion.

How about a GUC that enforces one mode or the other on startup?  Default
would be 700.  The GUC can be set automatically by initdb based on the
-g option.  We had this GUC originally, but since the front-end tools
can't read it we abandoned it.  Seems like it would be good as an
enforcing mechanism, though.

Thanks,
--
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Fri, Mar 09, 2018 at 01:51:14PM -0500, David Steele wrote:
> How about a GUC that enforces one mode or the other on startup?  Default
> would be 700.  The GUC can be set automatically by initdb based on the
> -g option.  We had this GUC originally, but since the front-end tools
> can't read it we abandoned it.  Seems like it would be good as an
> enforcing mechanism, though.

Hm.  OK.  I can see the whole set of points about that.  Please let me
think a bit more about that bit.  Do you think that there could be a
pool of users willing to switch from one mode to another?  Compared to
your v1, we could indeed have a GUC which enforces a restriction to not
allow group access, and enabled by default.  As the commit fest is
running and we don't have a clear picture yet, I am afraid that it may
be better to move that to v12, and focus on getting patches 1 and 2
committed. This will provide a good base for the next move.

There are three places where things are still not correct:

-   if (chmod(location, S_IRWXU) != 0)
+   current_umask = umask(0);
+   umask(current_umask);
+
+   if (chmod(location, PG_DIR_MODE_DEFAULT & ~current_umask) != 0)
This is in tablespace.c.

@@ -185,6 +186,9 @@ main(int argc, char **argv)
        exit(1);
            }

+   /* Set dir/file mode mask */
+   umask(PG_MODE_MASK_DEFAULT);
+
In pg_rewind and pg_resetwal, isn't that also a portion which is not
necessary without the group access feature?

This is all I have basically for patch 2, which would be good for
shipping.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Michael, David,

* Michael Paquier (michael@paquier.xyz) wrote:
> On Fri, Mar 09, 2018 at 01:51:14PM -0500, David Steele wrote:
> > How about a GUC that enforces one mode or the other on startup?  Default
> > would be 700.  The GUC can be set automatically by initdb based on the
> > -g option.  We had this GUC originally, but since the front-end tools
> > can't read it we abandoned it.  Seems like it would be good as an
> > enforcing mechanism, though.
>
> Hm.  OK.  I can see the whole set of points about that.  Please let me
> think a bit more about that bit.  Do you think that there could be a
> pool of users willing to switch from one mode to another?  Compared to
> your v1, we could indeed have a GUC which enforces a restriction to not
> allow group access, and enabled by default.  As the commit fest is
> running and we don't have a clear picture yet, I am afraid that it may
> be better to move that to v12, and focus on getting patches 1 and 2
> committed. This will provide a good base for the next move.

We already had a discussion about having a GUC for this and concluded,
rightly in my view, that it's not sensible to have since we don't want
all of the various tools having to read and parse out postgresql.conf.

I don't see anything in the discussion which has changed that and I
don't agree that there's an issue with using the privileges on the data
directory for this- it's a simple solution which all of the tools can
use and work with easily.  I certainly don't agree that it's a serious
issue to relax the explicit check- it's just a check, which a user could
implement themselves if they wished to and had a concern for.  On the
other hand, with the explicit check, we are actively preventing an
entirely reasonable goal of wanting to use a read-only role to perform a
backup of the system.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Mon, Mar 12, 2018 at 03:14:13PM -0400, Stephen Frost wrote:
> We already had a discussion about having a GUC for this and concluded,
> rightly in my view, that it's not sensible to have since we don't want
> all of the various tools having to read and parse out postgresql.conf.

If the problem is parsing, it could as well be more portable to put that
in the control file, no?  I have finished for example finished by
implementing my own flavor of pg_controldata to save parsing efforts
soas it prints control file fields on a per-call basis using individual
fields, which saved also games with locales for as translations of
pg_controldata can disturb the parsing logic.

> I don't see anything in the discussion which has changed that and I
> don't agree that there's an issue with using the privileges on the data
> directory for this- it's a simple solution which all of the tools can
> use and work with easily.  I certainly don't agree that it's a serious
> issue to relax the explicit check- it's just a check, which a user could
> implement themselves if they wished to and had a concern for.  On the
> other hand, with the explicit check, we are actively preventing an
> entirely reasonable goal of wanting to use a read-only role to perform a
> backup of the system.

Well, one thing is that the current checks in the postmaster make sure
that a data folder is never using anything else than 0700.  From a
security point of view, making it possible to allow a postmaster to
start with 0750 is a step backwards if users don't authorize it
explicitely.  There are a lot of systems which use a bunch of users with
only single group with systemd.  So this would remove an existing
safeguard.  I am not against the idea of this thread, just that I think
that secured defaults should be user-enforceable if they want Postgres
to behave so.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Michael,

* Michael Paquier (michael@paquier.xyz) wrote:
> On Mon, Mar 12, 2018 at 03:14:13PM -0400, Stephen Frost wrote:
> > We already had a discussion about having a GUC for this and concluded,
> > rightly in my view, that it's not sensible to have since we don't want
> > all of the various tools having to read and parse out postgresql.conf.
>
> If the problem is parsing, it could as well be more portable to put that
> in the control file, no?  I have finished for example finished by
> implementing my own flavor of pg_controldata to save parsing efforts
> soas it prints control file fields on a per-call basis using individual
> fields, which saved also games with locales for as translations of
> pg_controldata can disturb the parsing logic.

Then we'd need a tool to allow changing it for people who do want to
change it.  There's no reason we should have to have an extra tool for
this- an administrator who chooses to change the privileges on the data
folder should be able to do so and I don't think anyone is going to
thank us for requiring them to use some special tool to do so for
PostgreSQL.

> > I don't see anything in the discussion which has changed that and I
> > don't agree that there's an issue with using the privileges on the data
> > directory for this- it's a simple solution which all of the tools can
> > use and work with easily.  I certainly don't agree that it's a serious
> > issue to relax the explicit check- it's just a check, which a user could
> > implement themselves if they wished to and had a concern for.  On the
> > other hand, with the explicit check, we are actively preventing an
> > entirely reasonable goal of wanting to use a read-only role to perform a
> > backup of the system.
>
> Well, one thing is that the current checks in the postmaster make sure
> that a data folder is never using anything else than 0700.  From a
> security point of view, making it possible to allow a postmaster to
> start with 0750 is a step backwards if users don't authorize it
> explicitely.  There are a lot of systems which use a bunch of users with
> only single group with systemd.  So this would remove an existing
> safeguard.  I am not against the idea of this thread, just that I think
> that secured defaults should be user-enforceable if they want Postgres
> to behave so.

I'm aware of what the current one-time check in the postmaster does, and
that we don't implement it on all platforms, making me seriously doubt
that the level of concern being raised here makes sense.  Should we
consider it a security issue that the Windows builds don't perform this
check, and never has?

Further, if the permissions are changed without authorization, it's
probably done while the database is running and unlikely to be noticed
for days, weeks, or longer, if the administrator is depending on PG to
let them know of the change.  Considering that the only user who can
change the privileges is a database owner or root, it seems even less
likely to help (why would an attacker change those privileges when they
already have full access?).

Lastly, the user *is* able to enforce the privileges on the data
directory if they wish to, using tools such as tripwire which are built
specifically to provide such checks and to do so regularly instead of
the extremely ad-hoc check provided by PG.

PostgreSQL should, and does, secure the data directory when it's created
by initdb, and subsequent files and directories are similairly secured
appropriately.  Ultimately, the default which makes sense here isn't a
one-size-fits-all but is system dependent and the administrator should
be able to choose what permissions they want to have.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/13/18 2:46 AM, Michael Paquier wrote:
> On Mon, Mar 12, 2018 at 03:14:13PM -0400, Stephen Frost wrote:
>> We already had a discussion about having a GUC for this and concluded,
>> rightly in my view, that it's not sensible to have since we don't want
>> all of the various tools having to read and parse out postgresql.conf.
>
> If the problem is parsing, it could as well be more portable to put that
> in the control file, no?

The current approach is based on early discussion of this patch, around
[1] and [2] in particular.  I proposed an enforcing GUC at that time but
there wasn't any interest in the idea.

I definitely think it's overkill to put a field in pg_control as that
requires more tooling to update values.

>> I don't see anything in the discussion which has changed that and I
>> don't agree that there's an issue with using the privileges on the data
>> directory for this- it's a simple solution which all of the tools can
>> use and work with easily.  I certainly don't agree that it's a serious
>> issue to relax the explicit check- it's just a check, which a user could
>> implement themselves if they wished to and had a concern for.  On the
>> other hand, with the explicit check, we are actively preventing an
>> entirely reasonable goal of wanting to use a read-only role to perform a
>> backup of the system.
>
> Well, one thing is that the current checks in the postmaster make sure
> that a data folder is never using anything else than 0700.  From a
> security point of view, making it possible to allow a postmaster to
> start with 0750 is a step backwards if users don't authorize it
> explicitely.

I would argue that changing the mode of PGDATA is explicit, even if it
is accidental.  To be clear, after a pg_upgrade the behavior of the
cluster WRT to setting the mode would be exactly the same as now.  The
user would need to specify -g at initdb time or explicitly update PGDATA
to 750 for group access to be enabled.

> There are a lot of systems which use a bunch of users with
> only single group with systemd.  So this would remove an existing
> safeguard.  I am not against the idea of this thread, just that I think
> that secured defaults should be user-enforceable if they want Postgres
> to behave so.

As Stephen notes, this can be enforced by the user if they want to, and
without much effort (and with better tools).

Regards,
--
-David
david@pgmasters.net

[1] https://www.postgresql.org/message-id/20526.1489428968%40sss.pgh.pa.us
[2] https://www.postgresql.org/message-id/22248.1489431803%40sss.pgh.pa.us


Attachment

Re: PATCH: Configurable file mode mask

From
Tom Lane
Date:
Stephen Frost <sfrost@snowman.net> writes:
> * Michael Paquier (michael@paquier.xyz) wrote:
>> If the problem is parsing, it could as well be more portable to put that
>> in the control file, no?

> Then we'd need a tool to allow changing it for people who do want to
> change it.  There's no reason we should have to have an extra tool for
> this- an administrator who chooses to change the privileges on the data
> folder should be able to do so and I don't think anyone is going to
> thank us for requiring them to use some special tool to do so for
> PostgreSQL.

FWIW, I took a quick look through this patch and don't have any problem
with the approach, which appears to be "use the data directory's
startup-time permissions as the status indicator".  I am kinda wondering
about this though:

+    (These files can confuse <application>pg_ctl</application>.)  If group read
+    access is enabled on the data directory and an unprivileged user in the
+    <productname>PostgreSQL</productname> group is performing the backup, then
+    <filename>postmaster.pid</filename> will not be readable and must be
+    excluded.

If we're allowing group read on the data directory, why should that not
include postmaster.pid?  There's nothing terribly security-relevant in
there, and being able to find out the postmaster PID seems useful.  I can
see the point of restricting server key files, as documented elsewhere,
but it's possible to keep those somewhere else so they don't cause
problems for simple backup software.

Also, in general, this patch desperately needs a round of copy-editing,
particularly with attention to the comments.  For instance, there are a
minimum of three grammatical errors in this one comment:

+ * Group read/execute may optional be enabled on PGDATA so any frontend tools
+ * That write into PGDATA must know what mask to set and the permissions to
+ * use for creating files and directories.

In a larger sense, this fails to explain the operating principle,
namely what I stated above, that we allow the existing permissions
on PGDATA to decide what we allow as group permissions.  If you
don't already understand that, you're going to have a hard time
extracting it from either file_perm.h or file_perm.c.  (The latter
fails to even explain what the argument of DataDirectoryMask is.)

            regards, tom lane


Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/13/18 11:00 AM, Tom Lane wrote:
> Stephen Frost <sfrost@snowman.net> writes:
>> * Michael Paquier (michael@paquier.xyz) wrote:
>>> If the problem is parsing, it could as well be more portable to put that
>>> in the control file, no?
> 
>> Then we'd need a tool to allow changing it for people who do want to
>> change it.  There's no reason we should have to have an extra tool for
>> this- an administrator who chooses to change the privileges on the data
>> folder should be able to do so and I don't think anyone is going to
>> thank us for requiring them to use some special tool to do so for
>> PostgreSQL.
> 
> FWIW, I took a quick look through this patch and don't have any problem
> with the approach, which appears to be "use the data directory's
> startup-time permissions as the status indicator".  I am kinda wondering
> about this though:
> 
> +    (These files can confuse <application>pg_ctl</application>.)  If group read
> +    access is enabled on the data directory and an unprivileged user in the
> +    <productname>PostgreSQL</productname> group is performing the backup, then
> +    <filename>postmaster.pid</filename> will not be readable and must be
> +    excluded.
> 
> If we're allowing group read on the data directory, why should that not
> include postmaster.pid?  There's nothing terribly security-relevant in
> there, and being able to find out the postmaster PID seems useful.  I can
> see the point of restricting server key files, as documented elsewhere,
> but it's possible to keep those somewhere else so they don't cause
> problems for simple backup software.

I'm OK with that.  I had a look at the warnings regarding the required
mode of postmaster.pid in miscinit.c (889-911) and it seems to me they
still hold true if the mode is 640 instead of 600.

Do you agree, Tom?  Stephen?

If so, I'll make those changes.

> Also, in general, this patch desperately needs a round of copy-editing,
> particularly with attention to the comments.  For instance, there are a
> minimum of three grammatical errors in this one comment:
> 
> + * Group read/execute may optional be enabled on PGDATA so any frontend tools
> + * That write into PGDATA must know what mask to set and the permissions to
> + * use for creating files and directories.

> In a larger sense, this fails to explain the operating principle,
> namely what I stated above, that we allow the existing permissions
> on PGDATA to decide what we allow as group permissions.  If you
> don't already understand that, you're going to have a hard time
> extracting it from either file_perm.h or file_perm.c.  (The latter
> fails to even explain what the argument of DataDirectoryMask is.)
I'll do comment/doc review for the next round of patches.

Thanks,
-- 
-David
david@pgmasters.net


Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Greetings,

* David Steele (david@pgmasters.net) wrote:
> On 3/13/18 11:00 AM, Tom Lane wrote:
> > Stephen Frost <sfrost@snowman.net> writes:
> >> * Michael Paquier (michael@paquier.xyz) wrote:
> >>> If the problem is parsing, it could as well be more portable to put that
> >>> in the control file, no?
> >
> >> Then we'd need a tool to allow changing it for people who do want to
> >> change it.  There's no reason we should have to have an extra tool for
> >> this- an administrator who chooses to change the privileges on the data
> >> folder should be able to do so and I don't think anyone is going to
> >> thank us for requiring them to use some special tool to do so for
> >> PostgreSQL.
> >
> > FWIW, I took a quick look through this patch and don't have any problem
> > with the approach, which appears to be "use the data directory's
> > startup-time permissions as the status indicator".  I am kinda wondering
> > about this though:
> >
> > +    (These files can confuse <application>pg_ctl</application>.)  If group read
> > +    access is enabled on the data directory and an unprivileged user in the
> > +    <productname>PostgreSQL</productname> group is performing the backup, then
> > +    <filename>postmaster.pid</filename> will not be readable and must be
> > +    excluded.
> >
> > If we're allowing group read on the data directory, why should that not
> > include postmaster.pid?  There's nothing terribly security-relevant in
> > there, and being able to find out the postmaster PID seems useful.  I can
> > see the point of restricting server key files, as documented elsewhere,
> > but it's possible to keep those somewhere else so they don't cause
> > problems for simple backup software.
>
> I'm OK with that.  I had a look at the warnings regarding the required
> mode of postmaster.pid in miscinit.c (889-911) and it seems to me they
> still hold true if the mode is 640 instead of 600.
>
> Do you agree, Tom?  Stephen?
>
> If so, I'll make those changes.

I agree that we can still consider an EPERM-error case as being ok even
with the changes proposed, and with the same-user check happening
earlier in checkDataDir(), we won't even get to the point of looking at
the pid file if the userid's don't match.  The historical comment about
the old datadir permissions can likely just be removed, perhaps replaced
with a bit more commentary above that check in checkDataDir().  The
open() call should also fail if we only have group-read privileges on
the file (0640), but surely the kill() will in any case.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Michael,

On 3/12/18 3:28 AM, Michael Paquier wrote:
> On Fri, Mar 09, 2018 at 01:51:14PM -0500, David Steele wrote:
>> How about a GUC that enforces one mode or the other on startup?  Default
>> would be 700.  The GUC can be set automatically by initdb based on the
>> -g option.  We had this GUC originally, but since the front-end tools
>> can't read it we abandoned it.  Seems like it would be good as an
>> enforcing mechanism, though.
>
> Hm.  OK.  I can see the whole set of points about that.  Please let me
> think a bit more about that bit.  Do you think that there could be a
> pool of users willing to switch from one mode to another?  Compared to
> your v1, we could indeed have a GUC which enforces a restriction to not
> allow group access, and enabled by default.  As the commit fest is
> running and we don't have a clear picture yet, I am afraid that it may
> be better to move that to v12, and focus on getting patches 1 and 2
> committed. This will provide a good base for the next move.
>
> There are three places where things are still not correct:
>
> -   if (chmod(location, S_IRWXU) != 0)
> +   current_umask = umask(0);
> +   umask(current_umask);
> +
> +   if (chmod(location, PG_DIR_MODE_DEFAULT & ~current_umask) != 0)
> This is in tablespace.c.

I have moved this hunk to 03 and used only PG_DIR_MODE_DEFAULT instead.

> @@ -185,6 +186,9 @@ main(int argc, char **argv)
>         exit(1);
>             }
>
> +   /* Set dir/file mode mask */
> +   umask(PG_MODE_MASK_DEFAULT);
> +
> In pg_rewind and pg_resetwal, isn't that also a portion which is not
> necessary without the group access feature?

These seem like a good idea to me with or without patch 03.  Some of our
front-end tools (initdb, pg_upgrade) were setting umask and others
weren't.  I think it's more consistent (and safer) if they all do, at
least if they are writing into PGDATA.

> This is all I have basically for patch 2, which would be good for
> shipping.

Thanks!

I'll attach new patches in a reply to [1] once I have made the changes
Tom requested.

--
-David
david@pgmasters.net

[1] https://www.postgresql.org/message-id/22928.1520953220%40sss.pgh.pa.us


Attachment

Re: PATCH: Configurable file mode mask

From
Tom Lane
Date:
David Steele <david@pgmasters.net> writes:
> On 3/12/18 3:28 AM, Michael Paquier wrote:
>> In pg_rewind and pg_resetwal, isn't that also a portion which is not
>> necessary without the group access feature?

> These seem like a good idea to me with or without patch 03.  Some of our
> front-end tools (initdb, pg_upgrade) were setting umask and others
> weren't.  I think it's more consistent (and safer) if they all do, at
> least if they are writing into PGDATA.

+1 ... see a926eb84e for an example of how easy it is to screw up if
the process's overall umask is permissive.

            regards, tom lane


Re: PATCH: Configurable file mode mask

From
Chapman Flack
Date:
On 03/13/2018 10:40 AM, Stephen Frost wrote:
> * Michael Paquier (michael@paquier.xyz) wrote:
>> Well, one thing is that the current checks in the postmaster make sure
>> that a data folder is never using anything else than 0700.  From a
>> security point of view, making it possible to allow a postmaster to
>> start with 0750 is a step backwards ...

> Lastly, the user *is* able to enforce the privileges on the data
> directory if they wish to, using tools such as tripwire which are built
> specifically to provide such checks and to do so regularly instead of
> the extremely ad-hoc check provided by PG.
> 
> ...  Ultimately, the default which makes sense here isn't a
> one-size-fits-all but is system dependent and the administrator should
> be able to choose what permissions they want to have.

Hear, hear. Returning for a moment again to

https://www.postgresql.org/message-id/8b16cc30-0187-311e-04b5-1f32446d89dd%40anastigmatix.net

we see that a stat() returning mode 0750 on a modern system may not
even mean there is any group access at all. In that example, the
datadir had these permissions:

# getfacl .
# file: .
# owner: postgres
# group: postgres
user::rwx
user:root:r-x
group::---
mask::r-x
other::---

While PostgreSQL does its stat() and interprets the mode as if it is
still on a Unix box from the '80s, two things have changed underneath
it: POSIX ACLs and Linux capabilities. Capabilities take the place of
the former specialness of root, who now needs to be granted r-x
explicitly in the ACL to be able to read stuff there at all, and there
is clearly no access to group and no access to other. It would be hard
for anybody to call this an insecure configuration. But when you stat()
an object with a POSIX ACL, you get the 'mask' value where the 'group'
bits used to go, so postgres sees this as 0750, thinks the 5 represents
group access, and refuses to start. Purely a mistake.

It's the kind of mistake that is inherent in this sort of check,
which tries to draw conclusions from the semantics it assumes, while
systems evolve and semantics march along. One hypothetical fix would
be to add:

#ifdef HAS_POSIX_ACLS
... check if there's really an ACL here, and the S_IRWXG bits are
really just the mask, or even try to pass judgment on whether the
admin's chosen ACL is adequately secure ...
#endif

but then sooner or later it will still end up making assumptions
that aren't true under, say, SELinux, so there's another #ifdef,
and where does it end?

On 03/13/2018 11:00 AM, Tom Lane wrote:
> In a larger sense, this fails to explain the operating principle,
> namely what I stated above, that we allow the existing permissions
> on PGDATA to decide what we allow as group permissions.

I admit I've only skimmed the patches, trying to determine what
that will mean in practice. In a case like the ACL example above,
does this mean that postgres will stat PGDATA, conclude incorrectly
that group access is granted, and then, based on that, actually go
granting unwanted group access for real on newly-created files
and directories?

That doesn't seem ideal.

On 03/13/2018 10:45 AM, David Steele wrote:
> As Stephen notes, this can be enforced by the user if they want to,
> and without much effort (and with better tools).

To me, that seems really the key. An --allow-group-access option is
nice (but, as we see, misleading if its assumptions are outdated
regarding how the filesystem works), but I would plug even harder for
a --permission-transparency option, which would just assume that the
admin is making security arrangements, through mechanisms that
postgres may or may not even understand. The admin can create ACLs
with default entries that propagate to newly created objects.
SELinux contexts can work in similar ways. The admin controls the
umask inherited by the postmaster. A --permission-transparency option
would simply use open and mkdir in the traditional ways, allowing
the chosen umask, ACL defaults, SELinux contexts, etc., to do their
thing, and would avoid then stepping on the results with explicit
chmods (and of course skip the I-refuse-to-start-because-I-
misunderstand-your-setup check).

It wouldn't be for every casual install, but it would be the best
way to stay out of the way of an admin securing a system with modern
facilities.

A lot of the design effort put into debating what postgres itself
should or shouldn't insist on could then, perhaps, go into writing
postgres-specific configuration rule packages for some of those
better configuration-checking tools, and there it might even be
possible to write tests that incorporate knowledge of ACLs, SELinux,
etc.

-Chap


Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Greetings Chapman,

* Chapman Flack (chap@anastigmatix.net) wrote:
> On 03/13/2018 10:40 AM, Stephen Frost wrote:
> > ...  Ultimately, the default which makes sense here isn't a
> > one-size-fits-all but is system dependent and the administrator should
> > be able to choose what permissions they want to have.
>
> Hear, hear. Returning for a moment again to
>
> https://www.postgresql.org/message-id/8b16cc30-0187-311e-04b5-1f32446d89dd%40anastigmatix.net
>
> we see that a stat() returning mode 0750 on a modern system may not
> even mean there is any group access at all. In that example, the
> datadir had these permissions:

Yes, that's true, but PG has never paid attention to POSIX ACLs or Linux
capabilities.  Changing it to do so is quite a bit beyond the scope of
this particular patch and I don't see anything in what this patch is
doing which would preclude someone from putting in that effort in the
future.

> While PostgreSQL does its stat() and interprets the mode as if it is
> still on a Unix box from the '80s, two things have changed underneath
> it: POSIX ACLs and Linux capabilities. Capabilities take the place of
> the former specialness of root, who now needs to be granted r-x
> explicitly in the ACL to be able to read stuff there at all, and there
> is clearly no access to group and no access to other. It would be hard
> for anybody to call this an insecure configuration. But when you stat()
> an object with a POSIX ACL, you get the 'mask' value where the 'group'
> bits used to go, so postgres sees this as 0750, thinks the 5 represents
> group access, and refuses to start. Purely a mistake.

I'll point out that PG does run on quite a few other OS's beyond Linux.

> It's the kind of mistake that is inherent in this sort of check,
> which tries to draw conclusions from the semantics it assumes, while
> systems evolve and semantics march along. One hypothetical fix would
> be to add:
>
> #ifdef HAS_POSIX_ACLS
> ... check if there's really an ACL here, and the S_IRWXG bits are
> really just the mask, or even try to pass judgment on whether the
> admin's chosen ACL is adequately secure ...
> #endif
>
> but then sooner or later it will still end up making assumptions
> that aren't true under, say, SELinux, so there's another #ifdef,
> and where does it end?

I agree with this general concern.

> On 03/13/2018 11:00 AM, Tom Lane wrote:
> > In a larger sense, this fails to explain the operating principle,
> > namely what I stated above, that we allow the existing permissions
> > on PGDATA to decide what we allow as group permissions.
>
> I admit I've only skimmed the patches, trying to determine what
> that will mean in practice. In a case like the ACL example above,
> does this mean that postgres will stat PGDATA, conclude incorrectly
> that group access is granted, and then, based on that, actually go
> granting unwanted group access for real on newly-created files
> and directories?

PG will stat PGDATA and conclude that the system is saying that group
access has been granted on PGDATA and will do the same for subsequent
files created later on.  This is new in PG, so there isn't any concern
about this causing problems in an existing environment- you couldn't
have had those ACLs on an existing PGDATA dir in the first place, as you
note above.  The only issue that remains is that PG doesn't understand
or work with POSIX ACLs or Linux capabilities, but that's not anything
new.

> On 03/13/2018 10:45 AM, David Steele wrote:
> > As Stephen notes, this can be enforced by the user if they want to,
> > and without much effort (and with better tools).
>
> To me, that seems really the key. An --allow-group-access option is
> nice (but, as we see, misleading if its assumptions are outdated
> regarding how the filesystem works), but I would plug even harder for
> a --permission-transparency option, which would just assume that the
> admin is making security arrangements, through mechanisms that
> postgres may or may not even understand. The admin can create ACLs
> with default entries that propagate to newly created objects.
> SELinux contexts can work in similar ways. The admin controls the
> umask inherited by the postmaster. A --permission-transparency option
> would simply use open and mkdir in the traditional ways, allowing
> the chosen umask, ACL defaults, SELinux contexts, etc., to do their
> thing, and would avoid then stepping on the results with explicit
> chmods (and of course skip the I-refuse-to-start-because-I-
> misunderstand-your-setup check).
>
> It wouldn't be for every casual install, but it would be the best
> way to stay out of the way of an admin securing a system with modern
> facilities.
>
> A lot of the design effort put into debating what postgres itself
> should or shouldn't insist on could then, perhaps, go into writing
> postgres-specific configuration rule packages for some of those
> better configuration-checking tools, and there it might even be
> possible to write tests that incorporate knowledge of ACLs, SELinux,
> etc.

I'm a fan of this idea in general, but it's unclear how that
--permission-transparency option would work in practice.  Are you
suggesting that it be a compile-time flag, which would certainly work
but also then have to be debated among packagers as to the right setting
and if there's any need to be concerned about users misunderstanding it,
or a flag for each program, which hardly seems ideal as some invokations
of programs might forget to specify that, leading to inconsistent
permissions, or something else..?  We've pretty well established that
there's no particularly good way for PG to just "know" beyond looking at
the privileges on the data directory, but we'd have to build in complete
support for POSIX ACLs and Linux capabilities if we go down a route
where we want to enforce the same POSIX ACLs for every file that exists
in the data directory based on the data directory's ACLs.  I'm not
entirely sure that would even be possible when it comes to capabilities,
or if it would make sense..

From what I've seen with SELinux, thankfully, these same issues don't
really crop up (probably because PG never tried to force anything
SELinux related, and SELinux is largely independent of the POSIX ACLs
and Linux capabilities, so it doesn't impact things in this way).

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Chapman Flack
Date:
On 03/13/2018 01:50 PM, Stephen Frost wrote:

> Yes, that's true, but PG has never paid attention to POSIX ACLs or Linux
> capabilities.  Changing it to do so is quite a bit beyond the scope...

I think we're largely in agreement here, as my aim was not to advocate
that PG should work harder to understand the subtleties of every system
it could be installed on, but rather that it should work less hard at
pretending to understand them when it doesn't, and thus avoid
obstructing the admin, who presumably does.

> I'll point out that PG does run on quite a few other OS's beyond Linux.

I'll second that, as I think it is making my argument. When I can
supply three or four examples of semantic subtleties that undermine
PG's assumptions under Linux alone, the picture when broadened to
those quite-a-few other platforms as well certainly doesn't become
simpler!

>> but then sooner or later it will still end up making assumptions
>> that aren't true under, say, SELinux, so there's another #ifdef,
>> and where does it end?
> 
> I agree with this general concern.

:)  That's probably where it became clear that I'm not advocating
an add-#ifdefs-for-everything approach.

> PG will stat PGDATA and conclude that the system is saying that group
> access has been granted on PGDATA and will do the same for subsequent
> files created later on. ... The only issue that remains is that PG
> doesn't understand or work with POSIX ACLs or Linux capabilities,
> but that's not anything new.

What's new is that it is now pretending even more extravagantly to
understand what it doesn't understand. Where it would previously draw
in incorrect conclusion and refuse to start, which is annoying but
not very difficult to work around if need be, it would now draw the
same incorrect conclusion and then actively go about making the real
world embody the incorrect conclusion, contrary to the admin's efforts.

>> umask inherited by the postmaster. A --permission-transparency option
>> would simply use open and mkdir in the traditional ways, allowing
>> the chosen umask, ACL defaults, SELinux contexts, etc., to do their
>> thing, and would avoid then stepping on the results with explicit
>> chmods (and of course skip the I-refuse-to-start-because-I-
>> misunderstand-your-setup check).
>> ...
> 
> I'm a fan of this idea in general, but it's unclear how that
> --permission-transparency option would work in practice.  Are you
> suggesting that it be a compile-time flag, which would certainly work
> but also then have to be debated among packagers as to the right setting
> and if there's any need to be concerned about users misunderstanding it,
> or a flag for each program,

I was thinking of a command-line option ...

> which hardly seems ideal as some invokations
> of programs might forget to specify that, leading to inconsistent
> permissions, or something else..?

... but I see how that gets complicated with the various other command-
line utilities included.

> .. we'd have to build in complete
> support for POSIX ACLs and Linux capabilities if we go down a route

I'm wary of an argument that we can't do better except by building
in complete support for POSIX ACLs, and capabilities (and NFSv4
ACLs, and SELinux, and AppArmor, and #ifdef and #ifdef and #ifdef).

It seems to me that, in most cases, the designers of these sorts of
extensions to old traditional Unix behavior take great pains to design
them such that they can still usefully function in the presence of
programs that "don't pay attention to or understand or use" them, as
long as those programs are in some sense well-behaved, and not going
out of their way with active steps that insist on or impose permissions
that aren't appropriate under the non-understood circumstances.

So my suggestion boils down to PG having at least an option, somehow,
to be well-behaved in that sense.

-Chap


Re: PATCH: Configurable file mode mask

From
Tom Lane
Date:
Chapman Flack <chap@anastigmatix.net> writes:
> On 03/13/2018 01:50 PM, Stephen Frost wrote:
>> I'll point out that PG does run on quite a few other OS's beyond Linux.

> I'll second that, as I think it is making my argument. When I can
> supply three or four examples of semantic subtleties that undermine
> PG's assumptions under Linux alone, the picture when broadened to
> those quite-a-few other platforms as well certainly doesn't become
> simpler!

Well, to be blunt, what we target is POSIX-compatible systems.  If
you're telling us to worry about non-POSIX filesystem semantics,
and your name is not Microsoft, it's going to be a hard sell.
We have enough to do just keeping up with that scope of target
systems.

            regards, tom lane


Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Greetings Chapman,

* Chapman Flack (chap@anastigmatix.net) wrote:
> On 03/13/2018 01:50 PM, Stephen Frost wrote:
> > PG will stat PGDATA and conclude that the system is saying that group
> > access has been granted on PGDATA and will do the same for subsequent
> > files created later on. ... The only issue that remains is that PG
> > doesn't understand or work with POSIX ACLs or Linux capabilities,
> > but that's not anything new.
>
> What's new is that it is now pretending even more extravagantly to
> understand what it doesn't understand. Where it would previously draw
> in incorrect conclusion and refuse to start, which is annoying but
> not very difficult to work around if need be, it would now draw the
> same incorrect conclusion and then actively go about making the real
> world embody the incorrect conclusion, contrary to the admin's efforts.

I have to say that I disagree about it being "easy to work-around" PG
refusing to start.  Also, we're not pretending any more or less, we're
sticking to exactly what we do understand- which is the 80's unix
permission system, as you put it.  The options that I see here are to
stick with the user/group system and our naive understanding of it, to
go whole-hog and try to completely understand everything (with lots of
#ifdef's, as discussed), or to completely remove all checks- but we
don't have a clear proposal for that and it strikes me as at least
unlikely to go over well anyway, given all of the discussion here about
trying to simply change the one check we have.

> >> umask inherited by the postmaster. A --permission-transparency option
> >> would simply use open and mkdir in the traditional ways, allowing
> >> the chosen umask, ACL defaults, SELinux contexts, etc., to do their
> >> thing, and would avoid then stepping on the results with explicit
> >> chmods (and of course skip the I-refuse-to-start-because-I-
> >> misunderstand-your-setup check).
> >> ...
> >
> > I'm a fan of this idea in general, but it's unclear how that
> > --permission-transparency option would work in practice.  Are you
> > suggesting that it be a compile-time flag, which would certainly work
> > but also then have to be debated among packagers as to the right setting
> > and if there's any need to be concerned about users misunderstanding it,
> > or a flag for each program,
>
> I was thinking of a command-line option ...
>
> > which hardly seems ideal as some invokations
> > of programs might forget to specify that, leading to inconsistent
> > permissions, or something else..?
>
> ... but I see how that gets complicated with the various other command-
> line utilities included.

Indeed.

> > .. we'd have to build in complete
> > support for POSIX ACLs and Linux capabilities if we go down a route
>
> I'm wary of an argument that we can't do better except by building
> in complete support for POSIX ACLs, and capabilities (and NFSv4
> ACLs, and SELinux, and AppArmor, and #ifdef and #ifdef and #ifdef).

I don't think I meant to imply that we can't do better, I was just
trying to enumate what I saw the different options being.

> It seems to me that, in most cases, the designers of these sorts of
> extensions to old traditional Unix behavior take great pains to design
> them such that they can still usefully function in the presence of
> programs that "don't pay attention to or understand or use" them, as
> long as those programs are in some sense well-behaved, and not going
> out of their way with active steps that insist on or impose permissions
> that aren't appropriate under the non-understood circumstances.
>
> So my suggestion boils down to PG having at least an option, somehow,
> to be well-behaved in that sense.

I'm afraid that we haven't got any great answer to that "somehow".  I
was hoping you might have some other ideas beyond command-line switches
which could leave the system in an inconsistent state a bit too easily.
Unless there's a better way then the approach proposed by Tom
(originally) and implemented by David seems like the way to go and at
least an improvement over the current situation.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Chapman Flack
Date:
On 03/13/2018 02:47 PM, Tom Lane wrote:
> Well, to be blunt, what we target is POSIX-compatible systems.  If
> you're telling us to worry about non-POSIX filesystem semantics,
> and your name is not Microsoft, it's going to be a hard sell.
> We have enough to do just keeping up with that scope of target
> systems.

So, how many POSIX-compatible systems are available today (if any),
where you can actually safely assume that there are no additional
security/access-control-related considerations in effect beyond
three user bits/three group bits/three other bits, and not be wrong?

I'm not advocating the Sisyphean task of having PG incorporate
knowledge of all those possibilities. I'm advocating the conservative
approach: have PG be that well-behaved application that those extended
semantics are generally all designed to play well with, and just not
do stuff that obstructs or tramples over what the admin takes care
to set up.



On 03/13/2018 03:44 PM, Stephen Frost wrote:
> * Chapman Flack (chap@anastigmatix.net) wrote:
>> So my suggestion boils down to PG having at least an option, somehow,
>> to be well-behaved in that sense.
>
> I'm afraid that we haven't got any great answer to that "somehow".  I
> was hoping you might have some other ideas beyond command-line
> switches which could leave the system in an inconsistent state a bit
> too easily.


I wonder how complicated it would have to be really. On any system
with a POSIX base, I guess it's possible for PGDATA to have an S_ISVTX
"sticky" bit in the mode, which does have an official significance (but
one that only affects whether non-postgres can rename or unlink things
in the directory, which might be of little practical significance).
Perhaps its meaning could be overloaded with "the admin is handling
the permissions, thank you", and postmaster and various command-line
utilities could see it, and refrain from any gratuitous chmods or
refusals to function.



Or, if overloading S_ISVTX seems in poor taste, what would be wrong
with simply checking for an empty file PERMISSIONS-ARE-MANAGED in
PGDATA and responding the same way?



Or, assuming some form of ACL is available, just let the admin
change the owner and group of PGDATA to other than postgres,
grant no access to other, and give rwx to postgres in the ACL?

PG could then reason as follows: * I do not own this directory.
* I am not the group of this directory. * It grants no access to other.
* Yet, I find myself listing and accessing files in it without
difficulty. * The admin has set this up for me in a way I do not
understand. * I will refrain from messing with it.



Three ideas off the top of my head. Probably more where they came from.
:)

-Chap


Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Chapman,

* Chapman Flack (chap@anastigmatix.net) wrote:
> I'm not advocating the Sisyphean task of having PG incorporate
> knowledge of all those possibilities. I'm advocating the conservative
> approach: have PG be that well-behaved application that those extended
> semantics are generally all designed to play well with, and just not
> do stuff that obstructs or tramples over what the admin takes care
> to set up.

I think we get that you're advocating removing the checks and
permissions-setting that the PG tools do, however...

> I wonder how complicated it would have to be really. On any system
> with a POSIX base, I guess it's possible for PGDATA to have an S_ISVTX
> "sticky" bit in the mode, which does have an official significance (but
> one that only affects whether non-postgres can rename or unlink things
> in the directory, which might be of little practical significance).
> Perhaps its meaning could be overloaded with "the admin is handling
> the permissions, thank you", and postmaster and various command-line
> utilities could see it, and refrain from any gratuitous chmods or
> refusals to function.
>
> Or, if overloading S_ISVTX seems in poor taste, what would be wrong
> with simply checking for an empty file PERMISSIONS-ARE-MANAGED in
> PGDATA and responding the same way?
>
> Or, assuming some form of ACL is available, just let the admin
> change the owner and group of PGDATA to other than postgres,
> grant no access to other, and give rwx to postgres in the ACL?

None of these suggestions really sound workable to me.  I certainly
don't think we should be overloading the meaning of a specific and
entirely independent filesystem permission (and really don't even
want to imagine what it would require to do something like that on
Windows...), dropping an empty file in the directory strikes me as a
ripe target for confusion, and we have specific checks to try and
make sure we are running as the owner that owns the directory with
some pretty good reasons around that (avoiding multiple postmasters
running in the same PGDATA directory, specifically).

> PG could then reason as follows: * I do not own this directory.
> * I am not the group of this directory. * It grants no access to other.
> * Yet, I find myself listing and accessing files in it without
> difficulty. * The admin has set this up for me in a way I do not
> understand. * I will refrain from messing with it.

Removing the check that says "we aren't going to try to run PG in this
directory if we aren't the owner of it" also doesn't seem like it's
necessairly a great plan.

> Three ideas off the top of my head. Probably more where they came from.

None of them really seem workable though.  On the other hand, let's
consider what this patch actually ends up doing when POSIX ACLs are
involved.  This allows ACLs to be used where they weren't before and
with appropriate defaults set even to work for new files being created,
which wouldn't work before.  Yes, if you create a default ACL which
says "grant this other user write access to files in the PG data
directory" then that won't actually be honored because we will
chmod(640) the file and the POSIX ACL system actually works with the
user/group privilege system, like so:

Create the "data" dir, as initdb would:
➜  ~ mkdir xyz
➜  ~ chmod 750 xyz
➜  ~ ls -ld xyz
drwxr-x--- 2 sfrost sfrost 4096 Mar 13 19:07 xyz

Set a default ACL to allow the "daemon" user read/write access to files
created:

➜  ~ setfacl -dm u:daemon:rw xyz
➜  ~ getfacl xyz
# file: xyz
# owner: sfrost
# group: sfrost
user::rwx
group::r-x
other::---
default:user::rwx
default:user:daemon:rw-
default:group::r-x
default:mask::rwx
default:other::---

Create a file the way PG would:
➜  ~ touch xyz/a
➜  ~ chmod 640 xyz/a
➜  ~ getfacl xyz/a
# file: xyz/a
# owner: sfrost
# group: sfrost
user::rw-
user:daemon:rw-            #effective:r--
group::r-x            #effective:r--
mask::r--
other::---

The daemon user ends up with read-only access (note the '#effective',
which shows that the POSIX ACL system isn't overriding the "regular"
ACLs).

... but that's basically what we want.

Multiple users having write access to the data directory could be quite
bad as you might possibly get two postmasters running against the same
data directory at the same time and there's basically no case where
that's a good thing to have happen.  This change does let users grant
out read access to other users/groups, even beyond what's possible using
the traditional user/group system, so this opens up a lot more possible
options for advanced users, provided they set the defaults
appropriately at the directory level (which, presumably, an
administrator versed in POSIX ACLs and wishing to use them would know,
or would figure out quickly).

Yes, perhaps there's some argument to be made that we should have an
option where we don't force any privileges, but that can certainly be
considered a future capability and what's being implemented here doesn't
actually break use-cases which worked before and allows users more
freedom than they had before to use POSIX ACLs if they want to use them,
and without having to modify PG to understand POSIX ACLs explicitly.

Also, to the point you raise up-thread, where you remove access to the
data directory from the group that owns the directory, but grant it to
some other user, yes, files inside the data directory would end up with
group access for that other group.  That won't matter as long as the
group doesn't have rights on the directory, though it would certainly be
cleaner to just have a dedicated group where it isn't an issue for that
group to have read access to the files.  I would imagine anyone using
POSIX ACLs would understand this without too much difficulty.  Of
course, POSIX default ACLs would also continue to work for files created
under the data directory, as illustrated above.

In all, this is looking like a pretty good improvement while also having
some caution about what privileges are effectively allowed.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Tue, Mar 13, 2018 at 01:28:17PM -0400, Tom Lane wrote:
> David Steele <david@pgmasters.net> writes:
>> On 3/12/18 3:28 AM, Michael Paquier wrote:
>>> In pg_rewind and pg_resetwal, isn't that also a portion which is not
>>> necessary without the group access feature?
>
>> These seem like a good idea to me with or without patch 03.  Some of our
>> front-end tools (initdb, pg_upgrade) were setting umask and others
>> weren't.  I think it's more consistent (and safer) if they all do, at
>> least if they are writing into PGDATA.
>
> +1 ... see a926eb84e for an example of how easy it is to screw up if
> the process's overall umask is permissive.

Okay.  A suggestion that I have here would be to split those extra calls
into a separate patch.  That's a useful self-contained improvement.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Tue, Mar 13, 2018 at 12:19:07PM -0400, David Steele wrote:
> I'll attach new patches in a reply to [1] once I have made the changes
> Tom requested.

Cool, thanks for your patience.  Looking forward to seeing those.  I'll
spend time on 0003 at the same time.  Let's also put the additional
umask calls for pg_rewind and pg_resetwal into a separate patch.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi,

On 3/13/18 12:13 PM, Stephen Frost wrote:
> * David Steele (david@pgmasters.net) wrote:
>> On 3/13/18 11:00 AM, Tom Lane wrote:
>>>
>>> FWIW, I took a quick look through this patch and don't have any problem
>>> with the approach, which appears to be "use the data directory's
>>> startup-time permissions as the status indicator".  I am kinda wondering
>>> about this though:
>>>
>>> +    (These files can confuse <application>pg_ctl</application>.)  If group read
>>> +    access is enabled on the data directory and an unprivileged user in the
>>> +    <productname>PostgreSQL</productname> group is performing the backup, then
>>> +    <filename>postmaster.pid</filename> will not be readable and must be
>>> +    excluded.
>>>
>>> If we're allowing group read on the data directory, why should that not
>>> include postmaster.pid?  There's nothing terribly security-relevant in
>>> there, and being able to find out the postmaster PID seems useful.  I can
>>> see the point of restricting server key files, as documented elsewhere,
>>> but it's possible to keep those somewhere else so they don't cause
>>> problems for simple backup software.
>>
>> I'm OK with that.  I had a look at the warnings regarding the required
>> mode of postmaster.pid in miscinit.c (889-911) and it seems to me they
>> still hold true if the mode is 640 instead of 600.
>>
>> Do you agree, Tom?  Stephen?
>>
>> If so, I'll make those changes.
>
> I agree that we can still consider an EPERM-error case as being ok even
> with the changes proposed, and with the same-user check happening
> earlier in checkDataDir(), we won't even get to the point of looking at
> the pid file if the userid's don't match.  The historical comment about
> the old datadir permissions can likely just be removed, perhaps replaced
> with a bit more commentary above that check in checkDataDir().  The
> open() call should also fail if we only have group-read privileges on
> the file (0640), but surely the kill() will in any case.

OK, that being the case a new patch set is attached that sets the mode
of postmaster.pid the same as other files in PGDATA.

I also cleaned up / corrected / added comments in various places.

Thanks,
--
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Michael,

On 3/13/18 9:31 PM, Michael Paquier wrote:
> On Tue, Mar 13, 2018 at 12:19:07PM -0400, David Steele wrote:
>> I'll attach new patches in a reply to [1] once I have made the changes
>> Tom requested.
>
> Cool, thanks for your patience.  Looking forward to seeing those.  I'll
> spend time on 0003 at the same time.  Let's also put the additional
> umask calls for pg_rewind and pg_resetwal into a separate patch.

Do you mean a separate patch in this patch set, or a separate patch
entirely?  02 depends on this logic, so I guess you mean create a new
patch between 01 and 02?

Are you just trying to make sure it gets in?  I'd rather wait a bit - if
02 doesn't look like it will get in, then I'll pull this logic out into
a separate patch.

Thanks,
--
-David
david@pgmasters.net


Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Wed, Mar 14, 2018 at 02:15:03PM -0400, David Steele wrote:
> Do you mean a separate patch in this patch set, or a separate patch
> entirely?  02 depends on this logic, so I guess you mean create a new
> patch between 01 and 02?

Yes, one new patch that which can be applied on top of 1.

> Are you just trying to make sure it gets in?  I'd rather wait a bit - if
> 02 doesn't look like it will get in, then I'll pull this logic out into
> a separate patch.

Okay.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Wed, Mar 14, 2018 at 02:08:19PM -0400, David Steele wrote:
> OK, that being the case a new patch set is attached that sets the mode
> of postmaster.pid the same as other files in PGDATA.

+1.

> I also cleaned up / corrected / added comments in various places.

Patches 1 and 2 look fine to me.  The new umask calls in pg_rewind and
pg_resetwal could be split into a separate patch but that's a minor
issue.

When taking a base backup from a data folder which has group access,
then the tar data, as well as the untar'ed data, are still using
0600 as umask for files and 0700 for folders.  Is that an expected
behavior?  I would have imagined that sendFileWithContent() and
_tarWriteDir() should enforce the file mode to have group access if the
cluster has been initialized to work as such.  Still as this is a
feature aimed at being used for custom backups, that's not really a
blocker I guess.  Visibly there would be no need for a -g switch in
pg_basebackup as it is possible to guess from the received untar'ed
files what should be the permissions of the data based on what is
received in pg_basebackup.c.  It would also be necessary to change the
permissions of pg_wal as this is created before receiving any files.

Speaking of which, we may want to switch the values used for st_mode to
what file_perm.h is giving in basebackup.c?

We should also replace the hardcoded 0700 value in pg_backup_directory.c
by what file_perm.h offers?  I would recommend to not touch at mkdtemp.c
as this comes from NetBSD.

+=item $node->group_access()
+
+Does the data dir allow group access?
+
Nit: s/dir/directory/.

Indentation is weird in PostgresNode.pm for some of the chmod calls
(tabs not spaces please).
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/15/18 3:17 AM, Michael Paquier wrote:
> On Wed, Mar 14, 2018 at 02:08:19PM -0400, David Steele wrote:
>
> When taking a base backup from a data folder which has group access,
> then the tar data, as well as the untar'ed data, are still using
> 0600 as umask for files and 0700 for folders.  Is that an expected
> behavior?  I would have imagined that sendFileWithContent() and
> _tarWriteDir() should enforce the file mode to have group access if the
> cluster has been initialized to work as such.

We can certainly make base backup understand the group access mode.
Should we continue hard-coding the mode, or use the actual dir/file mode?

> Still as this is a
> feature aimed at being used for custom backups, that's not really a
> blocker I guess.

Seems like a good thing to do, though, so I'll have a look for the next
patch.

> Visibly there would be no need for a -g switch in
> pg_basebackup as it is possible to guess from the received untar'ed
> files what should be the permissions of the data based on what is
> received in pg_basebackup.c.  It would also be necessary to change the
> permissions of pg_wal as this is created before receiving any files.

This part might be trickier.

> Speaking of which, we may want to switch the values used for st_mode to
> what file_perm.h is giving in basebackup.c?

Will do.

> We should also replace the hardcoded 0700 value in pg_backup_directory.c
> by what file_perm.h offers?  I would recommend to not touch at mkdtemp.c
> as this comes from NetBSD.

Will do.

> +=item $node->group_access()
> +
> +Does the data dir allow group access?
> +
> Nit: s/dir/directory/.
>
> Indentation is weird in PostgresNode.pm for some of the chmod calls
> (tabs not spaces please).

I'll fix these in the next patch as well.

Thanks,
--
-David
david@pgmasters.net


Attachment

Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Greetings David, Michael, all,

* David Steele (david@pgmasters.net) wrote:
> On 3/15/18 3:17 AM, Michael Paquier wrote:
> > On Wed, Mar 14, 2018 at 02:08:19PM -0400, David Steele wrote:
> >
> > When taking a base backup from a data folder which has group access,
> > then the tar data, as well as the untar'ed data, are still using
> > 0600 as umask for files and 0700 for folders.  Is that an expected
> > behavior?  I would have imagined that sendFileWithContent() and
> > _tarWriteDir() should enforce the file mode to have group access if the
> > cluster has been initialized to work as such.
>
> We can certainly make base backup understand the group access mode.
> Should we continue hard-coding the mode, or use the actual dir/file mode?

Given that we're already, as I recall, including the owner/group of the
file being backed up through pg_basebackup in the tarball, it seems like
we should be including whatever the current dir/file mode is too.  Those
files may not have anything to do with PostgreSQL, after all, and a
'natural' tar of the directory would capture that information too.

> > Still as this is a
> > feature aimed at being used for custom backups, that's not really a
> > blocker I guess.
>
> Seems like a good thing to do, though, so I'll have a look for the next
> patch.

+1.

> > Visibly there would be no need for a -g switch in
> > pg_basebackup as it is possible to guess from the received untar'ed
> > files what should be the permissions of the data based on what is
> > received in pg_basebackup.c.  It would also be necessary to change the
> > permissions of pg_wal as this is created before receiving any files.
>
> This part might be trickier.

This seems like another case where what we should be doing, and what
people will be expecting, I'd think, is just what they're used to tar
doing in these cases- which would be setting the dir/file mode for each
file based on what's in the tarball.  Again, the files which are in the
data dir are, sadly, not always just those that PG is familiar with.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Fri, Mar 16, 2018 at 11:12:44AM -0400, Stephen Frost wrote:
> Given that we're already, as I recall, including the owner/group of the
> file being backed up through pg_basebackup in the tarball, it seems like
> we should be including whatever the current dir/file mode is too.  Those
> files may not have anything to do with PostgreSQL, after all, and a
> 'natural' tar of the directory would capture that information too.

Yes.  tar does include this information in the header associated to each
file.  Do we want an additional switch for pg_receivexlog as well by the
way which generates WAL segments with group access?  Some people take
base backups without slots and rely on an archive to look for remaining
segments up to the end-of-backup record.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/16/18 11:12 AM, Stephen Frost wrote:
>
>>> Visibly there would be no need for a -g switch in
>>> pg_basebackup as it is possible to guess from the received untar'ed
>>> files what should be the permissions of the data based on what is
>>> received in pg_basebackup.c.  It would also be necessary to change the
>>> permissions of pg_wal as this is created before receiving any files.
>>
>> This part might be trickier.
>
> This seems like another case where what we should be doing, and what
> people will be expecting, I'd think, is just what they're used to tar
> doing in these cases- which would be setting the dir/file mode for each
> file based on what's in the tarball.  Again, the files which are in the
> data dir are, sadly, not always just those that PG is familiar with.

I've been working on this and have become convinced that adding group
permissions to files that pg_basebackup writes to disk based on whether
group permissions are enabled in PGDATA isn't the right way to go.

To be clear, I'm not taking about the permissions set within the tar
file - I think it makes sense to use the actual PGDATA permissions in
that case.

pg_basebackup may not be running as postgres, and even if it is I don't
think we can assume that group access is appropriate for the files that
it writes.  It's a different environment and different security rules
may apply.

It seems to me that pg_basebackup and pg_receivexlog should have a -g
option to control the mode of the files that they write to disk (not
including the modes stored in the tar files).

Or perhaps we should just update the perms in the tar files for now and
leave the rest alone.

Thoughts?
--
-David
david@pgmasters.net


Attachment

Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
David,

* David Steele (david@pgmasters.net) wrote:
> On 3/16/18 11:12 AM, Stephen Frost wrote:
> >
> >>> Visibly there would be no need for a -g switch in
> >>> pg_basebackup as it is possible to guess from the received untar'ed
> >>> files what should be the permissions of the data based on what is
> >>> received in pg_basebackup.c.  It would also be necessary to change the
> >>> permissions of pg_wal as this is created before receiving any files.
> >>
> >> This part might be trickier.
> >
> > This seems like another case where what we should be doing, and what
> > people will be expecting, I'd think, is just what they're used to tar
> > doing in these cases- which would be setting the dir/file mode for each
> > file based on what's in the tarball.  Again, the files which are in the
> > data dir are, sadly, not always just those that PG is familiar with.
>
> I've been working on this and have become convinced that adding group
> permissions to files that pg_basebackup writes to disk based on whether
> group permissions are enabled in PGDATA isn't the right way to go.
>
> To be clear, I'm not taking about the permissions set within the tar
> file - I think it makes sense to use the actual PGDATA permissions in
> that case.

What that implies then, if I'm following, is that the results of a
pg_basebackup -Ft && tar -xvf ; would be different from the results of a
pg_basebackup -Fp ; .

That seems like it would be rather odd and confusing to users and so I
have a hard time agreeing that such an inconsistency makes sense.

> pg_basebackup may not be running as postgres, and even if it is I don't
> think we can assume that group access is appropriate for the files that
> it writes.  It's a different environment and different security rules
> may apply.

Sure, and the same security rules may also apply.  Consider an
environment which is managed through a change management system (as many
are these days...) where the pg_basebackup is being run specifically to
set up a replica (which is quite commonly done..) and then allow a tool
like pgbackrest to use both the primary and the replica for backups,
where pgbackrest is run as an independent user which shares the same
group as the PG user and needs group-read access on the replica.  After
building such a replica, the user would have to do a chmod across the
entire data directory, even though the primary was initialized with
group-read access, or, oddly, perform the pg_basebackup to tar files and
then extract those tar files instead of using the plain format.

The general pg_basebackup->replica process works great today and the
primary and the replica more-or-less match as if they were both initdb'd
the same way, or a backup/restore was done, and not preserving the
privileges as they exist would end up diverging from that.

In these cases we're really talking about the defaults here; as I
mention below, I agree that having the ability to control what ends up
happening definitely makes sense (as tar does...).

> It seems to me that pg_basebackup and pg_receivexlog should have a -g
> option to control the mode of the files that they write to disk (not
> including the modes stored in the tar files).
>
> Or perhaps we should just update the perms in the tar files for now and
> leave the rest alone.

Having options to pg_basebackup to control what's done makes sense to
me- but whatever those options do, I'd expect them to apply equally to
the tar files and to the files extracted with plain mode.  Having those
be different really strikes me as very odd.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Tue, Mar 20, 2018 at 05:44:22PM -0400, Stephen Frost wrote:
> * David Steele (david@pgmasters.net) wrote:
>> On 3/16/18 11:12 AM, Stephen Frost wrote:
>> It seems to me that pg_basebackup and pg_receivexlog should have a -g
>> option to control the mode of the files that they write to disk (not
>> including the modes stored in the tar files).
>>
>> Or perhaps we should just update the perms in the tar files for now and
>> leave the rest alone.
>
> Having options to pg_basebackup to control what's done makes sense to
> me- but whatever those options do, I'd expect them to apply equally to
> the tar files and to the files extracted with plain mode.  Having those
> be different really strikes me as very odd.

Agreed for the consistency part, permissions should be applied
consistently for the folder and the tar format.

Having the option for pg_receivewal definitely makes sense to me, as it
is the one in charge of opening and writing the WAL segments.  For
pg_basebackup, let's not forget that there is one tar file for each
tablespace, and that each file is received separately using a COPY
stream.  There is some logic already which parses the tar header part of
an individual file in order to look for recovery.conf (see
ReceiveTarFile() in pg_basebackup.c).  It would be possible to enforce
grouping permissions when receiving each file, and this would be rather
low-cost in performance I think.  Honestly, my vote would go for having
the permissions set correctly by the source server as this brings
consistency to the whole experience without complicating the interface
of pg_basebackup, and this also makes the footprint of this patch on
pg_basebackup way lighter.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
Peter Eisentraut
Date:
I have committed a basic pg_resetwal test suite as part of another
patch, so please adjust accordingly.

It looks to me like your pg_resetwal tests contain a bit of useless
copy-and-paste.  For example, you are not using use Config, nor
$tempdir, and you run $node->stop right after $node->start.  Please
clean that up a bit, or comment, if appropriate.

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Peter,

On 3/23/18 10:36 AM, Peter Eisentraut wrote:
> I have committed a basic pg_resetwal test suite as part of another
> patch, so please adjust accordingly.
> 
> It looks to me like your pg_resetwal tests contain a bit of useless
> copy-and-paste.  For example, you are not using use Config, nor
> $tempdir, and you run $node->stop right after $node->start.  Please
> clean that up a bit, or comment, if appropriate.

Yeah, definitely too much copy-paste going on.

The various start/stops were intended the ensure that PG actually starts
with the reset WAL.  I see that these tests don't do them, though, so
perhaps that's not a good use of test time.

The pg_rewind tests work for my purposes but it seems worth preserving
the ones I wrote since there is no overlap.

I've attached a patch that integrates my tests with the current tests.
If you don't think they are worth adding then I'll just drop them from
my patchset.

Thanks,
-- 
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Fri, Mar 23, 2018 at 12:26:47PM -0400, David Steele wrote:
> I've attached a patch that integrates my tests with the current tests.
> If you don't think they are worth adding then I'll just drop them from
> my patchset.

It seems to me that those tests have values (we can add more tests for
transaction ID and such in the future), but I would recommend to put
them in a separate file named like t/003_reset.pl for tests which
execute resets and checks their consistency on the cluster.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/20/18 11:14 PM, Michael Paquier wrote:
> On Tue, Mar 20, 2018 at 05:44:22PM -0400, Stephen Frost wrote:
>> * David Steele (david@pgmasters.net) wrote:
>>> On 3/16/18 11:12 AM, Stephen Frost wrote:
>>> It seems to me that pg_basebackup and pg_receivexlog should have a -g
>>> option to control the mode of the files that they write to disk (not
>>> including the modes stored in the tar files).
>>>
>>> Or perhaps we should just update the perms in the tar files for now and
>>> leave the rest alone.
>>
>> Having options to pg_basebackup to control what's done makes sense to
>> me- but whatever those options do, I'd expect them to apply equally to
>> the tar files and to the files extracted with plain mode.  Having those
>> be different really strikes me as very odd.
>
> Agreed for the consistency part, permissions should be applied
> consistently for the folder and the tar format.
>
> Having the option for pg_receivewal definitely makes sense to me, as it
> is the one in charge of opening and writing the WAL segments.  For
> pg_basebackup, let's not forget that there is one tar file for each
> tablespace, and that each file is received separately using a COPY
> stream.  There is some logic already which parses the tar header part of
> an individual file in order to look for recovery.conf (see
> ReceiveTarFile() in pg_basebackup.c).  It would be possible to enforce
> grouping permissions when receiving each file, and this would be rather
> low-cost in performance I think.  Honestly, my vote would go for having
> the permissions set correctly by the source server as this brings
> consistency to the whole experience without complicating the interface
> of pg_basebackup, and this also makes the footprint of this patch on
> pg_basebackup way lighter.

These updates address Michael's latest review and implement group access
for pg_basebackup, pg_receivewal, and pg_recvlogical.  A new internal
GUC, data_directory_group_access, allows remote processes to determine
the correct mode using the existing SHOW protocol command.

I have dropped patch 01, which added the pg_resetwal tests.  The tests
Peter added recently are sufficient for this patch so I'll pursue adding
the other tests separately to avoid noise on this thread.

Thanks,
--
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Tue, Mar 27, 2018 at 04:21:09PM -0400, David Steele wrote:
> These updates address Michael's latest review and implement group access
> for pg_basebackup, pg_receivewal, and pg_recvlogical.  A new internal
> GUC, data_directory_group_access, allows remote processes to determine
> the correct mode using the existing SHOW protocol command.

Neat idea.  This is another use case where the SHOW command in the
replication protocol proves to be useful.

> I have dropped patch 01, which added the pg_resetwal tests.  The tests
> Peter added recently are sufficient for this patch so I'll pursue adding
> the other tests separately to avoid noise on this thread.

That's fair.

Some nits from patch 1...

+   ok (check_mode_recursive($node_master->data_dir(), 0700, 0600));
[...]
+   ok (check_mode_recursive($node_master->data_dir(), 0700, 0600));
Incorrect indentations (space after "ok", yes that's a nit...).

+   /* Set dir/file mode mask */
+   umask(PG_MODE_MASK_DEFAULT);
I would still see that rather committed as a separate patch.  I am fine
to delegate the decision to the committer who is hopefully going to pick
up this patch.

And more things about patch 1 which are not nits.

In pg_backup_tar.c, we still have a 0600 hardcoded.  You should use
PG_FILE_MODE_DEFAULT there as well.

dsm_impl_posix() can create a new segment with shm_open using as mode
0600.  This is present in pg_dynshmem, which would be included in
backups.  First, it seems to me that this should use
PG_FILE_MODE_DEFAULT.  Then, with patch 2 it seems to me that if an
instance is using DSM then there is a risk of breaking a simple backup
which uses for example "tar" without --exclude filters with group access
(sometimes scripts are not smart enough to skip the same contents as
base backups).  So it seems to me that DSM should be also made more
aware of group access to ease the life of users.

And then for patch 2, a couple of issues spotted..

+   /* for previous versions set the default group access */
+   if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_GROUP_ACCESS)
+   {
+       DataDirGroupAccess = false;
+       return false;
+   }
Enforcing DataDirGroupAccess to false for servers older than v11 is
fine, but RetrieveDataDirGroupAccess() should return true.  If I read
your patch correctly then support for pg_basebackup on older server
would just fail.

+#if !defined(WIN32) && !defined(__CYGWIN__)
+   if ((stat_buf.st_mode & PG_DIR_MODE_DEFAULT) == PG_DIR_MODE_DEFAULT)
+   {
+       umask(PG_MODE_MASK_ALLOW_GROUP);
+       DataDirGroupAccess = true;
+   }
This should use SetConfigOption() or I am missing something?

+/*
+ * Does the data directory allow group read access?  The default is false, i.e.
+ * mode 0700, but may be changed in checkDataDir() to true, i.e. mode 0750.
+ */
+bool DataDirGroupAccess = false;

Instead of a boolean, I would suggest to use an integer, this is more
consistent with log_file_mode.  Actually, about that, should we complain
if log_file_mode is set to a value incompatible?
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/28/18 1:59 AM, Michael Paquier wrote:
> On Tue, Mar 27, 2018 at 04:21:09PM -0400, David Steele wrote:
>> These updates address Michael's latest review and implement group access
>> for pg_basebackup, pg_receivewal, and pg_recvlogical.  A new internal
>> GUC, data_directory_group_access, allows remote processes to determine
>> the correct mode using the existing SHOW protocol command.
>
> Some nits from patch 1...
>
> +   ok (check_mode_recursive($node_master->data_dir(), 0700, 0600));
> [...]
> +   ok (check_mode_recursive($node_master->data_dir(), 0700, 0600));
> Incorrect indentations (space after "ok", yes that's a nit...).

Fixed the space, not sure about the indentations?

> And more things about patch 1 which are not nits.
>
> In pg_backup_tar.c, we still have a 0600 hardcoded.  You should use
> PG_FILE_MODE_DEFAULT there as well.

I'm starting to wonder if these changes in pg_dump make sense.  The
file/tar permissions here do not map directly to anything in the PGDATA
directory (since the dump and restore are logical).  Perhaps we should
be adding a -g option for pg_dump (in a separate patch) if we want this
functionality?

> dsm_impl_posix() can create a new segment with shm_open using as mode
> 0600.  This is present in pg_dynshmem, which would be included in
> backups.  First, it seems to me that this should use
> PG_FILE_MODE_DEFAULT.  Then, with patch 2 it seems to me that if an
> instance is using DSM then there is a risk of breaking a simple backup
> which uses for example "tar" without --exclude filters with group access
> (sometimes scripts are not smart enough to skip the same contents as
> base backups).  So it seems to me that DSM should be also made more
> aware of group access to ease the life of users.

Done in patch 1.  For patch 2, do you see any issues with the shared
memory being group readable from a security perspective?  The user can
read everything on disk so it's hard to see how it's a problem.  Also,
if these files are ending up in people's backups...

> And then for patch 2, a couple of issues spotted..
>
> +   /* for previous versions set the default group access */
> +   if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_GROUP_ACCESS)
> +   {
> +       DataDirGroupAccess = false;
> +       return false;
> +   }
> Enforcing DataDirGroupAccess to false for servers older than v11 is
> fine, but RetrieveDataDirGroupAccess() should return true.  If I read
> your patch correctly then support for pg_basebackup on older server
> would just fail.

You are correct, fixed.

> +#if !defined(WIN32) && !defined(__CYGWIN__)
> +   if ((stat_buf.st_mode & PG_DIR_MODE_DEFAULT) == PG_DIR_MODE_DEFAULT)
> +   {
> +       umask(PG_MODE_MASK_ALLOW_GROUP);
> +       DataDirGroupAccess = true;
> +   }
> This should use SetConfigOption() or I am missing something?

Done.

> +/*
> + * Does the data directory allow group read access?  The default is false, i.e.
> + * mode 0700, but may be changed in checkDataDir() to true, i.e. mode 0750.
> + */
> +bool DataDirGroupAccess = false;
>
> Instead of a boolean, I would suggest to use an integer, this is more
> consistent with log_file_mode.

Well, the goal was to make this implementation independent, but I'm not
against the idea.  Anybody have a preference?

> Actually, about that, should we complain
> if log_file_mode is set to a value incompatible?

I think control of the log file mode should be independent.  I usually
don't store log files in PGDATA at all.  What if we set log_file_mode
based on the -g option passed to initdb?  That will work well for
default installations while providing flexibility to others.

Thanks,
--
-David
david@pgmasters.net


Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Thu, Mar 29, 2018 at 10:59:59AM -0400, David Steele wrote:
> On 3/28/18 1:59 AM, Michael Paquier wrote:
>> On Tue, Mar 27, 2018 at 04:21:09PM -0400, David Steele wrote:
>>> These updates address Michael's latest review and implement group access
>>> for pg_basebackup, pg_receivewal, and pg_recvlogical.  A new internal
>>> GUC, data_directory_group_access, allows remote processes to determine
>>> the correct mode using the existing SHOW protocol command.
>>
>> Some nits from patch 1...
>>
>> +   ok (check_mode_recursive($node_master->data_dir(), 0700, 0600));
>> [...]
>> +   ok (check_mode_recursive($node_master->data_dir(), 0700, 0600));
>> Incorrect indentations (space after "ok", yes that's a nit...).
>
> Fixed the space, not sure about the indentations?

That was only the space issues.  A nit.

>> And more things about patch 1 which are not nits.
>>
>> In pg_backup_tar.c, we still have a 0600 hardcoded.  You should use
>> PG_FILE_MODE_DEFAULT there as well.
>
> I'm starting to wonder if these changes in pg_dump make sense.  The
> file/tar permissions here do not map directly to anything in the PGDATA
> directory (since the dump and restore are logical).  Perhaps we should
> be adding a -g option for pg_dump (in a separate patch) if we want this
> functionality?

Yeah.  I am having second thoughts on this one actually.  pg_dump
handles logical backups which require just a connection to Postgres and
it does not care about the physical state of the relation files.  So I
am dropping my comment, and let's not bother about changing things
here.

>> dsm_impl_posix() can create a new segment with shm_open using as mode
>> 0600.  This is present in pg_dynshmem, which would be included in
>> backups.  First, it seems to me that this should use
>> PG_FILE_MODE_DEFAULT.  Then, with patch 2 it seems to me that if an
>> instance is using DSM then there is a risk of breaking a simple backup
>> which uses for example "tar" without --exclude filters with group access
>> (sometimes scripts are not smart enough to skip the same contents as
>> base backups).  So it seems to me that DSM should be also made more
>> aware of group access to ease the life of users.
>
> Done in patch 1.  For patch 2, do you see any issues with the shared
> memory being group readable from a security perspective?  The user can
> read everything on disk so it's hard to see how it's a problem.  Also,
> if these files are ending up in people's backups...

They would be nuked from the surface of earth when recovery kicks.
People should filter this folder, which is why any popular Postgres
backup tool I believe does so, and now so do both pg_rewind and
pg_basebackup.  Still if a user is able to read everything, being able
to read as well pg_dynshmem does not change much from a security's point
of view.  So consistency makes the most sense to me.

>> +/*
>> + * Does the data directory allow group read access?  The default is false, i.e.
>> + * mode 0700, but may be changed in checkDataDir() to true, i.e. mode 0750.
>> + */
>> +bool DataDirGroupAccess = false;
>>
>> Instead of a boolean, I would suggest to use an integer, this is more
>> consistent with log_file_mode.
>
> Well, the goal was to make this implementation independent, but I'm not
> against the idea.  Anybody have a preference?

You mean Windows here?  Perhaps you are right and just using a boolean
would be fine.  When commenting on that I have been likely wondering
about potential extensions in the future, like allowing a user to write
files in a data folder as well if member of the same group as the user
managing the Postgres intance, like for backup deployment?  Perhaps
that's just a crazy man's thoughts..

>> Actually, about that, should we complain
>> if log_file_mode is set to a value incompatible?
>
> I think control of the log file mode should be independent.  I usually
> don't store log files in PGDATA at all.  What if we set log_file_mode
> based on the -g option passed to initdb?  That will work well for
> default installations while providing flexibility to others.

Let's do nothing here as well.  This will keep the code more simple, and
normally-sane deployments put the log directory in an absolute path out
of the data folder.  Normally...  So it means that if I create a number
out of thin air I would imagine that less than 20% of deployments are
like that.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 3/29/18 11:04 PM, Michael Paquier wrote:
> On Thu, Mar 29, 2018 at 10:59:59AM -0400, David Steele wrote:
>> On 3/28/18 1:59 AM, Michael Paquier wrote:
>>
>>> In pg_backup_tar.c, we still have a 0600 hardcoded.  You should use
>>> PG_FILE_MODE_DEFAULT there as well.
>>
>> I'm starting to wonder if these changes in pg_dump make sense.  The
>> file/tar permissions here do not map directly to anything in the PGDATA
>> directory (since the dump and restore are logical).  Perhaps we should
>> be adding a -g option for pg_dump (in a separate patch) if we want this
>> functionality?
>
> Yeah.  I am having second thoughts on this one actually.  pg_dump
> handles logical backups which require just a connection to Postgres and
> it does not care about the physical state of the relation files.  So I
> am dropping my comment, and let's not bother about changing things
> here.

Glad you agree.  I have reverted the mode changes in pg_dump.

>>> dsm_impl_posix() can create a new segment with shm_open using as mode
>>> 0600.  This is present in pg_dynshmem, which would be included in
>>> backups.  First, it seems to me that this should use
>>> PG_FILE_MODE_DEFAULT.  Then, with patch 2 it seems to me that if an
>>> instance is using DSM then there is a risk of breaking a simple backup
>>> which uses for example "tar" without --exclude filters with group access
>>> (sometimes scripts are not smart enough to skip the same contents as
>>> base backups).  So it seems to me that DSM should be also made more
>>> aware of group access to ease the life of users.
>>
>> Done in patch 1.  For patch 2, do you see any issues with the shared
>> memory being group readable from a security perspective?  The user can
>> read everything on disk so it's hard to see how it's a problem.  Also,
>> if these files are ending up in people's backups...
>
> They would be nuked from the surface of earth when recovery kicks.
> People should filter this folder, which is why any popular Postgres
> backup tool I believe does so, and now so do both pg_rewind and
> pg_basebackup.  Still if a user is able to read everything, being able
> to read as well pg_dynshmem does not change much from a security's point
> of view.  So consistency makes the most sense to me.

Done.

>>> +/*
>>> + * Does the data directory allow group read access?  The default is false, i.e.
>>> + * mode 0700, but may be changed in checkDataDir() to true, i.e. mode 0750.
>>> + */
>>> +bool DataDirGroupAccess = false;
>>>
>>> Instead of a boolean, I would suggest to use an integer, this is more
>>> consistent with log_file_mode.
>>
>> Well, the goal was to make this implementation independent, but I'm not
>> against the idea.  Anybody have a preference?
>
> You mean Windows here?  Perhaps you are right and just using a boolean
> would be fine.  When commenting on that I have been likely wondering
> about potential extensions in the future, like allowing a user to write
> files in a data folder as well if member of the same group as the user
> managing the Postgres intance, like for backup deployment?  Perhaps
> that's just a crazy man's thoughts..

Haha!  But I think you are right that using the mode is more consistent
with how other GUCs are done.  It hardly makes sense to take a stand on
unix-y things here when we use them in other GUCs already.

I have replaced data_directory_group_access with data_directory_mode.

>>> Actually, about that, should we complain
>>> if log_file_mode is set to a value incompatible?
>>
>> I think control of the log file mode should be independent.  I usually
>> don't store log files in PGDATA at all.  What if we set log_file_mode
>> based on the -g option passed to initdb?  That will work well for
>> default installations while providing flexibility to others.
>
> Let's do nothing here as well.  This will keep the code more simple, and
> normally-sane deployments put the log directory in an absolute path out
> of the data folder.  Normally...  So it means that if I create a number
> out of thin air I would imagine that less than 20% of deployments are
> like that.

I decided this made sense to do.  It was only a few lines in initdb.c
using a very well established pattern.  It would be surprising if log
files did not follow the mode of the rest of PGDATA after initdb -g,
even if it is standard practice to relocate them.

Thanks,
--
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Fri, Mar 30, 2018 at 01:27:11PM -0400, David Steele wrote:
> I have replaced data_directory_group_access with data_directory_mode.

That looks way better.  Thanks for considering it.

> I decided this made sense to do.  It was only a few lines in initdb.c
> using a very well established pattern.  It would be surprising if log
> files did not follow the mode of the rest of PGDATA after initdb -g,
> even if it is standard practice to relocate them.

Okay for me.

@@ -285,7 +286,7 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size,
      * returning.
      */
     flags = O_RDWR | (op == DSM_OP_CREATE ? O_CREAT | O_EXCL : 0);
-    if ((fd = shm_open(name, flags, 0600)) == -1)
+    if ((fd = shm_open(name, flags, PG_FILE_MODE_DEFAULT)) == -1)

Hm.  Sorry for the extra noise.  This one is actually incorrect as
shm_open will use the path specified by glibc, which is out of
pg_dynshmem so it does not matter for base backups, and we can keep
0600.  pg_dymshmem is used for mmap, still this would map with the umask
setup by the postmaster as OpenTransientFile & friends are used.  sysv
uses IPCProtection but there is no need to care about it as well.  No
need for a comment perhaps..

pg_basebackup.c creates recovery.conf with 0600 all the time ;)

Except for those two nits, I am fine to pass down to a committer patch
number 1.  This has value in my opinion per the refactoring it does and
the umask handling of pg_rewind and pg_resetwal added.

Now for patch 2...

+  <para>
+    If the data directory allows group read access then certificate files may
+    need to be located outside of the data directory in order to conform to the
+    security requirements outlined above.  Generally, group access is enabled
+    to allow an unprivileged user to backup the database, and in that case the
+    backup software will not be able to read the certificate files and will
+    likely error.
+  </para
The answer is no for me and likely the same for others, but I am raising
the point for the archives.  Should we relax
check_ssl_key_file_permissions() for group permissions by the way from
0600 to 0640 when the file is owned by the user running Postgres?  If we
don't do that, then SSL private keys will need to be used with 0600,
potentially breaking backups...  At the same time this reduces the
security of private keys but if the administrator is ready to accept
group permissions that should be a risk he is ready to accept?

+        &DataDirMode,
+        0700, 0000, 0777,
+        NULL, NULL, show_data_directory_mode
Instead of a camel case, renaming that to data_directory_mode would be
nice to ease future greps.  I do that all the time for existing code,
pesting when things are not consistent.  A nit.

There is a noise diff in miscinit.c.

I am pretty sure that we want more documentation in pg_basebackup,
pg_rewind and pg_resetwal telling that those consider grouping access.

There is no need to include sys/stat.h as this is already part of
file_perm.h as DataDirectoryMask uses mode_t for its definition.

+/*
+ * Mode of the data directory.  The default is 0700 but may it be changed in
+ * checkDataDir() to 0750 if the data directory actually has that mode.
+ */
+int DataDirMode = PG_DIR_MODE_NOGROUP

 /*
- * Default mode for directories.
+ * Default mode for created files, unless something else is specified using
+ * the *Perm() function variants.
  */
-#define PG_DIR_MODE_DEFAULT            S_IRWXU
+#define PG_FILE_MODE_DEFAULT       (S_IRUSR | S_IWUSR | S_IRGRP)
To reduce the code churn and simplify the logic, I would recommend to
not use variables which have a negative meaning, so PG_DIR_MODE_DEFAULT
should remain the same in patch 2, and there should be PG_DIR_MODE_GROUP
instead of PG_DIR_MODE_NOGROUP.  That would be more consistent with the
file modes as well.

Yes, we can.
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Michael,

On 4/2/18 2:28 AM, Michael Paquier wrote:
>
> @@ -285,7 +286,7 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size,
>       * returning.
>       */
>      flags = O_RDWR | (op == DSM_OP_CREATE ? O_CREAT | O_EXCL : 0);
> -    if ((fd = shm_open(name, flags, 0600)) == -1)
> +    if ((fd = shm_open(name, flags, PG_FILE_MODE_DEFAULT)) == -1)
>
> Hm.  Sorry for the extra noise.  This one is actually incorrect as
> shm_open will use the path specified by glibc, which is out of
> pg_dynshmem so it does not matter for base backups, and we can keep
> 0600.  pg_dymshmem is used for mmap, still this would map with the umask
> setup by the postmaster as OpenTransientFile & friends are used.  sysv
> uses IPCProtection but there is no need to care about it as well.  No
> need for a comment perhaps..

Yeah, I think I figured that out when I first went through the code but
managed to forget it.  Reverted.

> pg_basebackup.c creates recovery.conf with 0600 all the time ;)

Fixed.

> +  <para>
> +    If the data directory allows group read access then certificate files may
> +    need to be located outside of the data directory in order to conform to the
> +    security requirements outlined above.  Generally, group access is enabled
> +    to allow an unprivileged user to backup the database, and in that case the
> +    backup software will not be able to read the certificate files and will
> +    likely error.
> +  </para
> The answer is no for me and likely the same for others, but I am raising
> the point for the archives.  Should we relax
> check_ssl_key_file_permissions() for group permissions by the way from
> 0600 to 0640 when the file is owned by the user running Postgres?  If we
> don't do that, then SSL private keys will need to be used with 0600,
> potentially breaking backups...  At the same time this reduces the
> security of private keys but if the administrator is ready to accept
> group permissions that should be a risk he is ready to accept?

I feel this should be considered in a separate patch.  These files are
not created by initdb so it seems to be an admin/packaging issue.  There
is always the option to locate the certs outside the data directory and
some distros do that by default.

> +        &DataDirMode,
> +        0700, 0000, 0777,
> +        NULL, NULL, show_data_directory_mode
> Instead of a camel case, renaming that to data_directory_mode would be
> nice to ease future greps.  I do that all the time for existing code,
> pesting when things are not consistent.  A nit.

Done.

> There is a noise diff in miscinit.c.

Fixed.

> I am pretty sure that we want more documentation in pg_basebackup,
> pg_rewind and pg_resetwal telling that those consider grouping access.

I think this makes sense for pg_basebackup, pg_receivewal, and
pg_recvlogical so I have added notes for those.  Not sure I'm happy with
the language but at least we have something to bikeshed.

It seems to me that pg_resetwal and pg_rewind should be expected to not
break the permissions in PGDATA, just as they do now.

> There is no need to include sys/stat.h as this is already part of
> file_perm.h as DataDirectoryMask uses mode_t for its definition.

I removed it from file_perm.h instead.  With the new variables (see
below), most call sites will have no need for the mode constants.

> +/*
> + * Mode of the data directory.  The default is 0700 but may it be changed in
> + * checkDataDir() to 0750 if the data directory actually has that mode.
> + */
> +int DataDirMode = PG_DIR_MODE_NOGROUP
>
>  /*
> - * Default mode for directories.
> + * Default mode for created files, unless something else is specified using
> + * the *Perm() function variants.
>   */
> -#define PG_DIR_MODE_DEFAULT            S_IRWXU
> +#define PG_FILE_MODE_DEFAULT       (S_IRUSR | S_IWUSR | S_IRGRP)
> To reduce the code churn and simplify the logic, I would recommend to
> not use variables which have a negative meaning, so PG_DIR_MODE_DEFAULT
> should remain the same in patch 2, and there should be PG_DIR_MODE_GROUP
> instead of PG_DIR_MODE_NOGROUP.  That would be more consistent with the
> file modes as well.

I decided that the constants were a bit confusing in general.  What does
"default" mean, anyway? Instead I have created variables in file_perm.c
that hold the current file create mode, dir create mode, and mode mask.
All call sites use those variables (e.g. pg_dir_create_mode), which I
think are much clear.

This causes a bit of churn with the constants we added last September
but those were added for v11 so it won't create more complications for
back-patching.

> Yes, we can.

Yes!  We can!

New patches attached.

Thanks,
--
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Wed, Apr 04, 2018 at 08:03:54PM -0400, David Steele wrote:
> On 4/2/18 2:28 AM, Michael Paquier wrote:
>> The answer is no for me and likely the same for others, but I am raising
>> the point for the archives.  Should we relax
>> check_ssl_key_file_permissions() for group permissions by the way from
>> 0600 to 0640 when the file is owned by the user running Postgres?  If we
>> don't do that, then SSL private keys will need to be used with 0600,
>> potentially breaking backups...  At the same time this reduces the
>> security of private keys but if the administrator is ready to accept
>> group permissions that should be a risk he is ready to accept?
>
> I feel this should be considered in a separate patch.  These files are
> not created by initdb so it seems to be an admin/packaging issue.  There
> is always the option to locate the certs outside the data directory and
> some distros do that by default.

OK, I agree with your final position.  Let's treat it later in a
separate thread, if need be.  However this is not really mandatory.

>> I am pretty sure that we want more documentation in pg_basebackup,
>> pg_rewind and pg_resetwal telling that those consider grouping access.
>
> I think this makes sense for pg_basebackup, pg_receivewal, and
> pg_recvlogical so I have added notes for those.  Not sure I'm happy with
> the language but at least we have something to bikeshed.
>
> It seems to me that pg_resetwal and pg_rewind should be expected to not
> break the permissions in PGDATA, just as they do now.

OK, I think that I am fine with this logic.

> I decided that the constants were a bit confusing in general.  What does
> "default" mean, anyway?

The value that user should have if he decides to not enforce it.

> Instead I have created variables in file_perm.c
> that hold the current file create mode, dir create mode, and mode mask.
> All call sites use those variables (e.g. pg_dir_create_mode), which I
> think are much clear.

Hm.  I personally find that even more confusing, especially with
SetDataDirectoryCreatePerm which basically is the same as
SetConfigOption for the backend.  In your case pg_dir_create_mode is not
aimed at remaining a constant as you may change it depending on if
grouping is enabled or not...  And all the other iterations of such
variables in src/common/ are constants (see NumScanKeywords or
forkNames[] for example), so I cannot see with a good eye this change.

You also forgot a call to SetDataDirectoryCreatePerm or
pg_dir_create_mode remains to its default.

The interface of file_perm.h that you are introducing is not confusing
anymore though..
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Michael,

On 4/5/18 2:55 AM, Michael Paquier wrote:
> On Wed, Apr 04, 2018 at 08:03:54PM -0400, David Steele wrote:
>
>> Instead I have created variables in file_perm.c
>> that hold the current file create mode, dir create mode, and mode mask.
>> All call sites use those variables (e.g. pg_dir_create_mode), which I
>> think are much clear.
>
> Hm.  I personally find that even more confusing, especially with
> SetDataDirectoryCreatePerm which basically is the same as
> SetConfigOption for the backend.

The GUC shows the current mode of the data directory, while the
variables in file_perm.c store the mode that should be used to create
new dirs/files.  One is certainly based on the other but I thought it
best to split them for clarity.

> In your case pg_dir_create_mode is not
> aimed at remaining a constant as you may change it depending on if
> grouping is enabled or not...  And all the other iterations of such
> variables in src/common/ are constants (see NumScanKeywords or
> forkNames[] for example), so I cannot see with a good eye this change.

The idea is to have a variable that give the fir dir/file create mode
without having to trust that umask() is set correctly or do mode masking
on chmod().  This makes a number of call sites simpler and, I hope,
easier to read.

> You also forgot a call to SetDataDirectoryCreatePerm or
> pg_dir_create_mode remains to its default.

Are saying *if* a call is forgotten?

Yes, the file/dir create modes will use the default restrictive
permissions unless set otherwise.  I see this as a good thing.  Worst
case, we miss some areas where group access should be enabled and we
find those over the next few months.

What we don't want is a regression in the current, default behavior.
This is design is intended to avoid that outcome.

> The interface of file_perm.h that you are introducing is not confusing
> anymore though..

Yes, that was the idea.  I think it makes it clearer what we are trying
to do and centralizes variables related to create modes in one place.

I've attached new patches that exclude Windows from permissions tests
and deal with bootstrap permissions in a better way.  PostgresMain() and
AuxiliaryProcessMain() now use checkDataDir() to set permissions.

Thanks!
--
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Thu, Apr 05, 2018 at 12:08:15PM -0400, David Steele wrote:
> On 4/5/18 2:55 AM, Michael Paquier wrote:
>> On Wed, Apr 04, 2018 at 08:03:54PM -0400, David Steele wrote:
>>
>>> Instead I have created variables in file_perm.c
>>> that hold the current file create mode, dir create mode, and mode mask.
>>> All call sites use those variables (e.g. pg_dir_create_mode), which I
>>> think are much clear.
>>
>> Hm.  I personally find that even more confusing, especially with
>> SetDataDirectoryCreatePerm which basically is the same as
>> SetConfigOption for the backend.
>
> The GUC shows the current mode of the data directory, while the
> variables in file_perm.c store the mode that should be used to create
> new dirs/files.  One is certainly based on the other but I thought it
> best to split them for clarity.

Yeah, there are arguments to actually have both things split so as they
can be concatenated.  This makes the code more modular.

>> You also forgot a call to SetDataDirectoryCreatePerm or
>> pg_dir_create_mode remains to its default.

My apologies, I forgot the last two words of this sentence: "for
pg_rewind".  Still, I am wrong because GetDataDirectoryCreatePerm calls
internally SetDataDirectoryCreatePerm.  So the API name is confusing
because not only the permissions are fetched, but they are also
applied.

> Are saying *if* a call is forgotten?

That applies as well.

>> The interface of file_perm.h that you are introducing is not confusing
>> anymore though..
>
> Yes, that was the idea.  I think it makes it clearer what we are trying
> to do and centralizes variables related to create modes in one place.
>
> I've attached new patches that exclude Windows from permissions tests
> and deal with bootstrap permissions in a better way.  PostgresMain() and
> AuxiliaryProcessMain() now use checkDataDir() to set permissions.

GetDataDirectoryCreatePerm() is defined in file_perm.h but it is only
declared for frontends.

At the end, this patch brings in a new abstraction concept to
src/common/ to control a set of pre-determined behaviors:
- The mode to create directories.
- The mode to create files.
- The mode number which can be used for umask.
I am not really convinced that we need to enforce all of them all the
time with a API layer aimed at controlling the behavior of all things at
the same time.  Getting this abstraction down one level by allowing each
frontend to set up things the way they want would be nicer in my
opinion.  Perhaps others feel differently...

It could be also less confusing if the set of variables in file_perm.h
was designed in such a way that we have the default, and then we can
apply on top of it the set to allow grouping, so as allowing grouping
access would be to do the operation of (default mask + group addition).

The design on the backend is rather neat however there is also
overlapping with SetDataDirectoryCreatePerm() and the GUC
data_directory_mode which are heading toward the same types of goals.
We could reduce that confusion by designing the interface as follows:
- Have read-only GUCs for the directory and file masks on the backend
which get set by the postmaster after looking at the permission of the
data folder at startup.  Then if a file or a folder needs to be created,
then look at those values and apply permissions as granted.  And also a
GUC to decide the umask to apply but that should not be necessary,
right?
- Frontends are responsible for the decision-making of the permissions.
Not all the variables are used for frontends as well.  For example
pg_resetwal and pg_upgrade only touch files.
- For frontends, there are two cases:
-- The client needs to connect to a live Postgres instance, in which
case it can use the SHOW command to get the wanted information.  This
applies to pg_rewind with the remote mode (should apply to the second
case actually), pg_basebackup, pg_receivexlog, etc.
-- Binaries work on a local data folder, so permissions can be guessed
from that: pg_rewind, pg_resetwal and pg_upgrade.  Having an API in
src/common/ which scans for what to apply is neat.  This was in v12 and
some older versions if I recall correctly.

We are two days away from the end of the commit fest, and this patch set
if not yet in a committable stagle, so perhaps at this stage we had
better just retreat and come back to it in next cycle?
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Greetings,

* Michael Paquier (michael@paquier.xyz) wrote:
> On Thu, Apr 05, 2018 at 12:08:15PM -0400, David Steele wrote:
> > On 4/5/18 2:55 AM, Michael Paquier wrote:
> >> On Wed, Apr 04, 2018 at 08:03:54PM -0400, David Steele wrote:
> >>
> >>> Instead I have created variables in file_perm.c
> >>> that hold the current file create mode, dir create mode, and mode mask.
> >>> All call sites use those variables (e.g. pg_dir_create_mode), which I
> >>> think are much clear.
> >>
> >> Hm.  I personally find that even more confusing, especially with
> >> SetDataDirectoryCreatePerm which basically is the same as
> >> SetConfigOption for the backend.
> >
> > The GUC shows the current mode of the data directory, while the
> > variables in file_perm.c store the mode that should be used to create
> > new dirs/files.  One is certainly based on the other but I thought it
> > best to split them for clarity.
>
> Yeah, there are arguments to actually have both things split so as they
> can be concatenated.  This makes the code more modular.

I prefer having them split as well.

> >> You also forgot a call to SetDataDirectoryCreatePerm or
> >> pg_dir_create_mode remains to its default.
>
> My apologies, I forgot the last two words of this sentence: "for
> pg_rewind".  Still, I am wrong because GetDataDirectoryCreatePerm calls
> internally SetDataDirectoryCreatePerm.  So the API name is confusing
> because not only the permissions are fetched, but they are also
> applied.

They're not *actually* applied though- that just sets the variable, and
having GetDataDirectoryCreatePerm get what the perm is and then set a
variable based off of that, so we know what it's set to later, seems
reasonable to me.

> >> The interface of file_perm.h that you are introducing is not confusing
> >> anymore though..
> >
> > Yes, that was the idea.  I think it makes it clearer what we are trying
> > to do and centralizes variables related to create modes in one place.
> >
> > I've attached new patches that exclude Windows from permissions tests
> > and deal with bootstrap permissions in a better way.  PostgresMain() and
> > AuxiliaryProcessMain() now use checkDataDir() to set permissions.
>
> GetDataDirectoryCreatePerm() is defined in file_perm.h but it is only
> declared for frontends.

Right, the job that GetDataDirectoryCreatePerm() has in the front-ends
is more complicated when the backend is starting up because we're also
checking who the data directory is owned by and we're setting the
internal GUC, all of which is done by checkDataDir(), which also calls
SetDataDirectoryCreatePerm() to set the variables.

> At the end, this patch brings in a new abstraction concept to
> src/common/ to control a set of pre-determined behaviors:
> - The mode to create directories.
> - The mode to create files.
> - The mode number which can be used for umask.
> I am not really convinced that we need to enforce all of them all the
> time with a API layer aimed at controlling the behavior of all things at
> the same time.  Getting this abstraction down one level by allowing each
> frontend to set up things the way they want would be nicer in my
> opinion.  Perhaps others feel differently...

I don't think we actually *want* the various tools making different
decisions about what permissions the files in a given data directory
have- that's initdb's job, not the job of pg_resetwal.

> It could be also less confusing if the set of variables in file_perm.h
> was designed in such a way that we have the default, and then we can
> apply on top of it the set to allow grouping, so as allowing grouping
> access would be to do the operation of (default mask + group addition).

This seems like we're going around-and-around.  We had all the different
masking things happening previously, but that got rather ugly as there
were just small variations between "right" and "wrong".  I like this
approach which makes it pretty clear that when we start up, we figure
out what the perms should be for files in this data dir, and then we set
the variables for the permissions and use them.

> The design on the backend is rather neat however there is also
> overlapping with SetDataDirectoryCreatePerm() and the GUC
> data_directory_mode which are heading toward the same types of goals.

Just above we discuss how we want those to be seperate, and here it
seems you're asking for them to be put together.  We really can't have
it both ways in this case and I tend to agree with the above discussion
where we keep them seperate.

> We could reduce that confusion by designing the interface as follows:
> - Have read-only GUCs for the directory and file masks on the backend
> which get set by the postmaster after looking at the permission of the
> data folder at startup.  Then if a file or a folder needs to be created,
> then look at those values and apply permissions as granted.  And also a
> GUC to decide the umask to apply but that should not be necessary,
> right?

This is more-or-less what we've got now- a read-only GUC for the
directory and file masks on the backend which gets set by the postmaster
after looking at the permission of the data folder on startup- that all
happens in checkDataDir() now, which looks good to me.  We then have the
variables set by SetDataDirectoryCreatePerm() which happens just before
the GUC is set in the same area of checkDataDir().  We need to set them
both if we're going to keep them seperate, which I believe is what we
really want here.

> - Frontends are responsible for the decision-making of the permissions.

No.  Frontends need to follow what the permissions are on the data
directory- having them decide independently will just lead to things
being inconsistent and that's definitely not something that we want.

> Not all the variables are used for frontends as well.  For example
> pg_resetwal and pg_upgrade only touch files.

While true today, I don't think it's an issue and I'd rather keep the
directory and file privilege settings in the same place (where else
would you put the directory ones?).

> - For frontends, there are two cases:
> -- The client needs to connect to a live Postgres instance, in which
> case it can use the SHOW command to get the wanted information.  This
> applies to pg_rewind with the remote mode (should apply to the second
> case actually), pg_basebackup, pg_receivexlog, etc.

Right, that's what pg_basebackup, pg_receivewal, etc, do now with this
patch..

> -- Binaries work on a local data folder, so permissions can be guessed
> from that: pg_rewind, pg_resetwal and pg_upgrade.  Having an API in
> src/common/ which scans for what to apply is neat.  This was in v12 and
> some older versions if I recall correctly.

I'm confused here as that's what GetDataDirectoryCreatePerm()
specifically does and that's why it's in src/common now for the
front-end tools to use, or were you just agreeing that this was in v12
previously and you're happy to see that it's back..?

> We are two days away from the end of the commit fest, and this patch set
> if not yet in a committable stagle, so perhaps at this stage we had
> better just retreat and come back to it in next cycle?

I've been watching this and discussing things with David while you and
he have been working on it and I think the discussion has generally been
good, so I didn't want to step in and disrupt it, but there's a few
things here which now seem to be going in circles without a lot of
benefit.  There's a few comments which I have on the patch after going
over it again, but I tend to feel it's actually pretty close as none of
the comments I have at this point are serious issues- you and David have
addressed those (I'm *very* glad that the pg_dump changes were ripped
out, for instance, and having the some of the regression tests committed
independently was certainly good...) and I don't see any of the above as
being really concerning, but do let me know if you think there's
something I'm missing or some other issue.

I'll reply to David's last email (where the latest set of patches were
included) with my comments/suggestions and I expect we'll be able to get
those addressed today and have a final patch to post tonight, with an
eye towards committing it tomorrow.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Michael Paquier
Date:
On Fri, Apr 06, 2018 at 09:15:15AM -0400, Stephen Frost wrote:
> I'll reply to David's last email (where the latest set of patches were
> included) with my comments/suggestions and I expect we'll be able to get
> those addressed today and have a final patch to post tonight, with an
> eye towards committing it tomorrow.

The feature freeze is on the 8th, so I am going to have limited room to
comment on things until that day.  If something gets committed, I am
pretty sure that I'll get out of my pocket a couple of things to improve
the feature and its interface anyway if of course you are ready to
accept that.  I have limited my role to be a reviewer, so I refrained
myself from writing any code ;)
--
Michael

Attachment

Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
David,

* David Steele (david@pgmasters.net) wrote:
> The GUC shows the current mode of the data directory, while the
> variables in file_perm.c store the mode that should be used to create
> new dirs/files.  One is certainly based on the other but I thought it
> best to split them for clarity.

Agreed.  I did have some other comments about the patches tho-

> > You also forgot a call to SetDataDirectoryCreatePerm or
> > pg_dir_create_mode remains to its default.
>
> Are saying *if* a call is forgotten?
>
> Yes, the file/dir create modes will use the default restrictive
> permissions unless set otherwise.  I see this as a good thing.  Worst
> case, we miss some areas where group access should be enabled and we
> find those over the next few months.

I tend to agree with this, though the space of concern is quite limited-
basically between the top of PostmasterMain() and when it calls
checkDataDir(), and we really shouldn't be creating any files before
we've check that the data dir looks sane.

> > The interface of file_perm.h that you are introducing is not confusing
> > anymore though..
>
> Yes, that was the idea.  I think it makes it clearer what we are trying
> to do and centralizes variables related to create modes in one place.
>
> I've attached new patches that exclude Windows from permissions tests
> and deal with bootstrap permissions in a better way.  PostgresMain() and
> AuxiliaryProcessMain() now use checkDataDir() to set permissions.

Alright, changes I've made, since I got impatient and it didn't seem to
make sense to bounce these back to David instead of just making them (I
did discuss them with him on the phone today tho, just to be clear).

- MakeDirectoryDefaultPerm() was quite a mouthful, so I've simplified
  that down to MakePGDirectory(), which I hope is clear in that it's for
  making directories related to PG (as it isn't a general mkdir() call
  or just some platform-agnostic mkdir(), which MakeDirectory() might
  imply, but is specific for working with PG data directories).

- The PG_FILE_MODE_DEFAULT, PG_DIR_MODE_DEFAULT, et al, were confusing.
  Those constants are used for the default file/dir mode, sure, but what
  that actually *are* is the 'owner'-only style mode, so they've been
  changed to PG_FILE_MODE_OWNER, PG_DIR_MODE_OWNER, etc.

- Where we're intentionally ignoring the MakePGDirectory() result,
  use (void).

- Various comment improvements.

- Improved the commit messages a bit.

Things that still need doing:

- Go back over with pgindent and make sure it's all happy.
- Improved documentation
- Likely more comments (I don't think I can ever have enough)
- Further discussion in the commit messages
- Perhaps a bit more review to try to minimize the risk that something
  breaks on Windows...  Looked ok to me, but probably still some risk
  that the Windows buildfarm members fall over, though I suppose that's
  also what they're there for.

Updated patch attached.

David, if you could look through this again and make sure I didn't break
anything with the changes made, and perhaps make improvements to the
docs/comments/commit messages, that'd be helpful for getting this over
the line.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Michael,

* Michael Paquier (michael@paquier.xyz) wrote:
> On Fri, Apr 06, 2018 at 09:15:15AM -0400, Stephen Frost wrote:
> > I'll reply to David's last email (where the latest set of patches were
> > included) with my comments/suggestions and I expect we'll be able to get
> > those addressed today and have a final patch to post tonight, with an
> > eye towards committing it tomorrow.
>
> The feature freeze is on the 8th, so I am going to have limited room to
> comment on things until that day.  If something gets committed, I am
> pretty sure that I'll get out of my pocket a couple of things to improve
> the feature and its interface anyway if of course you are ready to
> accept that.  I have limited my role to be a reviewer, so I refrained
> myself from writing any code ;)

I'm, of course, happy to accept any further comments or suggestions on
it, pre-commit, post-commit, next year, whenever. ;)

I've posted an updated patch with comments and next steps, as discussed,
which I'm hopeful that David will have a chance to review and comment
on, at least, and perhaps help wrap up those last items.  This patch has
been quite a slog, so thank you again for all of your help reviewing it
and moving it forward, it's been really appreciated.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Stephen,

On 4/6/18 3:02 PM, Stephen Frost wrote:
> 
> Alright, changes I've made, since I got impatient and it didn't seem to
> make sense to bounce these back to David instead of just making them (I
> did discuss them with him on the phone today tho, just to be clear).
> 
> - The PG_FILE_MODE_DEFAULT, PG_DIR_MODE_DEFAULT, et al, were confusing.
>    Those constants are used for the default file/dir mode, sure, but what
>    that actually *are* is the 'owner'-only style mode, so they've been
>    changed to PG_FILE_MODE_OWNER, PG_DIR_MODE_OWNER, etc.

This is definitely better.

There were a few missed replacements in 01 so I fixed those.

> Things that still need doing:
> 
> - Further discussion in the commit messages

Agreed, these need some more work.  I'm happy to do that but I'll need a 
bit more time.  Have a look at the new patches and I'll work on some 
better messages.

> - Perhaps a bit more review to try to minimize the risk that something
>    breaks on Windows...  Looked ok to me, but probably still some risk
>    that the Windows buildfarm members fall over, though I suppose that's
>    also what they're there for.

I did my best on this based on breakage from some of my other patches.

> David, if you could look through this again and make sure I didn't break
> anything with the changes made, and perhaps make improvements to the
> docs/comments/commit messages, that'd be helpful for getting this over
> the line.

I'm pretty happy with it overall.  As you say, there could always be 
more comments, but I'm not sure what to add without just running on.

New patches attached.

-- 
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 4/6/18 6:04 PM, David Steele wrote:
> On 4/6/18 3:02 PM, Stephen Frost wrote:
>>
>> - Further discussion in the commit messages
> 
> Agreed, these need some more work.  I'm happy to do that but I'll need a 
> bit more time.  Have a look at the new patches and I'll work on some 
> better messages.

I'm sure you'll want to reword some things, but I think these commit 
messages capture the essential changes for each patch.

01: Refactor file permissions in backend/frontend

Consolidate directory and file create permissions by adding a new module 
(common/file_perm.c) that contains variables (pg_file_create_mode, 
pg_dir_create_mode) and constants to initialize them (0600 for files and 
0700 for directories).

Convert mkdir() calls in the backend to MakePGDirectory() if the 
original call used default permissions (always the case for regular PG 
directories).

Add tests to make sure permissions in PGDATA are set correctly by the
front-end tools.

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

02: Allow group access on PGDATA

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 because 
there are a number of front-end utilities that write into PGDATA but not 
all of them read pg_control and none of them load GUCS.

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 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 front-end utilities to ensure 
that the correct mode is set based on the PGDATA permissions.

Author: David Steele <david@pgmasters.net>
Reviewed-By: Michael Paquier, with discussion amongst many others.
Discussion: 
https://postgr.es/m/https://www.postgresql.org/message-id/ad346fe6-b23e-59f1-ecb7-0e08390ad629%40pgmasters.net

Thanks!
-- 
-David
david@pgmasters.net


Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
David,

* David Steele (david@pgmasters.net) wrote:
> On 4/6/18 6:04 PM, David Steele wrote:
> >On 4/6/18 3:02 PM, Stephen Frost wrote:
> >>
> >>- Further discussion in the commit messages
> >
> >Agreed, these need some more work.  I'm happy to do that but I'll need a
> >bit more time.  Have a look at the new patches and I'll work on some
> >better messages.
>
> I'm sure you'll want to reword some things, but I think these commit
> messages capture the essential changes for each patch.

Thanks much.  I've taken (most) of these, adjusting a few bits here and
there.

I've been back over the patch again, mostly improving the commit
messages, comments, and docs.  I also looked over the code and tests
again and they're looking pretty good to me, so I'll be looking to
commit this tomorrow afternoon or so US/Eastern.

Attached is v18.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Stephen,

On 4/6/18 10:22 PM, Stephen Frost wrote:
>
> * David Steele (david@pgmasters.net) wrote:
>> On 4/6/18 6:04 PM, David Steele wrote:
>>> On 4/6/18 3:02 PM, Stephen Frost wrote:
>>>>
>>>> - Further discussion in the commit messages
>>>
>>> Agreed, these need some more work.  I'm happy to do that but I'll need a
>>> bit more time.  Have a look at the new patches and I'll work on some
>>> better messages.
>>
>> I'm sure you'll want to reword some things, but I think these commit
>> messages capture the essential changes for each patch.
>
> Thanks much.  I've taken (most) of these, adjusting a few bits here and
> there.
>
> I've been back over the patch again, mostly improving the commit
> messages, comments, and docs.  I also looked over the code and tests
> again and they're looking pretty good to me, so I'll be looking to
> commit this tomorrow afternoon or so US/Eastern.

OK, one last review.  I did't make any code changes, but I improved some
comments, added documentation and fixed a test.

01) Refactor dir/file permissions

* Small comment update, replace "such cases-" with "such cases --".

02) Allow group access on PGDATA

* Add data_directory_mode guc to "Preset Options" documentation.
* Add a section to the documentation that discusses changing the
permissions of an existing cluster.
* Improved comment on checkControlFile().
* Comment wordsmithing for SetDataDirectoryCreatePerm() and
RetrieveDataDirCreatePerm().
* Fixed ordering of -g option in initdb documentation.
* Fixed a new test that was "broken" by 032429701e477.  It was broken
before but the rmtrees added in 032429701e477 exposed the problem.

Attached are the v19 patches.

Thanks!
--
-David
david@pgmasters.net

Attachment

Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
David,

* David Steele (david@pgmasters.net) wrote:
> On 4/6/18 10:22 PM, Stephen Frost wrote:
> > * David Steele (david@pgmasters.net) wrote:
> >> On 4/6/18 6:04 PM, David Steele wrote:
> >>> On 4/6/18 3:02 PM, Stephen Frost wrote:
> >>>>
> >>>> - Further discussion in the commit messages
> >>>
> >>> Agreed, these need some more work.  I'm happy to do that but I'll need a
> >>> bit more time.  Have a look at the new patches and I'll work on some
> >>> better messages.
> >>
> >> I'm sure you'll want to reword some things, but I think these commit
> >> messages capture the essential changes for each patch.
> >
> > Thanks much.  I've taken (most) of these, adjusting a few bits here and
> > there.
> >
> > I've been back over the patch again, mostly improving the commit
> > messages, comments, and docs.  I also looked over the code and tests
> > again and they're looking pretty good to me, so I'll be looking to
> > commit this tomorrow afternoon or so US/Eastern.
>
> OK, one last review.  I did't make any code changes, but I improved some
> comments, added documentation and fixed a test.

Thanks!  I took those and then added a bit more commentary around the
umask() calls in the utilities and fixed a typo or two and then pushed
it.

Time to watch the buildfarm, particularly for Windows hosts just in case
there's something in the regression tests which aren't working correctly
on that platform.  I was able to run the full regression suite locally
before committing, though given the recent activity, we may see failures
attributed to this patch which are due to unrelated instability.

Thanks again!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
On 4/7/18 5:49 PM, Stephen Frost wrote:
> * David Steele (david@pgmasters.net) wrote:
>>
>> OK, one last review.  I did't make any code changes, but I improved some
>> comments, added documentation and fixed a test.
>
> Thanks!  I took those and then added a bit more commentary around the
> umask() calls in the utilities and fixed a typo or two and then pushed
> it.

Excellent, thank you!

> Time to watch the buildfarm, particularly for Windows hosts just in case
> there's something in the regression tests which aren't working correctly
> on that platform.  I was able to run the full regression suite locally
> before committing, though given the recent activity, we may see failures
> attributed to this patch which are due to unrelated instability.

I'll have dinner then come back and take a look.

--
-David
david@pgmasters.net


Attachment

Re: PATCH: Configurable file mode mask

From
Tom Lane
Date:
Stephen Frost <sfrost@snowman.net> writes:
> Time to watch the buildfarm,

That didn't take long.

https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=culicidae&dt=2018-04-07%2021%3A50%3A02

(I'm really starting to get a bit upset at the amount of stuff that's
being pushed in on the very last day.)

            regards, tom lane


Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Tom,

* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> Stephen Frost <sfrost@snowman.net> writes:
> > Time to watch the buildfarm,
>
> That didn't take long.
>
> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=culicidae&dt=2018-04-07%2021%3A50%3A02

Yes, I'm taking a look at it.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Tom Lane
Date:
Stephen Frost <sfrost@snowman.net> writes:
> * Tom Lane (tgl@sss.pgh.pa.us) wrote:
>> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=culicidae&dt=2018-04-07%2021%3A50%3A02

> Yes, I'm taking a look at it.

Since other animals are coming back successfully, my first suspicion
lights on culicidae's use of EXEC_BACKEND.  Did you test that case?
(If not, this bodes ill for the Windows results.)

            regards, tom lane


Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Greetings,

* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> Stephen Frost <sfrost@snowman.net> writes:
> > * Tom Lane (tgl@sss.pgh.pa.us) wrote:
> >> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=culicidae&dt=2018-04-07%2021%3A50%3A02
>
> > Yes, I'm taking a look at it.
>
> Since other animals are coming back successfully, my first suspicion
> lights on culicidae's use of EXEC_BACKEND.  Did you test that case?
> (If not, this bodes ill for the Windows results.)

The vast majority of this patch isn't something that's relevant to
Windows anyway, so I'm hopeful that those animals will stay green (if
not, it's probably that we need to mark some other test as
not-on-Windows).

We have EXEC_BACKEND on the Unix-y systems too though, so that needs to
be fixed.  I'm pretty sure the issue here is that SubPostmasterMain()
needs to also be checking/updating the umask() based on the data
directory, as is done in PostmasterMain.

Testing that out now and if that looks good then I'll push that and
hopefully it'll make cullcidae green.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
Stephen Frost
Date:
Greetings,

* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> (If not, this bodes ill for the Windows results.)

Ah, there go the Windows builds...  Missing a #else clause where we
should have one for those systems, will fix.

Thanks!

Stephen

Attachment

Re: PATCH: Configurable file mode mask

From
David Steele
Date:
Hi Michael,

On 4/6/18 10:20 AM, Michael Paquier wrote:
> On Fri, Apr 06, 2018 at 09:15:15AM -0400, Stephen Frost wrote:
>> I'll reply to David's last email (where the latest set of patches were
>> included) with my comments/suggestions and I expect we'll be able to get
>> those addressed today and have a final patch to post tonight, with an
>> eye towards committing it tomorrow.
>
> The feature freeze is on the 8th, so I am going to have limited room to
> comment on things until that day.  If something gets committed, I am
> pretty sure that I'll get out of my pocket a couple of things to improve
> the feature and its interface anyway if of course you are ready to
> accept that.

Improvements are always welcome!  The core focus of the patch hasn't
changed over the last year, but we've found better ways to implement it
over time.  I'm sure there's more we can do.

> I have limited my role to be a reviewer, so I refrained
> myself from writing any code ;)

Your dedicated and tireless review helped get this patch over the line.
Thank you very much for all your hard work.

--
-David
david@pgmasters.net


Attachment