| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582 |
- /** BEGIN COPYRIGHT BLOCK
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * END COPYRIGHT BLOCK **/
- /*
- * Description (nsadb.c)
- *
- * This module contains routines for retrieving information from
- * a Netscape authentication database. An authentication database
- * consists of a user database and a group database. This module
- * implements an authentication database based on Netscape user and
- * group databases defined in nsuser.h and nsgroup.h, which in turn
- * are based on the Netscape (server) database implementation
- * defined in nsdb.h. The interface for managing information in
- * an authentication database is described separately in nsamgmt.h.
- */
- #include <base/systems.h>
- #include <netsite.h>
- #include <base/file.h>
- #include <base/fsmutex.h>
- #include <libaccess/nsdbmgmt.h>
- #define __PRIVATE_NSADB
- #include <libaccess/nsadb.h>
- #include <libaccess/nsuser.h>
- #include <libaccess/nsgroup.h>
- /*
- * Description (NSADB_AuthIF)
- *
- * This structure defines a generic authentication database
- * interface for this module. It does not currently support
- * user/group id lookup.
- */
- AuthIF_t NSADB_AuthIF = {
- 0, /* find user/group by id */
- nsadbFindByName, /* find user/group by name */
- nsadbIdToName, /* lookup name for user/group id */
- nsadbOpen, /* open a named database */
- nsadbClose, /* close a database */
- };
- /*
- * Description (nsadbClose)
- *
- * This function closes an authentication database previously opened
- * via nsadbOpen().
- *
- * Arguments:
- *
- * authdb - handle returned by nsadbOpen()
- * flags - unused (must be zero)
- */
- NSAPI_PUBLIC void nsadbClose(void * authdb, int flags)
- {
- AuthDB_t * adb = (AuthDB_t *)authdb;
- if (adb->adb_userdb != 0) {
- ndbClose(adb->adb_userdb, 0);
- }
- if (adb->adb_groupdb != 0) {
- ndbClose(adb->adb_groupdb, 0);
- }
- #if defined(CLIENT_AUTH)
- nsadbCloseCerts(authdb, flags);
- #endif
- if (adb->adb_dbname) {
- FREE(adb->adb_dbname);
- }
- FREE(adb);
- }
- /*
- * Description (nsadbOpen)
- *
- * This function is used to open an authentication database.
- * The caller specifies a name for the database, which is actually
- * the name of a directory containing the files which comprise the
- * database. The caller also indicates whether this is a new
- * database, in which case it is created.
- *
- * Arguments:
- *
- * errp - error frame list pointer (may be null)
- * adbname - name of this database (directory)
- * flags - open flags:
- * AIF_CREATE - new database (create)
- * rptr - pointer to returned handle
- *
- * Returns:
- *
- * A handle for accessing the database is always returned via 'rptr'
- * unless there was a shortage of dynamic memory, in which case a
- * null handle is returned. The return value of the function is
- * 0 if it completes successfully. An error is indicated by a
- * negative return value (see nsautherr.h).
- */
- NSAPI_PUBLIC int nsadbOpen(NSErr_t * errp,
- char * adbname, int flags, void **rptr)
- {
- AuthDB_t * authdb = 0; /* pointer to database descriptor */
- SYS_DIR dbdir; /* database directory handle */
- int eid; /* error id code */
- int rv; /* result value */
- /* Make sure we have a place to return the database handle */
- if (rptr == 0) goto err_inval;
- /* Allocate the database descriptor */
- authdb = (AuthDB_t *)MALLOC(sizeof(AuthDB_t));
- if (authdb == 0) goto err_nomem;
- /* Return the descriptor pointer as the database handle */
- *rptr = (void *)authdb;
- authdb->adb_dbname = STRDUP(adbname);
- authdb->adb_userdb = 0;
- authdb->adb_groupdb = 0;
- #if defined(CLIENT_AUTH)
- authdb->adb_certdb = 0;
- authdb->adb_certlock = 0;
- authdb->adb_certnm = 0;
- #endif
- authdb->adb_flags = 0;
- /* See if the database directory exists */
- dbdir = dir_open(adbname);
- if (dbdir == 0) {
- /* No, create it if this is a new database, else error */
- if (flags & AIF_CREATE) {
- rv = dir_create(adbname);
- if (rv < 0) goto err_mkdir;
- authdb->adb_flags |= ADBF_NEW;
- }
- else goto err_dopen;
- }
- else {
- /* Ok, it's there */
- dir_close(dbdir);
- }
- return 0;
- err_inval:
- eid = NSAUERR3000;
- rv = NSAERRINVAL;
- goto err_ret;
- err_nomem:
- /* Error - insufficient dynamic memory */
- eid = NSAUERR3020;
- rv = NSAERRNOMEM;
- goto err_ret;
- err_ret:
- nserrGenerate(errp, rv, eid, NSAuth_Program, 0);
- goto punt;
- err_mkdir:
- eid = NSAUERR3040;
- rv = NSAERRMKDIR;
- goto err_dir;
- err_dopen:
- eid = NSAUERR3060;
- rv = NSAERROPEN;
- goto err_dir;
- err_dir:
- nserrGenerate(errp, rv, eid, NSAuth_Program, 1, adbname);
- goto punt;
- punt:
- /* Fatal error - free database descriptor and return null handle */
- if (authdb) {
- if (authdb->adb_dbname) {
- FREE(authdb->adb_dbname);
- }
- FREE(authdb);
- }
- if (rptr) *rptr = 0;
- return rv;
- }
- /*
- * Description (nsadbOpenUsers)
- *
- * This function is called to open the users subdatabase of an
- * open authentication database. The caller specifies flags to
- * indicate whether read or write access is required. This
- * function is normally called only by routines below the
- * nsadbOpen() API, in response to perform particular operations
- * on user or group objects. If the open is successful, the
- * resulting handle is stored in the AuthDB_t structure.
- *
- * Arguments:
- *
- * errp - error frame list pointer (may be null)
- * authdb - handle returned by nsadbOpen()
- * flags - open flags:
- * ADBF_UREAD - open for read
- * ADBF_UWRITE - open for read/write
- * Returns:
- *
- * The return value is zero if the operation is successfully
- * completed. An error is indicated by a negative return value
- * (see nsautherr.h), and an error frame is generated if an error
- * frame list was provided.
- */
- NSAPI_PUBLIC int nsadbOpenUsers(NSErr_t * errp, void * authdb, int flags)
- {
- AuthDB_t * adb = (AuthDB_t *)authdb;
- char * userfn = 0; /* user database name */
- int dblen; /* strlen(adb_dbname) */
- int uversion; /* user database version number */
- int eid; /* error id code */
- int rv; /* result value */
- if (adb == 0) goto err_inval;
- /* Is the user database already open? */
- if (adb->adb_userdb != 0) {
- /* Yes, is it open for the desired access? */
- if (adb->adb_flags & flags) {
- /* Yes, that was easy */
- return 0;
- }
- }
- else {
- /* We need to open the database */
- /* Allocate space for the user database filename */
- dblen = strlen(adb->adb_dbname);
- userfn = (char *)MALLOC(dblen + strlen(ADBUSERDBNAME) + 2);
- if (userfn == 0) goto err_nomem;
- /* Construct user database name */
- strcpy(userfn, adb->adb_dbname);
- /* Put in a '/' (or '\') if it's not there */
- if (userfn[dblen-1] != FILE_PATHSEP) {
- userfn[dblen] = FILE_PATHSEP;
- userfn[dblen+1] = 0;
- ++dblen;
- }
- strcpy(&userfn[dblen], ADBUSERDBNAME);
- adb->adb_userdb = ndbOpen(errp,
- userfn, 0, NDB_TYPE_USERDB, &uversion);
- if (adb->adb_userdb == 0) goto err_uopen;
- FREE(userfn);
- }
- /*
- * We don't really reopen the database to get the desired
- * access mode, since that is handled at the nsdb level.
- * But we do update the flags, just for the record.
- */
- adb->adb_flags &= ~(ADBF_UREAD|ADBF_UWRITE);
- if (flags & ADBF_UWRITE) adb->adb_flags |= ADBF_UWRITE;
- else adb->adb_flags |= ADBF_UREAD;
- return 0;
- err_inval:
- eid = NSAUERR3200;
- rv = NSAERRINVAL;
- goto err_ret;
- err_nomem:
- eid = NSAUERR3220;
- rv = NSAERRNOMEM;
- goto err_ret;
- err_ret:
- nserrGenerate(errp, rv, eid, NSAuth_Program, 0);
- goto punt;
- err_uopen:
- eid = NSAUERR3240;
- rv = NSAERROPEN;
- nserrGenerate(errp, rv, eid, NSAuth_Program, 1, userfn);
- goto punt;
- punt:
- return rv;
- }
- /*
- * Description (nsadbOpenGroups)
- *
- * This function is called to open the groups subdatabase of an
- * open authentication database. The caller specifies flags to
- * indicate whether read or write access is required. This
- * function is normally called only by routines below the
- * nsadbOpen() API, in response to perform particular operations
- * on user or group objects. If the open is successful, the
- * resulting handle is stored in the AuthDB_t structure.
- *
- * Arguments:
- *
- * errp - error frame list pointer (may be null)
- * authdb - handle returned by nsadbOpen()
- * flags - open flags:
- * ADBF_GREAD - open for read
- * ADBF_GWRITE - open for read/write
- * Returns:
- *
- * The return value is zero if the operation is successfully
- * completed. An error is indicated by a negative return value
- * (see nsautherr.h), and an error frame is generated if an error
- * frame list was provided.
- */
- NSAPI_PUBLIC int nsadbOpenGroups(NSErr_t * errp, void * authdb, int flags)
- {
- AuthDB_t * adb = (AuthDB_t *)authdb;
- char * groupfn = 0; /* group database name */
- int dblen; /* strlen(adb_dbname) */
- int gversion; /* group database version number */
- int eid; /* error id code */
- int rv; /* result value */
- if (adb == 0) goto err_inval;
- /* Is the group database already open? */
- if (adb->adb_groupdb != 0) {
- /* Yes, is it open for the desired access? */
- if (adb->adb_flags & flags) {
- /* Yes, that was easy */
- return 0;
- }
- }
- else {
- /* We need to open the database */
- /* Allocate space for the group database filename */
- dblen = strlen(adb->adb_dbname);
- groupfn = (char *)MALLOC(dblen + strlen(ADBGROUPDBNAME) + 2);
- if (groupfn == 0) goto err_nomem;
- /* Construct group database name */
- strcpy(groupfn, adb->adb_dbname);
- /* Put in a '/' (or '\') if it's not there */
- if (groupfn[dblen-1] != FILE_PATHSEP) {
- groupfn[dblen] = FILE_PATHSEP;
- groupfn[dblen+1] = 0;
- ++dblen;
- }
- strcpy(&groupfn[dblen], ADBGROUPDBNAME);
- adb->adb_groupdb = ndbOpen(errp,
- groupfn, 0, NDB_TYPE_GROUPDB, &gversion);
- if (adb->adb_groupdb == 0) goto err_gopen;
- FREE(groupfn);
- }
- /*
- * We don't really reopen the database to get the desired
- * access mode, since that is handled at the nsdb level.
- * But we do update the flags, just for the record.
- */
- adb->adb_flags &= ~(ADBF_GREAD|ADBF_GWRITE);
- if (flags & ADBF_GWRITE) adb->adb_flags |= ADBF_GWRITE;
- else adb->adb_flags |= ADBF_GREAD;
- return 0;
- err_inval:
- eid = NSAUERR3300;
- rv = NSAERRINVAL;
- goto err_ret;
- err_nomem:
- eid = NSAUERR3320;
- rv = NSAERRNOMEM;
- goto err_ret;
- err_ret:
- nserrGenerate(errp, rv, eid, NSAuth_Program, 0);
- goto punt;
- err_gopen:
- eid = NSAUERR3340;
- rv = NSAERROPEN;
- nserrGenerate(errp, rv, eid, NSAuth_Program, 1, groupfn);
- goto punt;
- punt:
- return rv;
- }
- /*
- * Description (nsadbIdToName)
- *
- * This function looks up a specified user or group id in the
- * authentication database. The name associated with the specified
- * id is returned.
- *
- * Arguments:
- *
- * errp - error frame list pointer (may be null)
- * authdb - handle returned by nsadbOpen()
- * id - user or group id
- * flags - AIF_USER or AIF_GROUP (defined in nsauth.h)
- * rptr - pointer to returned group or user name
- *
- * Returns:
- *
- * The return value is zero if no error occurs,
- * A negative return value indicates an error.
- */
- NSAPI_PUBLIC int nsadbIdToName(NSErr_t * errp,
- void * authdb, USI_t id, int flags, char **rptr)
- {
- AuthDB_t * adb = (AuthDB_t *)authdb;
- void * whichdb = 0;
- char * name;
- int rv;
- if (rptr != 0) *rptr = 0;
- /* Decide whether to use user or group database */
- if (flags & AIF_USER) {
- whichdb = adb->adb_userdb;
- if (whichdb == 0) {
- rv = nsadbOpenUsers(errp, authdb, ADBF_UREAD);
- if (rv < 0) goto punt;
- whichdb = adb->adb_userdb;
- }
- }
- else if (flags & AIF_GROUP) {
- whichdb = adb->adb_groupdb;
- if (whichdb == 0) {
- rv = nsadbOpenGroups(errp, authdb, ADBF_GREAD);
- if (rv < 0) goto punt;
- whichdb = adb->adb_groupdb;
- }
- }
- if (whichdb != 0) {
- /* Get the name corresponding to the id */
- rv = ndbIdToName(errp, whichdb, id, 0, &name);
- if (rv < 0) goto punt;
- if ((rptr != 0)) *rptr = name;
- rv = 0;
- }
- punt:
- return rv;
- }
- /*
- * Description (nsadbFindByName)
- *
- * This function looks up a specified name in the authentication
- * database. Flags specified by the caller indicate whether a
- * group name, user name, or either should be found. The caller
- * may optionally provide for the return of a user or group object
- * pointer, in which case the information associated with a
- * matching group or user is used to create a group or user object.
- *
- * Arguments:
- *
- * errp - error frame list pointer (may be null)
- * authdb - handle returned by nsadbOpen()
- * name - name of group or user
- * flags - search flags (defined in nsauth.h)
- * rptr - pointer to returned group or user
- * object pointer (may be null)
- *
- * Returns:
- *
- * The return value is a non-negative value if no error occurs,
- * and the value indicates whether the name matched a group or
- * user:
- *
- * AIF_NONE - name did not match a group or user name
- * AIF_GROUP - name matched a group name
- * AIF_USER - name matched a user name
- *
- * If the value is AIF_GROUP or AIF_USER, and rptr is non-null,
- * then a group or user object is created, and a pointer to it is
- * returned in the location indicated by rptr.
- *
- * A negative return value indicates an error.
- */
- NSAPI_PUBLIC int nsadbFindByName(NSErr_t * errp, void * authdb,
- char * name, int flags, void **rptr)
- {
- AuthDB_t * adb = (AuthDB_t *)authdb;
- ATR_t recptr;
- int reclen;
- int rv;
- if (rptr != 0) *rptr = 0;
- /* Search for group name? */
- if (flags & AIF_GROUP) {
- if (adb->adb_groupdb == 0) {
- rv = nsadbOpenGroups(errp, authdb, ADBF_GREAD);
- if (rv < 0) goto punt;
- }
- /* Look up the name in the group database */
- rv = ndbFindName(errp, adb->adb_groupdb, 0, (char *)name,
- &reclen, (char **)&recptr);
- if (rv == 0) {
- /* Found it. Make a group object if requested. */
- if (rptr != 0) {
- /* Got the group record. Decode into a group object. */
- *rptr = (void *)groupDecode((NTS_t)name, reclen, recptr);
- }
- return AIF_GROUP;
- }
- }
- /* Search for user name? */
- if (flags & AIF_USER) {
- if (adb->adb_userdb == 0) {
- rv = nsadbOpenUsers(errp, authdb, ADBF_UREAD);
- if (rv < 0) goto punt;
- }
- /* Look up the name in the user database */
- rv = ndbFindName(errp, adb->adb_userdb, 0, (char *)name,
- &reclen, (char **)&recptr);
- if (rv == 0) {
- /* Found it. Make a user object if requested. */
- if (rptr != 0) {
- /* Got the user record. Decode into a user object. */
- *rptr = (void *)userDecode((NTS_t)name, reclen, recptr);
- }
- return AIF_USER;
- }
- }
- /* Nothing found */
- nserrDispose(errp);
- return AIF_NONE;
- punt:
- return rv;
- }
|