summaryrefslogtreecommitdiff
path: root/source3/groupdb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/groupdb')
-rw-r--r--source3/groupdb/mapping.c981
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
********************************************************************/