From 0d45ad1b0d55546c6a4afcb002acefefc2e2feb0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 29 Feb 2004 16:48:19 +0000 Subject: Apply my experimental aliases support to HEAD. This will be a bit difficult to merge to 3_0, as the pdb interfaces has changed a bit between the two. This has not been tested too severly (which means it's completely broken ;-), but I want it in for review. Feel free to revert it :-) TODO: make 'net groupmap' a bit more friendly for alias members. Put that stuff into pdb_ldap. Getting the information over to winbind. One plan without linking pdb into winbind would be to fill group_mapping.tdb with the membership information and have that as a cache (or use gencache.tdb?). smbd on a PDC or stand-alone could trigger that itself, the problem is a BDC using LDAP. This needs to do it on a regular basis. The BDC smbd needs to be informed about SAM changes somehow... Volker (This used to be commit 30ef8fe1e85c0ca229b54f3f1595c4330f7191d1) --- source3/groupdb/mapping.c | 282 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 281 insertions(+), 1 deletion(-) (limited to 'source3/groupdb/mapping.c') diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 71ef38e6c8..5eaa4e1386 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -27,6 +27,7 @@ static TDB_CONTEXT *tdb; /* used for driver files */ #define DATABASE_VERSION_V2 2 /* le format. */ #define GROUP_PREFIX "UNIXGROUP/" +#define ALIASMEM_PREFIX "ALIASMEMBERS/" PRIVS privs[] = { {SE_PRIV_NONE, "no_privs", "No privilege" }, /* this one MUST be first */ @@ -489,6 +490,246 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, return True; } +static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member) +{ + GROUP_MAP map; + TDB_DATA kbuf, dbuf; + pstring key; + fstring string_sid; + char *new_memberstring; + int result; + + if(!init_group_mapping()) { + DEBUG(0,("failed to initialize group mapping")); + return NT_STATUS_ACCESS_DENIED; + } + + 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) ) + return NT_STATUS_NO_SUCH_ALIAS; + + sid_to_string(string_sid, alias); + slprintf(key, sizeof(key), "%s%s", ALIASMEM_PREFIX, string_sid); + + kbuf.dsize = strlen(key)+1; + kbuf.dptr = key; + + dbuf = tdb_fetch(tdb, kbuf); + + sid_to_string(string_sid, member); + + if (dbuf.dptr != NULL) { + asprintf(&new_memberstring, "%s %s", (char *)(dbuf.dptr), + string_sid); + } else { + new_memberstring = strdup(string_sid); + } + + if (new_memberstring == NULL) + return NT_STATUS_NO_MEMORY; + + SAFE_FREE(dbuf.dptr); + dbuf.dsize = strlen(new_memberstring)+1; + dbuf.dptr = new_memberstring; + + result = tdb_store(tdb, kbuf, dbuf, 0); + + SAFE_FREE(new_memberstring); + + return (result == 0 ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED); +} + +static BOOL add_sid_to_array(DOM_SID sid, DOM_SID **sids, int *num) +{ + *sids = Realloc(*sids, ((*num)+1) * sizeof(DOM_SID)); + + if (*sids == NULL) + return False; + + sid_copy(&((*sids)[*num]), &sid); + *num += 1; + + return True; +} + +static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num) +{ + GROUP_MAP map; + TDB_DATA kbuf, dbuf; + pstring key; + fstring string_sid; + const char *p; + + if(!init_group_mapping()) { + DEBUG(0,("failed to initialize group mapping")); + return NT_STATUS_ACCESS_DENIED; + } + + 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) ) + return NT_STATUS_NO_SUCH_ALIAS; + + *sids = NULL; + *num = 0; + + sid_to_string(string_sid, alias); + slprintf(key, sizeof(key), "%s%s", ALIASMEM_PREFIX, string_sid); + + kbuf.dsize = strlen(key)+1; + kbuf.dptr = key; + + dbuf = tdb_fetch(tdb, kbuf); + + if (dbuf.dptr == NULL) { + return NT_STATUS_OK; + } + + p = dbuf.dptr; + + while (next_token(&p, string_sid, " ", sizeof(string_sid))) { + + DOM_SID sid; + + if (!string_to_sid(&sid, string_sid)) + continue; + + if (!add_sid_to_array(sid, sids, num)) + return NT_STATUS_NO_MEMORY; + } + + SAFE_FREE(dbuf.dptr); + + return NT_STATUS_OK; +} + +/* This is racy as hell, but hey, it's only a prototype :-) */ + +static NTSTATUS del_aliasmem(const DOM_SID *alias, const DOM_SID *member) +{ + NTSTATUS result; + DOM_SID *sids; + int i, num; + BOOL found = False; + char *member_string; + TDB_DATA kbuf, dbuf; + pstring key; + fstring sid_string; + + result = enum_aliasmem(alias, &sids, &num); + + if (!NT_STATUS_IS_OK(result)) + return result; + + for (i=0; isid_name_use != SID_NAME_ALIAS) + if ( ( (map->sid_name_use != SID_NAME_ALIAS) && + (map->sid_name_use != SID_NAME_WKN_GRP) ) || (map->gid == -1) || (getgrgid(map->gid) == NULL) ) { @@ -704,6 +946,9 @@ BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids) int i=0; char *gr; DOM_SID *s; + DOM_SID sid; + DOM_SID *members; + int num_members; struct sys_pwent *userlist; struct sys_pwent *user; @@ -803,6 +1048,15 @@ BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids) DEBUG(10, ("got primary groups, members: [%d]\n", *num_sids)); winbind_on(); + + if ( NT_STATUS_IS_OK(gid_to_sid(&sid, gid)) && + NT_STATUS_IS_OK(enum_aliasmem(&sid, &members, &num_members)) ) { + + for (i=0; i