[bug#72316,v2,2/3] Add a guile-pam-module service.
Commit Message
Change-Id: I1da0fe25f542cf9d8c22d26a7434f952585119e6
---
doc/guix.texi | 89 ++++++++++++++++++++++++++++++++++++
gnu/local.mk | 1 +
gnu/services/pam.scm | 105 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 195 insertions(+)
create mode 100644 gnu/services/pam.scm
Comments
Hi!
Felix Lechner <felix.lechner@lease-up.com> writes:
> Change-Id: I1da0fe25f542cf9d8c22d26a7434f952585119e6
Missing GNU ChangeLog message. A system test to ensure it keeps working
n the future would be great. We already have a (gnu tests pam) module.
> ---
> doc/guix.texi | 89 ++++++++++++++++++++++++++++++++++++
> gnu/local.mk | 1 +
> gnu/services/pam.scm | 105 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 195 insertions(+)
> create mode 100644 gnu/services/pam.scm
>
> diff --git a/doc/guix.texi b/doc/guix.texi
> index 90d90b2e1eb..11480cb0ae5 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -412,6 +412,7 @@ Top
> * Telephony Services:: Telephony services.
> * File-Sharing Services:: File-sharing services.
> * Monitoring Services:: Monitoring services.
> +* Guile-PAM Services:: Guile-PAM services.
> * Kerberos Services:: Kerberos services.
> * LDAP Services:: LDAP services.
> * Web Services:: Web servers.
> @@ -19437,6 +19438,7 @@ Services
> * Telephony Services:: Telephony services.
> * File-Sharing Services:: File-sharing services.
> * Monitoring Services:: Monitoring services.
> +* Guile-PAM Services:: Guile-PAM services.
> * Kerberos Services:: Kerberos services.
> * LDAP Services:: LDAP services.
> * Web Services:: Web servers.
> @@ -33149,6 +33151,93 @@ Monitoring Services
> @end deftp
>
>
> +@c %end of fragment
Why do we get the %end before any %start? :-)
> +
> +@node Guile-PAM Services
> +@subsection Guile-PAM Services
> +@cindex Guile-PAM
The contextual index could have extra context, like:
--8<---------------cut here---------------start------------->8---
@cindex Guile-PAM, configuring PAM using Guile
@cindex PAM configuration using Guile, Guile-PAM
--8<---------------cut here---------------end--------------->8---
> +
> +The @code{(gnu services pam)} module provides services related to the
> +authentication mechanism @dfn{Guile-PAM}.
> +
> +Guile-PAM is a reimplementation in GNU Guile of the venerable Linux-PAM
> +authentication system. For details, please have a look at the Texinfo
> +manual in the @code{guile-pam} package.
You can make a proper Texinfo cross-reference to your guile-pam Manual
here, for extra convenience, see (info "(texinfo) Referring to a Manual
as a Whole").
> +@defvar guile-pam-module-service-type
> +A service type for Guile-PAM modules.
> +@end defvar
> +
> +@noindent
> +Here is an example of its use:
> +@lisp
> +(define welcome-pamda-file
> + (scheme-file
> + "welcome-pamda-file"
> + #~(begin
> + (use-modules (ice-9 format))
> +
> + (lambda (action handle flags options)
> + (case action
> + ;; authentication management
For all standalone comments, use complete sentences, or near complete
sentences, like ;; Authentication management.
for margin comment it's fine to use incomplete ones,
e.g. ;authentication management
> + ((pam_sm_authenticate)
> + (format #t "In a working module, we would now identify you.~%"))
> + ((pam_sm_setcred)
> + (format #t "In a working module, we would now help you manage additional credentials.~%"))
> + ;; account management
> + ((pam_sm_acct_mgmt)
> + (format #t "In a working module, we would now confirm your access rights.~%"))
> + ;; password management
> + ((pam_sm_chauthtok)
> + (format #t "In a working module, we would now change your password.~%"))
> + ;; session management
> + ((pam_sm_open_session)
> + (format #t "In a working module, we would now open a session for you.~%"))
> + ((pam_sm_close_session)
> + (format #t "In a working module, we would now close your session.~%"))
> + (else
> + (format #t "In a working module, we would not know what to do about action '~s'.~%"
> + action)))
> + 'PAM_SUCCESS))))
Please mind the maximum 80 chars width.
> +(service guile-pam-module-service-type
> + (guile-pam-module-configuration
> + (rules "optional")
> + (module welcome-pamda-file)
> + (services '("login"
> + "greetd"
> + "su"
> + "slim"
> + "gdm-password"
> + "sddm"))))
> +@end lisp
> +
> +@c %start of fragment
> +
> +@deftp {Data Type} guile-pam-module-configuration
> +Available @code{guile-pam-module-configuration} fields are:
> +
> +@table @asis
> +@item @code{rules} (type: maybe-string)
> +Determines how the module's return value is evaluated.
> +
> +@item @code{module} (type: maybe-file-like)
> +A Guile-PAM pamda file or a classical PAM module.
> +
> +@item @code{services} (type: maybe-list-of-strings)
> +List of PAM service names for which to install the module.
> +
> +@item @code{guile-inputs} (type: maybe-list-of-packages)
> +Guile inputs available in the PAM module
Missing ending period. ^
[...]
> +++ b/gnu/services/pam.scm
> @@ -0,0 +1,105 @@
> +;;; GNU Guix --- Functional package management for GNU
> +;;; Copyright © 2024 Felix Lechner <felix.lechner@lease-up.com>
> +;;;
> +;;; This file is part of GNU Guix.
> +;;;
> +;;; GNU Guix is free software; you can redistribute it and/or modify it
> +;;; under the terms of the GNU General Public License as published by
> +;;; the Free Software Foundation; either version 3 of the License, or (at
> +;;; your option) any later version.
> +;;;
> +;;; GNU Guix is distributed in the hope that it will be useful, but
> +;;; WITHOUT ANY WARRANTY; without even the implied warranty of
> +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +;;; GNU General Public License for more details.
> +;;;
> +;;; You should have received a copy of the GNU General Public License
> +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
> +
> +(define-module (gnu services pam)
> + #:use-module (gnu packages guile)
> + #:use-module (gnu packages guile-xyz)
> + #:use-module (gnu packages linux)
> + #:use-module (gnu packages mes)
> + #:use-module (gnu services)
> + #:use-module (gnu services configuration)
> + #:use-module (gnu system pam)
> + #:use-module (guix gexp)
> + #:use-module (guix packages)
> + #:use-module (guix records)
> + #:use-module (guix utils)
> + #:use-module (srfi srfi-1)
> + #:export (guile-pam-module-configuration))
> +
> +(define-maybe string)
> +(define-maybe list-of-strings)
> +(define-maybe file-like)
> +
> +(define-maybe string-or-file-like)
> +(define (string-or-file-like? val)
> + (or (string? val) (file-like? val)))
> +
> +(define-maybe list-of-packages)
> +(define (list-of-packages? val)
> + (and (list? val) (map package? val)))
> +
> +(define-configuration/no-serialization guile-pam-module-configuration
> + (rules
> + maybe-string
> + "Determines how the module's return value is evaluated.")
> + (module
> + maybe-file-like
> + "A Guile-PAM pamda file or a classical PAM module.")
> + (services
> + maybe-list-of-strings
> + "List of PAM service names for which to install the module.")
> + (guile-inputs
> + maybe-list-of-packages
> + "Guile inputs available in the PAM module")
The trailing period, as mentioned earlier.
> + (foreign-library-path
> + maybe-list-of-packages
> + "Search path for shared objects and libraries.") )
> +
> +(define (guile-pam-module-service config)
> + "Return a list of <shepherd-service> for guile-pam-module for CONFIG."
> + (match-record
> + config <guile-pam-module-configuration> (foreign-library-path
> + guile-inputs
> + module
> + rules
> + services)
The field names are more conventionally formatted on a line after the
record type. You can use the ( one two three
four five)
Emacs trick (leading space inside the opening parenthesis) to have them
indented as data rather than as a procedure call.
> + (list
> + (pam-extension
> + (transformer
> + (lambda (pam)
> + (if (member (pam-service-name pam) services)
> + (let* ((new-entry
> + (pam-entry
> + (control rules)
> + (module module)
> + (guile-inputs (if (eq? %unset-value guile-inputs)
Better use (maybe-value-set? guile-inputs) here.
> + '()
> + guile-inputs))
> + (foreign-library-path (if (eq? %unset-value foreign-library-path)
Likewise + 80 chars limit.
> + '()
> + foreign-library-path)))))
> + (pam-service
> + (inherit pam)
> + (auth (append (pam-service-auth pam)
> + (list new-entry)))
> + (account (append (pam-service-account pam)
> + (list new-entry)))
> + (session (append (pam-service-session pam)
> + (list new-entry)))
> + (password (append (pam-service-password pam)
> + (list new-entry)))))
> + pam)))))))
> +
> +(define-public guile-pam-module-service-type
> + (service-type
> + (name 'guile-pam-module)
> + (extensions (list (service-extension pam-root-service-type
> + guile-pam-module-service)))
> + (compose concatenate)
> + (default-value (guile-pam-module-configuration))
> + (description "Load Guile code as part of Linux-PAM.")))
Interesting. Other than my above comments, it LGTM.
Felix Lechner via Guix-patches via <guix-patches@gnu.org> writes:
> Change-Id: I1da0fe25f542cf9d8c22d26a7434f952585119e6
> ---
> doc/guix.texi | 89 ++++++++++++++++++++++++++++++++++++
> gnu/local.mk | 1 +
> gnu/services/pam.scm | 105 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 195 insertions(+)
> create mode 100644 gnu/services/pam.scm
>
> diff --git a/doc/guix.texi b/doc/guix.texi
> index 90d90b2e1eb..11480cb0ae5 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -412,6 +412,7 @@ Top
> * Telephony Services:: Telephony services.
> * File-Sharing Services:: File-sharing services.
> * Monitoring Services:: Monitoring services.
> +* Guile-PAM Services:: Guile-PAM services.
> * Kerberos Services:: Kerberos services.
> * LDAP Services:: LDAP services.
> * Web Services:: Web servers.
> @@ -19437,6 +19438,7 @@ Services
> * Telephony Services:: Telephony services.
> * File-Sharing Services:: File-sharing services.
> * Monitoring Services:: Monitoring services.
> +* Guile-PAM Services:: Guile-PAM services.
> * Kerberos Services:: Kerberos services.
> * LDAP Services:: LDAP services.
> * Web Services:: Web servers.
> @@ -33149,6 +33151,93 @@ Monitoring Services
> @end deftp
>
>
> +@c %end of fragment
> +
> +@node Guile-PAM Services
> +@subsection Guile-PAM Services
> +@cindex Guile-PAM
> +
> +The @code{(gnu services pam)} module provides services related to the
> +authentication mechanism @dfn{Guile-PAM}.
> +
> +Guile-PAM is a reimplementation in GNU Guile of the venerable Linux-PAM
> +authentication system. For details, please have a look at the Texinfo
> +manual in the @code{guile-pam} package.
> +
> +@defvar guile-pam-module-service-type
> +A service type for Guile-PAM modules.
> +@end defvar
> +
> +@noindent
> +Here is an example of its use:
> +@lisp
> +(define welcome-pamda-file
> + (scheme-file
> + "welcome-pamda-file"
> + #~(begin
> + (use-modules (ice-9 format))
> +
> + (lambda (action handle flags options)
> + (case action
> + ;; authentication management
> + ((pam_sm_authenticate)
> + (format #t "In a working module, we would now identify you.~%"))
> + ((pam_sm_setcred)
> + (format #t "In a working module, we would now help you manage additional credentials.~%"))
> + ;; account management
> + ((pam_sm_acct_mgmt)
> + (format #t "In a working module, we would now confirm your access rights.~%"))
> + ;; password management
> + ((pam_sm_chauthtok)
> + (format #t "In a working module, we would now change your password.~%"))
> + ;; session management
> + ((pam_sm_open_session)
> + (format #t "In a working module, we would now open a session for you.~%"))
> + ((pam_sm_close_session)
> + (format #t "In a working module, we would now close your session.~%"))
> + (else
> + (format #t "In a working module, we would not know what to do about action '~s'.~%"
> + action)))
> + 'PAM_SUCCESS))))
> +
> +(service guile-pam-module-service-type
> + (guile-pam-module-configuration
> + (rules "optional")
> + (module welcome-pamda-file)
> + (services '("login"
> + "greetd"
> + "su"
> + "slim"
> + "gdm-password"
> + "sddm"))))
> +@end lisp
> +
> +@c %start of fragment
> +
> +@deftp {Data Type} guile-pam-module-configuration
> +Available @code{guile-pam-module-configuration} fields are:
> +
> +@table @asis
> +@item @code{rules} (type: maybe-string)
> +Determines how the module's return value is evaluated.
> +
> +@item @code{module} (type: maybe-file-like)
> +A Guile-PAM pamda file or a classical PAM module.
> +
> +@item @code{services} (type: maybe-list-of-strings)
> +List of PAM service names for which to install the module.
> +
> +@item @code{guile-inputs} (type: maybe-list-of-packages)
> +Guile inputs available in the PAM module
> +
> +@item @code{foreign-library-path} (type: maybe-list-of-packages)
> +Search path for shared objects and libraries.
> +
> +@end table
> +
> +@end deftp
> +
> +
> @c %end of fragment
>
> @node Kerberos Services
> diff --git a/gnu/local.mk b/gnu/local.mk
> index f6f95bbf10b..3d3da58d659 100644
> --- a/gnu/local.mk
> +++ b/gnu/local.mk
> @@ -764,6 +764,7 @@ GNU_SYSTEM_MODULES = \
> %D%/services/networking.scm \
> %D%/services/nix.scm \
> %D%/services/nfs.scm \
> + %D%/services/pam.scm \
> %D%/services/pam-mount.scm \
> %D%/services/power.scm \
> %D%/services/science.scm \
> diff --git a/gnu/services/pam.scm b/gnu/services/pam.scm
> new file mode 100644
> index 00000000000..a242067e380
> --- /dev/null
> +++ b/gnu/services/pam.scm
> @@ -0,0 +1,105 @@
> +;;; GNU Guix --- Functional package management for GNU
> +;;; Copyright © 2024 Felix Lechner <felix.lechner@lease-up.com>
> +;;;
> +;;; This file is part of GNU Guix.
> +;;;
> +;;; GNU Guix is free software; you can redistribute it and/or modify it
> +;;; under the terms of the GNU General Public License as published by
> +;;; the Free Software Foundation; either version 3 of the License, or (at
> +;;; your option) any later version.
> +;;;
> +;;; GNU Guix is distributed in the hope that it will be useful, but
> +;;; WITHOUT ANY WARRANTY; without even the implied warranty of
> +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +;;; GNU General Public License for more details.
> +;;;
> +;;; You should have received a copy of the GNU General Public License
> +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
> +
> +(define-module (gnu services pam)
> + #:use-module (gnu packages guile)
> + #:use-module (gnu packages guile-xyz)
> + #:use-module (gnu packages linux)
> + #:use-module (gnu packages mes)
> + #:use-module (gnu services)
> + #:use-module (gnu services configuration)
> + #:use-module (gnu system pam)
> + #:use-module (guix gexp)
> + #:use-module (guix packages)
> + #:use-module (guix records)
> + #:use-module (guix utils)
> + #:use-module (srfi srfi-1)
> + #:export (guile-pam-module-configuration))
> +
> +(define-maybe string)
> +(define-maybe list-of-strings)
> +(define-maybe file-like)
> +
> +(define-maybe string-or-file-like)
> +(define (string-or-file-like? val)
> + (or (string? val) (file-like? val)))
> +
> +(define-maybe list-of-packages)
> +(define (list-of-packages? val)
> + (and (list? val) (map package? val)))
i think should use (@ (srfi srfi-1) every), not map, otherwise this has
always been #t. And should use `file-like?', friendly to inferior packages.
> +
> +(define-configuration/no-serialization guile-pam-module-configuration
> + (rules
> + maybe-string
> + "Determines how the module's return value is evaluated.")
> + (module
> + maybe-file-like
> + "A Guile-PAM pamda file or a classical PAM module.")
> + (services
> + maybe-list-of-strings
> + "List of PAM service names for which to install the module.")
> + (guile-inputs
> + maybe-list-of-packages
> + "Guile inputs available in the PAM module")
If I understand correctly, all guile-pam-modules share the same
pam_guile and dependencies, can we restrict this so that each different
pam-module is its own separate dependency
(If possible in the future, I would even like to compile each of them to
wasm separately, limiting the capabilities even more.)
> + (foreign-library-path
> + maybe-list-of-packages
> + "Search path for shared objects and libraries.") )
> +
> +(define (guile-pam-module-service config)
> + "Return a list of <shepherd-service> for guile-pam-module for CONFIG."
> + (match-record
> + config <guile-pam-module-configuration> (foreign-library-path
> + guile-inputs
> + module
> + rules
> + services)
> + (list
> + (pam-extension
> + (transformer
> + (lambda (pam)
> + (if (member (pam-service-name pam) services)
> + (let* ((new-entry
> + (pam-entry
> + (control rules)
> + (module module)
> + (guile-inputs (if (eq? %unset-value guile-inputs)
> + '()
> + guile-inputs))
looks like this patch depends on https://issues.guix.gnu.org/72316#10 ?.
I think it may not be possible to merge directly
> + (foreign-library-path (if (eq? %unset-value foreign-library-path)
> + '()
> + foreign-library-path)))))
> + (pam-service
> + (inherit pam)
> + (auth (append (pam-service-auth pam)
> + (list new-entry)))
> + (account (append (pam-service-account pam)
> + (list new-entry)))
> + (session (append (pam-service-session pam)
> + (list new-entry)))
> + (password (append (pam-service-password pam)
> + (list new-entry)))))
> + pam)))))))
> +
> +(define-public guile-pam-module-service-type
> + (service-type
> + (name 'guile-pam-module)
> + (extensions (list (service-extension pam-root-service-type
> + guile-pam-module-service)))
> + (compose concatenate)
> + (default-value (guile-pam-module-configuration))
> + (description "Load Guile code as part of Linux-PAM.")))
Hi Z572,
On Fri, May 02 2025, Z572 wrote:
> i think should use (@ (srfi srfi-1) every), not map, otherwise this has
> always been #t. And should use `file-like?', friendly to inferior packages.
You are probably right. Please feel free to adjust the validator.
I personally do not use the configuration-record's type checking
features anymore. I will present my configuration system, which also
disentangles the painful splicing of values into the command line, soon.
> If I understand correctly, all guile-pam-modules share the same
> pam_guile and dependencies, can we restrict this so that each different
> pam-module is its own separate dependency
I do not understand your sentence (and am not sure it's true). The
Guile prerequisites are for the modules your users write.
> (If possible in the future, I would even like to compile each of them to
> wasm separately, limiting the capabilities even more.)
I am a fan of WASM. What does it have to do with Guile-PAM, please?
> looks like this patch depends on https://issues.guix.gnu.org/72316#10 ?.
Yeah, that happened because I wrote the service to integrate Guile-PAM
into the existing Guix stack. It quickly proved superior, however, to
use Guile-PAM's stack, which is nearly identical. [1][2]
An easy solution would be to merge patches two and three into a single
patch.
Kind regards
Felix
[1]
https://juix.org/guile-pam/#Skipping-of-actions-on-PAM_005fIGNORE_002e
[2] https://juix.org/guile-pam/#Legacy-instruction-sets
Felix Lechner <felix.lechner@lease-up.com> writes:
> Hi Z572,
>
> On Fri, May 02 2025, Z572 wrote:
>
>> i think should use (@ (srfi srfi-1) every), not map, otherwise this has
>> always been #t. And should use `file-like?', friendly to inferior packages.
>
> You are probably right. Please feel free to adjust the validator.
>
> I personally do not use the configuration-record's type checking
> features anymore. I will present my configuration system, which also
> disentangles the painful splicing of values into the command line, soon.
>
>> If I understand correctly, all guile-pam-modules share the same
>> pam_guile and dependencies, can we restrict this so that each different
>> pam-module is its own separate dependency
>
> I do not understand your sentence (and am not sure it's true). The
> Guile prerequisites are for the modules your users write.
If my module a needs guile-json-1,
module b needs guile-json-4, they cannot be used by the same guile.
Also, if a pam module is broken, I don't want all pam modules to be broken.
>
>> (If possible in the future, I would even like to compile each of them to
>> wasm separately, limiting the capabilities even more.)
>
> I am a fan of WASM. What does it have to do with Guile-PAM, please?
For example, I use hoot to compile the code to wasm, and load and
interpret the wasm in pam-guile. If I don't need to access the file, I
don't need the ability to read the file.
>
>> looks like this patch depends on https://issues.guix.gnu.org/72316#10 ?.
>
> Yeah, that happened because I wrote the service to integrate Guile-PAM
> into the existing Guix stack. It quickly proved superior, however, to
> use Guile-PAM's stack, which is nearly identical. [1][2]
I think it is possible to use gexp's with-extensions,
with-imported-modules, etc., instead of adding a guile-inputs option.
>
> An easy solution would be to merge patches two and three into a single
> patch.
>
> Kind regards
> Felix
>
> [1]
> https://juix.org/guile-pam/#Skipping-of-actions-on-PAM_005fIGNORE_002e
> [2] https://juix.org/guile-pam/#Legacy-instruction-sets
Hi Z572,
On Tue, May 13 2025, Z572 wrote:
> If my module a needs guile-json-1,
> module b needs guile-json-4, they cannot be used by the same guile.
> Also, if a pam module is broken, I don't want all pam modules to be broken.
> For example, I use hoot to compile the code to wasm, and load and
> interpret the wasm in pam-guile. If I don't need to access the file, I
> don't need the ability to read the file.
>
> I think it is possible to use gexp's with-extensions,
> with-imported-modules, etc., instead of adding a guile-inputs option.
Feel free to adjust the patches. Otherwise, your ideas and demands are
vaporware. The patches I sent have been working in production for a
year.
For any changes needed at Guile-PAM, I am happy to look at your
contributions over there as long as you agree to release your code under
the GPLv3+ license.
Kind regards,
Felix
Hi Felix,
Felix Lechner <felix.lechner@lease-up.com> writes:
> Hi Z572,
>
> On Tue, May 13 2025, Z572 wrote:
>
>> If my module a needs guile-json-1,
>> module b needs guile-json-4, they cannot be used by the same guile.
>> Also, if a pam module is broken, I don't want all pam modules to be broken.
>
>> For example, I use hoot to compile the code to wasm, and load and
>> interpret the wasm in pam-guile. If I don't need to access the file, I
>> don't need the ability to read the file.
>>
>> I think it is possible to use gexp's with-extensions,
>> with-imported-modules, etc., instead of adding a guile-inputs option.
>
> Feel free to adjust the patches. Otherwise, your ideas and demands are
> vaporware. The patches I sent have been working in production for a
> year.
That's not a constructive way to approach code reviews. I'd like to
remind you that we strive for a welcoming and positive interactions in
the Guix project, as enshrined in our Code of Conduct.
People have graciously taken their own time to look at your changes and
suggest improvements or ideas. The least you can do in return is to
show some gratitude for it, not dismiss their feedback as something you
can't be bothered with.
Hi Maxim,
On Wed, May 14 2025, Maxim Cournoyer wrote:
> That's not a constructive way to approach code reviews.
Nitpicking people for missing spaces or other form errors is not
productive.
As for the commit messages, I do not get their point: They duplicate
facts from the diff and offer no forensic improvements over 'git blame.'
Furthermore, their use as ChangeLog entries is an anachronism for a
project with a rolling release model.
> I'd like to remind you that we strive for a welcoming and positive
> interactions in the Guix project, as enshrined in our Code of Conduct.
Please focus on the merits of Guile-PAM! This is the second time you
attacked my person and threatened me with condescending and moralizing
messages. The other time was unsolicited and in private on March 9, for
which you apologized. The code of conduct allows for these incidents to
be reported. What do you think about my patches, please?
Do you see any benefits or drawbacks in using Guile-PAM in Guix? Where
do you want to take authentication in Guix System?
Could Guile-PAM help your users to configure their authentication
methods with greater flexibility and individuality, or do you prefer the
trusted but precompiled modules of Linux-PAM?
In short, wouldn't Guile-PAM be a cool addition to GNU Guix?
> People have graciously taken their own time to look at your changes and
> suggest improvements or ideas. The least you can do in return is to
> show some gratitude for it, not dismiss their feedback as something you
> can't be bothered with.
As a maintainer, it your duty to review contributions. If that bothers
you, you might want to think about stepping aside.
Also, please stop using your elevated position to domineer people who
try to contribute in good faith. It's not good stewardship.
Thank you for GNU Guix! It's the coolest software project I ever saw.
Let's make it better together!
Kind regards
Felix
Hi Felix,
My previous email was about your way to interact with others in this
thread, which I think is below the expectations set in this community,
namely, being dismissive of other's feedback. Guix is a social project
before being a technical one, therefore being able to work together is
more valuable than technical merits alone.
I'm disappointed that instead of taking pause and adjusting, you appear
to have chosen to deflect with passive-aggressive assertions and other
not-so-kind suggestions. Please stop, and consider yourself warned.
@@ -412,6 +412,7 @@ Top
* Telephony Services:: Telephony services.
* File-Sharing Services:: File-sharing services.
* Monitoring Services:: Monitoring services.
+* Guile-PAM Services:: Guile-PAM services.
* Kerberos Services:: Kerberos services.
* LDAP Services:: LDAP services.
* Web Services:: Web servers.
@@ -19437,6 +19438,7 @@ Services
* Telephony Services:: Telephony services.
* File-Sharing Services:: File-sharing services.
* Monitoring Services:: Monitoring services.
+* Guile-PAM Services:: Guile-PAM services.
* Kerberos Services:: Kerberos services.
* LDAP Services:: LDAP services.
* Web Services:: Web servers.
@@ -33149,6 +33151,93 @@ Monitoring Services
@end deftp
+@c %end of fragment
+
+@node Guile-PAM Services
+@subsection Guile-PAM Services
+@cindex Guile-PAM
+
+The @code{(gnu services pam)} module provides services related to the
+authentication mechanism @dfn{Guile-PAM}.
+
+Guile-PAM is a reimplementation in GNU Guile of the venerable Linux-PAM
+authentication system. For details, please have a look at the Texinfo
+manual in the @code{guile-pam} package.
+
+@defvar guile-pam-module-service-type
+A service type for Guile-PAM modules.
+@end defvar
+
+@noindent
+Here is an example of its use:
+@lisp
+(define welcome-pamda-file
+ (scheme-file
+ "welcome-pamda-file"
+ #~(begin
+ (use-modules (ice-9 format))
+
+ (lambda (action handle flags options)
+ (case action
+ ;; authentication management
+ ((pam_sm_authenticate)
+ (format #t "In a working module, we would now identify you.~%"))
+ ((pam_sm_setcred)
+ (format #t "In a working module, we would now help you manage additional credentials.~%"))
+ ;; account management
+ ((pam_sm_acct_mgmt)
+ (format #t "In a working module, we would now confirm your access rights.~%"))
+ ;; password management
+ ((pam_sm_chauthtok)
+ (format #t "In a working module, we would now change your password.~%"))
+ ;; session management
+ ((pam_sm_open_session)
+ (format #t "In a working module, we would now open a session for you.~%"))
+ ((pam_sm_close_session)
+ (format #t "In a working module, we would now close your session.~%"))
+ (else
+ (format #t "In a working module, we would not know what to do about action '~s'.~%"
+ action)))
+ 'PAM_SUCCESS))))
+
+(service guile-pam-module-service-type
+ (guile-pam-module-configuration
+ (rules "optional")
+ (module welcome-pamda-file)
+ (services '("login"
+ "greetd"
+ "su"
+ "slim"
+ "gdm-password"
+ "sddm"))))
+@end lisp
+
+@c %start of fragment
+
+@deftp {Data Type} guile-pam-module-configuration
+Available @code{guile-pam-module-configuration} fields are:
+
+@table @asis
+@item @code{rules} (type: maybe-string)
+Determines how the module's return value is evaluated.
+
+@item @code{module} (type: maybe-file-like)
+A Guile-PAM pamda file or a classical PAM module.
+
+@item @code{services} (type: maybe-list-of-strings)
+List of PAM service names for which to install the module.
+
+@item @code{guile-inputs} (type: maybe-list-of-packages)
+Guile inputs available in the PAM module
+
+@item @code{foreign-library-path} (type: maybe-list-of-packages)
+Search path for shared objects and libraries.
+
+@end table
+
+@end deftp
+
+
@c %end of fragment
@node Kerberos Services
@@ -764,6 +764,7 @@ GNU_SYSTEM_MODULES = \
%D%/services/networking.scm \
%D%/services/nix.scm \
%D%/services/nfs.scm \
+ %D%/services/pam.scm \
%D%/services/pam-mount.scm \
%D%/services/power.scm \
%D%/services/science.scm \
new file mode 100644
@@ -0,0 +1,105 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2024 Felix Lechner <felix.lechner@lease-up.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu services pam)
+ #:use-module (gnu packages guile)
+ #:use-module (gnu packages guile-xyz)
+ #:use-module (gnu packages linux)
+ #:use-module (gnu packages mes)
+ #:use-module (gnu services)
+ #:use-module (gnu services configuration)
+ #:use-module (gnu system pam)
+ #:use-module (guix gexp)
+ #:use-module (guix packages)
+ #:use-module (guix records)
+ #:use-module (guix utils)
+ #:use-module (srfi srfi-1)
+ #:export (guile-pam-module-configuration))
+
+(define-maybe string)
+(define-maybe list-of-strings)
+(define-maybe file-like)
+
+(define-maybe string-or-file-like)
+(define (string-or-file-like? val)
+ (or (string? val) (file-like? val)))
+
+(define-maybe list-of-packages)
+(define (list-of-packages? val)
+ (and (list? val) (map package? val)))
+
+(define-configuration/no-serialization guile-pam-module-configuration
+ (rules
+ maybe-string
+ "Determines how the module's return value is evaluated.")
+ (module
+ maybe-file-like
+ "A Guile-PAM pamda file or a classical PAM module.")
+ (services
+ maybe-list-of-strings
+ "List of PAM service names for which to install the module.")
+ (guile-inputs
+ maybe-list-of-packages
+ "Guile inputs available in the PAM module")
+ (foreign-library-path
+ maybe-list-of-packages
+ "Search path for shared objects and libraries.") )
+
+(define (guile-pam-module-service config)
+ "Return a list of <shepherd-service> for guile-pam-module for CONFIG."
+ (match-record
+ config <guile-pam-module-configuration> (foreign-library-path
+ guile-inputs
+ module
+ rules
+ services)
+ (list
+ (pam-extension
+ (transformer
+ (lambda (pam)
+ (if (member (pam-service-name pam) services)
+ (let* ((new-entry
+ (pam-entry
+ (control rules)
+ (module module)
+ (guile-inputs (if (eq? %unset-value guile-inputs)
+ '()
+ guile-inputs))
+ (foreign-library-path (if (eq? %unset-value foreign-library-path)
+ '()
+ foreign-library-path)))))
+ (pam-service
+ (inherit pam)
+ (auth (append (pam-service-auth pam)
+ (list new-entry)))
+ (account (append (pam-service-account pam)
+ (list new-entry)))
+ (session (append (pam-service-session pam)
+ (list new-entry)))
+ (password (append (pam-service-password pam)
+ (list new-entry)))))
+ pam)))))))
+
+(define-public guile-pam-module-service-type
+ (service-type
+ (name 'guile-pam-module)
+ (extensions (list (service-extension pam-root-service-type
+ guile-pam-module-service)))
+ (compose concatenate)
+ (default-value (guile-pam-module-configuration))
+ (description "Load Guile code as part of Linux-PAM.")))