summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipa-admintools/ipa-adduser55
-rw-r--r--ipa-admintools/ipa-passwd36
-rw-r--r--ipa-python/ipaclient.py26
-rw-r--r--ipa-python/rpcclient.py22
-rw-r--r--ipa-server/ipa-gui/ipagui/controllers.py2
-rw-r--r--ipa-server/xmlrpc-server/funcs.py57
-rw-r--r--ipa-server/xmlrpc-server/ipaxmlrpc.py1
7 files changed, 111 insertions, 88 deletions
diff --git a/ipa-admintools/ipa-adduser b/ipa-admintools/ipa-adduser
index cefb2383..8bca98d7 100644
--- a/ipa-admintools/ipa-adduser
+++ b/ipa-admintools/ipa-adduser
@@ -28,6 +28,7 @@ import ipa.config
import xmlrpclib
import kerberos
+import krbV
import ldap
import getpass
@@ -51,8 +52,10 @@ def parse_options():
help="Set user's login shell to shell")
parser.add_option("-G", "--groups", dest="groups",
help="Add account to one or more groups (comma-separated)")
+ parser.add_option("-k", "--krb-principal", dest="principal",
+ help="Set user's Kerberos Principal Name")
parser.add_option("-M", "--mailAddress", dest="mail",
- help="Set uesr's e-mail address")
+ help="Set user's e-mail address")
parser.add_option("--usage", action="store_true",
help="Program usage")
@@ -66,8 +69,9 @@ def main():
givenname = ""
lastname = ""
username = ""
+ principal = ""
password = ""
- mail = ""
+ mail = ""
gecos = ""
directory = ""
shell = ""
@@ -100,7 +104,7 @@ def main():
cont = False
if not options.sn:
while (cont != True):
- lastname = raw_input(" Last name: ")
+ lastname = raw_input("Last name: ")
if (ipavalidate.plain(lastname, notEmpty=True)):
print "Field is required and must be letters or '"
else:
@@ -140,18 +144,10 @@ def main():
else:
password = options.sn
- cont = False
- if not options.mail:
- while (cont != True):
- mail = raw_input("E-mail addr: ")
- if (ipavalidate.email(mail)):
- print "Field is required and must include a user and domain name"
- else:
- cont = True
- else:
+ if options.mail:
mail = options.mail
if (ipavalidate.email(mail)):
- print "E-mail is required and must include a user and domain name"
+ print "The email provided seem not a valid email."
return 1
# Ask the questions we don't normally force. We don't require answers
@@ -168,8 +164,10 @@ def main():
cont = False
if not options.directory:
while (cont != True):
- directory = raw_input("home directory []: ")
- if (ipavalidate.path(gecos, notEmpty=False)):
+ directory = raw_input("home directory [/home/"+username+"]: ")
+ if directory == "":
+ directory = "/home/"+username
+ if (ipavalidate.path(directory, notEmpty=False)):
print "Must be letters, numbers, spaces or '"
else:
cont = True
@@ -180,29 +178,26 @@ def main():
if len(shell) < 1:
shell = None
- cont = True
- cont = False
- if not options.groups:
- while (cont != True):
- g = raw_input("Add to group [blank to exit]: ")
-
- if len(g) < 1:
- cont = True
- else:
- if (ipavalidate.path(g, notEmpty=False)):
- print "Must be letters, numbers, spaces or '"
- else:
- groups = groups + "," + g
+ cont = True
+
else:
gecos = options.gecos
directory = options.directory
shell = options.shell
groups = options.groups
+ if options.principal:
+ principal = options.principal
+ else:
+ ctx = krbV.default_context()
+ principal = username + "@" + ctx.default_realm
+
user.setValue('givenname', givenname)
user.setValue('sn', lastname)
user.setValue('uid', username)
- user.setValue('mail', mail)
+ user.setValue('krbprincipalname', principal)
+ if mail:
+ user.setValue('mail', mail)
if gecos:
user.setValue('gecos', gecos)
if directory:
@@ -231,7 +226,7 @@ def main():
# Set the User's password
if password is not None:
try:
- client.modifyPassword(username, None, password)
+ client.modifyPassword(principal, None, password)
except ipa.ipaerror.IPAError, e:
print "User added but setting the password failed."
print "%s" % (e.message)
diff --git a/ipa-admintools/ipa-passwd b/ipa-admintools/ipa-passwd
index 20dea562..4db0838f 100644
--- a/ipa-admintools/ipa-passwd
+++ b/ipa-admintools/ipa-passwd
@@ -44,12 +44,12 @@ def parse_options():
return options, args
-def get_principal():
+def get_principal(krbctx):
try:
- ctx = krbV.default_context()
- ccache = ctx.default_ccache()
+ ccache = krbctx.default_ccache()
cprinc = ccache.principal()
except krbV.Krb5Error, e:
+ #TODO: do a kinit
print "Unable to get kerberos principal: %s" % e[1]
return None
@@ -57,39 +57,47 @@ def get_principal():
def main():
match = False
+ username = None
+ principal = None
+ krbctx = krbV.default_context()
options, args = parse_options()
if len(args) == 2:
username = args[1]
else:
- username = get_principal()
- if username is None:
+ principal = get_principal(krbctx)
+ if principal is None:
return 1
- u = username.split('@')
- if len(u) > 1:
- username = u[0]
+ if not principal:
+ u = username.split('@')
+ if len(u) > 2 or len(u) == 0:
+ print "Invalid user name (%s)" % username
+ if len(u) == 1:
+ principal = username+"@"+krbctx.default_realm
+ else:
+ principal = username
- print "Changing password for %s" % username
+ print "Changing password for %s" % principal
while (match != True):
# No syntax checking of the password is required because that is done
# on the server side
password = getpass.getpass(" New Password: ")
- confirm = getpass.getpass(" New Password (again): ")
+ confirm = getpass.getpass(" Confirm Password: ")
if (password != confirm):
print "Passwords do not match"
match = False
+ elif (len(password) < 1):
+ print "Password cannot be empty"
+ match = False
else:
match = True
- if (len(password) < 1):
- print "Password cannot be empty"
- match = False
try:
client = ipaclient.IPAClient()
- client.modifyPassword(username, None, password)
+ client.modifyPassword(principal, None, password)
except ipa.ipaerror.IPAError, e:
print "%s" % (e.message)
return 1
diff --git a/ipa-python/ipaclient.py b/ipa-python/ipaclient.py
index 27ad1c24..47788f39 100644
--- a/ipa-python/ipaclient.py
+++ b/ipa-python/ipaclient.py
@@ -35,7 +35,6 @@ class IPAClient:
def __init__(self,local=None):
self.local = local
- ipa.config.init_config()
if local:
self.transport = funcs.IPAServer()
# client needs to call set_principal(user@REALM)
@@ -69,6 +68,13 @@ class IPAClient:
result = self.transport.get_user_by_dn(dn,sattrs)
return user.User(result)
+ def get_user_by_principal(self,principal,sattrs=None):
+ """Get a specific user by uid. If sattrs is set then only those
+ attributes will be returned, otherwise all available attributes
+ are returned."""
+ result = self.transport.get_user_by_principal(principal,sattrs)
+ return user.User(result)
+
def get_users_by_manager(self,manager_dn,sattrs=None):
"""Gets the users the report to a particular manager.
If sattrs is not None then only those
@@ -81,8 +87,6 @@ class IPAClient:
def add_user(self,user,user_container=None):
"""Add a user. user is a ipa.user.User object"""
- realm = config.config.get_realm()
-
user_dict = user.toDict()
# dn is set on the server-side
@@ -126,31 +130,25 @@ class IPAClient:
def update_user(self,user):
"""Update a user entry."""
- realm = config.config.get_realm()
-
result = self.transport.update_user(user.origDataDict(), user.toDict())
return result
def delete_user(self,uid):
"""Delete a user entry."""
- realm = config.config.get_realm()
-
result = self.transport.delete_user(uid)
return result
- def modifyPassword(self,uid,oldpass,newpass):
+ def modifyPassword(self,principal,oldpass,newpass):
"""Modify a user's password"""
- result = self.transport.modifyPassword(uid,oldpass,newpass)
+ result = self.transport.modifyPassword(principal,oldpass,newpass)
return result
def mark_user_deleted(self,uid):
"""Set a user as inactive by uid."""
- realm = config.config.get_realm()
-
result = self.transport.mark_user_deleted(uid)
return result
@@ -182,8 +180,6 @@ class IPAClient:
def add_group(self,group,group_container=None):
"""Add a group. group is a ipa.group.Group object"""
- realm = config.config.get_realm()
-
group_dict = group.toDict()
# dn is set on the server-side
@@ -238,6 +234,8 @@ class IPAClient:
def add_user_to_group(self, user_uid, group_cn):
"""Add a user to an existing group.
+ user is a uid of the user to add
+ group is the cn of the group to be added to
"""
return self.transport.add_user_to_group(user_uid, group_cn)
@@ -253,6 +251,8 @@ class IPAClient:
def remove_user_from_group(self, user_uid, group_cn):
"""Remove a user from an existing group.
+ user is a uid of the user to remove
+ group is the cn of the group to be removed from
"""
return self.transport.remove_user_from_group(user_uid, group_cn)
diff --git a/ipa-python/rpcclient.py b/ipa-python/rpcclient.py
index 9f02b374..0327357d 100644
--- a/ipa-python/rpcclient.py
+++ b/ipa-python/rpcclient.py
@@ -84,7 +84,7 @@ class RPCClient:
raise xmlrpclib.Fault(value, msg)
return ipautil.unwrap_binary_data(result)
-
+
def get_user_by_dn(self,dn,sattrs=None):
"""Get a specific user. If sattrs is not None then only those
attributes will be returned, otherwise all available
@@ -101,6 +101,22 @@ class RPCClient:
return ipautil.unwrap_binary_data(result)
+ def get_user_by_principal(self,principal,sattrs=None):
+ """Get a specific user. If sattrs is not None then only those
+ attributes will be returned, otherwise all available
+ attributes are returned. The result is a dict."""
+ server = self.setup_server()
+ if sattrs is None:
+ sattrs = "__NONE__"
+ try:
+ result = server.get_user_by_principal(principal, sattrs)
+ except xmlrpclib.Fault, fault:
+ raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
+ except socket.error, (value, msg):
+ raise xmlrpclib.Fault(value, msg)
+
+ return ipautil.unwrap_binary_data(result)
+
def get_users_by_manager(self,manager_dn,sattrs=None):
"""Gets the users that report to a manager.
If sattrs is not None then only those
@@ -212,7 +228,7 @@ class RPCClient:
return result
- def modifyPassword(self,uid,oldpass,newpass):
+ def modifyPassword(self,principal,oldpass,newpass):
"""Modify a user's password"""
server = self.setup_server()
@@ -220,7 +236,7 @@ class RPCClient:
oldpass = "__NONE__"
try:
- result = server.modifyPassword(uid,oldpass,newpass)
+ result = server.modifyPassword(principal,oldpass,newpass)
except xmlrpclib.Fault, fault:
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
except socket.error, (value, msg):
diff --git a/ipa-server/ipa-gui/ipagui/controllers.py b/ipa-server/ipa-gui/ipagui/controllers.py
index 41bd3b29..bdb7b102 100644
--- a/ipa-server/ipa-gui/ipagui/controllers.py
+++ b/ipa-server/ipa-gui/ipagui/controllers.py
@@ -338,7 +338,7 @@ class Root(controllers.RootController):
#
try:
if password_change:
- rv = client.modifyPassword(kw['uid'], "", kw.get('userpassword'))
+ rv = client.modifyPassword(kw['krbprincipalname'], "", kw.get('userpassword'))
except ipaerror.IPAError, e:
turbogears.flash("User password change failed: " + str(e))
return dict(form=user_edit_form, user=kw,
diff --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py
index e4e2f40e..de089b61 100644
--- a/ipa-server/xmlrpc-server/funcs.py
+++ b/ipa-server/xmlrpc-server/funcs.py
@@ -20,12 +20,12 @@
import sys
sys.path.append("/usr/share/ipa")
+import krbV
import ldap
import ipaserver.dsinstance
import ipaserver.ipaldap
import ipa.ipautil
import xmlrpclib
-import ipa.config
import copy
from ipa import ipaerror
@@ -86,11 +86,12 @@ class IPAServer:
self.bindcert = "/usr/share/ipa/cert.pem"
self.bindkey = "/usr/share/ipa/key.pem"
self.bindca = "/usr/share/ipa/cacert.asc"
-
+ self.krbctx = krbV.default_context()
+ self.realm = self.krbctx.default_realm
+
if _LDAPPool is None:
_LDAPPool = IPAConnPool()
- ipa.config.init_config()
- self.basedn = ipa.ipautil.realm_to_suffix(ipa.config.config.get_realm())
+ self.basedn = ipa.ipautil.realm_to_suffix(self.realm)
self.scope = ldap.SCOPE_SUBTREE
self.princ = None
self.krbccache = None
@@ -312,6 +313,15 @@ class IPAServer:
filter = "(objectClass=*)"
return self.__get_entry(dn, filter, sattrs, opts)
+ def get_user_by_principal(self, principal, sattrs=None, opts=None):
+ """Get a user entry searching by Kerberos Principal Name.
+ Return as a dict of values. Multi-valued fields are
+ represented as lists.
+ """
+
+ filter = "(krbPrincipalName="+self.__safe_filter(principal)+")"
+ return self.__get_entry(self.basedn, filter, sattrs, opts)
+
def get_users_by_manager (self, manager_dn, sattrs=None, opts=None):
"""Gets the users that report to a particular manager.
"""
@@ -342,9 +352,9 @@ class IPAServer:
# Let us add in some missing attributes
if user.get('homedirectory') is None:
- user['homedirectory'] = '/home/%s' % user.get('uid')
+ user['homedirectory'] = '/home/%s' % user.get('uid')
if not user.get('gecos') is None:
- user['gecos'] = user['uid']
+ user['gecos'] = user['uid']
# FIXME: This can be removed once the DS plugin is installed
user['uidnumber'] = '501'
@@ -352,8 +362,8 @@ class IPAServer:
# FIXME: What is the default group for users?
user['gidnumber'] = '501'
- realm = ipa.config.config.get_realm()
- user['krbprincipalname'] = "%s@%s" % (user.get('uid'), realm)
+ 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.
@@ -365,17 +375,7 @@ class IPAServer:
del user['gn']
# some required objectclasses
- entry.setValues('objectClass', 'top', 'posixAccount', 'shadowAccount', 'account', 'person', 'inetOrgPerson', 'organizationalPerson', 'krbPrincipalAux', 'krbTicketPolicyAux')
-
- # Fill in shadow fields
- entry.setValue('shadowMin', '0')
- entry.setValue('shadowMax', '99999')
- entry.setValue('shadowWarning', '7')
- entry.setValue('shadowExpire', '-1')
- entry.setValue('shadowInactive', '-1')
- entry.setValue('shadowFlag', '-1')
-
- # FIXME: calculate shadowLastChange
+ entry.setValues('objectClass', 'top', 'person', 'organizationalPerson', 'inetOrgPerson', 'posixAccount', 'krbPrincipalAux')
# fill in our new entry with everything sent by the user
for u in user:
@@ -426,7 +426,7 @@ class IPAServer:
"label": "E-mail address:",
"type": "text",
"validator": "email",
- "required": "true"
+ "required": "false"
}
fields.append(field1)
@@ -455,6 +455,9 @@ class IPAServer:
"""Returns a list: counter followed by the results.
If the results are truncated, counter will be set to -1."""
+ # TODO - retrieve from config
+ timelimit = 2
+
# Assume the list of fields to search will come from a central
# configuration repository. A good format for that would be
# a comma-separated list of fields
@@ -562,31 +565,31 @@ class IPAServer:
The memberOf plugin handles removing the user from any other
groups.
"""
- user_dn = self.get_user_by_uid(uid, ['dn', 'uid', 'objectclass'], opts)
- if user_dn is None:
+ user = self.get_user_by_uid(uid, ['dn', 'uid', 'objectclass'], opts)
+ if user is None:
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
conn = self.getConnection(opts)
try:
- res = conn.deleteEntry(user_dn['dn'])
+ res = conn.deleteEntry(user['dn'])
finally:
self.releaseConnection(conn)
return res
- def modifyPassword (self, uid, oldpass, newpass, opts=None):
+ def modifyPassword (self, principal, oldpass, newpass, opts=None):
"""Set/Reset a user's password
uid tells us who's password to change
oldpass is the old password (if available)
newpass is the new password
"""
- user_dn = self.get_user_by_uid(uid, ['dn', 'uid', 'objectclass'], opts)
- if user_dn is None:
+ user = self.get_user_by_principal(principal, ['krbprincipalname'], opts)
+ if user is None or user['krbprincipalname'] != principal:
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
conn = self.getConnection(opts)
try:
- res = conn.modifyPassword(user_dn['dn'], oldpass, newpass)
+ res = conn.modifyPassword(user['dn'], oldpass, newpass)
finally:
self.releaseConnection(conn)
return res
diff --git a/ipa-server/xmlrpc-server/ipaxmlrpc.py b/ipa-server/xmlrpc-server/ipaxmlrpc.py
index 96d9299c..9f70550a 100644
--- a/ipa-server/xmlrpc-server/ipaxmlrpc.py
+++ b/ipa-server/xmlrpc-server/ipaxmlrpc.py
@@ -319,6 +319,7 @@ def handler(req, profiling=False):
h = ModXMLRPCRequestHandler()
h.register_function(f.get_user_by_uid)
h.register_function(f.get_user_by_dn)
+ h.register_function(f.get_user_by_principal)
h.register_function(f.get_users_by_manager)
h.register_function(f.add_user)
h.register_function(f.get_add_schema)