From 013ff4d6b2648897f9ef0d6f0ba3eccee7353346 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 30 Nov 1998 15:42:40 +0000 Subject: builtin alias password API (This used to be commit 58c0f0a77c396a6021596c84d4a30b1c9a4b1419) --- source3/groupdb/builtindb.c | 459 ++++++++++++++++++++++++++++++++++++++++++ source3/groupdb/builtinunix.c | 268 ++++++++++++++++++++++++ 2 files changed, 727 insertions(+) create mode 100644 source3/groupdb/builtindb.c create mode 100644 source3/groupdb/builtinunix.c (limited to 'source3/groupdb') diff --git a/source3/groupdb/builtindb.c b/source3/groupdb/builtindb.c new file mode 100644 index 0000000000..a840c396f9 --- /dev/null +++ b/source3/groupdb/builtindb.c @@ -0,0 +1,459 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Pasesword and authentication handling + Copyright (C) Jeremy Allison 1996-1998 + Copyright (C) Luke Kenneth Caseson Leighton 1996-1998 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mases Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "nterr.h" + +extern int DEBUGLEVEL; + +extern fstring global_sam_name; +extern DOM_SID global_sam_sid; + +/* + * NOTE. All these functions are abstracted into a structure + * that points to the correct function for the selected database. JRA. + */ + +static struct aliasdb_ops *bidb_ops = NULL; + +/*************************************************************** + Initialise the builtin db operations. +***************************************************************/ + +BOOL initialise_builtin_db(void) +{ + if (bidb_ops) + { + return True; + } + +#ifdef WITH_NISPLUS + bidb_ops = nisplus_initialise_builtin_db(); +#elif defined(WITH_LDAP) + bidb_ops = ldap_initialise_builtin_db(); +#elif defined(USE_SMBUNIX_DB) + bidb_ops = unix_initialise_builtin_db(); +#endif + + return (bidb_ops != NULL); +} + +/* + * Functions that return/manipulate a LOCAL_GRP. + */ + +/************************************************************************ + Utility function to search builtin database by gid: the LOCAL_GRP + structure does not have a gid member, so we have to convert here + from gid to builtin rid. +*************************************************************************/ +LOCAL_GRP *iterate_getbuiltingid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem) +{ + DOM_NAME_MAP gmep; + uint32 rid; + if (!lookupsmbgrpgid(gid, &gmep)) + { + DEBUG(0,("iterate_getbuiltingid: gid %d does not map to one of our Domain's Aliases\n", gid)); + return NULL; + } + + if (gmep.type != SID_NAME_ALIAS ) + { + DEBUG(0,("iterate_getbuiltingid: gid %d does not map to one of our Domain's Aliases\n", gid)); + return NULL; + } + + sid_split_rid(&gmep.sid, &rid); + if (!sid_equal(&gmep.sid, &global_sam_sid)) + { + DEBUG(0,("iterate_getbuiltingid: gid %d does not map into our Domain SID\n", gid)); + return NULL; + } + + return iterate_getbuiltinrid(rid, mem, num_mem); +} + +/************************************************************************ + Utility function to search builtin database by rid. use this if your database + does not have search facilities. +*************************************************************************/ +LOCAL_GRP *iterate_getbuiltinrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem) +{ + LOCAL_GRP *blt = NULL; + void *fp = NULL; + + DEBUG(10, ("search by rid: 0x%x\n", rid)); + + /* Open the builtin database file - not for update. */ + fp = startbuiltinent(False); + + if (fp == NULL) + { + DEBUG(0, ("unable to open builtin database.\n")); + return NULL; + } + + while ((blt = getbuiltinent(fp, mem, num_mem)) != NULL && blt->rid != rid) + { + DEBUG(10,("iterate: %s 0x%x", blt->name, blt->rid)); + } + + if (blt != NULL) + { + DEBUG(10, ("found builtin %s by rid: 0x%x\n", blt->name, rid)); + } + + endbuiltinent(fp); + return blt; +} + +/************************************************************************ + Utility function to search builtin database by name. use this if your database + does not have search facilities. +*************************************************************************/ +LOCAL_GRP *iterate_getbuiltinntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem) +{ + LOCAL_GRP *blt = NULL; + void *fp = NULL; + + DEBUG(10, ("search by name: %s\n", name)); + + /* Open the builtin database file - not for update. */ + fp = startbuiltinent(False); + + if (fp == NULL) + { + DEBUG(0, ("unable to open builtin database.\n")); + return NULL; + } + + while ((blt = getbuiltinent(fp, mem, num_mem)) != NULL && !strequal(blt->name, name)) + { + } + + if (blt != NULL) + { + DEBUG(10, ("found by name: %s\n", name)); + } + + endbuiltinent(fp); + return blt; +} + +/************************************************************************* + Routine to return the next entry in the smbdomainbuiltin list. + *************************************************************************/ +BOOL add_domain_builtin(LOCAL_GRP **blts, int *num_blts, LOCAL_GRP *blt) +{ + if (blts == NULL || num_blts == NULL || blt == NULL) + { + return False; + } + + (*blts) = Realloc((*blts), ((*num_blts)+1) * sizeof(LOCAL_GRP)); + if ((*blts) == NULL) + { + return False; + } + + DEBUG(10,("adding builtin %s(%s)\n", blt->name, blt->comment)); + + fstrcpy((*blts)[(*num_blts)].name , blt->name); + fstrcpy((*blts)[(*num_blts)].comment, blt->comment); + (*blts)[(*num_blts)].rid = blt->rid; + + (*num_blts)++; + + return True; +} + +/************************************************************************* + checks to see if a user is a member of a domain builtin + *************************************************************************/ +static BOOL user_is_member(const char *user_name, LOCAL_GRP_MEMBER *mem, int num_mem) +{ + int i; + pstring name; + slprintf(name, sizeof(name)-1, "%s\\%s", global_sam_name, user_name); + + for (i = 0; i < num_mem; i++) + { + DEBUG(10,("searching against user %s...\n", mem[i].name)); + if (strequal(mem[i].name, name)) + { + DEBUG(10,("searching for user %s: found\n", name)); + return True; + } + } + DEBUG(10,("searching for user %s: not found\n", name)); + return False; +} + +/************************************************************************* + gets an array of builtin aliases that a user is in. use this if your database + does not have search facilities + *************************************************************************/ +BOOL iterate_getuserbuiltinntnam(const char *user_name, LOCAL_GRP **blts, int *num_blts) +{ + LOCAL_GRP *blt = NULL; + LOCAL_GRP_MEMBER *mem = NULL; + int num_mem = 0; + void *fp = NULL; + + DEBUG(10, ("search for userbuiltin by name: %s\n", user_name)); + + if (user_name == NULL || blts == NULL || num_blts == NULL) + { + return False; + } + + (*blts) = NULL; + (*num_blts) = 0; + + /* Open the builtin database file - not for update. */ + fp = startbuiltinent(False); + + if (fp == NULL) + { + DEBUG(0, ("unable to open builtin database.\n")); + return False; + } + + /* iterate through all builtin aliases. search members for required user */ + while ((blt = getbuiltinent(fp, &mem, &num_mem)) != NULL) + { + DEBUG(5,("builtin name %s members: %d\n", blt->name, num_mem)); + if (num_mem != 0 && mem != NULL) + { + BOOL ret = True; + if (user_is_member(user_name, mem, num_mem)) + { + ret = add_domain_builtin(blts, num_blts, blt); + } + + free(mem); + mem = NULL; + num_mem = 0; + + if (!ret) + { + (*num_blts) = 0; + break; + } + } + } + + if ((*num_blts) != 0) + { + DEBUG(10, ("found %d user builtin aliases:\n", (*num_blts))); + } + + endbuiltinent(fp); + return True; +} + +/************************************************************************* + gets an array of builtin aliases that a user is in. use this if your database + does not have search facilities + *************************************************************************/ +BOOL enumdombuiltins(LOCAL_GRP **blts, int *num_blts) +{ + LOCAL_GRP *blt = NULL; + void *fp = NULL; + + DEBUG(10, ("enum user builtin aliases\n")); + + if (blts == NULL || num_blts == NULL) + { + return False; + } + + (*blts) = NULL; + (*num_blts) = 0; + + /* Open the builtin database file - not for update. */ + fp = startbuiltinent(False); + + if (fp == NULL) + { + DEBUG(0, ("unable to open builtin database.\n")); + return False; + } + + /* iterate through all builtin aliases. */ + while ((blt = getbuiltinent(fp, NULL, NULL)) != NULL) + { + if (!add_domain_builtin(blts, num_blts, blt)) + { + DEBUG(0,("unable to add builtin while enumerating\n")); + return False; + } + } + + if ((*num_blts) != 0) + { + DEBUG(10, ("found %d user builtin aliases:\n", (*num_blts))); + } + + endbuiltinent(fp); + return True; +} + +/*************************************************************** + Start to enumerate the builtin database list. Returns a void pointer + to ensure no modification outside this module. +****************************************************************/ + +void *startbuiltinent(BOOL update) +{ + return bidb_ops->startaliasent(update); +} + +/*************************************************************** + End enumeration of the builtin database list. +****************************************************************/ + +void endbuiltinent(void *vp) +{ + bidb_ops->endaliasent(vp); +} + +/************************************************************************* + Routine to return the next entry in the builtin database list. + *************************************************************************/ + +LOCAL_GRP *getbuiltinent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem) +{ + return bidb_ops->getaliasent(vp, mem, num_mem); +} + +/************************************************************************ + Routine to add an entry to the builtin database file. +*************************************************************************/ + +BOOL add_builtin_entry(LOCAL_GRP *newblt) +{ + return bidb_ops->add_alias_entry(newblt); +} + +/************************************************************************ + Routine to search the builtin database file for an entry matching the builtinname. + and then replace the entry. +************************************************************************/ + +BOOL mod_builtin_entry(LOCAL_GRP* blt) +{ + return bidb_ops->mod_alias_entry(blt); +} + +/************************************************************************ + Routine to search builtin database by name. +*************************************************************************/ + +LOCAL_GRP *getbuiltinntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem) +{ + return bidb_ops->getaliasntnam(name, mem, num_mem); +} + +/************************************************************************ + Routine to search builtin database by builtin rid. +*************************************************************************/ + +LOCAL_GRP *getbuiltinrid(uint32 builtin_rid, LOCAL_GRP_MEMBER **mem, int *num_mem) +{ + return bidb_ops->getaliasrid(builtin_rid, mem, num_mem); +} + +/************************************************************************ + Routine to search builtin database by gid. +*************************************************************************/ + +LOCAL_GRP *getbuiltingid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem) +{ + return bidb_ops->getaliasgid(gid, mem, num_mem); +} + +/************************************************************************* + gets an array of builtin aliases that a user is in. + *************************************************************************/ +BOOL getuserbuiltinntnam(const char *user_name, LOCAL_GRP **blt, int *num_blts) +{ + return bidb_ops->getuseraliasntnam(user_name, blt, num_blts); +} + +/************************************************************* + initialises a LOCAL_GRP. + **************************************************************/ +void bidb_init_blt(LOCAL_GRP *blt) +{ + if (blt == NULL) return; + ZERO_STRUCTP(blt); +} + +/************************************************************* + turns an builtin entry into a string. + **************************************************************/ +BOOL make_builtin_line(char *p, int max_len, + LOCAL_GRP *blt, + LOCAL_GRP_MEMBER **mem, int *num_mem) +{ + int i; + int len; + len = slprintf(p, max_len-1, "%s:%s:%d:", blt->name, blt->comment, blt->rid); + + if (len == -1) + { + DEBUG(0,("make_builtin_line: cannot create entry\n")); + return False; + } + + p += len; + max_len -= len; + + if (mem == NULL || num_mem == NULL) + { + return True; + } + + for (i = 0; i < (*num_mem); i++) + { + len = strlen((*mem)[i].name); + p = safe_strcpy(p, (*mem)[i].name, max_len); + + if (p == NULL) + { + DEBUG(0, ("make_builtin_line: out of space for builtin aliases!\n")); + return False; + } + + max_len -= len; + + if (i != (*num_mem)-1) + { + *p = ','; + p++; + max_len--; + } + } + + return True; +} diff --git a/source3/groupdb/builtinunix.c b/source3/groupdb/builtinunix.c new file mode 100644 index 0000000000..dc70ffb3dc --- /dev/null +++ b/source3/groupdb/builtinunix.c @@ -0,0 +1,268 @@ +/* + * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup + * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995. + * + * 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 the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 675 + * Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +#ifdef USE_SMBUNIX_DB + +extern int DEBUGLEVEL; + + +extern DOM_SID global_sid_S_1_5_20; +extern DOM_SID global_sam_sid; +extern fstring global_sam_name; + +/*************************************************************** + Start to enumerate the bltpasswd list. Returns a void pointer + to ensure no modification outside this module. +****************************************************************/ + +static void *startbltunixpwent(BOOL update) +{ + setgrent(); + return (void*)(-1); +} + +/*************************************************************** + End enumeration of the bltpasswd list. +****************************************************************/ + +static void endbltunixpwent(void *vp) +{ + endgrent(); +} + +/************************************************************************* + Return the current position in the bltpasswd list as an SMB_BIG_UINT. + This must be treated as an opaque token. +*************************************************************************/ +static SMB_BIG_UINT getbltunixpwpos(void *vp) +{ + return (SMB_BIG_UINT)0; +} + +/************************************************************************* + Set the current position in the bltpasswd list from an SMB_BIG_UINT. + This must be treated as an opaque token. +*************************************************************************/ +static BOOL setbltunixpwpos(void *vp, SMB_BIG_UINT tok) +{ + return False; +} + +/************************************************************************* + Routine to return the next entry in the smbdomainbuiltin list. + *************************************************************************/ +BOOL get_unixbuiltin_members(struct group *grp, + int *num_mem, LOCAL_GRP_MEMBER **members) +{ + int i; + char *unix_name; + + if (num_mem == NULL || members == NULL) + { + return False; + } + + (*num_mem) = 0; + (*members) = NULL; + + for (i = 0; (unix_name = grp->gr_mem[i]) != NULL; i++) + { + fstring name; + DOM_NAME_MAP gmep; + LOCAL_GRP_MEMBER *mem; + + fstrcpy(name, unix_name); + + if (!lookupsmbgrpnam(name, &gmep) && + !lookupsmbpwnam (name, &gmep)) + { + continue; + } + + if (!sid_front_equal(&global_sam_sid, &gmep.sid)) + { + DEBUG(0,("builtin database: could not resolve name %s (wrong Domain SID)\n", + name)); + continue; + } + + (*num_mem)++; + (*members) = Realloc((*members), (*num_mem) * sizeof(LOCAL_GRP_MEMBER)); + if ((*members) == NULL) + { + DEBUG(0,("get_unixbuiltin_members: could not realloc LOCAL_GRP_MEMBERs\n")); + return False; + } + + mem = &(*members)[(*num_mem)-1]; + slprintf(mem->name, sizeof(mem->name)-1, "%s\\%s", + gmep.nt_domain, gmep.nt_name); + sid_copy(&mem->sid, &gmep.sid); + mem->sid_use = gmep.type; + + DEBUG(10,("get_unixbuiltin_members: adding to builtin alias %s\n", + mem->name)); + } + return True; +} + +/************************************************************************* + Routine to return the next entry in the domain builtin list. + + when we are a PDC or BDC, then unix groups that are explicitly NOT mapped + to builtin aliases are treated as DOMAIN groups (see groupunix.c). + + when we are a member of a domain (not a PDC or BDC) then unix groups + that are explicitly NOT mapped to builtin aliases are treated + as LOCAL groups. + + the reasoning behind this is to make it as simple as possible (not an easy + task) for people to set up a domain-aware samba server, in each role that + the server can take. + + *************************************************************************/ +static LOCAL_GRP *getbltunixpwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem) +{ + /* Static buffers we will return. */ + static LOCAL_GRP gp_buf; + struct group *unix_grp; + + if (lp_server_role() == ROLE_DOMAIN_NONE) + { + /* + * no domain role, no domain builtin aliases (or domain groups, + * but that's dealt with by groupdb...). + */ + + return NULL; + } + + bidb_init_blt(&gp_buf); + + /* cycle through unix groups */ + while ((unix_grp = getgrent()) != NULL) + { + DOM_NAME_MAP gmep; + fstring sid_str; + DEBUG(10,("getbltunixpwent: enum unix group entry %s\n", + unix_grp->gr_name)); + + if (!lookupsmbgrpgid(unix_grp->gr_gid, &gmep)) + { + continue; + } + + sid_to_string(sid_str, &gmep.sid); + DEBUG(10,("group %s found, sid %s type %d\n", + gmep.nt_name, sid_str, gmep.type)); + + if (gmep.type != SID_NAME_ALIAS) + { + continue; + } + + sid_split_rid(&gmep.sid, &gp_buf.rid); + if (!sid_equal(&global_sid_S_1_5_20, &gmep.sid)) + { + continue; + } + + fstrcpy(gp_buf.name, gmep.nt_name); + break; + } + + if (unix_grp == NULL) + { + return NULL; + } + + /* get the user's domain builtin aliases. there are a maximum of 32 */ + + if (mem != NULL && num_mem != NULL) + { + (*mem) = NULL; + (*num_mem) = 0; + + get_unixbuiltin_members(unix_grp, num_mem, mem); + } + + { + pstring linebuf; + make_builtin_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem); + DEBUG(10,("line: '%s'\n", linebuf)); + } + + return &gp_buf; +} + +/************************************************************************ + Routine to add an entry to the bltpasswd file. +*************************************************************************/ + +static BOOL add_bltunixgrp_entry(LOCAL_GRP *newblt) +{ + DEBUG(0, ("add_bltunixgrp_entry: NOT IMPLEMENTED\n")); + return False; +} + +/************************************************************************ + Routine to search the bltpasswd file for an entry matching the builtinname. + and then modify its builtin entry. We can't use the startbltpwent()/ + getbltpwent()/endbltpwent() interfaces here as we depend on looking + in the actual file to decide how much room we have to write data. + override = False, normal + override = True, override XXXXXXXX'd out builtin or NO PASS +************************************************************************/ + +static BOOL mod_bltunixgrp_entry(LOCAL_GRP* blt) +{ + DEBUG(0, ("mod_bltunixgrp_entry: NOT IMPLEMENTED\n")); + return False; +} + + +static struct aliasdb_ops unix_ops = +{ + startbltunixpwent, + endbltunixpwent, + getbltunixpwpos, + setbltunixpwpos, + + iterate_getbuiltinntnam, /* In builtindb.c */ + iterate_getbuiltingid, /* In builtindb.c */ + iterate_getbuiltinrid, /* In builtindb.c */ + getbltunixpwent, + + add_bltunixgrp_entry, + mod_bltunixgrp_entry, + + iterate_getuserbuiltinntnam /* in builtindb.c */ +}; + +struct aliasdb_ops *unix_initialise_builtin_db(void) +{ + return &unix_ops; +} + +#else + /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */ + void unix_bltpass_dummy_function(void) { } /* stop some compilers complaining */ +#endif /* USE_SMBPASS_DB */ -- cgit