]> git.samba.org - obnox/samba/samba-obnox.git/commitdiff
idmap: unify passdb *id_to_sid methods
authorGarming Sam <garming@catalyst.net.nz>
Tue, 25 Nov 2014 01:45:26 +0000 (14:45 +1300)
committerGarming Sam <garming@samba.org>
Wed, 3 Dec 2014 03:21:09 +0000 (04:21 +0100)
Instead of passing down gid or uid, a pointer to a unixid is now sent
down. This acts as an in-out variable so that the idmap functions can
correctly receive ID_TYPE_BOTH, filling in cache details correctly
rather than forcing the cache to store ID_TYPE_UID or ID_TYPE_GID.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=10720

Change-Id: I11409a0f498e61a3c0a6ae606dd7af1135e6b066
Pair-programmed-with: Andrew Bartlett <abarlet@samba.org>
Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/include/passdb.h
source3/passdb/lookup_sid.c
source3/passdb/pdb_interface.c
source3/passdb/pdb_ldap.c
source3/passdb/pdb_samba_dsdb.c
source3/passdb/pdb_wbc_sam.c
source3/passdb/py_passdb.c
source3/utils/net_sam.c
source3/winbindd/idmap_passdb.c

index 86cb16e29250966f08911020627fa85dace1f2df..16e3bef27ccbaf0917f3ee87279c27cc13c4b235 100644 (file)
@@ -415,9 +415,10 @@ enum pdb_policy_type {
  * Changed to 21, set/enum_upn_suffixes. AB.
  * Changed to 22, idmap control functions
  * Changed to 23, new idmap control functions
+ * Changed to 24, removed uid_to_sid and gid_to_sid, replaced with id_to_sid
  */
 
-#define PASSDB_INTERFACE_VERSION 23
+#define PASSDB_INTERFACE_VERSION 24
 
 struct pdb_methods 
 {
@@ -560,10 +561,16 @@ struct pdb_methods
                               struct pdb_search *search,
                               const struct dom_sid *sid);
 
-       bool (*uid_to_sid)(struct pdb_methods *methods, uid_t uid,
-                          struct dom_sid *sid);
-       bool (*gid_to_sid)(struct pdb_methods *methods, gid_t gid,
-                          struct dom_sid *sid);
+       /* 
+        * Instead of passing down a gid or uid, this function sends down a pointer
+        * to a unixid. 
+        *
+        * This acts as an in-out variable so that the idmap functions can correctly
+        * receive ID_TYPE_BOTH, filling in cache details correctly rather than forcing
+        * the cache to store ID_TYPE_UID or ID_TYPE_GID. 
+        */
+       bool (*id_to_sid)(struct pdb_methods *methods, struct unixid *id,
+                         struct dom_sid *sid);
        bool (*sid_to_id)(struct pdb_methods *methods, const struct dom_sid *sid,
                          struct unixid *id);
 
@@ -889,8 +896,15 @@ NTSTATUS pdb_lookup_names(const struct dom_sid *domain_sid,
 bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value);
 bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value);
 bool pdb_get_seq_num(time_t *seq_num);
-bool pdb_uid_to_sid(uid_t uid, struct dom_sid *sid);
-bool pdb_gid_to_sid(gid_t gid, struct dom_sid *sid);
+/* 
+ * Instead of passing down a gid or uid, this function sends down a pointer
+ * to a unixid. 
+ *
+ * This acts as an in-out variable so that the idmap functions can correctly
+ * receive ID_TYPE_BOTH, filling in cache details correctly rather than forcing
+ * the cache to store ID_TYPE_UID or ID_TYPE_GID. 
+ */
+bool pdb_id_to_sid(struct unixid *id, struct dom_sid *sid);
 bool pdb_sid_to_id(const struct dom_sid *sid, struct unixid *id);
 uint32_t pdb_capabilities(void);
 bool pdb_new_rid(uint32_t *rid);
index d541719ec85515965a93a4b455e83b5efb33aa18..494a8407c0a87e2941d08cc0ae16dfdc08efe3e1 100644 (file)
@@ -1029,11 +1029,15 @@ bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
 static void legacy_uid_to_sid(struct dom_sid *psid, uid_t uid)
 {
        bool ret;
+       struct unixid id;
 
        ZERO_STRUCTP(psid);
 
+       id.id = uid;
+       id.type = ID_TYPE_UID;
+
        become_root();
-       ret = pdb_uid_to_sid(uid, psid);
+       ret = pdb_id_to_sid(&id, psid);
        unbecome_root();
 
        if (ret) {
@@ -1059,11 +1063,15 @@ static void legacy_uid_to_sid(struct dom_sid *psid, uid_t uid)
 static void legacy_gid_to_sid(struct dom_sid *psid, gid_t gid)
 {
        bool ret;
+       struct unixid id;
 
        ZERO_STRUCTP(psid);
 
+       id.id = gid;
+       id.type = ID_TYPE_GID;
+
        become_root();
-       ret = pdb_gid_to_sid(gid, psid);
+       ret = pdb_id_to_sid(&id, psid);
        unbecome_root();
 
        if (ret) {
@@ -1527,8 +1535,13 @@ NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
                        }
                } else {
                        /* Try group mapping */
+                       struct unixid id;
+
+                       id.id = pwd->pw_gid;
+                       id.type = ID_TYPE_GID;
+
                        ZERO_STRUCTP(group_sid);
-                       if (pdb_gid_to_sid(pwd->pw_gid, group_sid)) {
+                       if (pdb_id_to_sid(&id, group_sid)) {
                                need_lookup_sid = true;
                        }
                }
index ed42961435dc5598e9074054c51975dd1f414465..9dee9d28b4e6e6419168e8ea3e54073e677090f1 100644 (file)
@@ -1204,35 +1204,23 @@ bool pdb_get_seq_num(time_t *seq_num)
        return NT_STATUS_IS_OK(pdb->get_seq_num(pdb, seq_num));
 }
 
-bool pdb_uid_to_sid(uid_t uid, struct dom_sid *sid)
-{
-       struct pdb_methods *pdb = pdb_get_methods();
-       bool ret;
-
-       ret = pdb->uid_to_sid(pdb, uid, sid);
-
-       if (ret == true) {
-               struct unixid id;
-               id.id = uid;
-               id.type = ID_TYPE_UID;
-               idmap_cache_set_sid2unixid(sid, &id);
-       }
-
-       return ret;
-}
-
-bool pdb_gid_to_sid(gid_t gid, struct dom_sid *sid)
+/* 
+ * Instead of passing down a gid or uid, this function sends down a pointer
+ * to a unixid. 
+ *
+ * This acts as an in-out variable so that the idmap functions can correctly
+ * receive ID_TYPE_BOTH, filling in cache details correctly rather than forcing
+ * the cache to store ID_TYPE_UID or ID_TYPE_GID. 
+ */
+bool pdb_id_to_sid(struct unixid *id, struct dom_sid *sid)
 {
        struct pdb_methods *pdb = pdb_get_methods();
        bool ret;
 
-       ret = pdb->gid_to_sid(pdb, gid, sid);
+       ret = pdb->id_to_sid(pdb, id, sid);
 
        if (ret == true) {
-               struct unixid id;
-               id.id = gid;
-               id.type = ID_TYPE_GID;
-               idmap_cache_set_sid2unixid(sid, &id);
+               idmap_cache_set_sid2unixid(sid, id);
        }
 
        return ret;
@@ -1458,6 +1446,20 @@ static bool pdb_default_gid_to_sid(struct pdb_methods *methods, gid_t gid,
        return true;
 }
 
+static bool pdb_default_id_to_sid(struct pdb_methods *methods, struct unixid *id,
+                                  struct dom_sid *sid)
+{
+       switch (id->type) {
+       case ID_TYPE_UID:
+               return pdb_default_uid_to_sid(methods, id->id, sid);
+
+       case ID_TYPE_GID:
+               return pdb_default_gid_to_sid(methods, id->id, sid);
+
+       default:
+               return false;
+       }
+}
 /**
  * The "Unix User" and "Unix Group" domains have a special
  * id mapping that is a rid-algorithm with range starting at 0.
@@ -2614,8 +2616,7 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods )
        (*methods)->get_account_policy = pdb_default_get_account_policy;
        (*methods)->set_account_policy = pdb_default_set_account_policy;
        (*methods)->get_seq_num = pdb_default_get_seq_num;
-       (*methods)->uid_to_sid = pdb_default_uid_to_sid;
-       (*methods)->gid_to_sid = pdb_default_gid_to_sid;
+       (*methods)->id_to_sid = pdb_default_id_to_sid;
        (*methods)->sid_to_id = pdb_default_sid_to_id;
 
        (*methods)->search_groups = pdb_default_search_groups;
index 0458e56263bb7910572b0aa0ba1070ca390fd09e..0d2c302081a485cea919f6046b783f65a679ad4d 100644 (file)
@@ -3017,6 +3017,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
        NTSTATUS result;
 
        struct dom_sid sid;
+       struct unixid id;
 
        int rc;
 
@@ -3082,7 +3083,10 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
                goto done;
        }
 
-       if (pdb_gid_to_sid(map->gid, &sid)) {
+       id.id = map->gid;
+       id.type = ID_TYPE_GID;
+
+       if (pdb_id_to_sid(&id, &sid)) {
                DEBUG(3, ("Gid %u is already mapped to SID %s, refusing to "
                          "add\n", (unsigned int)map->gid, sid_string_dbg(&sid)));
                result = NT_STATUS_GROUP_EXISTS;
@@ -5128,6 +5132,21 @@ static bool ldapsam_gid_to_sid(struct pdb_methods *methods, gid_t gid,
        return ret;
 }
 
+static bool ldapsam_id_to_sid(struct pdb_methods *methods, struct unixid *id,
+                                  struct dom_sid *sid)
+{
+       switch (id->type) {
+       case ID_TYPE_UID:
+               return ldapsam_uid_to_sid(methods, id->id, sid);
+
+       case ID_TYPE_GID:
+               return ldapsam_gid_to_sid(methods, id->id, sid);
+
+       default:
+               return false;
+       }
+}
+
 
 /*
  * The following functions are called only if
@@ -6487,8 +6506,7 @@ NTSTATUS pdb_ldapsam_init_common(struct pdb_methods **pdb_method,
                        ldapsam_enum_group_memberships;
                (*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;
+               (*pdb_method)->id_to_sid = ldapsam_id_to_sid;
 
                if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
                        (*pdb_method)->create_user = ldapsam_create_user;
index 465cc24dfd14045d88ccdc4249feab7b9763b442..5fa2c2fbbf0abe2a04beb017f40e6439956719a9 100644 (file)
@@ -2042,8 +2042,16 @@ static bool pdb_samba_dsdb_search_aliases(struct pdb_methods *m,
        return true;
 }
 
-static bool pdb_samba_dsdb_uid_to_sid(struct pdb_methods *m, uid_t uid,
-                              struct dom_sid *sid)
+/* 
+ * Instead of taking a gid or uid, this function takes a pointer to a 
+ * unixid. 
+ *
+ * This acts as an in-out variable so that the idmap functions can correctly
+ * receive ID_TYPE_BOTH, and this function ensures cache details are filled
+ * correctly rather than forcing the cache to store ID_TYPE_UID or ID_TYPE_GID. 
+ */
+static bool pdb_samba_dsdb_id_to_sid(struct pdb_methods *m, struct unixid *id,
+                                    struct dom_sid *sid)
 {
        struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
                m->private_data, struct pdb_samba_dsdb_state);
@@ -2055,8 +2063,7 @@ static bool pdb_samba_dsdb_uid_to_sid(struct pdb_methods *m, uid_t uid,
                return false;
        }
 
-       id_map.xid.id = uid;
-       id_map.xid.type = ID_TYPE_UID;
+       id_map.xid = *id;
        id_maps[0] = &id_map;
        id_maps[1] = NULL;
 
@@ -2065,33 +2072,9 @@ static bool pdb_samba_dsdb_uid_to_sid(struct pdb_methods *m, uid_t uid,
                talloc_free(tmp_ctx);
                return false;
        }
-       *sid = *id_map.sid;
-       talloc_free(tmp_ctx);
-       return true;
-}
 
-static bool pdb_samba_dsdb_gid_to_sid(struct pdb_methods *m, gid_t gid,
-                              struct dom_sid *sid)
-{
-       struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
-               m->private_data, struct pdb_samba_dsdb_state);
-       NTSTATUS status;
-       struct id_map id_map;
-       struct id_map *id_maps[2];
-       TALLOC_CTX *tmp_ctx = talloc_stackframe();
-       if (!tmp_ctx) {
-               return false;
-       }
-
-       id_map.xid.id = gid;
-       id_map.xid.type = ID_TYPE_GID;
-       id_maps[0] = &id_map;
-       id_maps[1] = NULL;
-
-       status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(tmp_ctx);
-               return false;
+       if (id_map.xid.type != ID_TYPE_NOT_SPECIFIED) {
+               id->type = id_map.xid.type;
        }
        *sid = *id_map.sid;
        talloc_free(tmp_ctx);
@@ -2341,8 +2324,7 @@ static void pdb_samba_dsdb_init_methods(struct pdb_methods *m)
        m->search_users = pdb_samba_dsdb_search_users;
        m->search_groups = pdb_samba_dsdb_search_groups;
        m->search_aliases = pdb_samba_dsdb_search_aliases;
-       m->uid_to_sid = pdb_samba_dsdb_uid_to_sid;
-       m->gid_to_sid = pdb_samba_dsdb_gid_to_sid;
+       m->id_to_sid = pdb_samba_dsdb_id_to_sid;
        m->sid_to_id = pdb_samba_dsdb_sid_to_id;
        m->capabilities = pdb_samba_dsdb_capabilities;
        m->new_rid = pdb_samba_dsdb_new_rid;
index 23436496cd4f636bf4631f0e17e986eb626821ec..b20a35a4fa963d1b7abef5d6884360f979e7f600 100644 (file)
@@ -40,6 +40,7 @@
 #include "passdb.h"
 #include "lib/winbind_util.h"
 #include "passdb/pdb_wbc_sam.h"
+#include "idmap.h"
 
 /***************************************************************************
   Default implementations of some functions.
@@ -72,16 +73,19 @@ static NTSTATUS pdb_wbc_sam_getsampwsid(struct pdb_methods *methods, struct samu
        return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwsid(sid));
 }
 
-static bool pdb_wbc_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid,
-                                  struct dom_sid *sid)
+static bool pdb_wbc_sam_id_to_sid(struct pdb_methods *methods, struct unixid *id,
+                                 struct dom_sid *sid)
 {
-       return winbind_uid_to_sid(sid, uid);
-}
+       switch (id->type) {
+       case ID_TYPE_UID:
+               return winbind_uid_to_sid(sid, id->id);
 
-static bool pdb_wbc_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid,
-                                  struct dom_sid *sid)
-{
-       return winbind_gid_to_sid(sid, gid);
+       case ID_TYPE_GID:
+               return winbind_gid_to_sid(sid, id->id);
+
+       default:
+               return false;
+       }
 }
 
 static NTSTATUS pdb_wbc_sam_enum_group_members(struct pdb_methods *methods,
@@ -426,8 +430,7 @@ static NTSTATUS pdb_init_wbc_sam(struct pdb_methods **pdb_method, const char *lo
        (*pdb_method)->lookup_rids = pdb_wbc_sam_lookup_rids;
        (*pdb_method)->get_account_policy = pdb_wbc_sam_get_account_policy;
        (*pdb_method)->set_account_policy = pdb_wbc_sam_set_account_policy;
-       (*pdb_method)->uid_to_sid = pdb_wbc_sam_uid_to_sid;
-       (*pdb_method)->gid_to_sid = pdb_wbc_sam_gid_to_sid;
+       (*pdb_method)->id_to_sid = pdb_wbc_sam_id_to_sid;
 
        (*pdb_method)->search_groups = pdb_wbc_sam_search_groups;
        (*pdb_method)->search_aliases = pdb_wbc_sam_search_aliases;
index dec45c3a5c44b428372a9c154320e0cf677c940f..3a1e583f0f6894d2b7ddee62490f79a5979464c6 100644 (file)
@@ -25,6 +25,7 @@
 #include "librpc/gen_ndr/idmap.h"
 #include "passdb.h"
 #include "secrets.h"
+#include "idmap.h"
 
 /* There's no Py_ssize_t in 2.4, apparently */
 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
@@ -2678,6 +2679,7 @@ static PyObject *py_pdb_uid_to_sid(pytalloc_Object *self, PyObject *args)
 {
        TALLOC_CTX *frame = talloc_stackframe();
        struct pdb_methods *methods;
+       struct unixid id;
        unsigned int uid;
        struct dom_sid user_sid, *copy_user_sid;
        PyObject *py_user_sid;
@@ -2689,7 +2691,10 @@ static PyObject *py_pdb_uid_to_sid(pytalloc_Object *self, PyObject *args)
 
        methods = pytalloc_get_ptr(self);
 
-       if (!methods->uid_to_sid(methods, uid, &user_sid)) {
+       id.id = uid;
+       id.type = ID_TYPE_UID;
+
+       if (!methods->id_to_sid(methods, &id, &user_sid)) {
                PyErr_Format(py_pdb_error, "Unable to get sid for uid=%d", uid);
                talloc_free(frame);
                return NULL;
@@ -2713,6 +2718,7 @@ static PyObject *py_pdb_gid_to_sid(pytalloc_Object *self, PyObject *args)
 {
        TALLOC_CTX *frame = talloc_stackframe();
        struct pdb_methods *methods;
+       struct unixid id;
        unsigned int gid;
        struct dom_sid group_sid, *copy_group_sid;
        PyObject *py_group_sid;
@@ -2722,9 +2728,12 @@ static PyObject *py_pdb_gid_to_sid(pytalloc_Object *self, PyObject *args)
                return NULL;
        }
 
+       id.id = gid;
+       id.type = ID_TYPE_GID;
+
        methods = pytalloc_get_ptr(self);
 
-       if (!methods->gid_to_sid(methods, gid, &group_sid)) {
+       if (!methods->id_to_sid(methods, &id, &group_sid)) {
                PyErr_Format(py_pdb_error, "Unable to get sid for gid=%d", gid);
                talloc_free(frame);
                return NULL;
index aadabc1435402999e696af8038cf23ea553f0de7..2ee9a91b704238e10713b1d9641481800f1d20c2 100644 (file)
@@ -30,6 +30,7 @@
 #include "passdb/pdb_ldap_schema.h"
 #include "lib/privileges.h"
 #include "secrets.h"
+#include "idmap.h"
 
 /*
  * Set a user's data
@@ -912,6 +913,7 @@ static int net_sam_mapunixgroup(struct net_context *c, int argc, const char **ar
 static NTSTATUS unmap_unix_group(const struct group *grp)
 {
         struct dom_sid dom_sid;
+       struct unixid id;
 
         if (!lookup_name(talloc_tos(), grp->gr_name, LOOKUP_NAME_LOCAL,
                         NULL, NULL, NULL, NULL)) {
@@ -919,7 +921,9 @@ static NTSTATUS unmap_unix_group(const struct group *grp)
                 return NT_STATUS_NO_SUCH_GROUP;
         }
 
-        if (!pdb_gid_to_sid(grp->gr_gid, &dom_sid)) {
+       id.id = grp->gr_gid;
+       id.type = ID_TYPE_GID;
+        if (!pdb_id_to_sid(&id, &dom_sid)) {
                 return NT_STATUS_UNSUCCESSFUL;
         }
 
index e547e9bf7cf1a3706bf834215ae25fba6f2e094e..cf8ad7446cebbbe37806f3bf40fde90fba3b8dcb 100644 (file)
@@ -44,23 +44,11 @@ static NTSTATUS idmap_pdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
        int i;
 
        for (i = 0; ids[i]; i++) {
-
                /* unmapped by default */
                ids[i]->status = ID_UNMAPPED;
 
-               switch (ids[i]->xid.type) {
-               case ID_TYPE_UID:
-                       if (pdb_uid_to_sid((uid_t)ids[i]->xid.id, ids[i]->sid)) {
-                               ids[i]->status = ID_MAPPED;
-                       }
-                       break;
-               case ID_TYPE_GID:
-                       if (pdb_gid_to_sid((gid_t)ids[i]->xid.id, ids[i]->sid)) {
-                               ids[i]->status = ID_MAPPED;
-                       }
-                       break;
-               default: /* ?? */
-                       ids[i]->status = ID_UNKNOWN;
+               if (pdb_id_to_sid(&ids[i]->xid, ids[i]->sid)) {
+                       ids[i]->status = ID_MAPPED;
                }
        }