summaryrefslogtreecommitdiffstats
path: root/ipa-server
diff options
context:
space:
mode:
authorJohn Dennis <jdennis@redhat.com>2007-12-04 10:08:08 -0500
committerJohn Dennis <jdennis@redhat.com>2007-12-04 10:08:08 -0500
commitd53915954e68ad2fa1625ed016e7e65cd6f4e4e0 (patch)
tree6963257f9c07a23cbe7a33d621edae5e7c327d9f /ipa-server
parent4e1d291d15e198a0517a2c6787f865fe41147440 (diff)
parent299e45769811c7573d1389e5eb25643e62b1d128 (diff)
downloadfreeipa-d53915954e68ad2fa1625ed016e7e65cd6f4e4e0.tar.gz
freeipa-d53915954e68ad2fa1625ed016e7e65cd6f4e4e0.tar.xz
freeipa-d53915954e68ad2fa1625ed016e7e65cd6f4e4e0.zip
merge
Diffstat (limited to 'ipa-server')
-rw-r--r--ipa-server/configure.ac2
-rw-r--r--ipa-server/ipa-gui/ipagui/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/config/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/forms/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/forms/delegate.py2
-rw-r--r--ipa-server/ipa-gui/ipagui/forms/group.py2
-rw-r--r--ipa-server/ipa-gui/ipagui/forms/ipapolicy.py8
-rw-r--r--ipa-server/ipa-gui/ipagui/forms/user.py2
-rw-r--r--ipa-server/ipa-gui/ipagui/helpers/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/static/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/static/css/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/static/images/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/static/images/branding/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/static/images/template/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/static/javascript/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/subcontrollers/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/subcontrollers/ipapolicy.py4
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/Makefile.am1
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/useredit.kid4
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/usershow.kid4
-rw-r--r--ipa-server/ipa-gui/ipagui/tests/Makefile.am1
-rw-r--r--ipa-server/ipa-install/share/bootstrap-template.ldif14
-rw-r--r--ipa-server/ipa-install/share/default-aci.ldif23
-rw-r--r--ipa-server/ipa-server.spec.in2
-rw-r--r--ipa-server/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c58
-rw-r--r--ipa-server/ipa-slapi-plugins/ipa-pwd-extop/pwd-extop-conf.ldif2
-rw-r--r--ipa-server/ipaserver/dsinstance.py27
-rw-r--r--ipa-server/ipaserver/httpinstance.py2
-rw-r--r--ipa-server/ipaserver/krbinstance.py14
-rw-r--r--ipa-server/xmlrpc-server/funcs.py93
30 files changed, 173 insertions, 103 deletions
diff --git a/ipa-server/configure.ac b/ipa-server/configure.ac
index 1e62a2f82..7492d4cf7 100644
--- a/ipa-server/configure.ac
+++ b/ipa-server/configure.ac
@@ -1,4 +1,4 @@
-AC_PREREQ(2.59c)
+AC_PREREQ(2.59)
AC_INIT([ipa-server],
[0.5],
[https://hosted.fedoraproject.org/projects/freeipa/newticket])
diff --git a/ipa-server/ipa-gui/ipagui/Makefile.am b/ipa-server/ipa-gui/ipagui/Makefile.am
index 683235678..83636323d 100644
--- a/ipa-server/ipa-gui/ipagui/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/Makefile.am
@@ -26,4 +26,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/config/Makefile.am b/ipa-server/ipa-gui/ipagui/config/Makefile.am
index 5d5492841..db96758f3 100644
--- a/ipa-server/ipa-gui/ipagui/config/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/config/Makefile.am
@@ -16,4 +16,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/forms/Makefile.am b/ipa-server/ipa-gui/ipagui/forms/Makefile.am
index c075b9f47..4f1f72d22 100644
--- a/ipa-server/ipa-gui/ipagui/forms/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/forms/Makefile.am
@@ -14,4 +14,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/forms/delegate.py b/ipa-server/ipa-gui/ipagui/forms/delegate.py
index 419df4fc7..d9d5d727c 100644
--- a/ipa-server/ipa-gui/ipagui/forms/delegate.py
+++ b/ipa-server/ipa-gui/ipagui/forms/delegate.py
@@ -43,7 +43,7 @@ aci_checkbox_attrs = [(field.name, field.label) for field in aci_attrs]
aci_name_to_label = dict(aci_checkbox_attrs)
-class DelegateFields():
+class DelegateFields(object):
name = widgets.TextField(name="name", label="Delegation Name")
source_group_dn = widgets.HiddenField(name="source_group_dn")
diff --git a/ipa-server/ipa-gui/ipagui/forms/group.py b/ipa-server/ipa-gui/ipagui/forms/group.py
index b67156641..fa3a0988a 100644
--- a/ipa-server/ipa-gui/ipagui/forms/group.py
+++ b/ipa-server/ipa-gui/ipagui/forms/group.py
@@ -2,7 +2,7 @@ import turbogears
from turbogears import validators, widgets
from tg_expanding_form_widget.tg_expanding_form_widget import ExpandingForm
-class GroupFields():
+class GroupFields(object):
cn = widgets.TextField(name="cn", label="Name")
gidnumber = widgets.TextField(name="gidnumber", label="GID")
description = widgets.TextField(name="description", label="Description")
diff --git a/ipa-server/ipa-gui/ipagui/forms/ipapolicy.py b/ipa-server/ipa-gui/ipagui/forms/ipapolicy.py
index ec0e8c6f8..78acac664 100644
--- a/ipa-server/ipa-gui/ipagui/forms/ipapolicy.py
+++ b/ipa-server/ipa-gui/ipagui/forms/ipapolicy.py
@@ -1,9 +1,9 @@
import turbogears
from turbogears import validators, widgets
-class IPAPolicyFields():
+class IPAPolicyFields(object):
# From cn=ipaConfig
- ipausersearchfields = widgets.TextField(name="ipausersearchfields", label="User Search Fields")
+ ipausersearchfields = widgets.TextField(name="ipausersearchfields", label="User Search Fields", attrs=dict(size=50))
ipagroupsearchfields = widgets.TextField(name="ipagroupsearchfields", label="Group Search Fields")
ipasearchtimelimit = widgets.TextField(name="ipasearchtimelimit", label="Search Time Limit (sec.)", attrs=dict(size=6,maxlength=6))
ipasearchrecordslimit = widgets.TextField(name="ipasearchrecordslimit", label="Search Records Limit", attrs=dict(size=6,maxlength=6))
@@ -16,8 +16,8 @@ class IPAPolicyFields():
ipapolicy_orig = widgets.HiddenField(name="ipapolicy_orig")
# From cn=accounts
- krbmaxpwdlife = widgets.TextField(name="krbmaxpwdlife", label="Max. Password Lifetime", attrs=dict(size=3,maxlength=3))
- krbminpwdlife = widgets.TextField(name="krbminpwdlife", label="Min. Password Lifetime", attrs=dict(size=3,maxlength=3))
+ krbmaxpwdlife = widgets.TextField(name="krbmaxpwdlife", label="Max. Password Lifetime (days)", attrs=dict(size=3,maxlength=3))
+ krbminpwdlife = widgets.TextField(name="krbminpwdlife", label="Min. Password Lifetime (hours)", attrs=dict(size=3,maxlength=3))
krbpwdmindiffchars = widgets.TextField(name="krbpwdmindiffchars", label="Min. number of character classes", attrs=dict(size=3,maxlength=3))
krbpwdminlength = widgets.TextField(name="krbpwdminlength", label="Min. Length of password", attrs=dict(size=3,maxlength=3))
krbpwdhistorylength = widgets.TextField(name="krbpwdhistorylength", label="Password History size", attrs=dict(size=3,maxlength=3))
diff --git a/ipa-server/ipa-gui/ipagui/forms/user.py b/ipa-server/ipa-gui/ipagui/forms/user.py
index 7d3d37193..f1bf48365 100644
--- a/ipa-server/ipa-gui/ipagui/forms/user.py
+++ b/ipa-server/ipa-gui/ipagui/forms/user.py
@@ -2,7 +2,7 @@ import turbogears
from turbogears import validators, widgets
from tg_expanding_form_widget.tg_expanding_form_widget import ExpandingForm
-class UserFields():
+class UserFields(object):
givenname = widgets.TextField(name="givenname", label="Given Name")
sn = widgets.TextField(name="sn", label="Family Name")
cn = widgets.TextField(name="cn", label="Common Names")
diff --git a/ipa-server/ipa-gui/ipagui/helpers/Makefile.am b/ipa-server/ipa-gui/ipagui/helpers/Makefile.am
index 490c8e4f1..aa3e75bf0 100644
--- a/ipa-server/ipa-gui/ipagui/helpers/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/helpers/Makefile.am
@@ -12,4 +12,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/static/Makefile.am b/ipa-server/ipa-gui/ipagui/static/Makefile.am
index 11c213841..d4ca45572 100644
--- a/ipa-server/ipa-gui/ipagui/static/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/static/Makefile.am
@@ -8,4 +8,5 @@ SUBDIRS = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/static/css/Makefile.am b/ipa-server/ipa-gui/ipagui/static/css/Makefile.am
index 482893466..fe8a39791 100644
--- a/ipa-server/ipa-gui/ipagui/static/css/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/static/css/Makefile.am
@@ -11,4 +11,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/static/images/Makefile.am b/ipa-server/ipa-gui/ipagui/static/images/Makefile.am
index d1f919848..011e24aec 100644
--- a/ipa-server/ipa-gui/ipagui/static/images/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/static/images/Makefile.am
@@ -24,4 +24,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/static/images/branding/Makefile.am b/ipa-server/ipa-gui/ipagui/static/images/branding/Makefile.am
index fcf2fdc11..cb0a81424 100644
--- a/ipa-server/ipa-gui/ipagui/static/images/branding/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/static/images/branding/Makefile.am
@@ -11,4 +11,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/static/images/template/Makefile.am b/ipa-server/ipa-gui/ipagui/static/images/template/Makefile.am
index dc769d846..a446ce637 100644
--- a/ipa-server/ipa-gui/ipagui/static/images/template/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/static/images/template/Makefile.am
@@ -17,4 +17,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/static/javascript/Makefile.am b/ipa-server/ipa-gui/ipagui/static/javascript/Makefile.am
index 908569afc..a2ca2289b 100644
--- a/ipa-server/ipa-gui/ipagui/static/javascript/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/static/javascript/Makefile.am
@@ -17,4 +17,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/subcontrollers/Makefile.am b/ipa-server/ipa-gui/ipagui/subcontrollers/Makefile.am
index 2f596f2ef..a0c6393fe 100644
--- a/ipa-server/ipa-gui/ipagui/subcontrollers/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/subcontrollers/Makefile.am
@@ -16,4 +16,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/subcontrollers/ipapolicy.py b/ipa-server/ipa-gui/ipagui/subcontrollers/ipapolicy.py
index 781ca35d4..a82b98888 100644
--- a/ipa-server/ipa-gui/ipagui/subcontrollers/ipapolicy.py
+++ b/ipa-server/ipa-gui/ipagui/subcontrollers/ipapolicy.py
@@ -104,7 +104,7 @@ class IPAPolicyController(IPAController):
new_ipapolicy = ipa.entity.Entity(orig_ipapolicy_dict)
new_password = ipa.entity.Entity(orig_password_dict)
-
+
if str(new_ipapolicy.ipasearchtimelimit) != str(kw.get('ipasearchtimelimit')):
policy_modified = True
new_ipapolicy.setValue('ipasearchtimelimit', kw.get('ipasearchtimelimit'))
@@ -158,7 +158,7 @@ class IPAPolicyController(IPAController):
turbogears.flash("IPA Policy updated")
raise turbogears.redirect('/ipapolicy/show')
except ipaerror.IPAError, e:
- turbogears.flash("Policy update failed: " + str(e) + e.detail[0]['desc'])
+ turbogears.flash("Policy update failed: " + str(e) + "<br/>" + e.detail[0]['desc'])
return dict(form=ipapolicy_edit_form, ipapolicy=kw,
tg_template='ipagui.templates.ipapolicyedit')
diff --git a/ipa-server/ipa-gui/ipagui/templates/Makefile.am b/ipa-server/ipa-gui/ipagui/templates/Makefile.am
index 6626ad8c2..4bf8f142d 100644
--- a/ipa-server/ipa-gui/ipagui/templates/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/templates/Makefile.am
@@ -45,4 +45,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-gui/ipagui/templates/useredit.kid b/ipa-server/ipa-gui/ipagui/templates/useredit.kid
index f5cb1b02e..a3d813339 100644
--- a/ipa-server/ipa-gui/ipagui/templates/useredit.kid
+++ b/ipa-server/ipa-gui/ipagui/templates/useredit.kid
@@ -29,10 +29,10 @@ else:
?>
<div py:if='pw_expires_soon' class="warning_message">
- Password will expire in ${pw_expires_days} day${days_suffix}
+ ${user.get("uid")}'s password will expire in ${pw_expires_days} day${days_suffix}
</div>
<div py:if='pw_is_expired' class="warning_message">
- Password has expired
+ ${user.get("uid")}'s password has expired
</div>
${form.display(action=tg.url('/user/update'), value=user, user_groups=user_groups)}
diff --git a/ipa-server/ipa-gui/ipagui/templates/usershow.kid b/ipa-server/ipa-gui/ipagui/templates/usershow.kid
index 8cc356b89..614988729 100644
--- a/ipa-server/ipa-gui/ipagui/templates/usershow.kid
+++ b/ipa-server/ipa-gui/ipagui/templates/usershow.kid
@@ -28,10 +28,10 @@ else:
?>
<div id="alertbox" py:if='pw_expires_soon' class="warning_message">
- Password will expire in ${pw_expires_days} day${days_suffix}
+ ${user.get("uid")}'s password will expire in ${pw_expires_days} day${days_suffix}
</div>
<div id="alertbox" py:if='pw_is_expired' class="warning_message">
- Password has expired
+ ${user.get("uid")}'s password has expired
</div>
<h2 class="formsection">Identity Details</h2>
diff --git a/ipa-server/ipa-gui/ipagui/tests/Makefile.am b/ipa-server/ipa-gui/ipagui/tests/Makefile.am
index 9902fef72..bf06ef2fa 100644
--- a/ipa-server/ipa-gui/ipagui/tests/Makefile.am
+++ b/ipa-server/ipa-gui/ipagui/tests/Makefile.am
@@ -12,4 +12,5 @@ EXTRA_DIST = \
MAINTAINERCLEANFILES = \
*~ \
+ *.pyc \
Makefile.in
diff --git a/ipa-server/ipa-install/share/bootstrap-template.ldif b/ipa-server/ipa-install/share/bootstrap-template.ldif
index f981005d2..e3fa89067 100644
--- a/ipa-server/ipa-install/share/bootstrap-template.ldif
+++ b/ipa-server/ipa-install/share/bootstrap-template.ldif
@@ -14,7 +14,7 @@ krbMinPwdLife: 3600
krbPwdMinDiffChars: 0
krbPwdMinLength: 8
krbPwdHistoryLength: 0
-krbMaxPwdLife: 864000
+krbMaxPwdLife: 7776000
dn: cn=users,cn=accounts,$SUFFIX
changetype: add
@@ -34,6 +34,12 @@ objectClass: top
objectClass: nsContainer
cn: services
+dn: cn=computers,cn=accounts,$SUFFIX
+changetype: add
+objectClass: top
+objectClass: nsContainer
+cn: computers
+
dn: cn=etc,$SUFFIX
changetype: add
objectClass: nsContainer
@@ -143,6 +149,7 @@ ipaMaxUsernameLength: 8
ipaPwdExpAdvNotify: 4
dn: cn=account inactivation,cn=accounts,$SUFFIX
+changetype: add
description: Lock accounts based on group membership
objectClass: top
objectClass: ldapsubentry
@@ -154,11 +161,13 @@ cosSpecifier: memberOf
cn: Account Inactivation
dn: cn=cosTemplates,cn=accounts,$SUFFIX
+changetype: add
objectclass: top
objectclass: nsContainer
cn: cosTemplates
dn: cn="cn=inactivated,cn=account inactivation,cn=accounts,$SUFFIX", cn=cosTemplates,cn=accounts,$SUFFIX
+changetype: add
objectClass: top
objectClass: cosTemplate
objectClass: extensibleobject
@@ -166,10 +175,12 @@ nsAccountLock: true
cosPriority: 1
dn: cn=inactivated,cn=account inactivation,cn=accounts,$SUFFIX
+changetype: add
objectclass: top
objectclass: groupofnames
dn: cn="cn=activated,cn=account inactivation,cn=accounts,$SUFFIX", cn=cosTemplates,cn=accounts,$SUFFIX
+changetype: add
objectClass: top
objectClass: cosTemplate
objectClass: extensibleobject
@@ -177,5 +188,6 @@ nsAccountLock: false
cosPriority: 0
dn: cn=Activated,cn=Account Inactivation,cn=accounts,$SUFFIX
+changetype: add
objectclass: top
objectclass: groupofnames
diff --git a/ipa-server/ipa-install/share/default-aci.ldif b/ipa-server/ipa-install/share/default-aci.ldif
index aac7272c6..b2c3f7980 100644
--- a/ipa-server/ipa-install/share/default-aci.ldif
+++ b/ipa-server/ipa-install/share/default-aci.ldif
@@ -1,20 +1,23 @@
# $SUFFIX (base entry)
+# FIXME: We need to allow truly anonymous access only to NIS data for older clients. We need to allow broad access to most attributes only to authewnticated users
dn: $SUFFIX
changetype: modify
replace: aci
-aci: (targetattr!="userPassword || krbPrincipalKey ||sambaLMPassword || sambaNTPassword")(version 3.0; acl "Enable anonymous access"; allow (read, search, compare) userdn="ldap:///anyone";)
-aci: (targetattr=*)(version 3.0; acl "Admin can manage any entry"; allow (all) userdn="ldap:///uid=admin,cn=sysaccounts,cn=etc,$SUFFIX";)
-aci: (targetattr="krbPrincipalName || krbUPEnabled || krbPrincipalKey || krbMKey || krbTicketPolicyReference || krbPrincipalExpiration || krbPasswordExpiration || krbPwdPolicyReference || krbPrincipalType || krbPwdHistory || krbLastPwdChange || krbPrincipalAliases || krbExtraData")(version 3.0; acl "KDC System Account"; allow (read, search, compare) userdn="ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
-aci: (targetattr="krbLastSuccessfulAuth || krbLastFailedAuth || krbLoginFailedCount")(version 3.0; acl "KDC System Account"; allow (read, search, compare, write) userdn="ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
-aci: (targetattr="userPassword || krbPrincipalKey ||sambaLMPassword || sambaNTPassword || krbPasswordExpiration || krbPwdHistory || krbLastPwdChange")(version 3.0; acl "Kpasswd access to passowrd hashes for passowrd changes"; allow (read, write) userdn="ldap:///krbprincipalname=kadmin/changepw@$REALM,cn=$REALM,cn=kerberos,$SUFFIX";)
-aci: (targetfilter="(|(objectClass=person)(objectClass=krbPrincipalAux)(objectClass=posixAccount)(objectClass=groupOfNames)(objectClass=posixGroup)(objectClass=radiusprofile))")(targetattr="*")(version 3.0; acl "Account Admins can manage Users and Groups"; allow (add,delete,read,write) groupdn="ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)
-aci: (targetattr = "givenName || sn || cn || displayName || initials || loginShell || homePhone || mobile || pager || facsimileTelephoneNumber || telephoneNumber || street || roomNumber || l || st || postalCode || manager || description || carLicense || labeledURI || inetUserHTTPURL || seeAlso || userPassword")(version 3.0;acl "Self service";allow (write) userdn="ldap:///self";)
-aci: (target="ldap:///cn=radius,cn=services,cn=etc,$SUFFIX")(version 3.0; acl "Only radius and admin can access radius service data"; deny (all) userdn!="ldap:///uid=admin,cn=sysaccounts,cn=etc,$SUFFIX || ldap:///krbprincipalname=radius/$FQDN@$REALM,cn=$REALM,cn=kerberos,$SUFFIX";)
+aci: (targetattr != "userPassword || krbPrincipalKey || krbMKey || sambaLMPassword || sambaNTPassword")(version 3.0; acl "Enable anonymous access"; allow (read, search, compare) userdn = "ldap:///anyone";)
+aci: (targetattr != "userPassword || krbPrincipalKey || krbMKey || sambaLMPassword || sambaNTPassword")(version 3.0; acl "Admin can manage any entry except for passwords"; allow (all) userdn = "ldap:///uid=admin,cn=sysaccounts,cn=etc,$SUFFIX";)
+aci: (targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword")(version 3.0; acl "Admin can write passwords"; allow (write) userdn="ldap:///uid=admin,cn=sysaccounts,cn=etc,$SUFFIX";)
+aci: (targetattr = "krbPrincipalName || krbUPEnabled || krbPrincipalKey || krbMKey || krbTicketPolicyReference || krbPrincipalExpiration || krbPasswordExpiration || krbPwdPolicyReference || krbPrincipalType || krbPwdHistory || krbLastPwdChange || krbPrincipalAliases || krbExtraData")(version 3.0; acl "KDC System Account has access to kerberos material"; allow (read, search, compare) userdn="ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
+aci: (targetattr = "krbLastSuccessfulAuth || krbLastFailedAuth || krbLoginFailedCount")(version 3.0; acl "KDC System Account can update some fields"; allow (read, search, compare, write) userdn="ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
+aci: (targetattr = "userPassword || krbPrincipalKey ||sambaLMPassword || sambaNTPassword || krbPasswordExpiration || krbPwdHistory || krbLastPwdChange")(version 3.0; acl "Kpasswd access to passowrd hashes for passowrd changes"; allow (read, write) userdn = "ldap:///krbprincipalname=kadmin/changepw@$REALM,cn=$REALM,cn=kerberos,$SUFFIX";)
+aci: (targetfilter = "(|(objectClass=person)(objectClass=krbPrincipalAux)(objectClass=posixAccount)(objectClass=groupOfNames)(objectClass=posixGroup)(objectClass=radiusprofile))")(targetattr != "aci")(version 3.0; acl "Account Admins can manage Users and Groups"; allow (add, delete, read, write) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)
+aci: (targetfilter = "(objectClass=krbPwdPolicy)")(targetattr = "krbMaxPwdLife || krbMinPwdLife || krbPwdMinDiffChars || krbPwdMinLength || krbPwdHistoryLength")(version 3.0;acl "Admins can write password policies"; allow (read, search, compare, write) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)
+aci: (targetattr = "givenName || sn || cn || displayName || initials || loginShell || homePhone || mobile || pager || facsimileTelephoneNumber || telephoneNumber || street || roomNumber || l || st || postalCode || manager || description || carLicense || labeledURI || inetUserHTTPURL || seeAlso")(version 3.0;acl "Self service";allow (write) userdn = "ldap:///self";)
+aci: (target="ldap:///cn=radius,$SUFFIX")(version 3.0; acl "Only radius and admin can access radius service data"; deny (all) userdn!="ldap:///uid=admin,cn=sysaccounts,cn=etc,$SUFFIX || ldap:///krbprincipalname=radius/$FQDN@$REALM,cn=$REALM,cn=kerberos,$SUFFIX";)
dn: cn=ipaConfig,cn=etc,$SUFFIX
changetype: modify
add: aci
-aci: (targetattr = "ipaUserSearchFields || ipaGroupSearchFields || ipaSearchTimeLimit || ipaSearchRecordsLimit || ipaCustomFields || ipaHomesRootDir || ipaDefaultLoginShell || ipaDefaultPrimaryGroup || ipaMaxUsernameLength || ipaPwdExpAdvNotify")(version 3.0;acl "Admins can write IPA policy"; allow (write) groupdn="ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)
+aci: (targetfilter = "(objectClass=ipaGuiConfig)")(targetattr != "aci")(version 3.0;acl "Admins can change GUI config"; allow (read, search, compare, write) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)
dn: cn=accounts,$SUFFIX
changetype: modify
@@ -24,4 +27,4 @@ aci: (targetattr = "krbMaxPwdLife || krbMinPwdLife || krbPwdMinDiffChars || krbP
dn: cn=services,cn=accounts,$SUFFIX
changetype: modify
add: aci
-aci: (targetattr="krbPrincipalName || krbUPEnabled || krbPrincipalKey || krbMKey || krbTicketPolicyReference || krbPrincipalExpiration || krbPasswordExpiration || krbPwdPolicyReference || krbPrincipalType || krbPwdHistory || krbLastPwdChange || krbPrincipalAliases || krbExtraData")(version 3.0; acl "KDC System Account"; allow (read, search, compare,write) userdn="ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
+aci: (targetattr="krbPrincipalName || krbUPEnabled || krbPrincipalKey || krbTicketPolicyReference || krbPrincipalExpiration || krbPasswordExpiration || krbPwdPolicyReference || krbPrincipalType || krbPwdHistory || krbLastPwdChange || krbPrincipalAliases || krbExtraData")(version 3.0; acl "KDC System Account"; allow (read, search, compare, write) userdn="ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
diff --git a/ipa-server/ipa-server.spec.in b/ipa-server/ipa-server.spec.in
index cfe9b8d79..874d82cfd 100644
--- a/ipa-server/ipa-server.spec.in
+++ b/ipa-server/ipa-server.spec.in
@@ -15,6 +15,7 @@ BuildRequires: openssl-devel
BuildRequires: openldap-devel
BuildRequires: krb5-devel
BuildRequires: nss-devel
+BuildRequires: libcap-devel
Requires: ipa-python
Requires: ipa-admintools
@@ -38,6 +39,7 @@ Requires: python-tgexpandingformwidget
Requires: acl
Requires: freeradius
Requires: pyasn1
+Requires: libcap
%define httpd_conf /etc/httpd/conf.d
%define plugin_dir %{_libdir}/dirsrv/plugins
diff --git a/ipa-server/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c b/ipa-server/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
index 558fdaea0..0d87b2ba2 100644
--- a/ipa-server/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
+++ b/ipa-server/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
@@ -93,11 +93,7 @@
/* OID of the extended operation handled by this plug-in */
#define EXOP_PASSWD_OID "1.3.6.1.4.1.4203.1.11.1"
-/* These are thye default enc:salt ypes if nothing is defined.
- * TODO: retrieve the configure set of ecntypes either from the
- * kfc.conf file or by synchronizing the the file content into
- * the directory */
-
+/* krbTicketFlags */
#define KTF_DISALLOW_POSTDATED 0x00000001
#define KTF_DISALLOW_FORWARDABLE 0x00000002
#define KTF_DISALLOW_TGT_BASED 0x00000004
@@ -111,6 +107,11 @@
#define KTF_DISALLOW_SVR 0x00001000
#define KTF_PWCHANGE_SERVICE 0x00002000
+/* These are the default enc:salt types if nothing is defined.
+ * TODO: retrieve the configure set of ecntypes either from the
+ * kfc.conf file or by synchronizing the the file content into
+ * the directory */
+
/* Salt types */
#define KRB5_KDB_SALTTYPE_NORMAL 0
#define KRB5_KDB_SALTTYPE_V4 1
@@ -1061,6 +1062,7 @@ static int ipapwd_CheckPolicy(struct ipapwd_data *data)
{
const char *krbPrincipalExpiration;
const char *krbLastPwdChange;
+ const char *krbPasswordExpiration;
int krbMaxPwdLife = IPAPWD_DEFAULT_PWDLIFE;
int krbPwdMinLength = IPAPWD_DEFAULT_MINLEN;
int krbPwdMinDiffChars = 0;
@@ -1105,6 +1107,7 @@ static int ipapwd_CheckPolicy(struct ipapwd_data *data)
goto no_policy;
}
+ krbPasswordExpiration = slapi_entry_attr_get_charptr(data->target, "krbPasswordExpiration");
krbLastPwdChange = slapi_entry_attr_get_charptr(data->target, "krbLastPwdChange");
/* if no previous change, it means this is probably a new account
* or imported, log and just ignore */
@@ -1138,9 +1141,17 @@ static int ipapwd_CheckPolicy(struct ipapwd_data *data)
/* if no default then treat it as no limit */
if (krbMinPwdLife != 0) {
- if (data->timeNow < data->lastPwChange + krbMinPwdLife) {
+ /* check for reset cases */
+ if (strcmp(krbPasswordExpiration, krbLastPwdChange) == 0) {
+ /* Expiration and last change time are the same
+ * this happens only when a password is reset by an admin
+ * or no expiration policy is set, PASS */
+ slapi_log_error(SLAPI_LOG_TRACE, "ipa_pwd_extop",
+ "ipapwd_checkPolicy: Ignore krbMinPwdLife Expiration and Last change dates match\n");
+
+ } else if (data->timeNow < data->lastPwChange + krbMinPwdLife) {
slapi_log_error(SLAPI_LOG_TRACE, "ipa_pwd_extop",
- "ipapwd_checkPassword: Too soon to change password\n");
+ "ipapwd_checkPolicy: Too soon to change password\n");
slapi_entry_free(policy);
return IPAPWD_POLICY_ERROR | LDAP_PWPOLICY_PWDTOOYOUNG;
}
@@ -1424,8 +1435,8 @@ static int ipapwd_SetPassword(struct ipapwd_data *data)
{
int ret = 0, i = 0;
Slapi_Mods *smods;
- Slapi_Value **svals;
- Slapi_Value **pwvals;
+ Slapi_Value **svals = NULL;
+ Slapi_Value **pwvals = NULL;
struct tm utctime;
char timestr[GENERALIZED_TIME_LENGTH+1];
krb5_context krbctx;
@@ -1608,17 +1619,6 @@ static int ipapwd_extop(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_TRACE, "ipa_pwd_extop", "=> ipapwd_extop\n");
- /* make sure we have the master key */
- if (ipa_kmkey == NULL) {
- ret = ipapwd_getMasterKey(ipa_realm_dn);
- if (ret != LDAP_SUCCESS) {
- errMesg = "Fatal Internal Error Retrieving Master Key";
- rc = LDAP_OPERATIONS_ERROR;
- slapi_log_error( SLAPI_LOG_PLUGIN, "ipa_pwd_extop", errMesg );
- goto free_and_return;
- }
- }
-
/* Before going any further, we'll make sure that the right extended operation plugin
* has been called: i.e., the OID shipped whithin the extended operation request must
* match this very plugin's OID: EXOP_PASSWD_OID. */
@@ -1641,9 +1641,19 @@ static int ipapwd_extop(Slapi_PBlock *pb)
slapi_log_error( SLAPI_LOG_PLUGIN, "ipa_pwd_extop",
"Password Modify extended operation request confirmed.\n" );
}
-
/* Now , at least we know that the request was indeed a Password Modify one. */
+ /* make sure we have the master key */
+ if (ipa_kmkey == NULL) {
+ ret = ipapwd_getMasterKey(ipa_realm_dn);
+ if (ret != LDAP_SUCCESS) {
+ errMesg = "Fatal Internal Error Retrieving Master Key";
+ rc = LDAP_OPERATIONS_ERROR;
+ slapi_log_error( SLAPI_LOG_PLUGIN, "ipa_pwd_extop", errMesg );
+ goto free_and_return;
+ }
+ }
+
#ifdef LDAP_EXTOP_PASSMOD_CONN_SECURE
/* Allow password modify only for SSL/TLS established connections and
* connections using SASL privacy layers */
@@ -1824,7 +1834,7 @@ parse_req_done:
slapi_pblock_set(pb, SLAPI_BACKEND, be);
}
- ret = slapi_access_allowed ( pb, targetEntry, SLAPI_USERPWD_ATTR, NULL, SLAPI_ACL_WRITE );
+ ret = slapi_access_allowed ( pb, targetEntry, "krbPrincipalKey", NULL, SLAPI_ACL_WRITE );
if ( ret != LDAP_SUCCESS ) {
errMesg = "Insufficient access rights\n";
rc = LDAP_INSUFFICIENT_ACCESS;
@@ -2140,7 +2150,6 @@ static int ipapwd_start( Slapi_PBlock *pb )
/*retrieve the master key from the stash file */
if (slapi_pblock_get(pb, SLAPI_TARGET_DN, &config_dn) != 0) {
slapi_log_error( SLAPI_LOG_FATAL, "ipapwd_start", "No config DN?\n");
- krb5_free_context(krbctx);
free(keysalts);
free(realm);
return LDAP_OPERATIONS_ERROR;
@@ -2148,7 +2157,6 @@ static int ipapwd_start( Slapi_PBlock *pb )
if (ipapwd_getEntry(config_dn, &config_entry, NULL) != LDAP_SUCCESS) {
slapi_log_error( SLAPI_LOG_FATAL, "ipapwd_start", "No config Entry?\n");
- krb5_free_context(krbctx);
free(keysalts);
free(realm);
return LDAP_OPERATIONS_ERROR;
@@ -2208,7 +2216,7 @@ int ipapwd_init( Slapi_PBlock *pb )
slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN, (void *) ipapwd_start ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_FN, (void *) ipapwd_extop ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_OIDLIST, ipapwd_oid_list ) != 0 ||
- slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_NAMELIST, ipapwd_name_list ) != 0 ) {
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_NAMELIST, ipapwd_name_list ) != 0) {
slapi_log_error( SLAPI_LOG_PLUGIN, "ipapwd_init",
"Failed to set plug-in version, function, and OID.\n" );
diff --git a/ipa-server/ipa-slapi-plugins/ipa-pwd-extop/pwd-extop-conf.ldif b/ipa-server/ipa-slapi-plugins/ipa-pwd-extop/pwd-extop-conf.ldif
index efd80ccf5..e31a8e79b 100644
--- a/ipa-server/ipa-slapi-plugins/ipa-pwd-extop/pwd-extop-conf.ldif
+++ b/ipa-server/ipa-slapi-plugins/ipa-pwd-extop/pwd-extop-conf.ldif
@@ -8,7 +8,7 @@ nsslapd-pluginpath: libipa_pwd_extop
nsslapd-plugininitfunc: ipapwd_init
nsslapd-plugintype: extendedop
nsslapd-pluginenabled: on
-nsslapd-pluginid: Multi-hash Change Password Extended Operation
+nsslapd-pluginid: ipa_pwd_extop
nsslapd-pluginversion: 1.0
nsslapd-pluginvendor: RedHat
nsslapd-plugindescription: Support saving passwords in multiple formats for different consumers (krb5, samba, freeradius, etc.)
diff --git a/ipa-server/ipaserver/dsinstance.py b/ipa-server/ipaserver/dsinstance.py
index 79a57182f..8735ebdaa 100644
--- a/ipa-server/ipaserver/dsinstance.py
+++ b/ipa-server/ipaserver/dsinstance.py
@@ -29,7 +29,6 @@ import sys
from ipa.ipautil import *
import service
-
import installutils
SERVER_ROOT_64 = "/usr/lib64/dirsrv"
@@ -188,7 +187,7 @@ class DsInstance(service.Service):
try:
run(args)
logging.debug("done adding user")
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
logging.critical("failed to add user %s" % e)
def __create_instance(self):
@@ -206,13 +205,13 @@ class DsInstance(service.Service):
try:
run(args)
logging.debug("completed creating ds instance")
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
logging.critical("failed to restart ds instance %s" % e)
logging.debug("restarting ds instance")
try:
self.restart()
logging.debug("done restarting ds instance")
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
print "failed to restart ds instance", e
logging.debug("failed to restart ds instance %s" % e)
@@ -233,7 +232,7 @@ class DsInstance(service.Service):
memberof_fd = write_tmp_file(memberof_txt)
try:
ldap_mod(memberof_fd, "cn=Directory Manager", self.dm_password)
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
logging.critical("Failed to load memberof-conf.ldif: %s" % str(e))
memberof_fd.close()
@@ -243,7 +242,7 @@ class DsInstance(service.Service):
memberof_fd = write_tmp_file(memberof_txt)
try:
ldap_mod(memberof_fd, "cn=Directory Manager", self.dm_password)
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
logging.critical("Failed to load memberof-conf.ldif: %s" % str(e))
memberof_fd.close()
@@ -253,7 +252,7 @@ class DsInstance(service.Service):
referint_fd = write_tmp_file(referint_txt)
try:
ldap_mod(referint_fd, "cn=Directory Manager", self.dm_password)
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
print "Failed to load referint-conf.ldif", e
referint_fd.close()
@@ -263,7 +262,7 @@ class DsInstance(service.Service):
dna_fd = write_tmp_file(dna_txt)
try:
ldap_mod(dna_fd, "cn=Directory Manager", self.dm_password)
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
print "Failed to load dna-conf.ldif", e
dna_fd.close()
@@ -273,7 +272,7 @@ class DsInstance(service.Service):
dna_fd = write_tmp_file(dna_txt)
try:
ldap_mod(dna_fd, "cn=Directory Manager", self.dm_password)
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
print "Failed to configure Posix uid/gid generation with dna-posix.ldif", e
dna_fd.close()
@@ -283,7 +282,7 @@ class DsInstance(service.Service):
master_fd = write_tmp_file(master_txt)
try:
ldap_mod(master_fd, "cn=Directory Manager", self.dm_password)
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
print "Failed to add master-entry.ldif", e
master_fd.close()
@@ -295,7 +294,7 @@ class DsInstance(service.Service):
try:
run(args)
logging.debug("done configuring ssl for ds instance")
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
logging.critical("Failed to configure ssl in ds instance %s" % e)
def __add_default_layout(self):
@@ -308,7 +307,7 @@ class DsInstance(service.Service):
try:
run(args)
logging.debug("done adding default ds layout")
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
print "Failed to add default ds layout", e
logging.critical("Failed to add default ds layout %s" % e)
@@ -322,7 +321,7 @@ class DsInstance(service.Service):
try:
run(args)
logging.debug("done adding/updating indeces")
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
logging.critical("Failed to add/update indeces %s" % str(e))
def __certmap_conf(self):
@@ -347,7 +346,7 @@ class DsInstance(service.Service):
try:
run(args)
logging.debug("ldappasswd done")
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
print "Unable to set admin password", e
logging.debug("Unable to set admin password %s" % e)
diff --git a/ipa-server/ipaserver/httpinstance.py b/ipa-server/ipaserver/httpinstance.py
index 60d33eedc..301035130 100644
--- a/ipa-server/ipaserver/httpinstance.py
+++ b/ipa-server/ipaserver/httpinstance.py
@@ -86,7 +86,7 @@ class HTTPInstance(service.Service):
if (os.path.exists('/usr/sbin/selinuxenabled')):
run(["/usr/sbin/selinuxenabled"])
selinux=1
- except subprocess.CalledProcessError:
+ except ipautil.CalledProcessError:
# selinuxenabled returns 1 if not enabled
pass
diff --git a/ipa-server/ipaserver/krbinstance.py b/ipa-server/ipaserver/krbinstance.py
index c83002f73..ede008a83 100644
--- a/ipa-server/ipaserver/krbinstance.py
+++ b/ipa-server/ipaserver/krbinstance.py
@@ -33,7 +33,6 @@ import time
import shutil
import service
-from ipa.ipautil import *
from ipa import ipaerror
import ipaldap
@@ -47,6 +46,7 @@ import pyasn1.codec.ber.encoder
import pyasn1.codec.ber.decoder
import struct
import base64
+from ipa.ipautil import *
def host_to_domain(fqdn):
s = fqdn.split(".")
@@ -89,7 +89,7 @@ class KrbInstance(service.Service):
self.host = host_name.split(".")[0]
self.ip = socket.gethostbyname(host_name)
self.domain = host_to_domain(host_name)
- self.suffix = realm_to_suffix(self.realm)
+ self.suffix = realm_to_suffix(self.realm)
self.kdc_password = ipa_generate_password()
self.admin_password = admin_password
@@ -133,7 +133,7 @@ class KrbInstance(service.Service):
self.start_creation(11, "Configuring Kerberos KDC")
- self.__configure_kdc_account_password()
+ self.__configure_kdc_account_password()
self.__configure_sasl_mappings()
self.__add_krb_entries()
self.__create_instance()
@@ -245,7 +245,7 @@ class KrbInstance(service.Service):
kerberos_fd = write_tmp_file(kerberos_txt)
try:
ldap_mod(kerberos_fd, "cn=Directory Manager", self.admin_password)
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
logging.critical("Failed to load kerberos.ldif: %s" % str(e))
kerberos_fd.close()
@@ -254,7 +254,7 @@ class KrbInstance(service.Service):
aci_fd = write_tmp_file(aci_txt)
try:
ldap_mod(aci_fd, "cn=Directory Manager", self.admin_password)
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
logging.critical("Failed to load default-aci.ldif: %s" % str(e))
aci_fd.close()
@@ -291,7 +291,7 @@ class KrbInstance(service.Service):
args = ["/usr/kerberos/sbin/kdb5_ldap_util", "-D", "uid=kdc,cn=sysaccounts,cn=etc,"+self.suffix, "-w", self.kdc_password, "create", "-s", "-P", self.master_password, "-r", self.realm, "-subtrees", self.suffix, "-sscope", "sub"]
try:
run(args)
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
print "Failed to populate the realm structure in kerberos", e
def __write_stash_from_ds(self):
@@ -322,7 +322,7 @@ class KrbInstance(service.Service):
extop_fd = write_tmp_file(extop_txt)
try:
ldap_mod(extop_fd, "cn=Directory Manager", self.admin_password)
- except subprocess.CalledProcessError, e:
+ except ipautil.CalledProcessError, e:
logging.critical("Failed to load pwd-extop-conf.ldif: %s" % str(e))
extop_fd.close()
diff --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py
index 3be619895..4e527dad5 100644
--- a/ipa-server/xmlrpc-server/funcs.py
+++ b/ipa-server/xmlrpc-server/funcs.py
@@ -332,7 +332,7 @@ class IPAServer:
# Higher-level API
- def get_aci_entry(self, sattrs=None, opts=None):
+ def get_aci_entry(self, sattrs, opts=None):
"""Returns the entry containing access control ACIs."""
dn="%s,%s" % (ACIContainer, self.basedn)
@@ -340,7 +340,7 @@ class IPAServer:
# General searches
- def get_entry_by_dn (self, dn, sattrs=None, opts=None):
+ def get_entry_by_dn (self, dn, sattrs, opts=None):
"""Get a specific entry. Return as a dict of values.
Multi-valued fields are represented as lists.
"""
@@ -348,7 +348,7 @@ class IPAServer:
filter = "(objectClass=*)"
return self.__get_base_entry(dn, filter, sattrs, opts)
- def get_entry_by_cn (self, cn, sattrs=None, opts=None):
+ def get_entry_by_cn (self, cn, sattrs, opts=None):
"""Get a specific entry by cn. Return as a dict of values.
Multi-valued fields are represented as lists.
"""
@@ -374,7 +374,7 @@ class IPAServer:
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
return 1
- def get_user_by_uid (self, uid, sattrs=None, opts=None):
+ def get_user_by_uid (self, uid, sattrs, opts=None):
"""Get a specific user's entry. Return as a dict of values.
Multi-valued fields are represented as lists.
"""
@@ -383,7 +383,7 @@ class IPAServer:
filter = "(uid=" + uid + ")"
return self.__get_sub_entry(self.basedn, filter, sattrs, opts)
- def get_user_by_principal(self, principal, sattrs=None, opts=None):
+ def get_user_by_principal(self, principal, sattrs, opts=None):
"""Get a user entry searching by Kerberos Principal Name.
Return as a dict of values. Multi-valued fields are
represented as lists.
@@ -392,7 +392,7 @@ class IPAServer:
filter = "(krbPrincipalName="+self.__safe_filter(principal)+")"
return self.__get_sub_entry(self.basedn, filter, sattrs, opts)
- def get_user_by_email (self, email, sattrs=None, opts=None):
+ def get_user_by_email (self, email, sattrs, opts=None):
"""Get a specific user's entry. Return as a dict of values.
Multi-valued fields are represented as lists.
"""
@@ -401,7 +401,7 @@ class IPAServer:
filter = "(mail=" + email + ")"
return self.__get_sub_entry(self.basedn, filter, sattrs, opts)
- def get_users_by_manager (self, manager_dn, sattrs=None, opts=None):
+ def get_users_by_manager (self, manager_dn, sattrs, opts=None):
"""Gets the users that report to a particular manager.
"""
@@ -413,12 +413,12 @@ class IPAServer:
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
return []
- def add_user (self, user, user_container=None, opts=None):
+ def add_user (self, user, user_container, opts=None):
"""Add a user in LDAP. Takes as input a dict where the key is the
attribute name and the value is either a string or in the case
of a multi-valued field a list of values. user_container sets
where in the tree the user is placed."""
- if user_container is None:
+ if not user_container:
user_container = DefaultUserContainer
if self.__is_user_unique(user['uid'], opts) == 0:
@@ -738,7 +738,7 @@ class IPAServer:
return self.update_entry(config, new_config, opts)
- def get_all_users (self, args=None, opts=None):
+ def get_all_users (self, opts=None):
"""Return a list containing a User object for each
existing user.
"""
@@ -756,7 +756,7 @@ class IPAServer:
return users
- def find_users (self, criteria, sattrs=None, searchlimit=-1, timelimit=-1,
+ def find_users (self, criteria, sattrs, searchlimit=-1, timelimit=-1,
opts=None):
"""Returns a list: counter followed by the results.
If the results are truncated, counter will be set to -1."""
@@ -1002,7 +1002,7 @@ class IPAServer:
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
return 1
- def get_groups_by_member (self, member_dn, sattrs=None, opts=None):
+ def get_groups_by_member (self, member_dn, sattrs, opts=None):
"""Get a specific group's entry. Return as a dict of values.
Multi-valued fields are represented as lists.
"""
@@ -1015,12 +1015,12 @@ class IPAServer:
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
return []
- def add_group (self, group, group_container=None, opts=None):
+ def add_group (self, group, group_container, opts=None):
"""Add a group in LDAP. Takes as input a dict where the key is the
attribute name and the value is either a string or in the case
of a multi-valued field a list of values. group_container sets
where in the tree the group is placed."""
- if group_container is None:
+ if not group_container:
group_container = DefaultGroupContainer
if self.__is_group_unique(group['cn'], opts) == 0:
@@ -1047,7 +1047,7 @@ class IPAServer:
finally:
self.releaseConnection(conn)
- def find_groups (self, criteria, sattrs=None, searchlimit=-1, timelimit=-1,
+ def find_groups (self, criteria, sattrs, searchlimit=-1, timelimit=-1,
opts=None):
"""Return a list containing a User object for each
existing group that matches the criteria.
@@ -1396,6 +1396,16 @@ class IPAServer:
if group is None:
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
+ # We have 2 special groups, don't allow them to be removed
+ if "admins" in group.get('cn') or "editors" in group.get('cn'):
+ raise ipaerror.gen_exception(ipaerror.CONFIG_REQUIRED_GROUPS)
+
+ # Don't allow the default user group to be removed
+ config=self.get_ipa_config(opts)
+ default_group = self.get_entry_by_cn(config.get('ipadefaultprimarygroup'), None, opts)
+ if group_dn == default_group.get('dn'):
+ raise ipaerror.gen_exception(ipaerror.CONFIG_DEFAULT_GROUP)
+
conn = self.getConnection(opts)
try:
res = conn.deleteEntry(group_dn)
@@ -1455,11 +1465,12 @@ class IPAServer:
conn = self.getConnection(opts)
try:
- results = conn.getListAsync(self.basedn, self.scope,
- filter, attr_list, 0, None, None, timelimit,
- searchlimit)
- except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
- results = [0]
+ try:
+ results = conn.getListAsync(self.basedn, self.scope,
+ filter, attr_list, 0, None, None, timelimit,
+ searchlimit)
+ except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
+ results = [0]
finally:
self.releaseConnection(conn)
@@ -1565,14 +1576,22 @@ class IPAServer:
# The LDAP routines want strings, not ints, so convert a few
# things. Otherwise it sees a string -> int conversion as a change.
try:
- newconfig['krbmaxpwdlife'] = str(newconfig.get('krbmaxpwdlife'))
- newconfig['krbminpwdlife'] = str(newconfig.get('krbminpwdlife'))
- newconfig['krbpwdmindiffchars'] = str(newconfig.get('krbpwdmindiffchars'))
- newconfig['krbpwdminlength'] = str(newconfig.get('krbpwdminlength'))
- newconfig['krbpwdhistorylength'] = str(newconfig.get('krbpwdhistorylength'))
+ newconfig['ipapwdexpadvnotify'] = str(newconfig.get('ipapwdexpadvnotify'))
+ newconfig['ipasearchtimelimit'] = str(newconfig.get('ipasearchtimelimit'))
+ newconfig['ipasearchrecordslimit'] = str(newconfig.get('ipasearchrecordslimit'))
+ newconfig['ipamaxusernamelength'] = str(newconfig.get('ipamaxusernamelength'))
except KeyError:
# These should all be there but if not, let things proceed
pass
+
+ # Ensure that the default group for users exists
+ try:
+ group = self.get_entry_by_cn(newconfig.get('ipadefaultprimarygroup'), None, opts)
+ except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
+ raise
+ except:
+ raise
+
return self.update_entry(oldconfig, newconfig, opts)
def get_password_policy(self, opts=None):
@@ -1582,6 +1601,10 @@ class IPAServer:
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
raise ipaerror.gen_exception(ipaerror.LDAP_NO_CONFIG)
+ # convert some values for display purposes
+ policy['krbmaxpwdlife'] = str(int(policy.get('krbmaxpwdlife')) / 86400)
+ policy['krbminpwdlife'] = str(int(policy.get('krbminpwdlife')) / 3600)
+
return policy
def update_password_policy(self, oldpolicy, newpolicy, opts=None):
@@ -1590,14 +1613,24 @@ class IPAServer:
# The LDAP routines want strings, not ints, so convert a few
# things. Otherwise it sees a string -> int conversion as a change.
try:
- newpolicy['krbmaxpwdlife'] = str(newpolicy.get('krbmaxpwdlife'))
- newpolicy['krbminpwdlife'] = str(newpolicy.get('krbminpwdlife'))
- newpolicy['krbpwdhistorylength'] = str(newpolicy.get('krbpwdhistorylength'))
- newpolicy['krbpwdmindiffchars'] = str(newpolicy.get('krbpwdmindiffchars'))
- newpolicy['krbpwdminlength'] = str(newpolicy.get('krbpwdminlength'))
+ for k in oldpolicy.iterkeys():
+ if k.startswith("krb", 0, 3):
+ oldpolicy[k] = str(oldpolicy[k])
+ for k in newpolicy.iterkeys():
+ if k.startswith("krb", 0, 3):
+ newpolicy[k] = str(newpolicy[k])
+
+ # Convert hours and days to seconds
+ oldpolicy['krbmaxpwdlife'] = str(int(oldpolicy.get('krbmaxpwdlife')) * 86400)
+ oldpolicy['krbminpwdlife'] = str(int(oldpolicy.get('krbminpwdlife')) * 3600)
+ newpolicy['krbmaxpwdlife'] = str(int(newpolicy.get('krbmaxpwdlife')) * 86400)
+ newpolicy['krbminpwdlife'] = str(int(newpolicy.get('krbminpwdlife')) * 3600)
except KeyError:
# These should all be there but if not, let things proceed
pass
+ except:
+ # Anything else raise an error
+ raise
return self.update_entry(oldpolicy, newpolicy, opts)