Remove the un-used and non-maintained PAM identity backend

The PAM identity backend has not been maintained nor could it have
functioned since (at least) the grizzly release of OpenStack as the
signatures of the authenticate method (among other methods) do not
match the required signature for the rest of Keystone to utilize it.
With the code bit-rotting and unusable for over two releases it
appears that we could re-evaluate the need for a PAM backend and
implement an auth-plugin that would provide the same basic auth
functionality if there is a demand for it.

Change-Id: I667aa34e252588e7cc840ef765c5f65ebd7d5b62
changes/11/77411/1
Morgan Fainberg 9 years ago
parent 3be2975626
commit 6bd2307930
  1. 152
      keystone/identity/backends/pam.py
  2. 68
      keystone/tests/test_backend_pam.py

@ -1,152 +0,0 @@
# Copyright 2012 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import absolute_import
try:
import pam
except ImportError:
pam = None
import PAM
from keystone import identity
def PAM_authenticate(username, password):
def _pam_conv(auth, query_list):
resp = []
for query, q_type in query_list:
if q_type in [PAM.PAM_PROMPT_ECHO_ON, PAM.PAM_PROMPT_ECHO_OFF]:
resp.append((password, 0))
elif q_type in [PAM.PAM_PROMPT_ERROR_MSG,
PAM.PAM_PROMPT_TEXT_INFO]:
resp.append(('', 0))
return resp
auth = PAM.pam()
auth.start('passwd')
auth.set_item(PAM.PAM_USER, username)
auth.set_item(PAM.PAM_CONV, _pam_conv)
try:
auth.authenticate()
auth.acct_mgmt()
except PAM.error:
raise AssertionError(_('Invalid user / password'))
return True
class PamIdentity(identity.Driver):
"""Very basic identity based on PAM.
Tenant is always the same as User, root user has admin role.
"""
def is_domain_aware(self):
return False
def authenticate(self, user_id, password):
auth = pam.authenticate if pam else PAM_authenticate
if not auth(user_id, password):
raise AssertionError(_('Invalid user / password'))
user = {'id': user_id, 'name': user_id}
return user
def get_project(self, tenant_id):
return {'id': tenant_id, 'name': tenant_id}
def get_project_by_name(self, tenant_name, domain_id):
# TODO(henry-nash): Used domain_id once domains are implemented
# in LDAP backend
return {'id': tenant_name, 'name': tenant_name}
def get_user(self, user_id):
return {'id': user_id, 'name': user_id}
def get_user_by_name(self, user_name, domain_id):
# TODO(henry-nash): Used domain_id once domains are implemented
# in LDAP backend
return {'id': user_name, 'name': user_name}
def get_role(self, role_id):
raise NotImplementedError()
def list_users(self, hints):
raise NotImplementedError()
def list_roles(self, hints):
raise NotImplementedError()
def add_user_to_project(self, tenant_id, user_id):
pass
def remove_user_from_project(self, tenant_id, user_id):
pass
def list_projects_for_user(self, user_id):
return [{'id': user_id, 'name': user_id}]
def create_user(self, user_id, user):
raise NotImplementedError()
def update_user(self, user_id, user):
raise NotImplementedError()
def delete_user(self, user_id):
raise NotImplementedError()
def _get_metadata(self, user_id, tenant_id):
metadata = {}
if user_id == 'root':
metadata['is_admin'] = True
return metadata
def _create_metadata(self, user_id, tenant_id, metadata):
raise NotImplementedError()
def _update_metadata(self, user_id, tenant_id, metadata):
raise NotImplementedError()
def add_user_to_group(self, user_id, group_id):
raise NotImplementedError()
def check_user_in_group(self, user_id, group_id):
raise NotImplementedError()
def remove_user_from_group(self, user_id, group_id):
raise NotImplementedError()
def create_group(self, group_id, group):
raise NotImplementedError()
def list_groups(self):
raise NotImplementedError()
def list_groups_for_user(self, user_id):
raise NotImplementedError()
def list_users_in_group(self, group_id):
raise NotImplementedError()
def get_group(self, group_id):
raise NotImplementedError()
def update_group(self, group_id, group):
raise NotImplementedError()
def delete_group(self, group_id):
raise NotImplementedError()

@ -1,68 +0,0 @@
# Copyright 2012 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import uuid
from keystone import config
from keystone.identity.backends import pam as identity_pam
from keystone import tests
CONF = config.CONF
DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id
class PamIdentity(tests.TestCase):
def setUp(self):
super(PamIdentity, self).setUp()
self.config([tests.dirs.etc('keystone.conf.sample'),
tests.dirs.tests('test_overrides.conf')])
self.config_fixture.config(
group='identity',
driver='keystone.identity.backends.pam.PamIdentity')
self.identity_api = identity_pam.PamIdentity()
tenant_id = uuid.uuid4().hex
self.tenant_in = {'id': tenant_id, 'name': tenant_id}
self.user_in = {'id': 'fakeuser', 'name': 'fakeuser'}
def test_get_project(self):
tenant_out = self.identity_api.get_project(self.tenant_in['id'])
self.assertDictEqual(self.tenant_in, tenant_out)
def test_get_project_by_name(self):
tenant_in_name = self.tenant_in['name']
tenant_out = self.identity_api.get_project_by_name(
tenant_in_name, DEFAULT_DOMAIN_ID)
self.assertDictEqual(self.tenant_in, tenant_out)
def test_get_user(self):
user_out = self.identity_api.get_user(self.user_in['id'])
self.assertDictEqual(self.user_in, user_out)
def test_get_user_by_name(self):
user_out = self.identity_api.get_user_by_name(
self.user_in['name'], DEFAULT_DOMAIN_ID)
self.assertDictEqual(self.user_in, user_out)
def test_get_metadata_for_non_root(self):
metadata_out = self.identity_api._get_metadata(self.user_in['id'],
self.tenant_in['id'])
self.assertDictEqual({}, metadata_out)
def test_get_metadata_for_root(self):
metadata = {'is_admin': True}
metadata_out = self.identity_api._get_metadata('root',
self.tenant_in['id'])
self.assertDictEqual(metadata, metadata_out)
Loading…
Cancel
Save