summaryrefslogtreecommitdiffstats
path: root/lib/libaccess/nsadb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libaccess/nsadb.cpp')
-rw-r--r--lib/libaccess/nsadb.cpp582
1 files changed, 582 insertions, 0 deletions
diff --git a/lib/libaccess/nsadb.cpp b/lib/libaccess/nsadb.cpp
new file mode 100644
index 00000000..a87951b8
--- /dev/null
+++ b/lib/libaccess/nsadb.cpp
@@ -0,0 +1,582 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * 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;
+}