From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/sam/idmap.c | 106 +++++------ source3/sam/idmap_ad.c | 14 +- source3/sam/idmap_ldap.c | 41 +++-- source3/sam/idmap_rid.c | 13 +- source3/sam/idmap_smbldap.c | 10 +- source3/sam/idmap_tdb.c | 436 +++++++++++++++++++++++++------------------- source3/sam/idmap_util.c | 61 ++++--- 7 files changed, 369 insertions(+), 312 deletions(-) (limited to 'source3/sam') diff --git a/source3/sam/idmap.c b/source3/sam/idmap.c index aa5b923d3d..e8ebd9272c 100644 --- a/source3/sam/idmap.c +++ b/source3/sam/idmap.c @@ -4,7 +4,7 @@ Copyright (C) Tim Potter 2000 Copyright (C) Jim McDonough 2003 Copyright (C) Simo Sorce 2003 - Copyright (C) Jeremy Allison 2003. + Copyright (C) Jeremy Allison 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -182,13 +182,14 @@ BOOL idmap_proxyonly(void) set up for a sid to a POSIX id. **************************************************************************/ -NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) +NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, enum idmap_type id_type) { struct idmap_methods *map = remote_map; DOM_SID tmp_sid; - if (proxyonly) + if (proxyonly) { return NT_STATUS_UNSUCCESSFUL; + } if (sid_check_is_in_our_domain(sid)) { DEBUG(3, ("Refusing to add SID %s to idmap, it's our own " @@ -204,14 +205,12 @@ NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) DEBUG(10, ("idmap_set_mapping: Set %s to %s %lu\n", sid_string_static(sid), - ((id_type & ID_TYPEMASK) == ID_USERID) ? "UID" : "GID", - ((id_type & ID_TYPEMASK) == ID_USERID) ? (unsigned long)id.uid : + (id_type == ID_USERID) ? "UID" : "GID", + (id_type == ID_USERID) ? (unsigned long)id.uid : (unsigned long)id.gid)); - if ( (NT_STATUS_IS_OK(cache_map-> - get_sid_from_id(&tmp_sid, id, - id_type | ID_QUERY_ONLY))) && - sid_equal(sid, &tmp_sid) ) { + if ( (NT_STATUS_IS_OK(cache_map->get_sid_from_id(&tmp_sid, id, id_type, IDMAP_FLAG_QUERY_ONLY))) && + sid_equal(sid, &tmp_sid) ) { /* Nothing to do, we already have that mapping */ DEBUG(10, ("idmap_set_mapping: Mapping already there\n")); return NT_STATUS_OK; @@ -230,14 +229,14 @@ NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) Get ID from SID. This can create a mapping for a SID to a POSIX id. **************************************************************************/ -NTSTATUS idmap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid) +NTSTATUS idmap_get_id_from_sid(unid_t *id, enum idmap_type *id_type, const DOM_SID *sid, int flags) { NTSTATUS ret; - int loc_type; - unid_t loc_id; + int cache_flags = flags; - if (proxyonly) + if (proxyonly) { return NT_STATUS_UNSUCCESSFUL; + } if (sid_check_is_in_our_domain(sid)) { DEBUG(9, ("sid %s is in our domain -- go look in passdb\n", @@ -251,55 +250,24 @@ NTSTATUS idmap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid) return NT_STATUS_NONE_MAPPED; } - loc_type = *id_type; - if (remote_map) { /* We have a central remote idmap so only look in - cache, don't allocate */ - loc_type |= ID_QUERY_ONLY; + cache, ensure we don't allocate */ + cache_flags |= IDMAP_FLAG_QUERY_ONLY; } - ret = cache_map->get_id_from_sid(id, &loc_type, sid); - + ret = cache_map->get_id_from_sid(id, id_type, sid, cache_flags); if (NT_STATUS_IS_OK(ret)) { - *id_type = loc_type & ID_TYPEMASK; return NT_STATUS_OK; } - if ((remote_map == NULL) || (loc_type & ID_CACHE_ONLY)) { + if ((remote_map == NULL) || (flags & IDMAP_FLAG_CACHE_ONLY)) { return ret; } - /* Before forking out to the possibly slow remote map, lets see if we - * already have the sid as uid when asking for a gid or vice versa. */ - - loc_type = *id_type & ID_TYPEMASK; - - switch (loc_type) { - case ID_USERID: - loc_type = ID_GROUPID; - break; - case ID_GROUPID: - loc_type = ID_USERID; - break; - default: - loc_type = ID_EMPTY; - } - - loc_type |= ID_QUERY_ONLY; - - ret = cache_map->get_id_from_sid(&loc_id, &loc_type, sid); - - if (NT_STATUS_IS_OK(ret)) { - /* Ok, we have the uid as gid or vice versa. The remote map - * would not know anything different, so return here. */ - return NT_STATUS_UNSUCCESSFUL; - } - - /* Ok, the mapping was not in the cache, give the remote map a - second try. */ + /* Ok, the mapping was not in the cache, give the remote map a try. */ - ret = remote_map->get_id_from_sid(id, id_type, sid); + ret = remote_map->get_id_from_sid(id, id_type, sid, flags); if (NT_STATUS_IS_OK(ret)) { /* The remote backend gave us a valid mapping, cache it. */ @@ -313,30 +281,34 @@ NTSTATUS idmap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid) Get SID from ID. This must have been created before. **************************************************************************/ -NTSTATUS idmap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) +NTSTATUS idmap_get_sid_from_id(DOM_SID *sid, unid_t id, enum idmap_type id_type, int flags) { NTSTATUS ret; - int loc_type; + int cache_flags = flags; - if (proxyonly) + if (proxyonly) { return NT_STATUS_UNSUCCESSFUL; + } - loc_type = id_type; if (remote_map) { - loc_type = id_type | ID_QUERY_ONLY; + /* We have a central remote idmap so only look in + cache, ensure we don't allocate */ + cache_flags |= IDMAP_FLAG_QUERY_ONLY; } - ret = cache_map->get_sid_from_id(sid, id, loc_type); + ret = cache_map->get_sid_from_id(sid, id, id_type, cache_flags); - if (NT_STATUS_IS_OK(ret)) + if (NT_STATUS_IS_OK(ret)) { return ret; + } - if ((remote_map == NULL) || (loc_type & ID_CACHE_ONLY)) + if ((remote_map == NULL) || (flags & IDMAP_FLAG_CACHE_ONLY)) { return ret; + } - /* We have a second chance, ask our authoritative backend */ + /* Not in cache, ask our authoritative backend */ - ret = remote_map->get_sid_from_id(sid, id, id_type); + ret = remote_map->get_sid_from_id(sid, id, id_type, flags); if (NT_STATUS_IS_OK(ret)) { /* The remote backend gave us a valid mapping, cache it. */ @@ -350,15 +322,17 @@ NTSTATUS idmap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) Alloocate a new UNIX uid/gid **************************************************************************/ -NTSTATUS idmap_allocate_id(unid_t *id, int id_type) +NTSTATUS idmap_allocate_id(unid_t *id, enum idmap_type id_type) { /* we have to allocate from the authoritative backend */ - if (proxyonly) + if (proxyonly) { return NT_STATUS_UNSUCCESSFUL; + } - if ( remote_map ) + if ( remote_map ) { return remote_map->allocate_id( id, id_type ); + } return cache_map->allocate_id( id, id_type ); } @@ -371,8 +345,9 @@ NTSTATUS idmap_close(void) { NTSTATUS ret; - if (proxyonly) + if (proxyonly) { return NT_STATUS_OK; + } ret = cache_map->close_fn(); if (!NT_STATUS_IS_OK(ret)) { @@ -398,6 +373,7 @@ NTSTATUS idmap_close(void) void idmap_status(void) { cache_map->status(); - if (remote_map) + if (remote_map) { remote_map->status(); + } } diff --git a/source3/sam/idmap_ad.c b/source3/sam/idmap_ad.c index 5edfad487d..f0adfa4028 100644 --- a/source3/sam/idmap_ad.c +++ b/source3/sam/idmap_ad.c @@ -139,7 +139,7 @@ static ADS_STRUCT *ad_idmap_cached_connection(void) return ads; } -static NTSTATUS ad_idmap_init(char *uri) +static NTSTATUS ad_idmap_init(const char *uri) { ad_idmap_uri = SMB_STRDUP(uri); if (ad_idmap_uri == NULL) { @@ -149,7 +149,7 @@ static NTSTATUS ad_idmap_init(char *uri) return NT_STATUS_OK; } -static NTSTATUS ad_idmap_get_sid_from_id(DOM_SID *sid, unid_t unid, int id_type) +static NTSTATUS ad_idmap_get_sid_from_id(DOM_SID *sid, unid_t unid, enum idmap_type id_type, int flags) { ADS_STATUS rc; NTSTATUS status = NT_STATUS_NONE_MAPPED; @@ -171,7 +171,7 @@ static NTSTATUS ad_idmap_get_sid_from_id(DOM_SID *sid, unid_t unid, int id_type) return NT_STATUS_NOT_SUPPORTED; } - switch (id_type & ID_TYPEMASK) { + switch (id_type) { case ID_USERID: if (asprintf(&expr, "(&(|(sAMAccountType=%d)(sAMAccountType=%d)(sAMAccountType=%d))(%s=%d))", ATYPE_NORMAL_ACCOUNT, ATYPE_WORKSTATION_TRUST, ATYPE_INTERDOMAIN_TRUST, @@ -231,7 +231,7 @@ done: return status; } -static NTSTATUS ad_idmap_get_id_from_sid(unid_t *unid, int *id_type, const DOM_SID *sid) +static NTSTATUS ad_idmap_get_id_from_sid(unid_t *unid, enum idmap_type *id_type, const DOM_SID *sid, int flags) { ADS_STATUS rc; NTSTATUS status = NT_STATUS_NONE_MAPPED; @@ -331,7 +331,7 @@ done: } -static NTSTATUS ad_idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) +static NTSTATUS ad_idmap_set_mapping(const DOM_SID *sid, unid_t id, enum idmap_type id_type) { /* Not supported, and probably won't be... */ /* (It's not particularly feasible with a single-master model.) */ @@ -356,7 +356,7 @@ static NTSTATUS ad_idmap_close(void) return NT_STATUS_OK; } -static NTSTATUS ad_idmap_allocate_id(unid_t *id, int id_type) +static NTSTATUS ad_idmap_allocate_id(unid_t *id, enum idmap_type id_type) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -378,7 +378,7 @@ static struct idmap_methods ad_methods = { /* support for new authentication subsystem */ -NTSTATUS init_module(void) +NTSTATUS idmap_ad_init(void) { return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ad", &ad_methods); } diff --git a/source3/sam/idmap_ldap.c b/source3/sam/idmap_ldap.c index 6169c89b3b..3fec3a142b 100644 --- a/source3/sam/idmap_ldap.c +++ b/source3/sam/idmap_ldap.c @@ -49,7 +49,7 @@ static struct ldap_idmap_state ldap_state; This function cannot be called to modify a mapping, only set a new one ***********************************************************************/ -static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) +static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, enum idmap_type id_type) { pstring dn; pstring id_str; @@ -66,12 +66,13 @@ static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID), sid_string, lp_ldap_idmap_suffix()); - if ( id_type & ID_USERID ) + if ( id_type == ID_USERID ) { fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ) ); - else + } else { fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ) ); + } - pstr_sprintf(id_str, "%lu", ((id_type & ID_USERID) ? (unsigned long)id.uid : + pstr_sprintf(id_str, "%lu", ((id_type == ID_USERID) ? (unsigned long)id.uid : (unsigned long)id.gid)); smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY ); @@ -117,7 +118,7 @@ static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) Allocate a new uid or gid *****************************************************************************/ -static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) +static NTSTATUS ldap_allocate_id(unid_t *id, enum idmap_type id_type) { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; int rc = LDAP_SERVER_DOWN; @@ -133,8 +134,11 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) uid_t luid, huid; gid_t lgid, hgid; + if (id_type != ID_USERID && id_type != ID_GROUPID) { + return NT_STATUS_INVALID_PARAMETER; + } - type = (id_type & ID_USERID) ? + type = (id_type == ID_USERID) ? get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) : get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); @@ -177,15 +181,14 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) /* make sure we still have room to grow */ - if (id_type & ID_USERID) { + if (id_type == ID_USERID) { id->uid = strtoul(id_str, NULL, 10); if (id->uid > huid ) { DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %lu!\n", (unsigned long)huid)); goto out; } - } - else { + } else { id->gid = strtoul(id_str, NULL, 10); if (id->gid > hgid ) { DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %lu!\n", @@ -195,7 +198,7 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) } pstr_sprintf(new_id_str, "%lu", - ((id_type & ID_USERID) ? (unsigned long)id->uid : + ((id_type == ID_USERID) ? (unsigned long)id->uid : (unsigned long)id->gid) + 1); smbldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str ); @@ -228,7 +231,7 @@ out: get a sid from an id *****************************************************************************/ -static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) +static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, enum idmap_type id_type, int flags) { LDAPMessage *result = NULL; LDAPMessage *entry = NULL; @@ -241,7 +244,7 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; const char **attr_list; - if ( id_type & ID_USERID ) + if ( id_type == ID_USERID ) type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ); else type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); @@ -289,10 +292,12 @@ out: } /*********************************************************************** - Get an id from a sid + Get an id from a sid - urg. This is assuming the *output* parameter id_type + has been initialized with the correct needed type - ID_USERID or ID_GROUPID. + This *sucks* and is bad design and needs fixing. JRA. ***********************************************************************/ -static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid) +static NTSTATUS ldap_get_id_from_sid(unid_t *id, enum idmap_type *id_type, const DOM_SID *sid, int flags) { LDAPMessage *result = NULL; LDAPMessage *entry = NULL; @@ -316,7 +321,7 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str); - if ( *id_type & ID_GROUPID ) + if ( *id_type == ID_GROUPID ) type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ); else type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ); @@ -348,7 +353,7 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si if ( !count ) { int i; - if (*id_type & ID_QUERY_ONLY) { + if (flags & IDMAP_FLAG_QUERY_ONLY) { DEBUG(5,("ldap_get_id_from_sid: No matching entry found and QUERY_ONLY flag set\n")); goto out; } @@ -387,7 +392,7 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn, type)); if ( smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, type, id_str) ) { - if ( (*id_type & ID_USERID) ) + if ( (*id_type == ID_USERID) ) id->uid = strtoul(id_str, NULL, 10); else id->gid = strtoul(id_str, NULL, 10); @@ -470,7 +475,7 @@ static NTSTATUS verify_idpool( void ) Initialise idmap database. *****************************************************************************/ -static NTSTATUS ldap_idmap_init( char *params ) +static NTSTATUS ldap_idmap_init( const char *params ) { NTSTATUS nt_status; diff --git a/source3/sam/idmap_rid.c b/source3/sam/idmap_rid.c index 58838512a6..23496d6969 100644 --- a/source3/sam/idmap_rid.c +++ b/source3/sam/idmap_rid.c @@ -334,7 +334,7 @@ out: return status; } -static NTSTATUS rid_idmap_init(char *init_param) +static NTSTATUS rid_idmap_init(const char *init_param) { int i, j; uid_t u_low, u_high; @@ -432,7 +432,8 @@ out: return nt_status; } -static NTSTATUS rid_idmap_get_sid_from_id(DOM_SID *sid, unid_t unid, int id_type) +static NTSTATUS rid_idmap_get_sid_from_id(DOM_SID *sid, unid_t unid, enum idmap_type id_type, int flags) + { fstring sid_string; int i; @@ -469,7 +470,7 @@ static NTSTATUS rid_idmap_get_sid_from_id(DOM_SID *sid, unid_t unid, int id_type return NT_STATUS_OK; } -static NTSTATUS rid_idmap_get_id_from_sid(unid_t *unid, int *id_type, const DOM_SID *sid) +static NTSTATUS rid_idmap_get_id_from_sid(unid_t *unid, enum idmap_type *id_type, const DOM_SID *sid, int flags) { fstring sid_string; int i; @@ -521,7 +522,7 @@ static NTSTATUS rid_idmap_get_id_from_sid(unid_t *unid, int *id_type, const DOM_ } -static NTSTATUS rid_idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) +static NTSTATUS rid_idmap_set_mapping(const DOM_SID *sid, unid_t id, enum idmap_type id_type) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -533,7 +534,7 @@ static NTSTATUS rid_idmap_close(void) return NT_STATUS_OK; } -static NTSTATUS rid_idmap_allocate_id(unid_t *id, int id_type) +static NTSTATUS rid_idmap_allocate_id(unid_t *id, enum idmap_type id_type) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -553,7 +554,7 @@ static struct idmap_methods rid_methods = { rid_idmap_status }; -NTSTATUS init_module(void) +NTSTATUS idmap_rid_init(void) { return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "rid", &rid_methods); } diff --git a/source3/sam/idmap_smbldap.c b/source3/sam/idmap_smbldap.c index 4d80364437..9850921fa3 100644 --- a/source3/sam/idmap_smbldap.c +++ b/source3/sam/idmap_smbldap.c @@ -90,7 +90,7 @@ static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) Allocate a new uid or gid *****************************************************************************/ -static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) +static NTSTATUS ldap_allocate_id(unid_t *id, enum idmap_type id_type) { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; uid_t luid, huid; @@ -104,7 +104,11 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) const char *id_attrib; char *mod; - id_attrib = (id_type & ID_USERID) ? "uidNumber" : "gidNumber"; + if (id_type != ID_USERID && id_type != ID_GROUPID) { + return NT_STATUS_INVALID_PARAMETER; + } + + id_attrib = (id_type == ID_USERID) ? "uidNumber" : "gidNumber"; idpool_s = new_ldap_search_message(lp_ldap_suffix(), LDAP_SEARCH_SCOPE_SUB, @@ -129,7 +133,7 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) /* make sure we still have room to grow */ - if (id_type & ID_USERID) { + if (id_type == ID_USERID) { id->uid = value; if (id->uid > huid ) { DEBUG(0,("ldap_allocate_id: Cannot allocate uid " diff --git a/source3/sam/idmap_tdb.c b/source3/sam/idmap_tdb.c index 665c56d2f6..02a3178d61 100644 --- a/source3/sam/idmap_tdb.c +++ b/source3/sam/idmap_tdb.c @@ -6,6 +6,7 @@ Copyright (C) Tim Potter 2000 Copyright (C) Jim McDonough 2003 Copyright (C) Simo Sorce 2003 + Copyright (C) Jeremy Allison 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -46,16 +47,13 @@ static struct idmap_state { Allocate either a user or group id from the pool **********************************************************************/ -static NTSTATUS db_allocate_id(unid_t *id, int id_type) +static NTSTATUS db_allocate_id(unid_t *id, enum idmap_type id_type) { BOOL ret; int hwm; - if (!id) - return NT_STATUS_INVALID_PARAMETER; - /* Get current high water mark */ - switch (id_type & ID_TYPEMASK) { + switch (id_type) { case ID_USERID: if ((hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) { @@ -125,274 +123,327 @@ static NTSTATUS db_allocate_id(unid_t *id, int id_type) return NT_STATUS_OK; } -/* Get a sid from an id */ -static NTSTATUS internal_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) +/* Get a sid from an id - internal non-reverse map checking function. */ + +static NTSTATUS db_internal_get_sid_from_id(DOM_SID *sid, unid_t id, enum idmap_type id_type) { TDB_DATA key, data; - fstring keystr; + TALLOC_CTX *memctx; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - if (!sid) - return NT_STATUS_INVALID_PARAMETER; + if ((memctx = talloc_new(NULL)) == NULL) { + DEBUG(0, ("ERROR: Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } - switch (id_type & ID_TYPEMASK) { + switch (id_type) { case ID_USERID: - slprintf(keystr, sizeof(keystr), "UID %lu", (unsigned long)id.uid); + key.dptr = talloc_asprintf(memctx, "UID %lu", (unsigned long)id.uid); break; case ID_GROUPID: - slprintf(keystr, sizeof(keystr), "GID %lu", (unsigned long)id.gid); + key.dptr = talloc_asprintf(memctx, "GID %lu", (unsigned long)id.gid); break; default: - return NT_STATUS_UNSUCCESSFUL; + ret = NT_STATUS_INVALID_PARAMETER; + goto done; + } + + if (key.dptr == NULL) { + DEBUG(0, ("ERROR: Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; } - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; + key.dsize = strlen(key.dptr) + 1; - DEBUG(10,("internal_get_sid_from_id: fetching record %s\n", keystr )); + DEBUG(10,("db_internal_get_sid_from_id: fetching record %s\n", key.dptr)); data = tdb_fetch(idmap_tdb, key); if (data.dptr) { if (string_to_sid(sid, data.dptr)) { - DEBUG(10,("internal_get_sid_from_id: fetching record %s -> %s\n", keystr, data.dptr )); + DEBUG(10,("db_internal_get_sid_from_id: fetching record %s -> %s\n", key.dptr, data.dptr )); ret = NT_STATUS_OK; } SAFE_FREE(data.dptr); } +done: + talloc_free(memctx); return ret; } -/* Error codes for get_id_from_sid */ -enum getidfromsiderr { GET_ID_FROM_SID_OK = 0, GET_ID_FROM_SID_NOTFOUND, GET_ID_FROM_SID_WRONG_TYPE, GET_ID_FROM_SID_ERR }; +/* Get an id from a sid - internal non-reverse map checking function. */ -static enum getidfromsiderr internal_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid) +static NTSTATUS db_internal_get_id_from_sid(unid_t *id, enum idmap_type *id_type, const DOM_SID *sid) { - enum getidfromsiderr ret = GET_ID_FROM_SID_ERR; - fstring keystr; + NTSTATUS ret; TDB_DATA key, data; - int type = *id_type & ID_TYPEMASK; + TALLOC_CTX *memctx; + unsigned long rec_id; + + if ((memctx = talloc_new(NULL)) == NULL) { + DEBUG(0, ("ERROR: Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } /* Check if sid is present in database */ - sid_to_string(keystr, sid); + if ((key.dptr = talloc_asprintf(memctx, "%s", sid_string_static(sid))) == NULL) { + DEBUG(0, ("ERROR: Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; + } - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; + key.dsize = strlen(key.dptr) + 1; - DEBUG(10,("internal_get_id_from_sid: fetching record %s of type 0x%x\n", keystr, type )); + DEBUG(10,("db_internal_get_id_from_sid: fetching record %s\n", key.dptr)); data = tdb_fetch(idmap_tdb, key); if (!data.dptr) { - DEBUG(10,("internal_get_id_from_sid: record %s not found\n", keystr )); - return GET_ID_FROM_SID_NOTFOUND; + DEBUG(10,("db_internal_get_id_from_sid: record %s not found\n", key.dptr)); + ret = NT_STATUS_NO_SUCH_USER; + goto done; } else { - DEBUG(10,("internal_get_id_from_sid: record %s -> %s\n", keystr, data.dptr )); + DEBUG(10,("db_internal_get_id_from_sid: record %s -> %s\n", key.dptr, data.dptr)); } - if (type == ID_EMPTY || type == ID_USERID) { - fstring scanstr; - /* Parse and return existing uid */ - fstrcpy(scanstr, "UID %d"); - - if (sscanf(data.dptr, scanstr, &((*id).uid)) == 1) { - /* uid ok? */ - if (type == ID_EMPTY) { - *id_type = ID_USERID; - } - DEBUG(10,("internal_get_id_from_sid: %s fetching record %s -> %s \n", - (type == ID_EMPTY) ? "ID_EMPTY" : "ID_USERID", - keystr, data.dptr )); - ret = GET_ID_FROM_SID_OK; - } else { - ret = GET_ID_FROM_SID_WRONG_TYPE; - } - } - - if ((ret != GET_ID_FROM_SID_OK) && (type == ID_EMPTY || type == ID_GROUPID)) { - fstring scanstr; - /* Parse and return existing gid */ - fstrcpy(scanstr, "GID %d"); - - if (sscanf(data.dptr, scanstr, &((*id).gid)) == 1) { - /* gid ok? */ - if (type == ID_EMPTY) { - *id_type = ID_GROUPID; - } - DEBUG(10,("internal_get_id_from_sid: %s fetching record %s -> %s \n", - (type == ID_EMPTY) ? "ID_EMPTY" : "ID_GROUPID", - keystr, data.dptr )); - ret = GET_ID_FROM_SID_OK; - } else { - ret = GET_ID_FROM_SID_WRONG_TYPE; - } + /* What type of record is this ? */ + + /* Try and parse and return a uid */ + if (sscanf(data.dptr, "UID %lu", &rec_id) == 1) { + id->uid = (uid_t)rec_id; + *id_type = ID_USERID; + DEBUG(10,("db_internal_get_id_from_sid: fetching uid record %s -> %s \n", + key.dptr, data.dptr )); + ret = NT_STATUS_OK; + } else if (sscanf(data.dptr, "GID %lu", &rec_id) == 1) { /* Try a GID record. */ + id->gid = (uid_t)rec_id; + *id_type = ID_GROUPID; + DEBUG(10,("db_internal_get_id_from_sid: fetching gid record %s -> %s \n", + key.dptr, data.dptr )); + ret = NT_STATUS_OK; + } else { + /* Unknown record type ! */ + ret = NT_STATUS_INTERNAL_DB_ERROR; } SAFE_FREE(data.dptr); +done: + talloc_free(memctx); return ret; } -/* Get a sid from an id */ -static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type_in) +/* Get a sid from an id - internal non-reverse map checking function. */ + +static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, enum idmap_type id_type, int flags) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - enum getidfromsiderr iderr; - int id_type = id_type_in & ID_TYPEMASK; - unid_t id_tmp = id; - int id_type_tmp = id_type; + NTSTATUS ret; + unid_t tmp_id; + enum idmap_type tmp_id_type; - DEBUG(10,("db_get_sid_from_id: id_type_in = 0x%x\n", id_type_in)); + ret = db_internal_get_sid_from_id(sid, id, id_type); - ret = internal_get_sid_from_id(sid, id, id_type); if (!NT_STATUS_IS_OK(ret)) { return ret; } - - iderr = internal_get_id_from_sid(&id_tmp, &id_type_tmp, sid); - if (iderr != GET_ID_FROM_SID_OK) { - return NT_STATUS_UNSUCCESSFUL; - } - if (id_type_tmp != id_type) { - return NT_STATUS_UNSUCCESSFUL; - } else if (id_type == ID_USERID) { - if (id_tmp.uid != id.uid) { - return NT_STATUS_UNSUCCESSFUL; - } - } else if (id_type == ID_GROUPID) { - if (id_tmp.gid != id.gid) { - return NT_STATUS_UNSUCCESSFUL; + + /* Ensure the reverse mapping exists. */ + + ret = db_internal_get_id_from_sid(&tmp_id, &tmp_id_type, sid); + if (NT_STATUS_IS_OK(ret)) { + /* Check the reverse mapping is the same. */ + if (tmp_id.uid != id.uid || tmp_id_type != id_type) { + DEBUG(10,("db_get_sid_from_id: reverse mapping mismatch " + "tmp_id = %u, id = %u, tmp_id_type = %u, id_type = %u\n", + (unsigned int)tmp_id.uid, (unsigned int)id.uid, + (unsigned int)tmp_id_type, (unsigned int)id_type )); + return NT_STATUS_NO_SUCH_USER; } - } else { - return NT_STATUS_UNSUCCESSFUL; } + return ret; } -/* Get an id from a sid */ -static NTSTATUS db_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid) + +/*********************************************************************** + Why is this function internal and not part of the interface ????? + This *sucks* and is bad design and needs fixing. JRA. +***********************************************************************/ + +static NTSTATUS db_internal_allocate_new_id_for_sid(unid_t *id, enum idmap_type *id_type, const DOM_SID *sid) { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - enum getidfromsiderr iderr; + TDB_DATA sid_data; + TDB_DATA ugid_data; + TALLOC_CTX *memctx; + + if ((memctx = talloc_new(NULL)) == NULL) { + DEBUG(0, ("ERROR: Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } - DEBUG(10,("db_get_id_from_sid\n")); + if ((sid_data.dptr = talloc_asprintf(memctx, "%s", sid_string_static(sid))) == NULL) { + DEBUG(0, ("ERROR: Out of memory!\n")); + talloc_free(memctx); + return NT_STATUS_NO_MEMORY; + } - if (!sid || !id || !id_type) - return NT_STATUS_INVALID_PARAMETER; + sid_data.dsize = strlen(sid_data.dptr) + 1; - iderr = internal_get_id_from_sid(id, id_type, sid); - if (iderr == GET_ID_FROM_SID_OK) { - DOM_SID sid_tmp; - ret = internal_get_sid_from_id(&sid_tmp, *id, *id_type); - if (NT_STATUS_IS_OK(ret)) { - if (!sid_equal(&sid_tmp, sid)) { - return NT_STATUS_UNSUCCESSFUL; - } - } - } else if (iderr == GET_ID_FROM_SID_WRONG_TYPE) { - /* We found a record but not the type we wanted. - * This is an error, not an opportunity to overwrite... - * JRA. - */ + /* Lock the record for this SID. */ + if (tdb_chainlock(idmap_tdb, sid_data) != 0) { + DEBUG(10,("db_internal_allocate_new_id_for_sid: failed to lock record %s. Error %s\n", + sid_data.dptr, tdb_errorstr(idmap_tdb) )); + talloc_free(memctx); return NT_STATUS_UNSUCCESSFUL; } - if (!(*id_type & ID_QUERY_ONLY) && (iderr != GET_ID_FROM_SID_OK) && - (((*id_type & ID_TYPEMASK) == ID_USERID) - || (*id_type & ID_TYPEMASK) == ID_GROUPID)) { - TDB_DATA sid_data; - TDB_DATA ugid_data; - fstring sid_string; - - sid_to_string(sid_string, sid); - - sid_data.dptr = sid_string; - sid_data.dsize = strlen(sid_string)+1; - - /* Lock the record for this SID. */ - if (tdb_chainlock(idmap_tdb, sid_data) != 0) { - DEBUG(10,("db_get_id_from_sid: failed to lock record %s. Error %s\n", - sid_string, tdb_errorstr(idmap_tdb) )); - return NT_STATUS_UNSUCCESSFUL; + do { + /* Allocate a new id for this sid */ + ret = db_allocate_id(id, *id_type); + if (!NT_STATUS_IS_OK(ret)) { + goto done; + } + + /* Store the UID side */ + /* Store new id */ + if (*id_type == ID_USERID) { + ugid_data.dptr = talloc_asprintf(memctx, "UID %lu", + (unsigned long)((*id).uid)); + } else { + ugid_data.dptr = talloc_asprintf(memctx, "GID %lu", + (unsigned long)((*id).gid)); } - do { - fstring ugid_str; + if (ugid_data.dptr == NULL) { + DEBUG(0, ("ERROR: Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; + } - /* Allocate a new id for this sid */ - ret = db_allocate_id(id, *id_type); - if (!NT_STATUS_IS_OK(ret)) - break; + ugid_data.dsize = strlen(ugid_data.dptr) + 1; - /* Store the UID side */ - /* Store new id */ - if (*id_type & ID_USERID) { - slprintf(ugid_str, sizeof(ugid_str), "UID %lu", - (unsigned long)((*id).uid)); - } else { - slprintf(ugid_str, sizeof(ugid_str), "GID %lu", - (unsigned long)((*id).gid)); - } - - ugid_data.dptr = ugid_str; - ugid_data.dsize = strlen(ugid_str) + 1; + DEBUG(10,("db_internal_allocate_new_id_for_sid: storing %s -> %s\n", + ugid_data.dptr, sid_data.dptr )); - DEBUG(10,("db_get_id_from_sid: storing %s -> %s\n", - ugid_data.dptr, sid_data.dptr )); + if (tdb_store(idmap_tdb, ugid_data, sid_data, TDB_INSERT) != -1) { + ret = NT_STATUS_OK; + break; + } + if (tdb_error(idmap_tdb) != TDB_ERR_EXISTS) { + DEBUG(10,("db_internal_allocate_new_id_for_sid: error %s\n", tdb_errorstr(idmap_tdb))); + } + + ret = NT_STATUS_INTERNAL_DB_ERROR; - if (tdb_store(idmap_tdb, ugid_data, sid_data, TDB_INSERT) != -1) { - ret = NT_STATUS_OK; - break; - } - if (tdb_error(idmap_tdb) != TDB_ERR_EXISTS) - DEBUG(10,("db_get_id_from_sid: error %s\n", tdb_errorstr(idmap_tdb) )); - ret = NT_STATUS_UNSUCCESSFUL; - } while (tdb_error(idmap_tdb) == TDB_ERR_EXISTS); + } while (tdb_error(idmap_tdb) == TDB_ERR_EXISTS); - if (NT_STATUS_IS_OK(ret)) { + if (NT_STATUS_IS_OK(ret)) { + DEBUG(10,("db_internal_allocate_new_id_for_sid: storing %s -> %s\n", + sid_data.dptr, ugid_data.dptr )); - DEBUG(10,("db_get_id_from_sid: storing %s -> %s\n", - sid_data.dptr, ugid_data.dptr )); + if (tdb_store(idmap_tdb, sid_data, ugid_data, TDB_REPLACE) == -1) { + DEBUG(10,("db_internal_allocate_new_id_for_sid: error %s\n", tdb_errorstr(idmap_tdb) )); + ret = NT_STATUS_INTERNAL_DB_ERROR; + } + } - if (tdb_store(idmap_tdb, sid_data, ugid_data, TDB_REPLACE) == -1) { - DEBUG(10,("db_get_id_from_sid: error %s\n", tdb_errorstr(idmap_tdb) )); - /* TODO: print tdb error !! */ - tdb_chainunlock(idmap_tdb, sid_data); - return NT_STATUS_UNSUCCESSFUL; + done: + + tdb_chainunlock(idmap_tdb, sid_data); + talloc_free(memctx); + + return ret; +} + +/*********************************************************************** + Get an id from a sid - urg. This is assuming the *output* parameter id_type + has been initialized with the correct needed type - ID_USERID or ID_GROUPID. + This function also allocates new mappings ! WTF ?????? + This *sucks* and is bad design and needs fixing. JRA. +***********************************************************************/ + +static NTSTATUS db_get_id_from_sid(unid_t *id, enum idmap_type *id_type, const DOM_SID *sid, int flags) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + enum idmap_type tmp_id_type = *id_type; + + DEBUG(10,("db_get_id_from_sid %s\n", sid_string_static(sid))); + + ret = db_internal_get_id_from_sid(id, &tmp_id_type, sid); + + if (NT_STATUS_IS_OK(ret)) { + DOM_SID sid_tmp; + + /* Check the reverse mapping is the same. Remember *id_type was set as a parameter + to this call... */ + if (tmp_id_type != *id_type) { + DEBUG(10,("db_get_sid_from_id: sid %s reverse mapping mismatch " + "tmp_id_type = %u, id_type = %u\n", + sid_string_static(sid), + (unsigned int)tmp_id_type, (unsigned int)(*id_type) )); + return NT_STATUS_NO_SUCH_USER; + } + + ret = db_internal_get_sid_from_id(&sid_tmp, *id, *id_type); + if (NT_STATUS_IS_OK(ret)) { + if (!sid_equal(&sid_tmp, sid)) { + DEBUG(10,("db_get_sid_from_id: sid %s reverse mapping SID mismatch" + "id = %u, id_type = %u\n", + sid_string_static(sid), + (unsigned int)id->uid, (unsigned int)(*id_type) )); + return NT_STATUS_NO_SUCH_USER; } } + return ret; + } - tdb_chainunlock(idmap_tdb, sid_data); + if (flags & IDMAP_FLAG_QUERY_ONLY) { + return ret; } - - return ret; + + /* We're in to bad design territory.... This call is now + *allocating* and storing a new mapping for sid -> id. This SHOULD + NOT BE DONE HERE ! There needs to be a separate upper + level call for this... I think the reason this was badly + designed this way was the desire to reuse cache code with + a tdb idmap implementation. They MUST be separated ! JRA */ + + return db_internal_allocate_new_id_for_sid(id, id_type, sid); } -static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type) +static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, enum idmap_type id_type) { + NTSTATUS ret; TDB_DATA ksid, kid, data; - fstring ksidstr; - fstring kidstr; + TALLOC_CTX *memctx; - DEBUG(10,("db_set_mapping: id_type = 0x%x\n", id_type)); + DEBUG(10,("db_set_mapping: id_type = 0x%x\n", (unsigned int)id_type)); - if (!sid) - return NT_STATUS_INVALID_PARAMETER; - - sid_to_string(ksidstr, sid); + if ((memctx = talloc_new(NULL)) == NULL) { + DEBUG(0, ("ERROR: Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } - ksid.dptr = ksidstr; - ksid.dsize = strlen(ksidstr) + 1; + if ((ksid.dptr = talloc_asprintf(memctx, "%s", sid_string_static(sid))) == NULL) { + DEBUG(0, ("ERROR: Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; + } + ksid.dsize = strlen(ksid.dptr) + 1; - if (id_type & ID_USERID) { - slprintf(kidstr, sizeof(kidstr), "UID %lu", (unsigned long)id.uid); - } else if (id_type & ID_GROUPID) { - slprintf(kidstr, sizeof(kidstr), "GID %lu", (unsigned long)id.gid); + if (id_type == ID_USERID) { + kid.dptr = talloc_asprintf(memctx, "UID %lu", (unsigned long)id.uid); } else { - return NT_STATUS_INVALID_PARAMETER; + kid.dptr = talloc_asprintf(memctx, "GID %lu", (unsigned long)id.gid); } - kid.dptr = kidstr; - kid.dsize = strlen(kidstr) + 1; + if (kid.dptr == NULL) { + DEBUG(0, ("ERROR: Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; + } + kid.dsize = strlen(kid.dptr) + 1; /* *DELETE* prevoius mappings if any. * This is done both SID and [U|G]ID passed in */ @@ -400,7 +451,7 @@ static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type) /* Lock the record for this SID. */ if (tdb_chainlock(idmap_tdb, ksid) != 0) { DEBUG(10,("db_set_mapping: failed to lock record %s. Error %s\n", - ksidstr, tdb_errorstr(idmap_tdb) )); + ksid.dptr, tdb_errorstr(idmap_tdb) )); return NT_STATUS_UNSUCCESSFUL; } @@ -424,24 +475,29 @@ static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type) if (tdb_store(idmap_tdb, ksid, kid, TDB_INSERT) == -1) { DEBUG(0, ("idb_set_mapping: tdb_store 1 error: %s\n", tdb_errorstr(idmap_tdb))); tdb_chainunlock(idmap_tdb, ksid); - return NT_STATUS_UNSUCCESSFUL; + ret = NT_STATUS_UNSUCCESSFUL; + goto done; } if (tdb_store(idmap_tdb, kid, ksid, TDB_INSERT) == -1) { DEBUG(0, ("idb_set_mapping: tdb_store 2 error: %s\n", tdb_errorstr(idmap_tdb))); tdb_chainunlock(idmap_tdb, ksid); - return NT_STATUS_UNSUCCESSFUL; + ret = NT_STATUS_UNSUCCESSFUL; + goto done; } tdb_chainunlock(idmap_tdb, ksid); DEBUG(10,("db_set_mapping: stored %s -> %s and %s -> %s\n", ksid.dptr, kid.dptr, kid.dptr, ksid.dptr )); - return NT_STATUS_OK; + ret = NT_STATUS_OK; +done: + talloc_free(memctx); + return ret; } /***************************************************************************** Initialise idmap database. *****************************************************************************/ -static NTSTATUS db_idmap_init( char *params ) +static NTSTATUS db_idmap_init( const char *params ) { SMB_STRUCT_STAT stbuf; char *tdbfile = NULL; diff --git a/source3/sam/idmap_util.c b/source3/sam/idmap_util.c index f78d3bdc23..8320b294f8 100644 --- a/source3/sam/idmap_util.c +++ b/source3/sam/idmap_util.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. ID Mapping Copyright (C) Simo Sorce 2003 + Copyright (C) Jeremy Allison 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,10 +33,9 @@ NTSTATUS idmap_uid_to_sid(DOM_SID *sid, uid_t uid, int flags) DEBUG(10,("idmap_uid_to_sid: uid = [%lu]\n", (unsigned long)uid)); - flags |= ID_USERID; id.uid = uid; - return idmap_get_sid_from_id(sid, id, flags); + return idmap_get_sid_from_id(sid, id, ID_USERID, flags); } /***************************************************************** @@ -49,10 +49,9 @@ NTSTATUS idmap_gid_to_sid(DOM_SID *sid, gid_t gid, int flags) DEBUG(10,("idmap_gid_to_sid: gid = [%lu]\n", (unsigned long)gid)); - flags |= ID_GROUPID; id.gid = gid; - return idmap_get_sid_from_id(sid, id, flags); + return idmap_get_sid_from_id(sid, id, ID_GROUPID, flags); } /***************************************************************** @@ -62,24 +61,32 @@ NTSTATUS idmap_gid_to_sid(DOM_SID *sid, gid_t gid, int flags) was done correctly, False if not. *****************************************************************/ -NTSTATUS idmap_sid_to_uid(const DOM_SID *sid, uid_t *uid, uint32 flags) +NTSTATUS idmap_sid_to_uid(const DOM_SID *sid, uid_t *uid, int flags) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + NTSTATUS ret; + enum idmap_type id_type; unid_t id; DEBUG(10,("idmap_sid_to_uid: sid = [%s]\n", sid_string_static(sid))); - flags |= ID_USERID; + /* For the LDAP and tdb backends we must *KNOW* what we're looking for. + This interface design *SUCKS* ! JRA. */ - ret = idmap_get_id_from_sid(&id, (int *)&flags, sid); - - if ( NT_STATUS_IS_OK(ret) ) { - DEBUG(10,("idmap_sid_to_uid: uid = [%lu]\n", (unsigned long)id.uid)); - *uid = id.uid; - } + id_type = ID_USERID; + ret = idmap_get_id_from_sid(&id, &id_type, sid, flags); + + if (!NT_STATUS_IS_OK(ret)) { + return ret; + } + + if (id_type != ID_USERID) { + return NT_STATUS_NONE_MAPPED; + } - return ret; + DEBUG(10,("idmap_sid_to_uid: uid = [%lu]\n", (unsigned long)id.uid)); + *uid = id.uid; + return NT_STATUS_OK; } /***************************************************************** @@ -91,22 +98,30 @@ NTSTATUS idmap_sid_to_uid(const DOM_SID *sid, uid_t *uid, uint32 flags) was done correctly, False if not. *****************************************************************/ -NTSTATUS idmap_sid_to_gid(const DOM_SID *sid, gid_t *gid, uint32 flags) +NTSTATUS idmap_sid_to_gid(const DOM_SID *sid, gid_t *gid, int flags) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + NTSTATUS ret; + enum idmap_type id_type; unid_t id; DEBUG(10,("sid_to_gid: sid = [%s]\n", sid_string_static(sid))); - flags |= ID_GROUPID; + /* For the LDAP and tdb backends we must *KNOW* what we're looking for. + This interface design *SUCKS* ! JRA. */ - ret = idmap_get_id_from_sid(&id, (int *)&flags, sid); + id_type = ID_GROUPID; + ret = idmap_get_id_from_sid(&id, &id_type, sid, flags); - if ( NT_STATUS_IS_OK(ret) ) - { - DEBUG(10,("idmap_sid_to_gid: gid = [%lu]\n", (unsigned long)id.gid)); - *gid = id.gid; + if (!NT_STATUS_IS_OK(ret)) { + return ret; + } + + if (id_type != ID_GROUPID) { + return NT_STATUS_NONE_MAPPED; } - return ret; + DEBUG(10,("idmap_sid_to_gid: gid = [%lu]\n", (unsigned long)id.gid)); + *gid = id.gid; + + return NT_STATUS_OK; } -- cgit