s3: shortcut gid_to_sid when "ldapsam:trusted = yes"
authorStefan Metzmacher <metze@samba.org>
Sat, 30 Jan 2010 21:28:19 +0000 (22:28 +0100)
committerStefan Metzmacher <metze@samba.org>
Mon, 8 Feb 2010 10:10:16 +0000 (11:10 +0100)
The normal gid_to_sid behaviour is to call sys_getgrgid()
to get the name for the given gid and then call the
getsamgrnam passdb method for the resulting name.

In the ldapsam:trusted case we can reduce the gid_to_sid
operation to one simple search for the gidNumber attribute
and only get the sambaSID attribute from the correspoinding
LDAP object. This reduces the number of ldap roundtrips
for this operation.

metze

source3/passdb/pdb_ldap.c

index 6e5f9acd9af5f76a7898f268bd0539d30c3bdd4d..6288782edcc54867b044034185e5e9dae7fe4052 100644 (file)
@@ -5069,6 +5069,77 @@ static bool ldapsam_uid_to_sid(struct pdb_methods *methods, uid_t uid,
        return ret;
 }
 
+/**
+ * Find the SID for a gid.
+ * This is shortcut is only used if ldapsam:trusted is set to true.
+ */
+static bool ldapsam_gid_to_sid(struct pdb_methods *methods, gid_t gid,
+                              DOM_SID *sid)
+{
+       struct ldapsam_privates *priv =
+               (struct ldapsam_privates *)methods->private_data;
+       char *filter;
+       const char *attrs[] = { "sambaSID", NULL };
+       LDAPMessage *result = NULL;
+       LDAPMessage *entry = NULL;
+       bool ret = false;
+       char *group_sid_string;
+       DOM_SID *group_sid;
+       int rc;
+       TALLOC_CTX *tmp_ctx = talloc_stackframe();
+
+       filter = talloc_asprintf(tmp_ctx,
+                                "(&(gidNumber=%u)"
+                                "(objectClass=%s))",
+                                (unsigned int)gid,
+                                LDAP_OBJ_GROUPMAP);
+       if (filter == NULL) {
+               DEBUG(3, ("talloc_asprintf failed\n"));
+               goto done;
+       }
+
+       rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
+       if (rc != LDAP_SUCCESS) {
+               goto done;
+       }
+       talloc_autofree_ldapmsg(tmp_ctx, result);
+
+       if (ldap_count_entries(priv2ld(priv), result) != 1) {
+               DEBUG(3, ("ERROR: Got %d entries for gid %u, expected one\n",
+                          ldap_count_entries(priv2ld(priv), result),
+                          (unsigned int)gid));
+               goto done;
+       }
+
+       entry = ldap_first_entry(priv2ld(priv), result);
+
+       group_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
+                                                         "sambaSID", tmp_ctx);
+       if (group_sid_string == NULL) {
+               DEBUG(1, ("Could not find sambaSID in object '%s'\n",
+                         smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
+               goto done;
+       }
+
+       group_sid = string_sid_talloc(tmp_ctx, group_sid_string);
+       if (group_sid == NULL) {
+               DEBUG(3, ("Error calling sid_string_talloc for sid '%s'\n",
+                         group_sid_string));
+               goto done;
+       }
+
+       sid_copy(sid, group_sid);
+
+       store_gid_sid_cache(sid, gid);
+       idmap_cache_set_sid2gid(sid, gid);
+
+       ret = true;
+
+ done:
+       TALLOC_FREE(tmp_ctx);
+       return ret;
+}
+
 
 /*
  * The following functions are called only if
@@ -6417,6 +6488,7 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
                (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
                (*pdb_method)->sid_to_id = ldapsam_sid_to_id;
                (*pdb_method)->uid_to_sid = ldapsam_uid_to_sid;
+               (*pdb_method)->gid_to_sid = ldapsam_gid_to_sid;
 
                if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
                        (*pdb_method)->create_user = ldapsam_create_user;