summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
authorPavel Zuna <pzuna@redhat.com>2009-04-21 15:22:56 +0200
committerRob Crittenden <rcritten@redhat.com>2009-04-22 15:16:51 -0400
commitaf82879009ba298cf7eb96a712b11be49281c854 (patch)
treec20ad07abf1761a9aff91fe3126920a6f7357ed3 /ipalib
parent9ecbd845d47231c742e46f04c98856ff672fdd81 (diff)
downloadfreeipa-af82879009ba298cf7eb96a712b11be49281c854.tar.gz
freeipa-af82879009ba298cf7eb96a712b11be49281c854.tar.xz
freeipa-af82879009ba298cf7eb96a712b11be49281c854.zip
Add user plugin port with some bugs fixed to the new LDAP backend.
Diffstat (limited to 'ipalib')
-rw-r--r--ipalib/plugins/user2.py405
1 files changed, 405 insertions, 0 deletions
diff --git a/ipalib/plugins/user2.py b/ipalib/plugins/user2.py
new file mode 100644
index 000000000..13bd37f5a
--- /dev/null
+++ b/ipalib/plugins/user2.py
@@ -0,0 +1,405 @@
+# Authors:
+# Jason Gerard DeRose <jderose@redhat.com>
+# Pavel Zuna <pzuna@redhat.com>
+#
+# Copyright (C) 2008 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program 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; version 2 only
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+Users (Identity)
+"""
+
+from ipalib import api, crud, errors2
+from ipalib import Command, Object
+from ipalib import Flag, Int, Password, Str
+
+# parent DN
+_container_dn = api.env.container_user
+
+# attributes displayed by default
+_default_attributes = [
+ 'uid', 'givenName', 'sn', 'homeDirectory', 'loginShell'
+]
+
+
+class user2(Object):
+ """
+ User object.
+ """
+
+ takes_params = (
+ Str('givenname',
+ cli_name='first',
+ doc='first name',
+ ),
+ Str('sn',
+ cli_name='last',
+ doc='last name',
+ ),
+ Str('uid',
+ cli_name='user',
+ doc='login name',
+ primary_key=True,
+ default_from=lambda givenname, sn: givenname[0] + sn,
+ normalizer=lambda value: value.lower(),
+ ),
+ Str('gecos?',
+ doc='GECOS field',
+ default_from=lambda uid: uid,
+ ),
+ Str('homedirectory?',
+ cli_name='homedir',
+ doc='home directory',
+ default_from=lambda uid: '/home/%s' % uid,
+ ),
+ Str('loginshell?',
+ cli_name='shell',
+ default=u'/bin/sh',
+ doc='login shell',
+ ),
+ Str('krbprincipalname?',
+ cli_name='principal',
+ doc='Kerberos principal name',
+ default_from=lambda uid: '%s@%s' % (uid, api.env.realm),
+ ),
+ Str('mailaddress?',
+ cli_name='e_mail',
+ doc='e-mail address',
+ ),
+ Password('userpassword?',
+ cli_name='password',
+ doc='password',
+ ),
+ Int('uidnumber?',
+ cli_name='uid',
+ doc='UID (use this option to set it manually)',
+ ),
+ Str('street?',
+ cli_name='street',
+ doc='street address',
+ ),
+ )
+
+api.register(user2)
+
+
+class user2_create(crud.Create):
+ """
+ Create new user.
+ """
+
+ def execute(self, *args, **options):
+ assert self.api.env.use_ldap2, 'use_ldap2 is False'
+ ldap = self.api.Backend.ldap2
+ uid = args[0]
+
+ # build entry attributes
+ entry_attrs = self.args_options_2_entry(*args, **options)
+
+ # build entry DN
+ dn = ldap.make_dn(entry_attrs, 'uid', _container_dn)
+
+ # get configuration entry attributes
+ config = ldap.get_ipa_config()[1]
+
+ # fill in required attributes
+ entry_attrs['objectclass'] = config.get('ipaUserObjectClasses')
+
+ # fill default values
+ # uidNumber gets filled automatically by the DS dna_plugin
+ entry_attrs.setdefault('loginshell', config.get('ipaDefaultLoginShell'))
+ entry_attrs.setdefault('gecos', uid)
+ entry_attrs.setdefault(
+ 'krbprincipalname', '%s@%s' % (uid, self.api.env.realm)
+ )
+ # hack so we can request separate first and last name in CLI
+ entry_attrs.setdefault(
+ 'cn', '%s %s' % (entry_attrs['givenname'], entry_attrs['sn'])
+ )
+ if 'homedirectory' not in entry_attrs:
+ # get home's root directory from config
+ homes_root = config.get('ipaHomesRootDir', '/home')[0]
+ # build user's home directory based on his uid
+ home_dir = '%s/%s' % (homes_root, uid)
+ home_dir = home_dir.replace('//', '/').rstrip('/')
+ entry_attrs['homedirectory'] = home_dir
+
+ # we're adding new users to a default group, get it's DN and gidNumber
+ # get default group name from config
+ def_primary_group = config.get('ipaDefaultPrimaryGroup')
+ # build the group's DN
+ group_parent_dn = self.api.env.container_group
+ group_rdn = ldap.make_rdn_from_attr('cn', def_primary_group)
+ group_dn = ldap.make_dn_from_rdn(group_rdn, group_parent_dn)
+ # try to retrieve the group's gidNumber
+ try:
+ (group_dn, group_attrs) = ldap.get_entry(group_dn, ['gidNumber'])
+ except errors2.NotFound:
+ error_msg = 'Default group for new users not found.'
+ raise errors2.NotFound(error_msg)
+ # fill default group's gidNumber
+ entry_attrs['gidnumber'] = group_attrs['gidNumber']
+
+ # create user entry
+ ldap.add_entry(dn, entry_attrs)
+
+ # add user to default group
+ ldap.add_entry_to_group(dn, group_dn)
+
+ # get user entry with created attributes for output
+ return ldap.get_entry(dn, entry_attrs.keys())
+
+ def output_for_cli(self, textui, result, *args, **options):
+ (dn, entry_attrs) = result
+ uid = args[0]
+
+ textui.print_name(self.name)
+ textui.print_attribute('dn', dn)
+ textui.print_entry(entry_attrs)
+ textui.print_dashed('Created user "%s".' % uid)
+
+api.register(user2_create)
+
+
+class user2_delete(crud.Delete):
+ """
+ Delete user.
+ """
+
+ def execute(self, uid):
+ assert self.api.env.use_ldap2, 'use_ldap2 is False'
+ ldap = self.api.Backend.ldap2
+
+ if uid == 'admin':
+ # FIXME: add a specific exception for this?
+ raise errors2.ExecutionError('Cannot delete user "admin".')
+
+ # build entry DN
+ rdn = ldap.make_rdn_from_attr('uid', uid)
+ dn = ldap.make_dn_from_rdn(rdn, _container_dn)
+
+ # delete user entry
+ ldap.delete_entry(dn)
+
+ # blog about it
+ self.log.info('IPA: %s "%s"' % (self.name, uid))
+
+ # return something positive
+ return True
+
+ def output_for_cli(self, textui, result, uid):
+ textui.print_name(self.name)
+ textui.print_dashed('Deleted user "%s".' % uid)
+
+api.register(user2_delete)
+
+
+class user2_mod(crud.Update):
+ """
+ Modify user.
+ """
+
+ def execute(self, uid, **options):
+ assert self.api.env.use_ldap2, 'use_ldap2 is False'
+ ldap = self.api.Backend.ldap2
+
+ # build entry attributes, don't include uid!
+ entry_attrs = self.args_options_2_entry(*tuple(), **options)
+
+ # build entry DN
+ rdn = ldap.make_rdn_from_attr('uid', uid)
+ dn = ldap.make_dn_from_rdn(rdn, _container_dn)
+
+ # update user entry
+ ldap.update_entry(dn, entry_attrs)
+
+ # get user entry with modified + default attributes for output
+ return ldap.get_entry(dn, (entry_attrs.keys() + _default_attributes))
+
+ def output_for_cli(self, textui, result, uid, **options):
+ (dn, entry_attrs) = result
+
+ textui.print_name(self.name)
+ textui.print_attribute('dn', dn)
+ textui.print_entry(entry_attrs)
+ textui.print_dashed('Modified user "%s".' % uid)
+
+api.register(user2_mod)
+
+
+class user2_find(crud.Search):
+ """
+ Search for users.
+ """
+
+ takes_options = (
+ Flag('all',
+ doc='retrieve all attributes?',
+ ),
+ )
+
+ def execute(self, term, **options):
+ assert self.api.env.use_ldap2, 'use_ldap2 is False'
+ ldap = self.api.Backend.ldap2
+
+ # get list of search fields from config
+ config = ldap.get_ipa_config()[1]
+ search_fields = config.get('ipaUserSearchFields')[0].split(',')
+
+ # look for term in all search fields
+ search_kw = {}
+ for f in search_fields:
+ search_kw[f] = '%s' % term
+ # build search filter
+ filter = ldap.make_filter(search_kw, exact=False)
+
+ # select attributes we want to retrieve
+ if options['all']:
+ attrs_list = ['*']
+ else:
+ attrs_list = _default_attributes
+
+ # get matching entries
+ try:
+ entries = ldap.find_entries(
+ filter, attrs_list, _container_dn, ldap.SCOPE_ONELEVEL
+ )
+ except errors2.NotFound:
+ entries = tuple()
+
+ return entries
+
+ def output_for_cli(self, textui, result, term, **options):
+ textui.print_name(self.name)
+ for e in result:
+ (dn, entry_attrs) = e
+ textui.print_attribute('dn', dn)
+ textui.print_entry(entry_attrs)
+ textui.print_plain('')
+ textui.print_count(
+ len(result), '%i user matched.', '%i users matched.'
+ )
+
+api.register(user2_find)
+
+
+class user2_show(crud.Search):
+ """
+ Display user.
+ """
+
+ takes_options = (
+ Flag('all',
+ doc='retrieve all attributes?',
+ ),
+ )
+
+ def execute(self, uid, **options):
+ assert self.api.env.use_ldap2, 'use_ldap2 is False'
+ ldap = self.api.Backend.ldap2
+
+ # build entry DN
+ rdn = ldap.make_rdn_from_attr('uid', uid)
+ dn = ldap.make_dn_from_rdn(rdn, _container_dn)
+
+ # select attributes we want to retrieve
+ if options['all']:
+ attrs_list = ['*']
+ else:
+ attrs_list = _default_attributes
+
+ return ldap.get_entry(dn, attrs_list)
+
+ def output_for_cli(self, textui, result, uid, **options):
+ (dn, entry_attrs) = result
+
+ textui.print_name(self.name)
+ textui.print_attribute('dn', dn)
+ textui.print_entry(entry_attrs)
+
+api.register(user2_show)
+
+
+class user2_lock(Command):
+ """
+ Lock user account.
+ """
+
+ takes_args = (
+ Str('uid',
+ cli_name='user',
+ doc='login name',
+ ),
+ )
+
+ def execute(self, uid):
+ assert self.api.env.use_ldap2, 'use_ldap2 is False'
+ ldap = self.api.Backend.ldap2
+
+ # build entry DN
+ rdn = ldap.make_rdn_from_attr('uid', uid)
+ dn = ldap.make_dn_from_rdn(rdn, _container_dn)
+
+ # lock!
+ try:
+ ldap.deactivate_entry(dn)
+ except errors2.AlreadyInactive:
+ pass
+
+ # return something positive
+ return True
+
+ def output_for_cli(self, textui, result, uid):
+ textui.print_name(self.name)
+ textui.print_dashed('Locked user "%s".' % uid)
+
+api.register(user2_lock)
+
+
+class user2_unlock(Command):
+ """
+ Unlock user account.
+ """
+
+ takes_args = (
+ Str('uid',
+ cli_name='user',
+ doc='login name',
+ ),
+ )
+
+ def execute(self, uid):
+ assert self.api.env.use_ldap2, 'use_ldap2 is False'
+ ldap = self.api.Backend.ldap2
+
+ # build entry DN
+ rdn = ldap.make_rdn_from_attr('uid', uid)
+ dn = ldap.make_dn_from_rdn(rdn, _container_dn)
+
+ # unlock!
+ try:
+ ldap.activate_entry(dn)
+ except errors2.AlreadyActive:
+ pass
+
+ # return something positive
+ return True
+
+ def output_for_cli(self, textui, result, uid):
+ textui.print_name(self.name)
+ textui.print_dashed('Unlocked user "%s".' % uid)
+
+api.register(user2_unlock)
+