On Tue, 2015-11-24 at 14:57 -0500, Simo Sorce wrote:
> On Tue, 2015-11-24 at 14:42 -0500, Simo Sorce wrote:
> > Since some time we use the getkeytab operation to fetch keytabs on newer
> > clients. According to bug #232 setkeytab can be used to circumvent
> > password quality controls so it needs to be slowly retired.
> > 
> > The attached patches implement #5485 in 2 parts.
> > 
> > The first introduces the option DisableSetKeytab which globally disables
> > the setkeytab extended operation. This is set to false by default for
> > backwards compatibility.
> > 
> > The second introduces an option called DisableUserSetKeytab, which is
> > active by default in new installs (but not in upgraded ones), and only
> > disables the use of setkeytab for ipa suers, but not for hosts/services.
> > This is because user's are the ones that may abuse the interface to
> > escape password policies and users also normally do not acquire keytabs,
> > so it is a safe bet to disable just them by default in new installs.
> > 
> > (Testing in progress)
> 
> Tested and working as expected.

I realized that adding options to ipaConfig require to add them in the
UI as well, attached patches add options in API.txt and config.py
Make now complain I should change API Major or Minor, but it is not
clear to me why given this are additional values and no real change or
new function is introduced. What's the recommendation ?

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York
From 417f423d6f0786f3bb7a5284577548cdf117f6e2 Mon Sep 17 00:00:00 2001
From: Simo Sorce <s...@redhat.com>
Date: Tue, 24 Nov 2015 13:42:10 -0500
Subject: [PATCH 1/3] Introduce option to disable the SetKeytab exop

If DisableSetKeytab is set in ipaConfig options then setkeytab will not be
available. The default is still to allow this operation for backwards
compatibility towards older clients that do not know how to use the new
GetKeytab extended operation.

Signed-off-by: Simo Sorce <s...@redhat.com>

Ticket: https://fedorahosted.org/freeipa/ticket/5485
---
 API.txt                                                 | 2 +-
 daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c        | 4 ++++
 daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c | 5 +++++
 daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h        | 1 +
 ipalib/plugins/config.py                                | 1 +
 5 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/API.txt b/API.txt
index 0976c97213775d79da43ee382a0badbe029b7960..763ec12413fc1267b2cf7f519cf8c9bc14360c8c 100644
--- a/API.txt
+++ b/API.txt
@@ -766,7 +766,7 @@ args: 0,25,3
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('delattr*', cli_name='delattr', exclude='webui')
-option: StrEnum('ipaconfigstring', attribute=True, autofill=False, cli_name='ipaconfigstring', csv=True, multivalue=True, required=False, values=(u'AllowNThash', u'KDC:Disable Last Success', u'KDC:Disable Lockout'))
+option: StrEnum('ipaconfigstring', attribute=True, autofill=False, cli_name='ipaconfigstring', csv=True, multivalue=True, required=False, values=(u'AllowNThash', u'DisableSetKeytab', u'KDC:Disable Last Success', u'KDC:Disable Lockout'))
 option: Str('ipadefaultemaildomain', attribute=True, autofill=False, cli_name='emaildomain', multivalue=False, required=False)
 option: Str('ipadefaultloginshell', attribute=True, autofill=False, cli_name='defaultshell', multivalue=False, required=False)
 option: Str('ipadefaultprimarygroup', attribute=True, autofill=False, cli_name='defaultgroup', multivalue=False, required=False)
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c
index 5dc606d22305cf63a16feca30aab2728bb20b80d..f79c0b4a6652773807a6bad388a5a857ab321755 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c
@@ -232,6 +232,7 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
 
     /* get the ipa etc/ipaConfig entry */
     config->allow_nt_hash = false;
+    config->disable_setkeytab = false;
     ret = ipapwd_getEntry(ipa_etc_config_dn, &config_entry, NULL);
     if (ret != LDAP_SUCCESS) {
         LOG_FATAL("No config Entry?\n");
@@ -243,6 +244,9 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
             if (strcasecmp(tmparray[i], "AllowNThash") == 0) {
                 config->allow_nt_hash = true;
                 continue;
+            } else if (strcasecmp(tmparray[i], "DisableSetKeytab") == 0) {
+                config->disable_setkeytab = true;
+                continue;
             }
         }
         if (tmparray) slapi_ch_array_free(tmparray);
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
index dc657cc4ebff987cde9d9ab07704ba171d650194..aa45ed3e79ca3d488fd4f3aac6c16370e98e3ed6 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
@@ -1742,6 +1742,11 @@ static int ipapwd_extop(Slapi_PBlock *pb)
 		return ret;
 	}
 	if (strcasecmp(oid, KEYTAB_SET_OID) == 0) {
+            if (krbcfg->disable_setkeytab) {
+                errMesg = "Operation administratively disabled.\n";
+                rc = LDAP_UNWILLING_TO_PERFORM;
+                goto free_and_return;
+            }
 		ret = ipapwd_setkeytab(pb, krbcfg);
 		free_ipapwd_krbcfg(&krbcfg);
 		return ret;
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h
index 2e9d4fe86b34c64731728882db7c81e3871d7d07..a6a85d78d1fc76715dd20715424fc4cab98fd426 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h
@@ -109,6 +109,7 @@ struct ipapwd_krbcfg {
     char **passsync_mgrs;
     int num_passsync_mgrs;
     bool allow_nt_hash;
+    bool disable_setkeytab;
 };
 
 int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
diff --git a/ipalib/plugins/config.py b/ipalib/plugins/config.py
index 86b7ca863bcc90ff329a85588f2f33a705162a9d..ce7966bf5115229e19bbecb1df4b9f8968292b50 100644
--- a/ipalib/plugins/config.py
+++ b/ipalib/plugins/config.py
@@ -201,6 +201,7 @@ class config(LDAPObject):
             label=_('Password plugin features'),
             doc=_('Extra hashes to generate in password plug-in'),
             values=(u'AllowNThash',
+                    u'DisableSetKeytab',
                     u'KDC:Disable Last Success', u'KDC:Disable Lockout'),
             csv=True,
         ),
-- 
2.5.0

From 8d79dd7e287509359c97897582ae3d1ce52ed92a Mon Sep 17 00:00:00 2001
From: Simo Sorce <s...@redhat.com>
Date: Tue, 24 Nov 2015 14:02:01 -0500
Subject: [PATCH 2/3] Disable User's ability to use the setkeytab exop.

Users can still obtain a keytab for themselves using the getkeytab exop
which does not circumvent password policy checks.

Users are disallowed from using setkeytab by default in new installations
but not in existing installations (no forced upgrade).

Signed-off-by: Simo Sorce <s...@redhat.com>

Ticket: https://fedorahosted.org/freeipa/ticket/5485
---
 API.txt                                                |  2 +-
 daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c       |  4 ++++
 .../ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c    | 18 +++++++++++++++++-
 daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h       |  1 +
 install/share/bootstrap-template.ldif                  |  1 +
 ipalib/plugins/config.py                               |  2 +-
 6 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/API.txt b/API.txt
index 763ec12413fc1267b2cf7f519cf8c9bc14360c8c..9a7a23f0d6e3efcdaa355e15a37e8879d8f030d7 100644
--- a/API.txt
+++ b/API.txt
@@ -766,7 +766,7 @@ args: 0,25,3
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('delattr*', cli_name='delattr', exclude='webui')
-option: StrEnum('ipaconfigstring', attribute=True, autofill=False, cli_name='ipaconfigstring', csv=True, multivalue=True, required=False, values=(u'AllowNThash', u'DisableSetKeytab', u'KDC:Disable Last Success', u'KDC:Disable Lockout'))
+option: StrEnum('ipaconfigstring', attribute=True, autofill=False, cli_name='ipaconfigstring', csv=True, multivalue=True, required=False, values=(u'AllowNThash', u'DisableSetKeytab', u'DisableUserSetKeytab', u'KDC:Disable Last Success', u'KDC:Disable Lockout'))
 option: Str('ipadefaultemaildomain', attribute=True, autofill=False, cli_name='emaildomain', multivalue=False, required=False)
 option: Str('ipadefaultloginshell', attribute=True, autofill=False, cli_name='defaultshell', multivalue=False, required=False)
 option: Str('ipadefaultprimarygroup', attribute=True, autofill=False, cli_name='defaultgroup', multivalue=False, required=False)
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c
index f79c0b4a6652773807a6bad388a5a857ab321755..9a56176741896d197201ed4bbd16c83ffb3c208c 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c
@@ -233,6 +233,7 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
     /* get the ipa etc/ipaConfig entry */
     config->allow_nt_hash = false;
     config->disable_setkeytab = false;
+    config->disable_user_setkeytab = false;
     ret = ipapwd_getEntry(ipa_etc_config_dn, &config_entry, NULL);
     if (ret != LDAP_SUCCESS) {
         LOG_FATAL("No config Entry?\n");
@@ -247,6 +248,9 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
             } else if (strcasecmp(tmparray[i], "DisableSetKeytab") == 0) {
                 config->disable_setkeytab = true;
                 continue;
+            } else if (strcasecmp(tmparray[i], "DisableUserSetKeytab") == 0) {
+                config->disable_user_setkeytab = true;
+                continue;
             }
         }
         if (tmparray) slapi_ch_array_free(tmparray);
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
index aa45ed3e79ca3d488fd4f3aac6c16370e98e3ed6..a910625cea711ca8c564f3c547a1d61788b071be 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
@@ -661,7 +661,7 @@ static Slapi_Entry *get_entry_by_principal(const char *principal)
     Slapi_PBlock *pb = NULL;
     char *attrlist[] = { "krbPrincipalKey", "krbLastPwdChange",
                          "userPassword", "krbPrincipalName",
-                         "enrolledBy", NULL };
+                         "enrolledBy", "objectClass", NULL };
     Slapi_Entry **es = NULL;
     int res, ret, i;
     Slapi_Entry *entry = NULL;
@@ -1217,6 +1217,22 @@ static int ipapwd_setkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
         goto free_and_return;
     }
 
+    /* Check if setkeytab is disabled for users */
+    if (krbcfg->disable_user_setkeytab) {
+        Slapi_Value *val;
+
+        val = slapi_value_new_string("person");
+        rc = slapi_entry_attr_has_syntax_value(targetEntry,
+                                               "objectClass", val);
+        slapi_value_free(&val);
+
+        if (rc == 1) {
+            errMesg = "Operation administratively disabled.\n";
+            rc = LDAP_UNWILLING_TO_PERFORM;
+            goto free_and_return;
+        }
+    }
+
     /* Accesseck strategy:
      * If the user has WRITE access, a new keytab can be set on the entry.
      * If not, then we fail immediately with insufficient access. This
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h
index a6a85d78d1fc76715dd20715424fc4cab98fd426..36366949633ab5faf331991f0e1994f7432b2f38 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h
@@ -110,6 +110,7 @@ struct ipapwd_krbcfg {
     int num_passsync_mgrs;
     bool allow_nt_hash;
     bool disable_setkeytab;
+    bool disable_user_setkeytab;
 };
 
 int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
diff --git a/install/share/bootstrap-template.ldif b/install/share/bootstrap-template.ldif
index 357062780c5011f477a592af4422bb77466472a8..797fce22e6fe6ceb15f2fd4895afd45846317099 100644
--- a/install/share/bootstrap-template.ldif
+++ b/install/share/bootstrap-template.ldif
@@ -387,6 +387,7 @@ ipaUserObjectClasses: ipasshuser
 ipaDefaultEmailDomain: $DOMAIN
 ipaMigrationEnabled: FALSE
 ipaConfigString: AllowNThash
+ipaConfigString: DisableUserSetKeytab
 ipaSELinuxUserMapOrder: guest_u:s0$$xguest_u:s0$$user_u:s0$$staff_u:s0-s0:c0.c1023$$unconfined_u:s0-s0:c0.c1023
 ipaSELinuxUserMapDefault: unconfined_u:s0-s0:c0.c1023
 
diff --git a/ipalib/plugins/config.py b/ipalib/plugins/config.py
index ce7966bf5115229e19bbecb1df4b9f8968292b50..a6b4d4349a9ac6de453d9ad3c679ec32add4e43b 100644
--- a/ipalib/plugins/config.py
+++ b/ipalib/plugins/config.py
@@ -201,7 +201,7 @@ class config(LDAPObject):
             label=_('Password plugin features'),
             doc=_('Extra hashes to generate in password plug-in'),
             values=(u'AllowNThash',
-                    u'DisableSetKeytab',
+                    u'DisableSetKeytab', u'DisableUserSetKeytab',
                     u'KDC:Disable Last Success', u'KDC:Disable Lockout'),
             csv=True,
         ),
-- 
2.5.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to