[Freeipa-devel] [PATCH] 75-78 Add fallback group

Sumit Bose sbose at redhat.com
Tue Oct 2 19:29:01 UTC 2012


Hi,

this patch should fix https://fedorahosted.org/freeipa/ticket/2955 by
adding a fallback group as described in comment 2 of the ticket in
ipa-adtrust-install.

If you prefer to use a different kind of group I can change the patch
accordingly.

bye,
Sumit
-------------- next part --------------
From 9cb3514cd7c73810ce4b5dceb82d36b739124854 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 18 Sep 2012 11:32:10 +0200
Subject: [PATCH 75/78] ipa-adtrust-install: Add fallback group

---
 ipaserver/install/adtrustinstance.py | 79 ++++++++++++++++++++++++++++++------
 1 Datei ge?ndert, 67 Zeilen hinzugef?gt(+), 12 Zeilen entfernt(-)

diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py
index c44037754dfd74cf6a9ceda4c9f4d2a6a224b1ea..1aebdad3ce8169952489d2ddce8f19917635b5e8 100644
--- a/ipaserver/install/adtrustinstance.py
+++ b/ipaserver/install/adtrustinstance.py
@@ -96,9 +96,11 @@ class ADTRUSTInstance(service.Service):
     ATTR_SID = "ipaNTSecurityIdentifier"
     ATTR_FLAT_NAME = "ipaNTFlatName"
     ATTR_GUID = "ipaNTDomainGUID"
+    ATTR_FALLBACK_GROUP = "ipaNTFallbackPrimaryGroup"
     OBJC_USER = "ipaNTUserAttrs"
     OBJC_GROUP = "ipaNTGroupAttrs"
     OBJC_DOMAIN = "ipaNTDomainAttrs"
+    FALLBACK_GROUP_NAME = u'fallback_primary_group'
 
     def __init__(self, fstore=None):
         self.fqdn = None
@@ -134,6 +136,18 @@ class ADTRUSTInstance(service.Service):
         return "S-1-5-21-%d-%d-%d" % (sub_ids[0], sub_ids[1], sub_ids[2])
 
     def __add_admin_sids(self):
+        """
+        The IPA admin and the IPA admins group with get the well knows SIDs
+        used by AD for the administrator and the administrator group.
+        Additonally the well know domain users SID will be assinged to a
+        special fallback group.
+
+        By default new users belong only to a user private group (UPG) and no
+        other Posix group since ipausers is not a Posix group anymore. To be
+        able to add a RID to the primary RID attribute in a PAC a fallback
+        group is added.
+        """
+
         admin_dn = DN(('uid', 'admin'), api.env.container_user,
                       self.suffix)
         admin_group_dn = DN(('cn', 'admins'), api.env.container_group,
@@ -163,24 +177,65 @@ class ADTRUSTInstance(service.Service):
             print "IPA admin group object not found"
             return
 
-        if admin_entry.getValue(self.ATTR_SID) or \
-           admin_group_entry.getValue(self.ATTR_SID):
-            print "Admin SID already set, nothing to do"
+        if admin_entry.getValue(self.ATTR_SID):
+            self.print_msg("Admin SID already set, nothing to do")
+        else:
+            try:
+                self.admin_conn.modify_s(admin_dn, \
+                            [(ldap.MOD_ADD, "objectclass", self.OBJC_USER), \
+                             (ldap.MOD_ADD, self.ATTR_SID, dom_sid + "-500")])
+            except:
+                self.print_msg("Failed to modify IPA admin object")
+
+        if admin_group_entry.getValue(self.ATTR_SID):
+            self.print_msg("Admin group SID already set, nothing to do")
+        else:
+            try:
+                self.admin_conn.modify_s(admin_group_dn, \
+                            [(ldap.MOD_ADD, "objectclass", self.OBJC_GROUP), \
+                             (ldap.MOD_ADD, self.ATTR_SID, dom_sid + "-512")])
+            except:
+                self.print_msg("Failed to modify IPA admin group object")
+
+        if dom_entry.getValue(self.ATTR_FALLBACK_GROUP):
+            self.print_msg("Fallback group already set, nothing to do")
             return
 
+        fb_group_dn = DN(('cn', self.FALLBACK_GROUP_NAME),
+                         api.env.container_group, self.suffix)
+        has_sid = False
         try:
-            self.admin_conn.modify_s(admin_dn, \
-                        [(ldap.MOD_ADD, "objectclass", self.OBJC_USER), \
-                         (ldap.MOD_ADD, self.ATTR_SID, dom_sid + "-500")])
-        except:
-            print "Failed to modify IPA admin object"
+            fb_group = self.admin_conn.getEntry(fb_group_dn, ldap.SCOPE_BASE)
+
+            if fb_group.getValue(self.ATTR_SID):
+                has_sid = True
+        except errors.NotFound:
+            try:
+                fallback = api.Command['group_add'](self.FALLBACK_GROUP_NAME,
+                                           description= u'Fallback group for ' \
+                                                         'primary group RID, ' \
+                                                         'do not add user to ' \
+                                                         'this group',
+                                           nonposix=True)
+                fb_group_dn = fallback['result']['dn']
+            except Exception, e:
+                self.print_msg("Failed to add fallback group.")
+                raise e
+
+        if not has_sid:
+            try:
+                mod = [(ldap.MOD_ADD, "objectclass", self.OBJC_GROUP), \
+                       (ldap.MOD_ADD, self.ATTR_SID, dom_sid + "-513")]
+                self.admin_conn.modify_s(DN(fallback['result']['dn']), mod)
+            except:
+                self.print_msg("Failed to modify fallback group object")
 
         try:
-            self.admin_conn.modify_s(admin_group_dn, \
-                        [(ldap.MOD_ADD, "objectclass", self.OBJC_GROUP), \
-                         (ldap.MOD_ADD, self.ATTR_SID, dom_sid + "-512")])
+            mod = [(ldap.MOD_ADD, self.ATTR_FALLBACK_GROUP,
+                    fallback['result']['dn'])]
+            self.admin_conn.modify_s(self.smb_dom_dn, mod)
         except:
-            print "Failed to modify IPA admin group object"
+            self.print_msg("Failed to add fallback group to domain object")
 
     def __add_rid_bases(self):
         """
-- 
1.7.11.4

-------------- next part --------------
From 40ff99524544730d1106c6e8cfe268dcc7ec2cbf Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 18 Sep 2012 11:35:57 +0200
Subject: [PATCH 76/78] ipa-adtrust-install: replace print with self.print_msg

---
 ipaserver/install/adtrustinstance.py | 28 ++++++++++++++--------------
 1 Datei ge?ndert, 14 Zeilen hinzugef?gt(+), 14 Zeilen entfernt(-)

diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py
index 1aebdad3ce8169952489d2ddce8f19917635b5e8..8b8364929a9f063ad66fac0d7bca4d13977f9543 100644
--- a/ipaserver/install/adtrustinstance.py
+++ b/ipaserver/install/adtrustinstance.py
@@ -156,25 +156,25 @@ class ADTRUSTInstance(service.Service):
             dom_entry = self.admin_conn.getEntry(self.smb_dom_dn, \
                                                  ldap.SCOPE_BASE)
         except errors.NotFound:
-            print "Samba domain object not found"
+            self.print_msg("Samba domain object not found")
             return
 
         dom_sid = dom_entry.getValue(self.ATTR_SID)
         if not dom_sid:
-            print "Samba domain object does not have a SID"
+            self.print_msg("Samba domain object does not have a SID")
             return
 
         try:
             admin_entry = self.admin_conn.getEntry(admin_dn, ldap.SCOPE_BASE)
         except:
-            print "IPA admin object not found"
+            self.print_msg("IPA admin object not found")
             return
 
         try:
             admin_group_entry = self.admin_conn.getEntry(admin_group_dn, \
                                                          ldap.SCOPE_BASE)
         except:
-            print "IPA admin group object not found"
+            self.print_msg("IPA admin group object not found")
             return
 
         if admin_entry.getValue(self.ATTR_SID):
@@ -255,13 +255,13 @@ class ADTRUSTInstance(service.Service):
 
             if res[0].getValue('ipaBaseRID') or \
                res[0].getValue('ipaSecondaryBaseRID'):
-                print "RID bases already set, nothing to do"
+                self.print_msg("RID bases already set, nothing to do")
                 return
 
             size = res[0].getValue('ipaIDRangeSize')
             if abs(self.rid_base - self.secondary_rid_base) > size:
-                print "Primary and secondary RID base are too close. " \
-                      "They have to differ at least by %d." % size
+                self.print_msg("Primary and secondary RID base are too close. " \
+                      "They have to differ at least by %d." % size)
                 raise RuntimeError("RID bases too close.\n")
 
             try:
@@ -271,7 +271,7 @@ class ADTRUSTInstance(service.Service):
                                          (ldap.MOD_ADD, "ipaSecondaryBaseRID", \
                                                  str(self.secondary_rid_base))])
             except:
-                print "Failed to add RID bases to the local range object"
+                self.print_msg("Failed to add RID bases to the local range object")
 
         except errors.NotFound as e:
             root_logger.critical("ID range of the local domain not found, " \
@@ -298,8 +298,8 @@ class ADTRUSTInstance(service.Service):
                 try:
                     name = new_dn[1].attr
                 except Exception, e:
-                    print 'Cannot extract RDN attribute value from "%s": %s' % \
-                          (new_dn, e)
+                    self.print_msg('Cannot extract RDN attribute value from "%s": %s' % \
+                          (new_dn, e))
                     return
                 entry.setValues("cn", name)
                 self.admin_conn.addEntry(entry)
@@ -416,12 +416,12 @@ class ADTRUSTInstance(service.Service):
                           "as it is not defined in IPA" % zone
 
         if err_msg:
-            print err_msg
-            print "Add the following service records to your DNS server " \
-                  "for DNS zone %s: " % zone
+            self.print_msg(err_msg)
+            self.print_msg("Add the following service records to your DNS " \
+                           "server for DNS zone %s: " % zone)
             for (srv, rdata) in ipa_srv_rec:
                 for suff in win_srv_suffix:
-                    print " - %s%s"  % (srv, suff)
+                    self.print_msg(" - %s%s"  % (srv, suff))
             return
 
         for (srv, rdata) in ipa_srv_rec:
-- 
1.7.11.4

-------------- next part --------------
From afb7f3aadf8d56a7b82ca357f9a97c5aeec05742 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Mon, 24 Sep 2012 17:25:07 +0200
Subject: [PATCH 77/78] ipasam: add fallback primary group

---
 daemons/ipa-sam/ipa_sam.c | 148 +++++++++++++++++++++++++++++++++++++++++++++-
 1 Datei ge?ndert, 147 Zeilen hinzugef?gt(+), 1 Zeile entfernt(-)

diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c
index db300022af0a29c32a2df5e5ef2bc12f39ed2886..7dc4549cb8f6390827642f14c4cff29539916261 100644
--- a/daemons/ipa-sam/ipa_sam.c
+++ b/daemons/ipa-sam/ipa_sam.c
@@ -121,6 +121,8 @@ bool secrets_store(const char *key, const void *data, size_t size); /* available
 #define LDAP_ATTRIBUTE_LOGON_SCRIPT "ipaNTLogonScript"
 #define LDAP_ATTRIBUTE_PROFILE_PATH "ipaNTProfilePath"
 #define LDAP_ATTRIBUTE_NTHASH "ipaNTHash"
+#define LDAP_ATTRIBUTE_UIDNUMBER "uidnumber"
+#define LDAP_ATTRIBUTE_GIDNUMBER "gidnumber"
 
 #define LDAP_OBJ_KRB_PRINCIPAL "krbPrincipal"
 #define LDAP_OBJ_KRB_PRINCIPAL_AUX "krbPrincipalAux"
@@ -155,7 +157,7 @@ struct ipasam_privates {
 	char *base_dn;
 	char *trust_dn;
 	char *flat_name;
-	char *fallback_primary_group;
+	struct dom_sid fallback_primary_group;
 	char *server_princ;
 	char *client_princ;
 	struct sss_idmap_ctx *idmap_ctx;
@@ -2677,6 +2679,141 @@ static bool ipasam_nthash_regen(struct ldapsam_privates *ldap_state,
 	return (ret == LDAP_SUCCESS);
 }
 
+static int ipasam_get_sid_by_gid(struct ldapsam_privates *ldap_state,
+				 uint32_t gid,
+				 struct dom_sid *_sid)
+{
+	int ret;
+	char *filter;
+	TALLOC_CTX *tmp_ctx;
+	LDAPMessage *entry = NULL;
+	LDAPMessage *result = NULL;
+	char *sid_str = NULL;
+	struct dom_sid *sid = NULL;
+	int count;
+	enum idmap_error_code err;
+
+	tmp_ctx = talloc_new("ipasam_get_sid_by_gid");
+	if (tmp_ctx == NULL) {
+		return ENOMEM;
+	}
+
+	filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(%s=%lu))",
+					  LDAP_ATTRIBUTE_OBJECTCLASS,
+					  LDAP_OBJ_POSIXGROUP,
+					  LDAP_ATTRIBUTE_GIDNUMBER,
+					  (unsigned long) gid);
+	if (filter == NULL) {
+		ret = ENOMEM;
+		goto done;
+	}
+
+	ret = smbldap_search(ldap_state->smbldap_state,
+			     ldap_state->ipasam_privates->base_dn,
+			     LDAP_SCOPE_SUBTREE,filter, NULL, 0,
+			     &result);
+	if (ret != LDAP_SUCCESS) {
+		ret = ENOENT;
+		goto done;
+	}
+
+	count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
+				   result);
+	if (count != 1) {
+		ret = ENOENT;
+		goto done;
+	}
+
+	entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
+	if (entry == NULL) {
+		ret = ENOENT;
+		goto done;
+	}
+
+	sid_str = get_single_attribute(tmp_ctx,
+				       ldap_state->smbldap_state->ldap_struct,
+				       entry, LDAP_ATTRIBUTE_SID);
+	if (sid_str == NULL) {
+		ret = ENOENT;
+		goto done;
+	}
+
+	err = sss_idmap_sid_to_smb_sid(ldap_state->ipasam_privates->idmap_ctx,
+				       sid_str, &sid);
+	if (err != IDMAP_SUCCESS) {
+		ret = EFAULT;
+		goto done;
+	}
+	sid_copy(_sid, sid);
+
+	ret = 0;
+
+done:
+	talloc_free(sid);
+	ldap_msgfree(result);
+	talloc_free(tmp_ctx);
+
+	return ret;
+}
+
+static int ipasam_get_primary_group_sid(TALLOC_CTX *mem_ctx,
+					struct ldapsam_privates *ldap_state,
+					LDAPMessage *entry,
+					struct dom_sid **_group_sid)
+{
+	int ret;
+	uint32_t uid;
+	uint32_t gid;
+	struct dom_sid *group_sid;
+
+	TALLOC_CTX *tmp_ctx = talloc_init("ipasam_get_primary_group_sid");
+	if (tmp_ctx == NULL) {
+		return ENOMEM;
+	}
+
+	if (!get_uint32_t_from_ldap_msg(ldap_state, entry,
+					LDAP_ATTRIBUTE_UIDNUMBER, &uid)) {
+		ret = ENOENT;
+		DEBUG(1, ("No uidnumber attribute found for this user!\n"));
+		goto done;
+	}
+
+	if (!get_uint32_t_from_ldap_msg(ldap_state, entry,
+					LDAP_ATTRIBUTE_GIDNUMBER, &gid)) {
+		ret = ENOENT;
+		DEBUG(1, ("No gidnumber attribute found for this user!\n"));
+		goto done;
+	}
+
+	group_sid = talloc(tmp_ctx, struct dom_sid);
+	if (group_sid == NULL) {
+		ret = ENOMEM;
+		goto done;
+	}
+
+	if (uid == gid) { /* User private group, use default fallback group */
+		sid_copy(group_sid,
+			 &ldap_state->ipasam_privates->fallback_primary_group);
+		ret = 0;
+		goto done;
+	} else {
+		ret = ipasam_get_sid_by_gid(ldap_state, gid, group_sid);
+		if (ret != 0) {
+			goto done;
+		}
+	}
+
+        ret = 0;
+done:
+	if (ret == 0) {
+		*_group_sid = talloc_steal(mem_ctx, group_sid);
+	}
+
+	talloc_free(tmp_ctx);
+
+	return ret;
+}
+
 static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
 				struct samu * sampass,
 				LDAPMessage * entry)
@@ -2692,7 +2829,9 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
 	char *temp = NULL;
 	bool ret = false;
 	bool retval = false;
+	int status;
 	DATA_BLOB nthash;
+	struct dom_sid *group_sid;
 
 	TALLOC_CTX *tmp_ctx = talloc_init("init_sam_from_ldap");
 	if (!tmp_ctx) {
@@ -2738,6 +2877,12 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
 			entry, LDAP_ATTRIBUTE_SECURITY_IDENTIFIER,
 			tmp_ctx)) != NULL) {
 		pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
+
+		status = ipasam_get_primary_group_sid(tmp_ctx, ldap_state,
+						      entry, &group_sid);
+		if (status != 0) {
+			goto fn_exit;
+		}
 	} else {
 		goto fn_exit;
 	}
@@ -2872,6 +3017,7 @@ done:
 	talloc_free(tmp_ctx);
 	return status;
 }
+
 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *methods,
 				    struct samu *user,
 				    const char *sname)
-- 
1.7.11.4

-------------- next part --------------
From 67ff93ca4f8ace991079662bf44144d7dc1587b0 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 25 Sep 2012 11:11:40 +0200
Subject: [PATCH 78/78] ipadb: use ipaNTGroupAttrs to search for the fallback
 group

Since we are primarily interested in the SID of the fallback group we
should use the objectclass containing it in the search filter.
---
 daemons/ipa-kdb/ipa_kdb_mspac.c | 2 +-
 1 Datei ge?ndert, 1 Zeile hinzugef?gt(+), 1 Zeile entfernt(-)

diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index b3cef97db1bfe120d00b3bbfd30ed392dbb7b385..1a03323d137a2b89a08f5b12ca00752e4e190de7 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -1590,7 +1590,7 @@ krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx)
     if (ret != ENOENT) {
         kerr = ipadb_simple_search(ipactx, ipactx->mspac->fallback_group,
                                    LDAP_SCOPE_BASE,
-                                   "(objectclass=posixGroup)",
+                                   "(objectclass=ipaNTGroupAttrs)",
                                    grp_attrs, &result);
         if (kerr && kerr != KRB5_KDB_NOENTRY) {
             kerr = ret;
-- 
1.7.11.4



More information about the Freeipa-devel mailing list