diff options
Diffstat (limited to 'lib/libaccess/nsgroup.cpp')
-rw-r--r-- | lib/libaccess/nsgroup.cpp | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/lib/libaccess/nsgroup.cpp b/lib/libaccess/nsgroup.cpp new file mode 100644 index 00000000..c67c85ba --- /dev/null +++ b/lib/libaccess/nsgroup.cpp @@ -0,0 +1,336 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright 2001 Sun Microsystems, Inc. + * Portions copyright 1999, 2001-2003 Netscape Communications Corporation. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +/* + * Description (nsgroup.c) + * + * This module contains routines for accessing information in a + * Netscape group database. Group information is returned in the + * form of a group object (GroupObj_t), defined in nsauth.h. + */ + +#include "base/systems.h" +#include "netsite.h" +#include "assert.h" +#define __PRIVATE_NSGROUP +#include "libaccess/nsgroup.h" + +/* + * Description (groupDecode) + * + * This function decodes an external group DB record into a + * dynamically allocated GroupObj_t structure. The DB record is + * encoded as an attribute record as defined in attrec.h. + * + * Arguments: + * + * name - pointer to group name string + * greclen - length of the group DB record, in octets + * grecptr - pointer to group DB record + * + * Returns: + * + * A pointer to the allocated GroupObj_t structure is returned. + */ + +NSAPI_PUBLIC GroupObj_t * groupDecode(NTS_t name, int greclen, ATR_t grecptr) +{ + ATR_t cp = grecptr; /* current pointer into DB record */ + USI_t tag; /* attribute tag */ + USI_t len; /* attribute value encoding length */ + int i; /* group id index */ + int idcnt; /* count of user or group ids */ + USI_t * ids; /* pointer to array of ids */ + GroupObj_t * goptr; /* group object pointer */ + + /* Allocate a group object structure */ + goptr = (GroupObj_t *)MALLOC(sizeof(GroupObj_t)); + if (goptr) { + + goptr->go_name = (unsigned char *) STRDUP((char *)name); + goptr->go_gid = 0; + goptr->go_flags = GOF_MODIFIED; + goptr->go_desc = 0; + UILINIT(&goptr->go_users); + UILINIT(&goptr->go_groups); + UILINIT(&goptr->go_pgroups); + + /* Parse group DB record */ + while ((cp - grecptr) < greclen) { + + /* Get the attribute tag */ + cp = USIDECODE(cp, &tag); + + /* Get the length of the encoding of the attribute value */ + cp = USIDECODE(cp, &len); + + /* Process this attribute */ + switch (tag) { + + case GAT_GID: /* group id */ + cp = USIDECODE(cp, &goptr->go_gid); + break; + + case GAT_FLAGS: /* flags */ + cp = USIDECODE(cp, &goptr->go_flags); + break; + + case GAT_DESCRIPT: /* group description */ + cp = NTSDECODE(cp, &goptr->go_desc); + break; + + case GAT_USERS: /* member users of this group */ + + /* First get the number of user ids following */ + cp = USIDECODE(cp, (unsigned *)&idcnt); + + if (idcnt > 0) { + + /* Allocate space for user ids */ + ids = usiAlloc(&goptr->go_users, idcnt); + if (ids) { + for (i = 0; i < idcnt; ++i) { + cp = USIDECODE(cp, ids + i); + } + } + } + break; + + case GAT_GROUPS: /* member groups of this group */ + + /* First get the number of group ids following */ + cp = USIDECODE(cp, (unsigned *)&idcnt); + + if (idcnt > 0) { + + /* Allocate space for group ids */ + ids = usiAlloc(&goptr->go_groups, idcnt); + if (ids) { + for (i = 0; i < idcnt; ++i) { + cp = USIDECODE(cp, ids + i); + } + } + } + break; + + case GAT_PGROUPS: /* parent groups of this group */ + + /* First get the number of group ids following */ + cp = USIDECODE(cp, (USI_t *)&idcnt); + + if (idcnt > 0) { + + /* Allocate space for group ids */ + ids = usiAlloc(&goptr->go_pgroups, idcnt); + if (ids) { + for (i = 0; i < idcnt; ++i) { + cp = USIDECODE(cp, ids + i); + } + } + } + break; + + default: /* unrecognized attribute */ + /* Just skip it */ + cp += len; + break; + } + } + } + + return goptr; +} + +/* + * Description (groupEnumHelp) + * + * This is a local function that is called by NSDB during group + * database enumeration. It decodes group records into group + * objects, and presents them to the caller of groupEnumerate(). + * + * Arguments: + * + * errp - error frame list pointer (may be null) + * parg - pointer to GroupEnumArgs_t structure + * namelen - length of group record key, including null + * terminator + * name - group record key (group account name) + * reclen - length of group record + * recptr - pointer to group record contents + * + * Returns: + * + * Returns whatever value is returned from the upcall to the caller + * of groupEnumerate(). + */ + +static int groupEnumHelp(NSErr_t * errp, void * parg, + int namelen, char * name, int reclen, char * recptr) +{ + GroupEnumArgs_t * ge = (GroupEnumArgs_t *)parg; + GroupObj_t * goptr; /* group object pointer */ + int rv; + + goptr = groupDecode((NTS_t)name, reclen, (ATR_t)recptr); + + rv = (*ge->func)(errp, ge->user, goptr); + + if (!(ge->flags & GOF_ENUMKEEP)) { + FREE(goptr); + } + + return rv; +} + +/* + * Description (groupEnumerate) + * + * This function enumerates all of the groups in a specified group + * database, calling a caller-specified function with a group object + * for each group in the database. A 'flags' value of GOF_ENUMKEEP + * can be specified to keep the group objects around (not free them) + * after the caller's function returns. Otherwise, each group + * object is freed after being presented to the caller's function. + * The 'argp' argument is an opaque pointer, which is passed to + * the caller's function as 'parg' on each call, along with a + * group object pointer. + * + * Arguments: + * + * errp - error frame list pointer (may be null) + * groupdb - handle for group DB access + * flags - bit flags: + * GOF_ENUMKEEP - keep group objects + * argp - passed to 'func' as 'parg' + * func - pointer to caller's enumeration function + * + * Returns: + * + * If successful, the return value is zero. Otherwise it is a + * non-zero error code. + */ + +NSAPI_PUBLIC int groupEnumerate(NSErr_t * errp, void * groupdb, int flags, void * argp, + int (*func)(NSErr_t * ferrp, + void * parg, GroupObj_t * goptr)) +{ + int rv; + GroupEnumArgs_t args; + + args.groupdb = groupdb; + args.flags = flags; + args.func = func; + args.user = argp; + + rv = ndbEnumerate(errp, + groupdb, NDBF_ENUMNORM, (void *)&args, groupEnumHelp); + + return rv; +} + +/* + * Description (groupFindByName) + * + * This function looks up a group record for a specified group name, + * converts the group record to the internal group object form, and + * returns a pointer to the group object. + * + * Arguments: + * + * errp - error frame list pointer (may be null) + * groupdb - handle for group DB access + * name - group name to find + * + * Returns: + * + * If successful, the return value is a pointer to a group object + * for the specified group. Otherwise it is 0. + */ + +NSAPI_PUBLIC GroupObj_t * groupFindByName(NSErr_t * errp, void * groupdb, NTS_t name) +{ + GroupObj_t * goptr = 0; + ATR_t grecptr; + int greclen; + int rv; + + /* Look up the group name in the database */ + rv = ndbFindName(errp, groupdb, 0, (char *)name, &greclen, (char **)&grecptr); + if (rv == 0) { + + /* Got the group record. Decode into a group object. */ + goptr = groupDecode(name, greclen, grecptr); + } + + return goptr; +} + +/* + * Description (groupFindByGid) + * + * This function looks up a group record for a specified group id, + * converts the group record to the internal group object form, and + * returns a pointer to the group object. + * + * Arguments: + * + * errp - error frame list pointer (may be null) + * groupdb - handle for group DB access + * gid - group id to find + * + * Returns: + * + * If successful, the return value is a pointer to a group object + * for the specified group. Otherwise it is 0. + */ + +NSAPI_PUBLIC GroupObj_t * groupFindByGid(NSErr_t * errp, void * groupdb, USI_t gid) +{ + GroupObj_t * goptr = 0; + NTS_t name; + ATR_t grecptr; + int greclen; + int rv; + + /* Get the group account name corresponding to the gid */ + rv = ndbIdToName(errp, groupdb, gid, 0, (char **)&name); + if (rv == 0) { + + rv = ndbFindName(errp, groupdb, 0, (char *)name, &greclen, (char **)&grecptr); + if (rv == 0) { + + /* Got the group record. Decode into a group object. */ + goptr = groupDecode(name, greclen, grecptr); + } + } + + return goptr; +} + +/* + * Description (groupFree) + * + * This function is called to free a group object. Group objects + * are not automatically freed when a group database is closed. + * + * Arguments: + * + * goptr - group object pointer + * + */ + +NSAPI_PUBLIC void groupFree(GroupObj_t * goptr) +{ + if (goptr) { + + if (goptr->go_name) FREE(goptr->go_name); + if (goptr->go_desc) FREE(goptr->go_desc); + UILFREE(&goptr->go_users); + UILFREE(&goptr->go_groups); + UILFREE(&goptr->go_pgroups); + FREE(goptr); + } +} |