#61 Use Ipsilon specific PAM service file
Merged 8 years ago by puiterwijk. Opened 8 years ago by jdennis.
jdennis/ipsilon ticket-176  into  master

file modified
+1 -1
@@ -31,7 +31,7 @@ 

  Currently there are only two available authentication modules, GSSAPI and

  PAM. The Kerberos module uses mod_auth_gssapi (which it will configure for

  you at install time), the Pam module simply uses the PAM stack with a default service

- name set to 'remote'.

+ name set to 'ipsilon'.

  

  NOTE: The PAM module is invoked as an unprivileged user so if you are using the

  pam_unix plugin to authenticate users you'll find out that authentication does

@@ -42,6 +42,7 @@ 

  Requires:       python-lxml

  Requires:       python-sqlalchemy

  Requires:       open-sans-fonts

+ Requires:       pam

  Requires(pre):  shadow-utils

  Requires(post): %_sbindir/semanage, %_sbindir/restorecon

  Requires(postun): %_sbindir/semanage
@@ -245,6 +246,9 @@ 

  rm -fr %{buildroot}%{python2_sitelib}/tests

  ln -s %{_datadir}/fonts %{buildroot}%{_datadir}/ipsilon/ui/fonts

  

+ mkdir -p  %{buildroot}%{_sysconfdir}/pam.d

+ cp %{buildroot}%{_datadir}/ipsilon/templates/install/pam/ipsilon.pamd %{buildroot}%{_sysconfdir}/pam.d/ipsilon

+ 

  #%check

  # The test suite is not being run because:

  #  1. The last step of %%install removes the entire test suite
@@ -326,6 +330,9 @@ 

  %dir %attr(0751,root,root) %{_sharedstatedir}/ipsilon

  %dir %attr(0751,root,root) %{_sysconfdir}/ipsilon

  %dir %attr(0750,ipsilon,apache) %{_localstatedir}/cache/ipsilon

+ %dir %{_datadir}/ipsilon/templates/install/pam

+ %{_sysconfdir}/pam.d/ipsilon

+ %{_datadir}/ipsilon/templates/install/pam/*.pamd

  

  %files client

  %{_bindir}/ipsilon-client-install

file modified
+1 -1
@@ -106,7 +106,7 @@ 

      def install_args(self, group):

          group.add_argument('--form', choices=['yes', 'no'], default='no',

                             help='Configure External Form authentication')

-         group.add_argument('--form-service', action='store', default='remote',

+         group.add_argument('--form-service', action='store', default='ipsilon',

                             help='PAM service name to use for authentication')

  

      def configure(self, opts, changes):

file modified
+2 -2
@@ -65,7 +65,7 @@ 

              pconfig.String(

                  'service name',

                  'The name of the PAM service used to authenticate.',

-                 'remote',

+                 'ipsilon',

                  readonly=True,

                  ),

              pconfig.String(
@@ -113,7 +113,7 @@ 

      def install_args(self, group):

          group.add_argument('--pam', choices=['yes', 'no'], default='no',

                             help='Configure PAM authentication')

-         group.add_argument('--pam-service', action='store', default='remote',

+         group.add_argument('--pam-service', action='store', default='ipsilon',

                             help='PAM service name to use for authentication')

  

      def configure(self, opts, changes):

file modified
+2
@@ -42,6 +42,8 @@ 

                    (DATA+'templates/openid', glob('templates/openid/*')),

                    (DATA+'templates/persona', glob('templates/persona/*.html')),

                    (DATA+'templates/install', glob('templates/install/*.conf')),

+                   (DATA+'templates/install/pam',

+                    glob('templates/install/pam/*.pamd')),

                    (DATA+'templates/install/saml2',

                     glob('templates/install/saml2/*.conf')),

                    (DATA+'templates/admin/providers',

@@ -0,0 +1,15 @@ 

+ #%PAM-1.0

+ auth       substack     password-auth

+ auth       include      postlogin

+ account    required     pam_nologin.so

+ account    include      password-auth

+ password   include      password-auth

+ # pam_selinux.so close should be the first session rule

+ session    required     pam_selinux.so close

+ session    required     pam_loginuid.so

+ # pam_selinux.so open should only be followed by sessions to be executed in the user context

+ session    required     pam_selinux.so open

+ session    required     pam_namespace.so

+ session    optional     pam_keyinit.so force revoke

+ session    include      password-auth

+ session    include      postlogin

no initial comment

Upgrade the bits and then uninstall fails:

Traceback (most recent call last):
File "/sbin/ipsilon-server-install", line 460, in <module>
uninstall(fplugins, opts)
File "/sbin/ipsilon-server-install", line 284, in uninstall
if plugin.unconfigure(args, plugin_changes) == False:
File "/usr/lib/python2.7/site-packages/ipsilon/login/authpam.py", line 164, in unconfigure
installed_files = changes['installed_files']
KeyError: 'installed_files'

Authentication is failing but I have yet been able to identify why.

Just pushed a new commit that wraps the

installed_files['installed_files']

in a try/except block that catches the key error and returns earl.

I'd have preferred install_files.get('installed_files', [])

And I still can't authenticate with the new pam service for some reason I can't deduce.

I redid the commit per your preference.

I can't explain the auth failure either. I have a tiny C program that calls pam and if I pass it exactly the same username, password and service name that Ipsilon is seeing (I logged those values) it succeeds. The pam.py module can be invoked as a program, if I pass it the exact same parameters it also succeeds. It appears to only not work when called from Apache. I put SELinux in permissive mode, but it didn't help. So I'm befuddled as well. When was the last time we confirmed pam was working in Ipsilon? I'm not seeing anything in my patch that would explain the auth failure, both a C based pam test and a Python based pam test using the ipsilon service name and same username and password works. Go figure.

As a data point I installed another version of Ipsilon without my pam patch, it also fails to authenticate. At this point I'm guessing it's something in the way the python pam is interacting when executed from inside Apache. I think to get further we'll have to run Ipsilon under GDB and see what the PAM code is doing.

I spent a day trying to debug this but failed to find a root cause, here is what I know at this point:

The user is local with an entry in /etc/passwd and /etc/shadow.

SELinux is in permissive mode.

Running a pam test program with the exact same parameters works.

I built a special version of pam with debug logging, the log goes to /var/run/pam-debug.log which must be manually created and be chmod a+rw.

The failure occurs when running the suid helper program /usr/sbin/unix_chkpwd which pam_unix invokes via fork/execv.

unix_chkpwd calls get_account_info() passing the username, which then invokes pam_modutil_getspnam() which due to macros is really just a call to getspnam().

getspnam() is a nss switch function. The nssswitch config for both passwd and shadow is "files sss", so it should hit the local file entry first.

I set a breakpoint for getspname and it broke at ../nss/getXXbyYY.c:102. I lost the trail there. It returns null, and everything is a cascading set of errors after that.

So it appears that getspnam when called from the setuid unix_chkpwd succeeds when invoked from a standalone pam test program but fails when called from Ipsilon. At this point I still do not know why, but that is as much as I can do for today.

Sorry to hear you spent a day on trying the pam module with a local account, as that is a known fail.

pam_unix uses a helper that allows you to only ever perform a password change from a non-root process, and, of course, only for the calling user. Authentication is not allowed from non-root processes.

The ipsilon pam module works with pam_sss though.

I figured out why it was failing for me: the pam configuration file ipsilon is only created if the pam auth module is enabled.

These are not linked together as the form module relies indirectly on pam for authentication as well. I copied remote to ipsilon and authentication started working for me.

New commit has been pushed for review.

authpam no longer installs and uninstalls the ipsilon pam service file because the ipsilon pam service file is utilized by both the pam and form login managers. Ipsilon currently has no mechanism to express shared dependencies. So instead the ipsilon pam service file is installed by the base RPM subpackage, thus it's always available irregardless of the pam or form login manager installation/configuration. The consensus is that a unreferenced pam service file is benign.