0

This is a question about finding an ideal way to deal with a particular situation.

In a folder under my home folder is a group of psql script files that reference each others through \include_relative meta-commands. These scripts sometimes need to be run through psql as a database superuser. Because postgres is peer-authenticated, I must call psql with sudo --user postgres. But since the files are in my home folder, the OS user postgres has no access to them. Now, if there was only a single script file to read, I could simply use a shell redirection, as in sudo -u postgres psql < ~/psql/myscript.psql, but as soon as myscript.psql includes another file, then psql won't find it.

There are various simple and trivial ways of making this work. However, I exclude manually copying/moving/deleting files around every time I need to run a script, and I want to retain the ability to freely move around and rename the source folder and script files without breaking things. Furthermore, this is a mission-critical production server, so interfering with the PostgreSQL service, as in changing the cluster's configuration — for example, creating additional superusers, or changing authentication settings — is out of the question. Ideally, we want this to be transparent to the rest of the server, which excludes solutions involving pre-configured (e.g. ftab, systemd-mount) bind-mount and overlays, or other changes to the server's configuration.

I am looking specifically for a command that makes the script folder available on-the-fly to psql, and only for the duration of the script run. My solution so far is this:

$ sudo mount --bind -o ro,X-mount.mkdir=777 ./psql ~postgres/tmp && \
  sudo -iu postgres psql -f ~postgres/tmp/myscript.psql; \
  sudo umount ~postgres/tmp && \
  sudo rmdir ~postgres/tmp

But still, I find it verbose and I'm trying to improve on it. And I don't like the creation of a tmp folder in ~postgres. Has anybody better ideas?

Edit: Following @larsks' comment below, I realize that my above solution has a privacy flaw in systems where multiple user are given access to the postgres user.

3
  • 1
    Move those commands into a script so you just run sudo myscript instead. I'm not sure anything is going to be more graceful than that. Or set a+x on your home directory (and possibly intervening directories) so that the postgres user can read the files in their existing location; it doesn't appear to be a file ownership or permissions problem (you're never calling chown or chmod). Commented Aug 8, 2022 at 12:30
  • Yes, a script or an alias is a good way to conceal the verbosity. The permission thing, we've thought of it already, but the scripts should ideally stay private to each particular user (sudoer), and giving any access to postgres would allow anyone with sudo access to postgres to see each other's scripts. This could become an issue. This is actually already the case, I realize, for a short window while the mount is active. Thanks for initiating this line of thoughts. Commented Aug 8, 2022 at 15:07
  • Is there a reason you can't use the straight-forward solution of simply creating a postgres role for your own username, and then granting rights to that role to do whatever it is you need to do? Doing it this way would be roughly analogous to using sudo to lock down a specific user's root privileges instead of giving them the root password. Commented Aug 8, 2022 at 15:44

1 Answer 1

1

We create a shell script run-with-tempdir that looks like this:

#!/bin/sh

tmpdir=$(mktemp -d ~postgres/tmp/psqlXXXXXX)
trap "rm -rf $tmpdir" EXIT

tar -C "$tmpdir" -xf- &&
  psql -f "$tmpdir/$1"

And then we run it like this:

tar -C psql -cf- . | sudo -u postgres run-with-tempdir myscript.psql

This (a) doesn't expose your home directory to the postgres user, (b) doesn't expose your scripts to any other users on the system (because the tmpdir is create with mode 700), (c) doesn't require bind mounts (which can cause problems if an error prevents the unmount from happening), and (d) cleans up after itself automatically.

4
  • Point (c) and (d) are two more good issues raised. Regarding this proposed solution, though, isn't anyone who can sudo as postgres still able to just do sudo -u postgres ls ~postgres/tmp/psqlXXXXXX and see all the scripts file there? Commented Aug 8, 2022 at 15:42
  • That depends on your sudoers configuration: do you allow arbitrary commands? Or do you just allow people to run the run-with-tempdir script? Commented Aug 8, 2022 at 15:45
  • I ended up using a different approach for ensuring script privacy. I realized that all requirements of the problem that I'm trying to solve cannot be met with a "temporary duplicates" approach, which must involve some extant of server configuration (as larsks pointed out above, limiting the privileges of sudoers with regard to what commands they can run as postgres). So I'll go ahead an accept larsks' answer because it does answer the initial question by bringing significant improvements over my initial attempt. Commented Aug 10, 2022 at 18:54
  • For reference, my solution to this other question ended up providing the answer to the issue underlying the present question (the "different approach" mentioned in the above comment): unix.stackexchange.com/questions/712751/… Commented Aug 16, 2022 at 15:35

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.