From 7e4b0a072e69351496010d7b2151c9b434c8fdb0 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Sat, 4 Oct 2008 01:50:59 -0400 Subject: Implement user-find and user-add backend functions so they work over XML-RPC Change port to 8880 to not conflict with a running IPA v1 instance Encode incoming values from unicode as utf-8 before sending to LDAP --- ipalib/plugins/f_user.py | 91 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 6 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 29f0f8a0..320666aa 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -25,7 +25,10 @@ from ipalib import frontend from ipalib import crud from ipalib.frontend import Param from ipalib import api - +from ipa_server import servercore +from ipa_server import ipaldap +import ldap +from ipa_server.context import context # Command to get the idea how plugins will interact with api.env class envtest(frontend.Command): @@ -71,7 +74,79 @@ api.register(user) class user_add(crud.Add): 'Add a new user.' def execute(self, *args, **kw): - return 1 + """args[0] = uid of the user to add + kw{container} is the location in the DIT to add the user, not + required + kw otherwise contains all the attributes + """ + # FIXME: ug, really? + if not kw.get('container'): + user_container = servercore.DefaultUserContainer + else: + user_container = kw['container'] + del kw['container'] + + user = kw + + if not isinstance(user, dict): + # FIXME, need proper error + raise SyntaxError + + user['uid'] = args[0] + + # dn is set here, not by the user + try: + del user['dn'] + except KeyError: + pass + + # No need to set empty fields, and they can cause issues when they + # get to LDAP, like: + # TypeError: ('expected a string in the list', None) + for k in user.keys(): + if not user[k] or len(user[k]) == 0 or (isinstance(user[k],list) and len(user[k]) == 1 and '' in user[k]): + del user[k] + + dn="uid=%s,%s,%s" % (ldap.dn.escape_dn_chars(user['uid']), + user_container,servercore.basedn) + + entry = ipaldap.Entry(dn) + + # Let us add in some missing attributes + # FIXME, get config +# if user.get('homedirectory') is None: +# user['homedirectory'] = '%s/%s' % (config.get('ipahomesrootdir'), user.get('uid')) +# user['homedirectory'] = user['homedirectory'].replace('//', '/') +# user['homedirectory'] = user['homedirectory'].rstrip('/') +# if user.get('loginshell') is None: +# user['loginshell'] = config.get('ipadefaultloginshell') + if user.get('gecos') is None: + user['gecos'] = user['uid'] + + # FIXME: add to default group + user['gidNumber'] = "500" + + if user.get('krbprincipalname') is None: + user['krbprincipalname'] = "%s@%s" % (user.get('uid'), self.realm) + + # FIXME. This is a hack so we can request separate First and Last + # name in the GUI. + if user.get('cn') is None: + user['cn'] = "%s %s" % (user.get('givenname'), + user.get('sn')) + + # some required objectclasses + # FIXME + # entry.setValues('objectClass', (config.get('ipauserobjectclasses'))) + entry.setValues('objectClass', ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'inetUser', 'posixAccount', 'krbPrincipalAux']) + + # fill in our new entry with everything sent by the user + for u in user: + entry.setValues(u, user[u]) + + result = context.conn.getConn().addEntry(entry) + return result + api.register(user_add) @@ -87,10 +162,14 @@ api.register(user_mod) class user_find(crud.Find): 'Search the users.' -# def execute(self, *args, **kw): -# uid=args[0] -# result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) -# return result + def execute(self, *args, **kw): + uid=args[0] + result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) + return result + def forward(self, *args, **kw): + result = super(crud.Find, self).forward(*args, **kw) + for a in result: + print a, ": ", res[a] api.register(user_find) -- cgit From cb795fa14bc2798fd8f1c6e2b87d19432e3f84a1 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Sat, 4 Oct 2008 05:17:11 -0400 Subject: Add group plugin, routine to get cn=ipaconfig --- ipalib/plugins/f_user.py | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 320666aa..0e62b833 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -112,19 +112,35 @@ class user_add(crud.Add): entry = ipaldap.Entry(dn) + # Get our configuration + config = servercore.get_ipa_config() + # Let us add in some missing attributes - # FIXME, get config -# if user.get('homedirectory') is None: -# user['homedirectory'] = '%s/%s' % (config.get('ipahomesrootdir'), user.get('uid')) -# user['homedirectory'] = user['homedirectory'].replace('//', '/') -# user['homedirectory'] = user['homedirectory'].rstrip('/') -# if user.get('loginshell') is None: -# user['loginshell'] = config.get('ipadefaultloginshell') + if user.get('homedirectory') is None: + user['homedirectory'] = '%s/%s' % (config.get('ipahomesrootdir'), user.get('uid')) + user['homedirectory'] = user['homedirectory'].replace('//', '/') + user['homedirectory'] = user['homedirectory'].rstrip('/') + if user.get('loginshell') is None: + user['loginshell'] = config.get('ipadefaultloginshell') if user.get('gecos') is None: user['gecos'] = user['uid'] - # FIXME: add to default group - user['gidNumber'] = "500" + # If uidnumber is blank the the FDS dna_plugin will automatically + # assign the next value. So we don't have to do anything with it. + + group_dn="cn=%s,%s,%s" % (config.get('ipadefaultprimarygroup'), servercore.DefaultGroupContainer, servercore.basedn) + try: + default_group = servercore.get_entry_by_dn(group_dn, ['dn','gidNumber']) + if default_group: + user['gidnumber'] = default_group.get('gidnumber') +# except ipaerror.exception_for(ipaerror.LDAP_DATABASE_ERROR), e: +# raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, message=None, nested_exception=e.detail) +# except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): +# # Fake an LDAP error so we can return something useful to the user +# raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND, "The default group for new users, '%s', cannot be found." % config.get('ipadefaultprimarygroup')) + except Exception, e: + # FIXME + raise e if user.get('krbprincipalname') is None: user['krbprincipalname'] = "%s@%s" % (user.get('uid'), self.realm) @@ -136,9 +152,8 @@ class user_add(crud.Add): user.get('sn')) # some required objectclasses - # FIXME - # entry.setValues('objectClass', (config.get('ipauserobjectclasses'))) - entry.setValues('objectClass', ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'inetUser', 'posixAccount', 'krbPrincipalAux']) + entry.setValues('objectClass', (config.get('ipauserobjectclasses'))) + # entry.setValues('objectClass', ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'inetUser', 'posixAccount', 'krbPrincipalAux']) # fill in our new entry with everything sent by the user for u in user: @@ -169,7 +184,7 @@ class user_find(crud.Find): def forward(self, *args, **kw): result = super(crud.Find, self).forward(*args, **kw) for a in result: - print a, ": ", res[a] + print a, ": ", result[a] api.register(user_find) -- cgit From 69bc5ad77adecaf7d8fde4a6578c3d2f3ef355df Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 7 Oct 2008 02:10:15 -0400 Subject: Add some more supporting functions Do a little bit more error handling and checking --- ipalib/plugins/f_user.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 0e62b833..49b6a370 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -28,7 +28,6 @@ from ipalib import api from ipa_server import servercore from ipa_server import ipaldap import ldap -from ipa_server.context import context # Command to get the idea how plugins will interact with api.env class envtest(frontend.Command): @@ -94,6 +93,13 @@ class user_add(crud.Add): user['uid'] = args[0] + if not servercore.is_user_unique(user['uid']): + # FIXME, specific error + raise SyntaxError("user already exists") + if servercore.uid_too_long(user['uid']): + # FIXME, specific error + raise SyntaxError("uid is too long") + # dn is set here, not by the user try: del user['dn'] @@ -159,8 +165,12 @@ class user_add(crud.Add): for u in user: entry.setValues(u, user[u]) - result = context.conn.getConn().addEntry(entry) + result = servercore.add_entry(entry) return result + def forward(self, *args, **kw): + result = super(crud.Add, self).forward(*args, **kw) + if result != False: + print result api.register(user_add) -- cgit From e012e860b472bcb5a00a089e73113fb6989fde20 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 7 Oct 2008 04:31:22 -0400 Subject: Implement user-mod --- ipalib/plugins/f_user.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 49b6a370..0b424d35 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -170,7 +170,7 @@ class user_add(crud.Add): def forward(self, *args, **kw): result = super(crud.Add, self).forward(*args, **kw) if result != False: - print result + print "User %s added" % args[0] api.register(user_add) @@ -182,6 +182,25 @@ api.register(user_del) class user_mod(crud.Mod): 'Edit an existing user.' + def execute(self, *args, **kw): + uid=args[0] + result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) + + user = kw + dn = result.get('dn') + del result['dn'] + entry = ipaldap.Entry((dn, servercore.convert_scalar_values(result))) + + for u in user: + entry.setValues(u, user[u]) + + result = servercore.update_entry(entry.toDict()) + + return result + def forward(self, *args, **kw): + result = super(crud.Mod, self).forward(*args, **kw) + if result != False: + print "User %s modified" % args[0] api.register(user_mod) -- cgit From db9d8dd3e0924bb9c7f9c89a56e6b6057dabc710 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 7 Oct 2008 06:15:34 -0400 Subject: Implement a real user_find and move existing user_find to user_show --- ipalib/plugins/f_user.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 0b424d35..e560d03c 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -208,15 +208,33 @@ class user_find(crud.Find): 'Search the users.' def execute(self, *args, **kw): uid=args[0] - result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) + result = servercore.find_users(uid, ["*"]) return result def forward(self, *args, **kw): - result = super(crud.Find, self).forward(*args, **kw) - for a in result: - print a, ": ", result[a] + users = super(crud.Find, self).forward(*args, **kw) + counter = users[0] + users = users[1:] + if counter == 0: + print "No entries found for", args[0] + return + elif counter == -1: + print "These results are truncated." + print "Please refine your search and try again." + + for u in users: + for a in u.keys(): + print "%s: %s" % (a, u[a]) api.register(user_find) class user_show(crud.Get): 'Examine an existing user.' + def execute(self, *args, **kw): + uid=args[0] + result = servercore.get_user_by_uid(uid, ["*"]) + return result + def forward(self, *args, **kw): + result = super(crud.Get, self).forward(*args, **kw) + for a in result: + print a, ": ", result[a] api.register(user_show) -- cgit