From a6e29f23f09ba5b6b6d362f7683ae8088bc0ba85 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 16 Mar 2012 09:16:23 +1100 Subject: s3-passdb: Change pdb_sid_to_id() to return struct unixid This will make it easier to consistantly pass a struct unixid all the way up and down the idmap stack, and allow ID_TYPE_BOTH to be handled correctly. Andrew Bartlett Signed-off-by: Michael Adam --- source3/include/passdb.h | 6 +-- source3/passdb/lookup_sid.c | 111 +++++++++++++++------------------------- source3/passdb/lookup_sid.h | 1 + source3/passdb/pdb_ads.c | 17 +++--- source3/passdb/pdb_interface.c | 45 ++++++++++------ source3/passdb/pdb_ldap.c | 16 +++--- source3/passdb/pdb_samba4.c | 76 +++++++++++++++++---------- source3/passdb/py_passdb.c | 9 ++-- source3/winbindd/idmap_passdb.c | 27 +--------- 9 files changed, 147 insertions(+), 161 deletions(-) (limited to 'source3') diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 905a5d1955..b22d17aa63 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -33,6 +33,7 @@ #include "../librpc/gen_ndr/lsa.h" #include +struct unixid; /* group mapping headers */ @@ -561,7 +562,7 @@ struct pdb_methods bool (*gid_to_sid)(struct pdb_methods *methods, gid_t gid, struct dom_sid *sid); bool (*sid_to_id)(struct pdb_methods *methods, const struct dom_sid *sid, - uid_t *uid, gid_t *gid, enum lsa_SidType *type); + struct unixid *id); uint32_t (*capabilities)(struct pdb_methods *methods); bool (*new_rid)(struct pdb_methods *methods, uint32_t *rid); @@ -866,8 +867,7 @@ 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); -bool pdb_sid_to_id(const struct dom_sid *sid, uid_t *uid, gid_t *gid, - enum lsa_SidType *type); +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); bool initialize_password_db(bool reload, struct tevent_context *tevent_ctx); diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index 3f7be2a0de..d31693de4e 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -27,6 +27,7 @@ #include "idmap_cache.h" #include "../libcli/security/security.h" #include "lib/winbind_util.h" +#include "../librpc/gen_ndr/idmap.h" /***************************************************************** Dissect a user-provided name into domain, name, sid and type. @@ -1074,115 +1075,85 @@ static void legacy_gid_to_sid(struct dom_sid *psid, gid_t gid) } /***************************************************************** - *THE LEGACY* convert SID to uid function. + *THE LEGACY* convert SID to id function. *****************************************************************/ -static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid) +static bool legacy_sid_to_id(const struct dom_sid *psid, struct unixid *id) { - enum lsa_SidType type; - + GROUP_MAP *map; if (sid_check_is_in_our_domain(psid)) { - uid_t uid; - gid_t gid; bool ret; become_root(); - ret = pdb_sid_to_id(psid, &uid, &gid, &type); + ret = pdb_sid_to_id(psid, id); unbecome_root(); if (ret) { - if (type != SID_NAME_USER) { - DEBUG(5, ("sid %s is a %s, expected a user\n", - sid_string_dbg(psid), - sid_type_lookup(type))); - return false; - } - *puid = uid; goto done; } /* This was ours, but it was not mapped. Fail */ } - DEBUG(10,("LEGACY: mapping failed for sid %s\n", - sid_string_dbg(psid))); - return false; - -done: - DEBUG(10,("LEGACY: sid %s -> uid %u\n", sid_string_dbg(psid), - (unsigned int)*puid )); - - return true; -} - -/***************************************************************** - *THE LEGACY* convert SID to gid function. - Group mapping is used for gids that maps to Wellknown SIDs -*****************************************************************/ - -static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid) -{ - GROUP_MAP *map; - enum lsa_SidType type; - - map = talloc_zero(NULL, GROUP_MAP); - if (!map) { - return false; - } - if ((sid_check_is_in_builtin(psid) || sid_check_is_in_wellknown_domain(psid))) { bool ret; + map = talloc_zero(NULL, GROUP_MAP); + if (!map) { + return false; + } + become_root(); ret = pdb_getgrsid(map, *psid); unbecome_root(); if (ret) { - *pgid = map->gid; + id->id = map->gid; + id->type = ID_TYPE_GID; + TALLOC_FREE(map); goto done; } + TALLOC_FREE(map); DEBUG(10,("LEGACY: mapping failed for sid %s\n", sid_string_dbg(psid))); return false; } - if (sid_check_is_in_our_domain(psid)) { - uid_t uid; - gid_t gid; - bool ret; - - become_root(); - ret = pdb_sid_to_id(psid, &uid, &gid, &type); - unbecome_root(); - - if (ret) { - if ((type != SID_NAME_DOM_GRP) && - (type != SID_NAME_ALIAS)) { - DEBUG(5, ("LEGACY: sid %s is a %s, expected " - "a group\n", sid_string_dbg(psid), - sid_type_lookup(type))); - return false; - } - *pgid = gid; - goto done; - } - - /* This was ours, but it was not mapped. Fail */ - } - DEBUG(10,("LEGACY: mapping failed for sid %s\n", sid_string_dbg(psid))); return false; - done: - DEBUG(10,("LEGACY: sid %s -> gid %u\n", sid_string_dbg(psid), - (unsigned int)*pgid )); - - TALLOC_FREE(map); +done: return true; } +static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid) +{ + struct unixid id; + if (!legacy_sid_to_id(psid, &id)) { + return false; + } + if (id.type == ID_TYPE_GID || id.type == ID_TYPE_BOTH) { + *pgid = id.id; + return true; + } + return false; +} + +static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid) +{ + struct unixid id; + if (!legacy_sid_to_id(psid, &id)) { + return false; + } + if (id.type == ID_TYPE_UID || id.type == ID_TYPE_BOTH) { + *puid = id.id; + return true; + } + return false; +} + /***************************************************************** *THE CANONICAL* convert uid_t to SID function. *****************************************************************/ diff --git a/source3/passdb/lookup_sid.h b/source3/passdb/lookup_sid.h index 693e001ad9..65444c39a6 100644 --- a/source3/passdb/lookup_sid.h +++ b/source3/passdb/lookup_sid.h @@ -26,6 +26,7 @@ #include "../librpc/gen_ndr/lsa.h" struct passwd; +struct unixid; #define LOOKUP_NAME_NONE 0x00000000 #define LOOKUP_NAME_ISOLATED 0x00000001 /* Look up unqualified names */ diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index cd7781a1af..f88ad75de7 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -24,6 +24,7 @@ #include "../libds/common/flags.h" #include "secrets.h" #include "../librpc/gen_ndr/samr.h" +#include "../librpc/gen_ndr/idmap.h" #include "../libcli/ldap/ldap_ndr.h" #include "../libcli/security/security.h" #include "../libds/common/flag_mapping.h" @@ -2204,7 +2205,7 @@ static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid, } static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid, - uid_t *uid, gid_t *gid, enum lsa_SidType *type) + struct unixid *id) { struct pdb_ads_state *state = talloc_get_type_abort( m->private_data, struct pdb_ads_state); @@ -2216,8 +2217,8 @@ static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid, int rc; bool ret = false; - *uid = -1; - *gid = -1; + id->id = -1; + id->type = ID_TYPE_NOT_SPECIFIED; sidstr = sid_binstring_hex(sid); if (sidstr == NULL) { @@ -2247,17 +2248,21 @@ static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid, goto fail; } if (atype == ATYPE_ACCOUNT) { - *type = SID_NAME_USER; - if (!tldap_pull_uint32(msg[0], "uidNumber", uid)) { + uid_t uid; + id->type = ID_TYPE_UID; + if (!tldap_pull_uint32(msg[0], "uidNumber", &uid)) { DEBUG(10, ("Did not find uidNumber\n")); goto fail; } + id->id = uid; } else { - *type = SID_NAME_DOM_GRP; + gid_t gid; + id->type = ID_TYPE_GID; if (!tldap_pull_uint32(msg[0], "gidNumber", gid)) { DEBUG(10, ("Did not find gidNumber\n")); goto fail; } + id->id = gid; } ret = true; fail: diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index e2fc67981e..b7c9bace2a 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -28,6 +28,7 @@ #include "../librpc/gen_ndr/samr.h" #include "../librpc/gen_ndr/drsblobs.h" #include "../librpc/gen_ndr/ndr_drsblobs.h" +#include "../librpc/gen_ndr/idmap.h" #include "memcache.h" #include "nsswitch/winbind_client.h" #include "../libcli/security/security.h" @@ -1232,11 +1233,10 @@ bool pdb_gid_to_sid(gid_t gid, struct dom_sid *sid) return pdb->gid_to_sid(pdb, gid, sid); } -bool pdb_sid_to_id(const struct dom_sid *sid, uid_t *uid, gid_t *gid, - enum lsa_SidType *type) +bool pdb_sid_to_id(const struct dom_sid *sid, struct unixid *id) { struct pdb_methods *pdb = pdb_get_methods(); - return pdb->sid_to_id(pdb, sid, uid, gid, type); + return pdb->sid_to_id(pdb, sid, id); } uint32_t pdb_capabilities(void) @@ -1441,16 +1441,12 @@ static bool pdb_default_gid_to_sid(struct pdb_methods *methods, gid_t gid, static bool pdb_default_sid_to_id(struct pdb_methods *methods, const struct dom_sid *sid, - uid_t *uid, gid_t *gid, - enum lsa_SidType *type) + struct unixid *id) { TALLOC_CTX *mem_ctx; bool ret = False; - const char *name; uint32_t rid; - - *uid = -1; - *gid = -1; + id->id = -1; mem_ctx = talloc_new(NULL); @@ -1460,16 +1456,33 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods, } if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) { + const char *name; + enum lsa_SidType type; + uid_t uid; + gid_t gid; /* Here we might have users as well as groups and aliases */ - ret = lookup_global_sam_rid(mem_ctx, rid, &name, type, uid, gid); + ret = lookup_global_sam_rid(mem_ctx, rid, &name, &type, &uid, &gid); + if (ret) { + switch (type) { + case SID_NAME_DOM_GRP: + case SID_NAME_ALIAS: + id->type = ID_TYPE_GID; + id->id = gid; + break; + case SID_NAME_USER: + id->type = ID_TYPE_UID; + id->id = uid; + break; + } + } goto done; } /* check for "Unix User" */ if ( sid_peek_check_rid(&global_sid_Unix_Users, sid, &rid) ) { - *uid = rid; - *type = SID_NAME_USER; + id->id = rid; + id->type = ID_TYPE_UID; ret = True; goto done; } @@ -1477,8 +1490,8 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods, /* check for "Unix Group" */ if ( sid_peek_check_rid(&global_sid_Unix_Groups, sid, &rid) ) { - *gid = rid; - *type = SID_NAME_ALIAS; + id->id = rid; + id->type = ID_TYPE_GID; ret = True; goto done; } @@ -1509,8 +1522,8 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods, goto done; } - *gid = map->gid; - *type = SID_NAME_ALIAS; + id->id = map->gid; + id->type = ID_TYPE_GID; ret = True; goto done; } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index d9e272ed6d..89e05c0169 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -51,6 +51,7 @@ #include "../libcli/security/security.h" #include "../lib/util/util_pw.h" #include "lib/winbind_util.h" +#include "librpc/gen_ndr/idmap.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB @@ -4970,8 +4971,7 @@ static bool ldapsam_new_rid(struct pdb_methods *methods, uint32_t *rid) static bool ldapsam_sid_to_id(struct pdb_methods *methods, const struct dom_sid *sid, - uid_t *uid, gid_t *gid, - enum lsa_SidType *type) + struct unixid *id) { struct ldapsam_privates *priv = (struct ldapsam_privates *)methods->private_data; @@ -5033,9 +5033,9 @@ static bool ldapsam_sid_to_id(struct pdb_methods *methods, goto done; } - *gid = strtoul(gid_str, NULL, 10); - *type = (enum lsa_SidType)strtoul(value, NULL, 10); - idmap_cache_set_sid2gid(sid, *gid); + id->id = strtoul(gid_str, NULL, 10); + id->type = ID_TYPE_GID; + idmap_cache_set_sid2gid(sid, id->id); ret = True; goto done; } @@ -5050,9 +5050,9 @@ static bool ldapsam_sid_to_id(struct pdb_methods *methods, goto done; } - *uid = strtoul(value, NULL, 10); - *type = SID_NAME_USER; - idmap_cache_set_sid2uid(sid, *uid); + id->id = strtoul(value, NULL, 10); + id->type = ID_TYPE_UID; + idmap_cache_set_sid2uid(sid, id->id); ret = True; done: diff --git a/source3/passdb/pdb_samba4.c b/source3/passdb/pdb_samba4.c index 024c293aa1..22a59084d7 100644 --- a/source3/passdb/pdb_samba4.c +++ b/source3/passdb/pdb_samba4.c @@ -51,7 +51,7 @@ static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state, TALLOC_CTX *mem_ctx, struct ldb_message **pmsg); static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid, - uid_t *uid, gid_t *gid, enum lsa_SidType *type); + struct unixid *id); static bool pdb_samba4_pull_time(struct ldb_message *msg, const char *attr, time_t *ptime) @@ -852,7 +852,7 @@ static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map, { struct pdb_samba4_state *state = talloc_get_type_abort( m->private_data, struct pdb_samba4_state); - const char *attrs[] = { "objectSid", "description", "samAccountName", + const char *attrs[] = { "objectSid", "description", "samAccountName", "groupType", NULL }; struct ldb_message *msg; va_list ap; @@ -860,7 +860,8 @@ static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map, struct dom_sid *sid; const char *str; int rc; - uid_t uid; + struct id_map id_map; + struct id_map *id_maps[2]; TALLOC_CTX *tmp_ctx = talloc_stackframe(); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); @@ -893,12 +894,46 @@ static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map, map->sid = *sid; - if (!pdb_samba4_sid_to_id(m, sid, &uid, &map->gid, &map->sid_name_use)) { + if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) { + NTSTATUS status; + uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0); + switch (grouptype) { + case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: + case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: + map->sid_name_use = SID_NAME_ALIAS; + break; + case GTYPE_SECURITY_GLOBAL_GROUP: + map->sid_name_use = SID_NAME_DOM_GRP; + break; + default: + talloc_free(tmp_ctx); + DEBUG(10, ("Could not pull groupType\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + map->sid_name_use = SID_NAME_DOM_GRP; + + ZERO_STRUCT(id_map); + id_map.sid = sid; + id_maps[0] = &id_map; + id_maps[1] = NULL; + + status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps); talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_GROUP; - } - if (map->sid_name_use == SID_NAME_USER) { + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) { + map->gid = id_map.xid.id; + } else { + DEBUG(1, (__location__ "Did not get GUID when mapping SID for %s", expression)); + talloc_free(tmp_ctx); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) { DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression)); + talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -2008,13 +2043,13 @@ static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid, } static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid, - uid_t *uid, gid_t *gid, enum lsa_SidType *type) + struct unixid *id) { struct pdb_samba4_state *state = talloc_get_type_abort( m->private_data, struct pdb_samba4_state); struct id_map id_map; struct id_map *id_maps[2]; - const char *attrs[] = { "objectClass", "groupType", NULL }; + const char *attrs[] = { "objectClass", NULL }; struct ldb_message *msg; struct ldb_dn *dn; NTSTATUS status; @@ -2038,22 +2073,7 @@ static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *si return false; } if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) { - uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0); - switch (grouptype) { - case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: - case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: - *type = SID_NAME_ALIAS; - break; - case GTYPE_SECURITY_GLOBAL_GROUP: - *type = SID_NAME_DOM_GRP; - break; - default: - talloc_free(tmp_ctx); - DEBUG(10, ("Could not pull groupType\n")); - return false; - } - - *type = SID_NAME_DOM_GRP; + id->type = ID_TYPE_GID; ZERO_STRUCT(id_map); id_map.sid = sid; @@ -2066,12 +2086,12 @@ static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *si return false; } if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) { - *gid = id_map.xid.id; + id->id = id_map.xid.id; return true; } return false; } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) { - *type = SID_NAME_USER; + id->type = ID_TYPE_UID; ZERO_STRUCT(id_map); id_map.sid = sid; id_maps[0] = &id_map; @@ -2083,7 +2103,7 @@ static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *si return false; } if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) { - *uid = id_map.xid.id; + id->id = id_map.xid.id; return true; } return false; diff --git a/source3/passdb/py_passdb.c b/source3/passdb/py_passdb.c index d0ef567738..17ae476b52 100644 --- a/source3/passdb/py_passdb.c +++ b/source3/passdb/py_passdb.c @@ -22,6 +22,7 @@ #include "includes.h" #include "lib/util/talloc_stack.h" #include "libcli/security/security.h" +#include "librpc/gen_ndr/idmap.h" #include "passdb.h" #include "secrets.h" @@ -2669,9 +2670,7 @@ static PyObject *py_pdb_sid_to_id(pytalloc_Object *self, PyObject *args) TALLOC_CTX *tframe; PyObject *py_sid; struct dom_sid *sid; - uid_t uid = -1; - gid_t gid = -1; - enum lsa_SidType type; + struct unixid id; if (!PyArg_ParseTuple(args, "O!:sid_to_id", dom_sid_Type, &py_sid)) { return NULL; @@ -2686,7 +2685,7 @@ static PyObject *py_pdb_sid_to_id(pytalloc_Object *self, PyObject *args) sid = pytalloc_get_ptr(py_sid); - if (!methods->sid_to_id(methods, sid, &uid, &gid, &type)) { + if (!methods->sid_to_id(methods, sid, &id)) { PyErr_Format(py_pdb_error, "Unable to get id for sid"); talloc_free(tframe); return NULL; @@ -2694,7 +2693,7 @@ static PyObject *py_pdb_sid_to_id(pytalloc_Object *self, PyObject *args) talloc_free(tframe); - return Py_BuildValue("(II)", (uid != -1)?uid:gid, type); + return Py_BuildValue("(II)", id.id, id.type); } diff --git a/source3/winbindd/idmap_passdb.c b/source3/winbindd/idmap_passdb.c index 4c26c5c466..e547e9bf7c 100644 --- a/source3/winbindd/idmap_passdb.c +++ b/source3/winbindd/idmap_passdb.c @@ -76,31 +76,8 @@ static NTSTATUS idmap_pdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma int i; for (i = 0; ids[i]; i++) { - enum lsa_SidType type; - uid_t uid; - gid_t gid; - - if (pdb_sid_to_id(ids[i]->sid, &uid, &gid, &type)) { - switch (type) { - case SID_NAME_USER: - ids[i]->xid.id = uid; - ids[i]->xid.type = ID_TYPE_UID; - ids[i]->status = ID_MAPPED; - break; - - case SID_NAME_DOM_GRP: - case SID_NAME_ALIAS: - case SID_NAME_WKN_GRP: - ids[i]->xid.id = gid; - ids[i]->xid.type = ID_TYPE_GID; - ids[i]->status = ID_MAPPED; - break; - - default: /* ?? */ - /* make sure it is marked as unmapped */ - ids[i]->status = ID_UNKNOWN; - break; - } + if (pdb_sid_to_id(ids[i]->sid, &ids[i]->xid)) { + ids[i]->status = ID_MAPPED; } else { /* Query Failed */ ids[i]->status = ID_UNMAPPED; -- cgit