diff options
Diffstat (limited to 'source3/groupdb')
-rw-r--r-- | source3/groupdb/mapping.c | 981 |
1 files changed, 450 insertions, 531 deletions
diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index b617e34565..c701ef165d 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -2,7 +2,7 @@ * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-2000, - * Copyright (C) Jean Francois Micouleau 1998-2001. + * Copyright (C) Jean François Micouleau 1998-2001. * Copyright (C) Volker Lendecke 2006. * Copyright (C) Gerald Carter 2006. * @@ -27,7 +27,6 @@ static TDB_CONTEXT *tdb; /* used for driver files */ #define DATABASE_VERSION_V1 1 /* native byte format. */ #define DATABASE_VERSION_V2 2 /* le format. */ -#define DATABASE_VERSION_V3 3 /* Indexed format */ #define GROUP_PREFIX "UNIXGROUP/" @@ -38,243 +37,125 @@ static TDB_CONTEXT *tdb; /* used for driver files */ */ #define MEMBEROF_PREFIX "MEMBEROF/" -static BOOL pack_group_map(TALLOC_CTX *mem_ctx, const GROUP_MAP *map, - TDB_DATA *data) -{ - return tdb_pack_append(mem_ctx, &data->dptr, &data->dsize, "fddff", - sid_string_static(&map->sid), map->gid, - map->sid_name_use, map->nt_name, map->comment); -} - -static BOOL unpack_group_map(TDB_DATA data, GROUP_MAP *map) -{ - fstring sidstr; - - if (!tdb_unpack(data.dptr, data.dsize, "fddff", sidstr, &map->gid, - &map->sid_name_use, &map->nt_name, &map->comment)) { - DEBUG(0, ("tdb_unpack failed\n")); - return False; - } - if (!string_to_sid(&map->sid, sidstr)) { - DEBUG(0, ("sid_string %s invalid\n", sidstr)); - return False; - } - - return True; -} - -/* - * Calculate keys from the group mapping record - * - * We've got 3 keys: SID, Name (uppercased) and gid - */ - -#define KEYNUM_SID (0) -#define KEYNUM_NAME (1) -#define KEYNUM_GID (2) - -static char **group_mapping_keys(TALLOC_CTX *mem_ctx, TDB_DATA data, - void *private_data) -{ - char **result; - GROUP_MAP map; - GROUP_MAP *mapp = (GROUP_MAP *)private_data; - - if (mapp == NULL) { - if (!unpack_group_map(data, &map)) { - DEBUG(0, ("unpack_groupmap failed\n")); - return NULL; - } - mapp = ↦ - } - - result = TALLOC_ARRAY(mem_ctx, char *, 4); - if (result == NULL) { - DEBUG(0, ("talloc_array failed\n")); - return NULL; - } - - result[KEYNUM_SID] = talloc_strdup(result, - sid_string_static(&mapp->sid)); - result[KEYNUM_NAME] = talloc_strdup(result, mapp->nt_name); - result[KEYNUM_GID] = talloc_asprintf(result, "%d", (int)mapp->gid); - result[3] = NULL; - - if ((result[0] == NULL) || (result[1] == NULL) || - (result[2] == NULL)) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - /* name lookups are case insensitive, store the key in upper case */ - strupper_m(result[KEYNUM_NAME]); - - return result; -} - -static NTSTATUS upgrade_groupdb_to_v3(struct tdb_context *groupdb) -{ - TDB_DATA kbuf, newkey; - NTSTATUS status; - - for (kbuf = tdb_firstkey(groupdb); - kbuf.dptr; - newkey = tdb_nextkey(groupdb, kbuf), safe_free(kbuf.dptr), - kbuf=newkey) { - - fstring string_sid; - TDB_DATA data, newdata; - GROUP_MAP map; - int ret; - - if (strncmp(kbuf.dptr, GROUP_PREFIX, - strlen(GROUP_PREFIX)) != 0) { - continue; - } - - data = tdb_fetch(groupdb, kbuf); - if (!data.dptr) { - continue; - } - - fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX)); - - ret = tdb_unpack(data.dptr, data.dsize, "ddff", - &map.gid, &map.sid_name_use, &map.nt_name, - &map.comment); - SAFE_FREE(data.dptr); - - if ( ret == -1 ) { - DEBUG(3,("upgrade_groupdb_to_v3: tdb_unpack " - "failure\n")); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - if (!string_to_sid(&map.sid, string_sid)) { - DEBUG(3, ("Got invalid sid: %s\n", string_sid)); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - if (tdb_delete(groupdb, kbuf) < 0) { - status = map_ntstatus_from_tdb(groupdb); - DEBUG(3, ("tdb_delete failed: %s\n", - nt_errstr(status))); - return status; - } - - if (map.gid == -1) { - DEBUG(3, ("Deleting umapped group %s\n", map.nt_name)); - continue; - } - - ZERO_STRUCT(newdata); - - if (!pack_group_map(NULL, &map, &newdata)) { - DEBUG(0, ("pack_group_map_failed\n")); - return NT_STATUS_NO_MEMORY; - } - - status = tdb_add_keyed(groupdb, group_mapping_keys, - newdata, &map); - TALLOC_FREE(newdata.dptr); - - if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECTID_EXISTS)) { - DEBUG(0, ("mapping for gid %d / name %s maps to " - "multiple SIDs -- rejected\n", - map.gid, map.nt_name)); - return status; - } - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(5, ("tdb_add_keyed failed: %s\n", - nt_errstr(status))); - return status; - } - } - - return NT_STATUS_OK; -} +static BOOL enum_group_mapping(const DOM_SID *sid, enum SID_NAME_USE sid_name_use, GROUP_MAP **pp_rmap, + size_t *p_num_entries, BOOL unix_only); +static BOOL group_map_remove(const DOM_SID *sid); /**************************************************************************** Open the group mapping tdb. ****************************************************************************/ -static NTSTATUS init_group_mapping(void) +static BOOL init_group_mapping(void) { const char *vstring = "INFO/version"; int32 vers_id; - NTSTATUS status; + GROUP_MAP *map_table = NULL; + size_t num_entries = 0; if (tdb) - return NT_STATUS_OK; + return True; - tdb = tdb_open_log(lock_path("group_mapping.tdb"), 0, TDB_DEFAULT, - O_RDWR|O_CREAT, 0600); + tdb = tdb_open_log(lock_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if (!tdb) { - DEBUG(0,("Failed to open group mapping database: %s\n", - strerror(errno))); - return map_nt_error_from_unix(errno); + DEBUG(0,("Failed to open group mapping database\n")); + return False; } - if (tdb_transaction_start(tdb) < 0) { - status = map_ntstatus_from_tdb(tdb); - DEBUG(5, ("Could not start transaction: %s\n", - nt_errstr(status))); - tdb_close(tdb); - tdb = NULL; - return status; - } + /* handle a Samba upgrade */ + tdb_lock_bystring(tdb, vstring); /* Cope with byte-reversed older versions of the db. */ vers_id = tdb_fetch_int32(tdb, vstring); - - if (vers_id == DATABASE_VERSION_V3) { - if (tdb_transaction_cancel(tdb) < 0) { - smb_panic("tdb_cancel_transaction failed\n"); - } - return NT_STATUS_OK; + if ((vers_id == DATABASE_VERSION_V1) || (IREV(vers_id) == DATABASE_VERSION_V1)) { + /* Written on a bigendian machine with old fetch_int code. Save as le. */ + tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2); + vers_id = DATABASE_VERSION_V2; } - if (vers_id < 0) { - tdb_store_int32(tdb, vstring, DATABASE_VERSION_V3); - } - - if ((vers_id == DATABASE_VERSION_V1) || - (IREV(vers_id) == DATABASE_VERSION_V1)) { - - /* Written on a bigendian machine with old fetch_int - * code. Save as le. */ + /* if its an unknown version we remove everthing in the db */ + + if (vers_id != DATABASE_VERSION_V2) { + tdb_traverse(tdb, tdb_traverse_delete_fn, NULL); tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2); - vers_id = DATABASE_VERSION_V2; } - if (vers_id == DATABASE_VERSION_V2) { - status = upgrade_groupdb_to_v3(tdb); - if (!NT_STATUS_IS_OK(status)) { - goto fail; + tdb_unlock_bystring(tdb, vstring); + + /* cleanup any map entries with a gid == -1 */ + + if ( enum_group_mapping( NULL, SID_NAME_UNKNOWN, &map_table, &num_entries, False ) ) { + int i; + + for ( i=0; i<num_entries; i++ ) { + if ( map_table[i].gid == -1 ) { + group_map_remove( &map_table[i].sid ); + } } - tdb_store_int32(tdb, vstring, DATABASE_VERSION_V3); + + SAFE_FREE( map_table ); } - if (tdb_transaction_commit(tdb) < 0) { - status = map_ntstatus_from_tdb(tdb); - DEBUG(5, ("tdb_transaction_commit failed: %s\n", - nt_errstr(status))); - goto fail; + + return True; +} + +/**************************************************************************** +****************************************************************************/ +static BOOL add_mapping_entry(GROUP_MAP *map, int flag) +{ + TDB_DATA kbuf, dbuf; + pstring key, buf; + fstring string_sid=""; + int len; + + if(!init_group_mapping()) { + DEBUG(0,("failed to initialize group mapping\n")); + return(False); } + + sid_to_string(string_sid, &map->sid); - return NT_STATUS_OK; + len = tdb_pack(buf, sizeof(buf), "ddff", + map->gid, map->sid_name_use, map->nt_name, map->comment); + + if (len > sizeof(buf)) + return False; - fail: - if (tdb_transaction_cancel(tdb) < 0) { - smb_panic("tdb_cancel_transaction failed\n"); + slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid); + + kbuf.dsize = strlen(key)+1; + kbuf.dptr = key; + dbuf.dsize = len; + dbuf.dptr = buf; + if (tdb_store(tdb, kbuf, dbuf, flag) != 0) return False; + + return True; +} + +/**************************************************************************** +initialise first time the mapping list +****************************************************************************/ +NTSTATUS add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_use, const char *nt_name, const char *comment) +{ + GROUP_MAP map; + + if(!init_group_mapping()) { + DEBUG(0,("failed to initialize group mapping\n")); + return NT_STATUS_UNSUCCESSFUL; } - tdb_close(tdb); - tdb = NULL; + + map.gid=gid; + if (!string_to_sid(&map.sid, sid)) { + DEBUG(0, ("string_to_sid failed: %s", sid)); + return NT_STATUS_UNSUCCESSFUL; + } + + map.sid_name_use=sid_name_use; + fstrcpy(map.nt_name, nt_name); + fstrcpy(map.comment, comment); - return status; + return pdb_add_group_mapping_entry(&map); } /**************************************************************************** @@ -287,7 +168,7 @@ NTSTATUS map_unix_group(const struct group *grp, GROUP_MAP *pmap) const char *grpname, *dom, *name; uint32 rid; - if (NT_STATUS_IS_OK(pdb_getgrgid(&map, grp->gr_gid))) { + if (pdb_getgrgid(&map, grp->gr_gid)) { return NT_STATUS_GROUP_EXISTS; } @@ -339,172 +220,248 @@ NTSTATUS map_unix_group(const struct group *grp, GROUP_MAP *pmap) Return the sid and the type of the unix group. ****************************************************************************/ -static NTSTATUS get_group_map_from_sid(const DOM_SID *sid, GROUP_MAP *map) +static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map) { - TDB_DATA data; - NTSTATUS status; - - status = init_group_mapping(); - if(!NT_STATUS_IS_OK(status)) { + TDB_DATA kbuf, dbuf; + pstring key; + fstring string_sid; + int ret = 0; + + if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping\n")); - return status; + return(False); } - status = tdb_find_keyed(NULL, tdb, KEYNUM_SID, sid_string_static(sid), - &data, NULL); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + /* the key is the SID, retrieving is direct */ - status = unpack_group_map(data, map) ? - NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION; + sid_to_string(string_sid, &sid); + slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid); - TALLOC_FREE(data.dptr); - return status; + kbuf.dptr = key; + kbuf.dsize = strlen(key)+1; + + dbuf = tdb_fetch(tdb, kbuf); + if (!dbuf.dptr) + return False; + + ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", + &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); + + SAFE_FREE(dbuf.dptr); + + if ( ret == -1 ) { + DEBUG(3,("get_group_map_from_sid: tdb_unpack failure\n")); + return False; + } + + sid_copy(&map->sid, &sid); + + return True; } /**************************************************************************** Return the sid and the type of the unix group. ****************************************************************************/ -static NTSTATUS get_group_map_from_gid(gid_t gid, GROUP_MAP *map) +static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map) { - TDB_DATA data; - NTSTATUS status; - char *gidstr; + TDB_DATA kbuf, dbuf, newkey; + fstring string_sid; + int ret; - status = init_group_mapping(); - if(!NT_STATUS_IS_OK(status)) { + if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping\n")); - return status; + return(False); } - if (asprintf(&gidstr, "%d", (int)gid) < 0) { - DEBUG(0, ("asprintf failed\n")); - return NT_STATUS_NO_MEMORY; - } + /* we need to enumerate the TDB to find the GID */ - status = tdb_find_keyed(NULL, tdb, KEYNUM_GID, gidstr, &data, NULL); - SAFE_FREE(gidstr); + for (kbuf = tdb_firstkey(tdb); + kbuf.dptr; + newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { - if (!NT_STATUS_IS_OK(status)) { - return status; - } + if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue; + + dbuf = tdb_fetch(tdb, kbuf); + if (!dbuf.dptr) + continue; - status = unpack_group_map(data, map) ? - NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION; + fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX)); - TALLOC_FREE(data.dptr); - return status; + string_to_sid(&map->sid, string_sid); + + ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", + &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); + + SAFE_FREE(dbuf.dptr); + + if ( ret == -1 ) { + DEBUG(3,("get_group_map_from_gid: tdb_unpack failure\n")); + return False; + } + + if (gid==map->gid) { + SAFE_FREE(kbuf.dptr); + return True; + } + } + + return False; } /**************************************************************************** Return the sid and the type of the unix group. ****************************************************************************/ -static NTSTATUS get_group_map_from_ntname(const char *name, GROUP_MAP *map) +static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map) { - TDB_DATA data; - NTSTATUS status; - char *tmp; + TDB_DATA kbuf, dbuf, newkey; + fstring string_sid; + int ret; - status = init_group_mapping(); - if(!NT_STATUS_IS_OK(status)) { - DEBUG(0,("failed to initialize group mapping\n")); - return status; + if(!init_group_mapping()) { + DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping\n")); + return(False); } - tmp = SMB_STRDUP(name); - if (tmp == NULL) { - DEBUG(0, ("strdup failed\n")); - return NT_STATUS_NO_MEMORY; - } + /* we need to enumerate the TDB to find the name */ + + for (kbuf = tdb_firstkey(tdb); + kbuf.dptr; + newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { + + if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue; + + dbuf = tdb_fetch(tdb, kbuf); + if (!dbuf.dptr) + continue; - /* - * The name is stored uppercase to make the search case insensitive - */ + fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX)); - strupper_m(tmp); + string_to_sid(&map->sid, string_sid); + + ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", + &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); - status = tdb_find_keyed(NULL, tdb, KEYNUM_NAME, tmp, &data, NULL); - SAFE_FREE(tmp); + SAFE_FREE(dbuf.dptr); + + if ( ret == -1 ) { + DEBUG(3,("get_group_map_from_ntname: tdb_unpack failure\n")); + return False; + } - if (!NT_STATUS_IS_OK(status)) { - return status; + if ( strequal(name, map->nt_name) ) { + SAFE_FREE(kbuf.dptr); + return True; + } } - status = unpack_group_map(data, map) ? - NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION; + return False; +} + +/**************************************************************************** + Remove a group mapping entry. +****************************************************************************/ - TALLOC_FREE(data.dptr); - return status; +static BOOL group_map_remove(const DOM_SID *sid) +{ + TDB_DATA kbuf, dbuf; + pstring key; + fstring string_sid; + + if(!init_group_mapping()) { + DEBUG(0,("failed to initialize group mapping\n")); + return(False); + } + + /* the key is the SID, retrieving is direct */ + + sid_to_string(string_sid, sid); + slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid); + + kbuf.dptr = key; + kbuf.dsize = strlen(key)+1; + + dbuf = tdb_fetch(tdb, kbuf); + if (!dbuf.dptr) + return False; + + SAFE_FREE(dbuf.dptr); + + if(tdb_delete(tdb, kbuf) != TDB_SUCCESS) + return False; + + return True; } /**************************************************************************** Enumerate the group mapping. ****************************************************************************/ -static NTSTATUS enum_group_mapping(const DOM_SID *domsid, - enum SID_NAME_USE sid_name_use, - GROUP_MAP **pp_rmap, - size_t *p_num_entries, BOOL unix_only) +static BOOL enum_group_mapping(const DOM_SID *domsid, enum SID_NAME_USE sid_name_use, GROUP_MAP **pp_rmap, + size_t *p_num_entries, BOOL unix_only) { - struct tdb_keyed_iterator *iterator; - TDB_DATA dbuf; - NTSTATUS status; + TDB_DATA kbuf, dbuf, newkey; + fstring string_sid; + GROUP_MAP map; + GROUP_MAP *mapt; + int ret; + size_t entries=0; + DOM_SID grpsid; + uint32 rid; - status = init_group_mapping(); - if (!NT_STATUS_IS_OK(status)) { + if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping\n")); - return status; + return(False); } *p_num_entries=0; *pp_rmap=NULL; - iterator = tdb_enum_keyed(NULL, tdb); - if (iterator == NULL) { - DEBUG(0, ("tdb_enum_keyed failed\n")); - return NT_STATUS_NO_MEMORY; - } - - while (tdb_next_keyed(iterator, &dbuf)) { + for (kbuf = tdb_firstkey(tdb); + kbuf.dptr; + newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { - GROUP_MAP map; - DOM_SID grpsid; - uint32 rid; + if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) + continue; - if (!unpack_group_map(dbuf, &map)) { - DEBUG(5, ("Got invalid group mapping entry\n")); - TALLOC_FREE(dbuf.dptr); + dbuf = tdb_fetch(tdb, kbuf); + if (!dbuf.dptr) continue; - } + + fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX)); + + ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", + &map.gid, &map.sid_name_use, &map.nt_name, &map.comment); SAFE_FREE(dbuf.dptr); + if ( ret == -1 ) { + DEBUG(3,("enum_group_mapping: tdb_unpack failure\n")); + continue; + } + /* list only the type or everything if UNKNOWN */ - if (sid_name_use!=SID_NAME_UNKNOWN && - sid_name_use!=map.sid_name_use) { - DEBUG(11,("enum_group_mapping: group %s is not of the " - "requested type\n", map.nt_name)); + if (sid_name_use!=SID_NAME_UNKNOWN && sid_name_use!=map.sid_name_use) { + DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name)); continue; } if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) { - DEBUG(11,("enum_group_mapping: group %s is non " - "mapped\n", map.nt_name)); + DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name)); continue; } - sid_copy( &grpsid, &map.sid ); + string_to_sid(&grpsid, string_sid); + sid_copy( &map.sid, &grpsid ); + sid_split_rid( &grpsid, &rid ); /* Only check the domain if we were given one */ if ( domsid && !sid_equal( domsid, &grpsid ) ) { - DEBUG(11,("enum_group_mapping: group %s is not in " - "domain %s\n", sid_string_static(&map.sid), - sid_string_static(domsid))); + DEBUG(11,("enum_group_mapping: group %s is not in domain %s\n", + string_sid, sid_string_static(domsid))); continue; } @@ -512,14 +469,27 @@ static NTSTATUS enum_group_mapping(const DOM_SID *domsid, "type %s\n", map.nt_name, sid_type_lookup(map.sid_name_use))); - ADD_TO_ARRAY(NULL, GROUP_MAP, map, pp_rmap, p_num_entries); - if (*pp_rmap == NULL) { - DEBUG(0, ("ADD_TO_ARRAY failed\n")); - return NT_STATUS_NO_MEMORY; + (*pp_rmap) = SMB_REALLOC_ARRAY((*pp_rmap), GROUP_MAP, entries+1); + if (!(*pp_rmap)) { + DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n")); + return False; } + + mapt = (*pp_rmap); + + mapt[entries].gid = map.gid; + sid_copy( &mapt[entries].sid, &map.sid); + mapt[entries].sid_name_use = map.sid_name_use; + fstrcpy(mapt[entries].nt_name, map.nt_name); + fstrcpy(mapt[entries].comment, map.comment); + + entries++; + } - return NT_STATUS_OK; + *p_num_entries=entries; + + return True; } /* This operation happens on session setup, so it should better be fast. We @@ -532,7 +502,7 @@ static NTSTATUS one_alias_membership(const DOM_SID *member, TDB_DATA kbuf, dbuf; const char *p; - if (!NT_STATUS_IS_OK(init_group_mapping())) { + if (!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping\n")); return NT_STATUS_ACCESS_DENIED; } @@ -611,41 +581,22 @@ static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member) pstring key; fstring string_sid; char *new_memberstring; - NTSTATUS status; + int result; - status = init_group_mapping(); - if(!NT_STATUS_IS_OK(status)) { + if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping\n")); - return status; - } - - if (tdb_transaction_start(tdb) < 0) { - status = map_ntstatus_from_tdb(tdb); - DEBUG(5, ("Could not start transaction: %s\n", - nt_errstr(status))); - return status; - } - - status = get_group_map_from_sid(alias, &map); - - if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { - status = NT_STATUS_NO_SUCH_ALIAS; + return NT_STATUS_ACCESS_DENIED; } - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } + if (!get_group_map_from_sid(*alias, &map)) + return NT_STATUS_NO_SUCH_ALIAS; if ( (map.sid_name_use != SID_NAME_ALIAS) && - (map.sid_name_use != SID_NAME_WKN_GRP) ) { - status = NT_STATUS_NO_SUCH_ALIAS; - goto fail; - } + (map.sid_name_use != SID_NAME_WKN_GRP) ) + return NT_STATUS_NO_SUCH_ALIAS; - if (is_aliasmem(alias, member)) { - status = NT_STATUS_MEMBER_IN_ALIAS; - goto fail; - } + if (is_aliasmem(alias, member)) + return NT_STATUS_MEMBER_IN_ALIAS; sid_to_string(string_sid, member); slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid); @@ -664,38 +615,18 @@ static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member) new_memberstring = SMB_STRDUP(string_sid); } - if (new_memberstring == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } + if (new_memberstring == NULL) + return NT_STATUS_NO_MEMORY; SAFE_FREE(dbuf.dptr); dbuf.dsize = strlen(new_memberstring)+1; dbuf.dptr = new_memberstring; - if (tdb_store(tdb, kbuf, dbuf, 0) < 0) { - status = map_ntstatus_from_tdb(tdb); - DEBUG(5, ("tdb_store failed: %s\n", nt_errstr(status))); - SAFE_FREE(new_memberstring); - goto fail; - } + result = tdb_store(tdb, kbuf, dbuf, 0); SAFE_FREE(new_memberstring); - if (tdb_transaction_commit(tdb) < 0) { - status = map_ntstatus_from_tdb(tdb); - DEBUG(5, ("tdb_transaction_commit failed: %s\n", - nt_errstr(status))); - goto fail; - } - - return NT_STATUS_OK; - - fail: - if (tdb_transaction_cancel(tdb) < 0) { - smb_panic("tdb_cancel_transaction failed\n"); - } - return status; + return (result == 0 ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED); } struct aliasmem_closure { @@ -750,18 +681,17 @@ static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data, return 0; } -static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, - size_t *num) +static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, size_t *num) { GROUP_MAP map; struct aliasmem_closure closure; - if(!NT_STATUS_IS_OK(init_group_mapping())) { + if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping\n")); return NT_STATUS_ACCESS_DENIED; } - if (!NT_STATUS_IS_OK(get_group_map_from_sid(alias, &map))) + if (!get_group_map_from_sid(*alias, &map)) return NT_STATUS_NO_SUCH_ALIAS; if ( (map.sid_name_use != SID_NAME_ALIAS) && @@ -781,33 +711,19 @@ static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member) { - NTSTATUS status; - DOM_SID *sids = NULL; + NTSTATUS result; + DOM_SID *sids; size_t i, num; BOOL found = False; - char *member_string = NULL; + char *member_string; TDB_DATA kbuf, dbuf; pstring key; fstring sid_string; - status = init_group_mapping(); - if(!NT_STATUS_IS_OK(status)) { - DEBUG(0,("failed to initialize group mapping\n")); - return status; - } - - if (tdb_transaction_start(tdb) < 0) { - status = map_ntstatus_from_tdb(tdb); - DEBUG(5, ("Could not start transaction: %s\n", - nt_errstr(status))); - return status; - } - - status = alias_memberships(member, 1, &sids, &num); + result = alias_memberships(member, 1, &sids, &num); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } + if (!NT_STATUS_IS_OK(result)) + return result; for (i=0; i<num; i++) { if (sid_compare(&sids[i], alias) == 0) { @@ -818,8 +734,7 @@ static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member) if (!found) { SAFE_FREE(sids); - status = NT_STATUS_MEMBER_NOT_IN_ALIAS; - goto fail; + return NT_STATUS_MEMBER_NOT_IN_ALIAS; } if (i < num) @@ -833,21 +748,15 @@ static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member) kbuf.dsize = strlen(key)+1; kbuf.dptr = key; - if (num == 0) { - if (tdb_delete(tdb, kbuf) < 0) { - status = map_ntstatus_from_tdb(tdb); - DEBUG(5, ("tdb_delete failed: %s\n", - nt_errstr(status))); - goto fail; - } - goto ok; - } + if (num == 0) + return tdb_delete(tdb, kbuf) == 0 ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; member_string = SMB_STRDUP(""); if (member_string == NULL) { SAFE_FREE(sids); - status = NT_STATUS_NO_MEMORY; + return NT_STATUS_NO_MEMORY; } for (i=0; i<num; i++) { @@ -859,43 +768,20 @@ static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member) SAFE_FREE(s); if (member_string == NULL) { SAFE_FREE(sids); - status = NT_STATUS_NO_MEMORY; - goto fail; + return NT_STATUS_NO_MEMORY; } } dbuf.dsize = strlen(member_string)+1; dbuf.dptr = member_string; - if (tdb_store(tdb, kbuf, dbuf, 0) < 0) { - status = map_ntstatus_from_tdb(tdb); - DEBUG(5, ("tdb_store failed: %s\n", nt_errstr(status))); - SAFE_FREE(sids); - SAFE_FREE(member_string); - goto fail; - } - - ok: - SAFE_FREE(sids); - SAFE_FREE(member_string); - - if (tdb_transaction_commit(tdb) < 0) { - status = map_ntstatus_from_tdb(tdb); - DEBUG(5, ("tdb_transaction_commit failed: %s\n", - nt_errstr(status))); - goto fail; - } - - return NT_STATUS_OK; + result = tdb_store(tdb, kbuf, dbuf, 0) == 0 ? + NT_STATUS_OK : NT_STATUS_ACCESS_DENIED; - fail: SAFE_FREE(sids); SAFE_FREE(member_string); - if (tdb_transaction_cancel(tdb) < 0) { - smb_panic("tdb_cancel_transaction failed\n"); - } - return status; + return result; } /* @@ -910,16 +796,14 @@ static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member) /* get a domain group from it's SID */ -NTSTATUS get_domain_group_from_sid(const DOM_SID *sid, GROUP_MAP *map) +BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map) { struct group *grp; - NTSTATUS status; - - status = init_group_mapping(); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("failed to initialize group mapping: %s\n", - nt_errstr(status))); - return status; + BOOL ret; + + if(!init_group_mapping()) { + DEBUG(0,("failed to initialize group mapping\n")); + return(False); } DEBUG(10, ("get_domain_group_from_sid\n")); @@ -927,55 +811,52 @@ NTSTATUS get_domain_group_from_sid(const DOM_SID *sid, GROUP_MAP *map) /* if the group is NOT in the database, it CAN NOT be a domain group */ become_root(); - status = pdb_getgrsid(map, sid); + ret = pdb_getgrsid(map, sid); unbecome_root(); /* special case check for rid 513 */ - if ( !NT_STATUS_IS_OK(status) ) { + if ( !ret ) { uint32 rid; - sid_peek_rid( sid, &rid ); + sid_peek_rid( &sid, &rid ); if ( rid == DOMAIN_GROUP_RID_USERS ) { fstrcpy( map->nt_name, "None" ); fstrcpy( map->comment, "Ordinary Users" ); - sid_copy( &map->sid, sid ); + sid_copy( &map->sid, &sid ); map->sid_name_use = SID_NAME_DOM_GRP; - return NT_STATUS_OK; + return True; } - return status; + return False; } DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n")); /* if it's not a domain group, continue */ if (map->sid_name_use!=SID_NAME_DOM_GRP) { - return NT_STATUS_OBJECT_TYPE_MISMATCH; + return False; } DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n")); if (map->gid==-1) { - return NT_STATUS_NOT_FOUND; + return False; } - DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%lu\n", - (unsigned long)map->gid)); + DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%lu\n",(unsigned long)map->gid)); grp = getgrgid(map->gid); if ( !grp ) { - DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in " - "UNIX security\n")); - return NT_STATUS_NOT_FOUND; + DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n")); + return False; } - DEBUG(10, ("get_domain_group_from_sid: gid exists in UNIX " - "security\n")); + DEBUG(10, ("get_domain_group_from_sid: gid exists in UNIX security\n")); - return NT_STATUS_OK; + return True; } /**************************************************************************** @@ -1117,114 +998,70 @@ int smb_delete_user_group(const char *unix_group, const char *unix_user) NTSTATUS pdb_default_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, - const DOM_SID *sid) + DOM_SID sid) { - return get_group_map_from_sid(sid, map); + return get_group_map_from_sid(sid, map) ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } NTSTATUS pdb_default_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, gid_t gid) { - return get_group_map_from_gid(gid, map); + return get_group_map_from_gid(gid, map) ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } NTSTATUS pdb_default_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, const char *name) { - return get_group_map_from_ntname(name, map); + return get_group_map_from_ntname(name, map) ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } NTSTATUS pdb_default_add_group_mapping_entry(struct pdb_methods *methods, - GROUP_MAP *map) + GROUP_MAP *map) { - TDB_DATA data; - NTSTATUS status; - - status = init_group_mapping(); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("failed to initialize group mapping\n")); - return status; - } - - ZERO_STRUCT(data); - if (!pack_group_map(NULL, map, &data)) { - DEBUG(0, ("pack_group_map failed\n")); - return NT_STATUS_NO_MEMORY; - } - - status = tdb_add_keyed(tdb, group_mapping_keys, data, map); - TALLOC_FREE(data.dptr); - - return status; + return add_mapping_entry(map, TDB_INSERT) ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods, - GROUP_MAP *map) + GROUP_MAP *map) { - TDB_DATA data; - char *primary_key; - NTSTATUS status; - - status = tdb_find_keyed(NULL, tdb, KEYNUM_SID, - sid_string_static(&map->sid), - &data, &primary_key); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - TALLOC_FREE(data.dptr); - ZERO_STRUCT(data); - - if (!pack_group_map(NULL, map, &data)) { - DEBUG(0, ("pack_group_map failed\n")); - SAFE_FREE(primary_key); - return NT_STATUS_NO_MEMORY; - } - - status = tdb_update_keyed(tdb, primary_key, group_mapping_keys, - data, NULL); - TALLOC_FREE(data.dptr); - TALLOC_FREE(primary_key); - return status; + return add_mapping_entry(map, TDB_REPLACE) ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods, - DOM_SID sid) + DOM_SID sid) { - TDB_DATA data; - char *primary_key; - NTSTATUS status; - GROUP_MAP map; - - status = tdb_find_keyed(NULL, tdb, KEYNUM_SID, sid_string_static(&sid), - &data, &primary_key); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + return group_map_remove(&sid) ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} - if (!unpack_group_map(data, &map)) { - DEBUG(0, ("unpack_group_map failed\n")); - TALLOC_FREE(data.dptr); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } +NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods, + const DOM_SID *sid, enum SID_NAME_USE sid_name_use, + GROUP_MAP **pp_rmap, size_t *p_num_entries, + BOOL unix_only) +{ + return enum_group_mapping(sid, sid_name_use, pp_rmap, p_num_entries, unix_only) ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} - TALLOC_FREE(data.dptr); +NTSTATUS pdb_default_find_alias(struct pdb_methods *methods, + const char *name, DOM_SID *sid) +{ + GROUP_MAP map; - status = tdb_del_keyed(tdb, group_mapping_keys, primary_key, &map); + if (!pdb_getgrnam(&map, name)) + return NT_STATUS_NO_SUCH_ALIAS; - TALLOC_FREE(primary_key); - return status; -} + if ((map.sid_name_use != SID_NAME_WKN_GRP) && + (map.sid_name_use != SID_NAME_ALIAS)) + return NT_STATUS_OBJECT_TYPE_MISMATCH; -NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods, - const DOM_SID *sid, - enum SID_NAME_USE sid_name_use, - GROUP_MAP **pp_rmap, - size_t *p_num_entries, - BOOL unix_only) -{ - return enum_group_mapping(sid, sid_name_use, pp_rmap, p_num_entries, - unix_only); + sid_copy(sid, &map.sid); + return NT_STATUS_OK; } NTSTATUS pdb_default_create_alias(struct pdb_methods *methods, @@ -1301,7 +1138,7 @@ NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods, { GROUP_MAP map; - if (!NT_STATUS_IS_OK(pdb_getgrsid(&map, sid))) + if (!pdb_getgrsid(&map, *sid)) return NT_STATUS_NO_SUCH_ALIAS; if ((map.sid_name_use != SID_NAME_ALIAS) && @@ -1324,7 +1161,7 @@ NTSTATUS pdb_default_set_aliasinfo(struct pdb_methods *methods, { GROUP_MAP map; - if (!NT_STATUS_IS_OK(pdb_getgrsid(&map, sid))) + if (!pdb_getgrsid(&map, *sid)) return NT_STATUS_NO_SUCH_ALIAS; fstrcpy(map.nt_name, info->acct_name); @@ -1391,6 +1228,88 @@ NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods, return NT_STATUS_OK; } +/********************************************************************** + no ops for passdb backends that don't implement group mapping + *********************************************************************/ + +NTSTATUS pdb_nop_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, + DOM_SID sid) +{ + return NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS pdb_nop_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, + gid_t gid) +{ + return NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS pdb_nop_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, + const char *name) +{ + return NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS pdb_nop_add_group_mapping_entry(struct pdb_methods *methods, + GROUP_MAP *map) +{ + return NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS pdb_nop_update_group_mapping_entry(struct pdb_methods *methods, + GROUP_MAP *map) +{ + return NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS pdb_nop_delete_group_mapping_entry(struct pdb_methods *methods, + DOM_SID sid) +{ + return NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS pdb_nop_enum_group_mapping(struct pdb_methods *methods, + enum SID_NAME_USE sid_name_use, + GROUP_MAP **rmap, size_t *num_entries, + BOOL unix_only) +{ + return NT_STATUS_UNSUCCESSFUL; +} + +/**************************************************************************** + These need to be redirected through pdb_interface.c +****************************************************************************/ +BOOL pdb_get_dom_grp_info(const DOM_SID *sid, struct acct_info *info) +{ + GROUP_MAP map; + BOOL res; + + become_root(); + res = get_domain_group_from_sid(*sid, &map); + unbecome_root(); + + if (!res) + return False; + + fstrcpy(info->acct_name, map.nt_name); + fstrcpy(info->acct_desc, map.comment); + sid_peek_rid(sid, &info->rid); + return True; +} + +BOOL pdb_set_dom_grp_info(const DOM_SID *sid, const struct acct_info *info) +{ + GROUP_MAP map; + + if (!get_domain_group_from_sid(*sid, &map)) + return False; + + fstrcpy(map.nt_name, info->acct_name); + fstrcpy(map.comment, info->acct_desc); + + return NT_STATUS_IS_OK(pdb_update_group_mapping_entry(&map)); +} + /******************************************************************** Really just intended to be called by smbd ********************************************************************/ |