summaryrefslogtreecommitdiffstats
path: root/lib/libaccess/nsumgmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libaccess/nsumgmt.cpp')
-rw-r--r--lib/libaccess/nsumgmt.cpp456
1 files changed, 456 insertions, 0 deletions
diff --git a/lib/libaccess/nsumgmt.cpp b/lib/libaccess/nsumgmt.cpp
new file mode 100644
index 00000000..3db677f0
--- /dev/null
+++ b/lib/libaccess/nsumgmt.cpp
@@ -0,0 +1,456 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+/*
+ * Description (nsumgmt.c)
+ *
+ * This module contains routines for managing information in a
+ * Netscape user database. Information for a particular user
+ * is modified by retrieving the current information in the form
+ * of a user object (UserObj_t), calling functions in this module,
+ * to modify the user object, and then calling userStore() to
+ * write the information in the user object back to the database.
+ */
+
+#include "base/systems.h"
+#include "netsite.h"
+#include "assert.h"
+#include "libaccess/nsdbmgmt.h"
+#define __PRIVATE_NSUSER
+#include "libaccess/nsumgmt.h"
+
+/*
+ * Description (userAddGroup)
+ *
+ * This function adds a group id to the list of group ids associated
+ * with a user object.
+ *
+ * Arguments:
+ *
+ * uoptr - user object pointer
+ * gid - group id to be added
+ *
+ * Returns:
+ *
+ * Returns zero if the group id is already present in the group id list.
+ * Returns one if the group id was added successfully.
+ * Returns a negative value if an error occurs.
+ */
+
+int userAddGroup(UserObj_t * uoptr, USI_t gid)
+{
+ int rv;
+
+ rv = usiInsert(&uoptr->uo_groups, gid);
+
+ if (rv > 0) {
+
+ uoptr->uo_flags |= UOF_MODIFIED;
+ }
+
+ return rv;
+}
+
+/*
+ * Description (userCreate)
+ *
+ * This function creates a user object, using information about
+ * the user provided by the caller. The strings passed for the
+ * user account name, password, and real user name may be on the
+ * stack. The user id is set to zero, but the user object is
+ * marked as being new. A user id will be assigned when
+ * userStore() is called to add the user to a user database.
+ *
+ * Arguments:
+ *
+ * name - pointer to user account name string
+ * pwd - pointer to (encrypted) password string
+ * rname - real user name (gecos string)
+ *
+ * Returns:
+ *
+ * A pointer to a dynamically allocated UserObj_t structure is
+ * returned.
+ */
+
+NSAPI_PUBLIC UserObj_t * userCreate(NTS_t name, NTS_t pwd, NTS_t rname)
+{
+ UserObj_t * uoptr; /* user object pointer */
+
+ uoptr = (UserObj_t *)MALLOC(sizeof(UserObj_t));
+ if (uoptr) {
+ uoptr->uo_name = (NTS_t)STRDUP((char *)name);
+ uoptr->uo_pwd = (pwd) ? (NTS_t)STRDUP((char *)pwd) : 0;
+ uoptr->uo_uid = 0;
+ uoptr->uo_flags = (UOF_MODIFIED | UOF_NEW);
+ uoptr->uo_rname = (rname) ? (NTS_t)STRDUP((char *)rname) : 0;
+ UILINIT(&uoptr->uo_groups);
+ }
+
+ return uoptr;
+}
+
+/*
+ * Description (userDeleteGroup)
+ *
+ * This function removes a specified group id from a user object's
+ * list of groups.
+ *
+ * Arguments:
+ *
+ * uoptr - pointer to user object
+ * gid - group id to remove
+ *
+ * Returns:
+ *
+ * The return value is zero if the specified group id was not present
+ * in the user object, or one if the group was successfully removed.
+ */
+
+int userDeleteGroup(UserObj_t * uoptr, USI_t gid)
+{
+ int rv; /* return value */
+
+ rv = usiRemove(&uoptr->uo_groups, gid);
+ if (rv > 0) {
+ uoptr->uo_flags |= UOF_MODIFIED;
+ }
+
+ return rv;
+}
+
+/*
+ * Description (userEncode)
+ *
+ * This function encodes a user object into a user DB record.
+ *
+ * Arguments:
+ *
+ * uoptr - pointer to user object
+ * ureclen - pointer to returned record length
+ * urecptr - pointer to returned record pointer
+ *
+ * Returns:
+ *
+ * The function return value is zero if successful. The length
+ * and location of the created attribute record are returned
+ * through 'ureclen' and 'urecptr'. A non-zero function value
+ * is returned if there's an error.
+ */
+
+int userEncode(UserObj_t * uoptr, int * ureclen, ATR_t * urecptr)
+{
+ int reclen; /* length of DB record */
+ ATR_t rptr; /* DB record pointer */
+ ATR_t rstart = 0; /* pointer to beginning of DB record */
+ ATR_t glptr; /* saved pointer to UAT_GROUPS length */
+ ATR_t gptr; /* saved pointer to after length at glptr */
+ int pwdlen; /* password encoding length */
+ int uidlen; /* uid encoding length */
+ int fllen; /* account flags encoding length */
+ USI_t rnlen; /* real name encoding length */
+ USI_t nglen; /* group count encoding length */
+ USI_t gcnt; /* number of group ids */
+ USI_t * gids; /* pointer to array of group ids */
+ int i; /* group id index */
+ int rv = -1;
+
+ /*
+ * First we need to figure out how long the generated record will be.
+ * This doesn't have to be exact, but it must not be smaller than the
+ * actual record size.
+ */
+
+ /* UAT_PASSWORD attribute: tag, length, NTS */
+ pwdlen = NTSLENGTH(uoptr->uo_pwd);
+ reclen = 1 + 1 + pwdlen;
+ if (pwdlen > 127) goto punt;
+
+ /* UAT_UID attribute: tag, length, USI */
+ uidlen = USILENGTH(uoptr->uo_uid);
+ reclen += (1 + 1 + uidlen);
+
+ /* UAT_ACCFLAGS attribute: tag, length, USI */
+ fllen = USILENGTH(uoptr->uo_flags & UOF_DBFLAGS);
+ reclen += (1 + 1 + fllen);
+
+ /* UAT_REALNAME attribute: tag, length, NTS */
+ rnlen = NTSLENGTH(uoptr->uo_rname);
+ reclen += (1 + USILENGTH(rnlen) + rnlen);
+
+ /* UAT_GROUPS attribute: tag, length, USI(count), USI(gid)... */
+ gcnt = UILCOUNT(&uoptr->uo_groups);
+ nglen = USILENGTH(gcnt);
+ reclen += (1 + USIALLOC() + nglen + (5 * gcnt));
+
+ /* Allocate the attribute record buffer */
+ rptr = (ATR_t)MALLOC(reclen);
+ if (rptr) {
+
+ /* Save pointer to start of record */
+ rstart = rptr;
+
+ /* Encode UAT_PASSWORD attribute */
+ *rptr++ = UAT_PASSWORD;
+ *rptr++ = pwdlen;
+ rptr = NTSENCODE(rptr, uoptr->uo_pwd);
+
+ /* Encode UAT_UID attribute */
+ *rptr++ = UAT_UID;
+ *rptr++ = uidlen;
+ rptr = USIENCODE(rptr, uoptr->uo_uid);
+
+ /* Encode UAT_ACCFLAGS attribute */
+ *rptr++ = UAT_ACCFLAGS;
+ *rptr++ = fllen;
+ rptr = USIENCODE(rptr, (uoptr->uo_flags & UOF_DBFLAGS));
+
+ /* Encode UAT_REALNAME attribute */
+ *rptr++ = UAT_REALNAME;
+ rptr = USIENCODE(rptr, rnlen);
+ rptr = NTSENCODE(rptr, uoptr->uo_rname);
+
+ /* Encode UAT_GROUPS attribute */
+ *rptr++ = UAT_GROUPS;
+
+ /*
+ * Save a pointer to the attribute encoding length, and reserve
+ * space for the maximum encoding size of a USI_t value.
+ */
+ glptr = rptr;
+ rptr += USIALLOC();
+ gptr = rptr;
+
+ /* Encode number of groups */
+ rptr = USIENCODE(rptr, gcnt);
+
+ /* Generate group ids encodings */
+ gids = UILLIST(&uoptr->uo_groups);
+ for (i = 0; i < gcnt; ++i) {
+ rptr = USIENCODE(rptr, gids[i]);
+ }
+
+ /* Now fix up the UAT_GROUPS attribute encoding length */
+ glptr = USIINSERT(glptr, (USI_t)(rptr - gptr));
+
+ /* Return record length and location if requested */
+ if (ureclen) *ureclen = rptr - rstart;
+ if (urecptr) *urecptr = rstart;
+
+ /* Indicate success */
+ rv = 0;
+ }
+
+ punt:
+ return rv;
+}
+
+/*
+ * Description (userRemove)
+ *
+ * This function is called to remove a user from a specified user
+ * database. Both the primary DB file and the id-to-name DB file
+ * are updated.
+ *
+ * Arguments:
+ *
+ * errp - error frame list pointer (may be null)
+ * userdb - handle for user DB access
+ * flags - (unused - must be zero)
+ * name - pointer to user account name
+ *
+ * Returns:
+ *
+ * If successful, the return value is zero. Otherwise it is a
+ * non-zero error code.
+ */
+
+NSAPI_PUBLIC int userRemove(NSErr_t * errp, void * userdb, int flags, NTS_t name)
+{
+ UserObj_t * uoptr; /* user object pointer */
+ int rv;
+ int rv2;
+
+ /* First retrieve the user record */
+ uoptr = userFindByName(errp, userdb, name);
+ if (!uoptr) {
+ /* Error - specified user not found */
+ return NSAERRNAME;
+ }
+
+ /* Free the user id value, if any */
+ rv = 0;
+ if (uoptr->uo_uid != 0) {
+ rv = ndbFreeId(errp, userdb, 0, (char *)name, uoptr->uo_uid);
+ }
+
+ rv2 = ndbDeleteName(errp, userdb, 0, 0, (char *)name);
+
+ return (rv) ? rv : rv2;
+}
+
+/*
+ * Description (userRename)
+ *
+ * This function is called to change the account name associated
+ * with an existing user. The caller provides a pointer to a
+ * user object for the existing user (with the current user account
+ * name referenced by uo_name), and the new account name for this
+ * user. A check is made to ensure the uniqueness of the new name
+ * in the specified user database. The account name in the user
+ * object is modified. The user database is not modified until
+ * userStore() is called.
+ *
+ * Arguments:
+ *
+ * errp - error frame list pointer (may be null)
+ * userdb - handle for user DB access
+ * uoptr - user object pointer
+ * newname - pointer to new account name string
+ *
+ * Returns:
+ *
+ * If successful, the return value is zero. Otherwise it is a
+ * non-zero error code. The user object remains intact in either
+ * case.
+ */
+
+NSAPI_PUBLIC int userRename(NSErr_t * errp, void * userdb, UserObj_t * uoptr, NTS_t newname)
+{
+ int reclen; /* user record length */
+ ATR_t recptr = 0; /* user record pointer */
+ char * oldname; /* old user account name */
+ int eid; /* error id code */
+ int rv; /* result value */
+
+ /* Save the current account name and replace it with the new one */
+ oldname = (char *)uoptr->uo_name;
+ uoptr->uo_name = (unsigned char *) STRDUP((char *)newname);
+
+ if ((oldname != 0) && !(uoptr->uo_flags & UOF_NEW)) {
+
+ /* Convert the information in the user object to a DB record */
+ rv = userEncode(uoptr, &reclen, &recptr);
+ if (rv) goto err_nomem;
+
+ /*
+ * Store the record in the database
+ * under the new user account name.
+ */
+ rv = ndbStoreName(errp, userdb, NDBF_NEWNAME,
+ 0, (char *)uoptr->uo_name, reclen, (char *)recptr);
+ if (rv) goto punt;
+
+ /* Change the mapping of the user id to the new name */
+ rv = ndbRenameId(errp, userdb, 0, (char *)uoptr->uo_name, uoptr->uo_uid);
+ if (rv) goto punt;
+
+ /* Delete the user record with the old account name */
+ rv = ndbDeleteName(errp, userdb, 0, 0, oldname);
+ if (rv) goto punt;
+ }
+ else {
+ /* Set flags in user object for userStore() */
+ uoptr->uo_flags |= UOF_MODIFIED;
+ }
+
+ punt:
+ if (recptr) {
+ FREE(recptr);
+ }
+ if (oldname) {
+ FREE(oldname);
+ }
+ return rv;
+
+ err_nomem:
+ eid = NSAUERR1000;
+ rv = NSAERRNOMEM;
+ nserrGenerate(errp, rv, eid, NSAuth_Program, 0);
+ goto punt;
+}
+
+/*
+ * Description (userStore)
+ *
+ * This function is called to store a user object in the database.
+ * If the object was created by userCreate(), it is assumed to be
+ * a new user account, the user account name must not match any
+ * existing user account names in the database, and a uid is
+ * assigned before adding the user to the database. If the object
+ * was created by userFindByName(), the information in the user
+ * object will replace the existing database entry for the
+ * indicated user account name.
+ *
+ * Arguments:
+ *
+ * errp - error frame list pointer (may be null)
+ * userdb - handle for user DB access
+ * flags - (unused - must be zero)
+ * uoptr - user object pointer
+ *
+ * Returns:
+ *
+ * If successful, the return value is zero. Otherwise it is a
+ * non-zero error code. The user object remains intact in either
+ * case.
+ */
+
+NSAPI_PUBLIC int userStore(NSErr_t * errp, void * userdb, int flags, UserObj_t * uoptr)
+{
+ ATR_t recptr = 0;
+ USI_t uid;
+ int reclen = 0;
+ int stflags = 0;
+ int eid;
+ int rv;
+
+ /* If this is a new user, allocate a uid value */
+ if (uoptr->uo_flags & UOF_NEW) {
+ /*
+ * Yes, allocate a user id and add a user id to user
+ * account name mapping to the id-to-name DB file.
+ */
+ uid = 0;
+ rv = ndbAllocId(errp, userdb, 0, (char *)uoptr->uo_name, &uid);
+ if (rv) goto punt;
+
+ uoptr->uo_uid = uid;
+
+ /* Let the database manager know that this is a new entry */
+ stflags = NDBF_NEWNAME;
+ }
+
+ /* Convert the information in the user object to a DB record */
+ rv = userEncode(uoptr, &reclen, &recptr);
+ if (rv) goto err_nomem;
+
+ /* Store the record in the database under the user account name. */
+ rv = ndbStoreName(errp, userdb, stflags,
+ 0, (char *)uoptr->uo_name, reclen, (char *)recptr);
+ if (rv) goto punt;
+
+ FREE(recptr);
+ recptr = 0;
+
+ uoptr->uo_flags &= ~(UOF_NEW | UOF_MODIFIED);
+ return 0;
+
+ err_nomem:
+ eid = NSAUERR1100;
+ rv = NSAERRNOMEM;
+ nserrGenerate(errp, rv, eid, NSAuth_Program, 0);
+
+ punt:
+ if (recptr) {
+ FREE(recptr);
+ }
+ if ((uoptr->uo_flags & UOF_NEW) && (uid != 0)) {
+ /* Free the user id value if we failed after allocating it */
+ ndbFreeId(errp, userdb, 0, (char *)uoptr->uo_name, uid);
+ }
+ return rv;
+}