1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-02 09:47:23 +03:00

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 <obnox@samba.org>
This commit is contained in:
Andrew Bartlett 2012-03-16 09:16:23 +11:00 committed by Michael Adam
parent 8026550115
commit a6e29f23f0
9 changed files with 153 additions and 167 deletions

View File

@ -33,6 +33,7 @@
#include "../librpc/gen_ndr/lsa.h"
#include <tevent.h>
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);

View File

@ -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,113 +1075,83 @@ 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 */
}
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) {
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;
}
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) {
struct unixid id;
if (!legacy_sid_to_id(psid, &id)) {
return false;
}
if ((sid_check_is_in_builtin(psid) ||
sid_check_is_in_wellknown_domain(psid))) {
bool ret;
become_root();
ret = pdb_getgrsid(map, *psid);
unbecome_root();
if (ret) {
*pgid = map->gid;
goto done;
}
DEBUG(10,("LEGACY: mapping failed for sid %s\n",
sid_string_dbg(psid)));
return false;
if (id.type == ID_TYPE_GID || id.type == ID_TYPE_BOTH) {
*pgid = id.id;
return true;
}
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);
return true;
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;
}
/*****************************************************************

View File

@ -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 */

View File

@ -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:

View File

@ -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;
}

View File

@ -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:

View File

@ -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;

View File

@ -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);
}

View File

@ -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;