[bug#77413] services: postgresql-service-type: Allow allowing to log into the user.

Message ID 9ac891e4fdb07ec4fd0e92f232a923d33d4c20ec.1743449155.git.~@wolfsden.cz
State New
Headers
Series [bug#77413] services: postgresql-service-type: Allow allowing to log into the user. |

Commit Message

Tomas Volf March 31, 2025, 7:25 p.m. UTC
  It is often useful to be able to use the `postgres' user for management tasks,
so this commit allows setting that.  The default behavior is not changed.

I have also added missing exports and sorted them by alphabet.

* gnu/services/databases.scm (%default-home-directory): New variable.
(<postgresql-configuration>): Add home-directory, allow-login? fields.
(create-postgresql-account): Use them.
* doc/guix.texi (Database Services): Document it.

Change-Id: I2212e5082ff4e87c49a5a8a4711bf929dd08626a
---
 doc/guix.texi              | 17 ++++++++++++-----
 gnu/services/databases.scm | 31 +++++++++++++++++++++++--------
 2 files changed, 35 insertions(+), 13 deletions(-)
  

Comments

Ludovic Courtès April 1, 2025, 12:28 p.m. UTC | #1
Tomas Volf <~@wolfsden.cz> skribis:

> It is often useful to be able to use the `postgres' user for management tasks,
> so this commit allows setting that.  The default behavior is not changed.
>
> I have also added missing exports and sorted them by alphabet.
>
> * gnu/services/databases.scm (%default-home-directory): New variable.
> (<postgresql-configuration>): Add home-directory, allow-login? fields.
> (create-postgresql-account): Use them.
> * doc/guix.texi (Database Services): Document it.
>
> Change-Id: I2212e5082ff4e87c49a5a8a4711bf929dd08626a

Hi!  I’m rather against this change, because it’s unnecessary.  Let me
share a protip:

  sudo su - cuirass -s /bin/sh -c $(type -P psql)

(From
<https://git.savannah.gnu.org/cgit/guix/maintenance.git/tree/doc/cuirass.org#n118>.)

Ludo’.
  
Tomas Volf April 1, 2025, 9:06 p.m. UTC | #2
Ludovic Courtès <ludo@gnu.org> writes:

> Tomas Volf <~@wolfsden.cz> skribis:
>
>> It is often useful to be able to use the `postgres' user for management tasks,
>> so this commit allows setting that.  The default behavior is not changed.
>>
>> I have also added missing exports and sorted them by alphabet.
>>
>> * gnu/services/databases.scm (%default-home-directory): New variable.
>> (<postgresql-configuration>): Add home-directory, allow-login? fields.
>> (create-postgresql-account): Use them.
>> * doc/guix.texi (Database Services): Document it.
>>
>> Change-Id: I2212e5082ff4e87c49a5a8a4711bf929dd08626a
>
> Hi!  I’m rather against this change, because it’s unnecessary.

The default is not changed though, this just gives people more options.
Some people (me included) prefer to have postgres account as a fully
working user, with working psql history.  Unless this opens security
issues (Does it?  For example Archlinux has /usr/bin/bash for postgres
user.), it there a reason not to allow users to make the choice here?
Especially since the default behavior is not modified and still adheres
to your preference?

> Let me share a protip:
>
>   sudo su - cuirass -s /bin/sh -c $(type -P psql)
>

Thank you for the -s flag, I was not aware of it.  That make the initial
setup possible, but still annoying.  I needed to run `initdb' (with
modified $PATH), `pg_upgrade' and `vacuumdb'.  I believe that running
those after `sudo -iu postgres' is much easier than trying to figure out
correct quoting while passing all these things as a string to -c
argument of /bin/sh.

Additionally the service I am running does *not* have a full permissions
to the database, so I need to be able to connect somehow for manual
modifications.  I *could* just alias `psql' to `sudo -u postgres -s
/bin/sh -c 'psql'', but I would still not get working history.
Alternatively I could start using the TCP connection and rely on
scram-sha-256 instead of peer authentication.  Or I could create special
dummy account I would sudo into and used that one.  But... I already
have a perfect account, postgres.  So I would like to use it.

So to sum up, I now agree all is possible even without this change
(TIL!), but convenience (and personal preference) is a different matter.

Tomas
  

Patch

diff --git a/doc/guix.texi b/doc/guix.texi
index cb4c1b2430..a152a9623e 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -27523,11 +27523,11 @@  Database Services
 restart the service.
 
 Peer authentication is used by default and the @code{postgres} user
-account has no shell, which prevents the direct execution of @code{psql}
-commands as this user.  To use @code{psql}, you can temporarily log in
-as @code{postgres} using a shell, create a PostgreSQL superuser with the
-same name as one of the system users and then create the associated
-database.
+account has no shell (unless @code{allow-login?} is @code{#t}), which
+prevents the direct execution of @code{psql} commands as this user.  To
+use @code{psql}, you can temporarily log in as @code{postgres} using a
+shell, create a PostgreSQL superuser with the same name as one of the
+system users and then create the associated database.
 
 @example
 sudo -u postgres -s /bin/sh
@@ -27606,6 +27606,13 @@  Database Services
 @item @code{create-account?} (default: @code{#t})
 Whether or not the @code{postgres} user and group should be created.
 
+@item @code{allow-login?} (default: @code{#f})
+Whether or not to allow login into the created account.
+
+@item @code{home-directory} (default: @code{"/var/empty"})
+The home directory of the user.  It is strongly advised to change this
+if you set @code{allow-login?} to @code{#t}.
+
 @item @code{uid} (default: @code{#f})
 Explicitly specify the UID of the @code{postgres} daemon account.
 You normally do not need to specify this, in which case a free UID will
diff --git a/gnu/services/databases.scm b/gnu/services/databases.scm
index 6d80376d90..b45aad2c0b 100644
--- a/gnu/services/databases.scm
+++ b/gnu/services/databases.scm
@@ -51,13 +51,18 @@  (define-module (gnu services databases)
 
             postgresql-configuration
             postgresql-configuration?
-            postgresql-configuration-postgresql
-            postgresql-configuration-port
-            postgresql-configuration-locale
-            postgresql-configuration-file
-            postgresql-configuration-log-directory
+            postgresql-configuration-allow-login?
+            postgresql-configuration-create-account?
             postgresql-configuration-data-directory
             postgresql-configuration-extension-packages
+            postgresql-configuration-file
+            postgresql-configuration-gid
+            postgresql-configuration-home-directory
+            postgresql-configuration-locale
+            postgresql-configuration-log-directory
+            postgresql-configuration-port
+            postgresql-configuration-postgresql
+            postgresql-configuration-uid
 
             postgresql-service
             postgresql-service-type
@@ -164,6 +169,8 @@  (define-gexp-compiler (postgresql-config-file-compiler
              port)))
       #:local-build? #t))))
 
+(define %default-home-directory "/var/empty")
+
 (define-record-type* <postgresql-configuration>
   postgresql-configuration make-postgresql-configuration
   postgresql-configuration?
@@ -186,6 +193,10 @@  (define-record-type* <postgresql-configuration>
                       (default '()))
   (create-account?    postgresql-configuration-create-account?
                       (default #t))
+  (home-directory     postgresql-configuration-home-directory
+                      (default %default-home-directory))
+  (allow-login?       postgresql-configuration-allow-login?
+                      (default #f))
   (uid                postgresql-configuration-uid
                       (default #f))
   (gid                postgresql-configuration-gid
@@ -193,7 +204,7 @@  (define-record-type* <postgresql-configuration>
 
 (define (create-postgresql-account config)
   (match-record config <postgresql-configuration>
-    (create-account? uid gid)
+                (create-account? allow-login? home-directory uid gid)
     (if (not create-account?) '()
         (list (user-group
                (name "postgres")
@@ -205,8 +216,12 @@  (define (create-postgresql-account config)
                (system? #t)
                (uid uid)
                (comment "PostgreSQL server user")
-               (home-directory "/var/empty")
-               (shell (file-append shadow "/sbin/nologin")))))))
+               (create-home-directory?
+                (not (string=? home-directory %default-home-directory)))
+               (home-directory home-directory)
+               (shell (if allow-login?
+                          ((@ (gnu system accounts) default-shell))
+                          (file-append shadow "/sbin/nologin"))))))))
 
 (define (final-postgresql postgresql extension-packages)
   (if (null? extension-packages)