Mark the service as readonly in the UI in authpam plugin
[cascardo/ipsilon.git] / ipsilon / login / authpam.py
1 # Copyright (C) 2013 Ipsilon project Contributors, for license see COPYING
2
3 from ipsilon.login.common import LoginFormBase, LoginManagerBase, \
4     LoginManagerInstaller
5 from ipsilon.util.plugin import PluginObject
6 from ipsilon.util import config as pconfig
7 import pam
8 import subprocess
9
10
11 class Pam(LoginFormBase):
12
13     def _authenticate(self, username, password):
14         if self.lm.service_name:
15             ok = pam.authenticate(username, password, self.lm.service_name)
16         else:
17             ok = pam.authenticate(username, password)
18
19         if ok:
20             self.log("User %s successfully authenticated." % username)
21             return username
22
23         self.log("User %s failed authentication." % username)
24         return None
25
26     def POST(self, *args, **kwargs):
27         username = kwargs.get("login_name")
28         password = kwargs.get("login_password")
29         user = None
30         error = None
31
32         if username and password:
33             user = self._authenticate(username, password)
34             if user:
35                 return self.lm.auth_successful(self.trans, user, 'password')
36             else:
37                 error = "Authentication failed"
38                 self.error(error)
39         else:
40             error = "Username or password is missing"
41             self.error("Error: " + error)
42
43         context = self.create_tmpl_context(
44             username=username,
45             error=error,
46             error_password=not password,
47             error_username=not username
48         )
49         self.lm.set_auth_error()
50         return self._template('login/form.html', **context)
51
52
53 class LoginManager(LoginManagerBase):
54
55     def __init__(self, *args, **kwargs):
56         super(LoginManager, self).__init__(*args, **kwargs)
57         self.name = 'pam'
58         self.path = 'pam'
59         self.page = None
60         self.description = """
61 Form based login Manager that uses the system's PAM infrastructure
62 for authentication. """
63         self.new_config(
64             self.name,
65             pconfig.String(
66                 'service name',
67                 'The name of the PAM service used to authenticate.',
68                 'remote',
69                 readonly=True,
70                 ),
71             pconfig.String(
72                 'username text',
73                 'Text used to ask for the username at login time.',
74                 'Username'),
75             pconfig.String(
76                 'password text',
77                 'Text used to ask for the password at login time.',
78                 'Password'),
79             pconfig.String(
80                 'help text',
81                 'Text used to guide the user at login time.',
82                 'Provide your Username and Password')
83         )
84
85     @property
86     def service_name(self):
87         return self.get_config_value('service name')
88
89     @property
90     def help_text(self):
91         return self.get_config_value('help text')
92
93     @property
94     def username_text(self):
95         return self.get_config_value('username text')
96
97     @property
98     def password_text(self):
99         return self.get_config_value('password text')
100
101     def get_tree(self, site):
102         self.page = Pam(site, self, 'login/pam')
103         return self.page
104
105
106 class Installer(LoginManagerInstaller):
107
108     def __init__(self, *pargs):
109         super(Installer, self).__init__()
110         self.name = 'pam'
111         self.pargs = pargs
112
113     def install_args(self, group):
114         group.add_argument('--pam', choices=['yes', 'no'], default='no',
115                            help='Configure PAM authentication')
116         group.add_argument('--pam-service', action='store', default='remote',
117                            help='PAM service name to use for authentication')
118
119     def configure(self, opts, changes):
120         if opts['pam'] != 'yes':
121             return
122
123         # Add configuration data to database
124         po = PluginObject(*self.pargs)
125         po.name = 'pam'
126         po.wipe_data()
127         po.wipe_config_values()
128         config = {'service name': opts['pam_service']}
129         po.save_plugin_config(config)
130
131         # Update global config to add login plugin
132         po.is_enabled = True
133         po.save_enabled_state()
134
135         # for selinux enabled platforms, ignore if it fails just report
136         try:
137             subprocess.call(['/usr/sbin/setsebool', '-P',
138                              'httpd_mod_auth_pam=on',
139                              'httpd_tmp_exec=on'])
140         except Exception:  # pylint: disable=broad-except
141             pass