From b2093e3016027d6b5cf06b3f91f30769bfc099e2 Mon Sep 17 00:00:00 2001 From: cvsadm Date: Fri, 21 Jan 2005 00:44:34 +0000 Subject: Moving NSCP Directory Server from DirectoryBranch to TRUNK, initial drop. (foxworth) --- lib/libadmin/authdb.c | 2467 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2467 insertions(+) create mode 100644 lib/libadmin/authdb.c (limited to 'lib/libadmin/authdb.c') diff --git a/lib/libadmin/authdb.c b/lib/libadmin/authdb.c new file mode 100644 index 00000000..8aff4ca8 --- /dev/null +++ b/lib/libadmin/authdb.c @@ -0,0 +1,2467 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright 2001 Sun Microsystems, Inc. + * Portions copyright 1999, 2001-2003 Netscape Communications Corporation. + * All rights reserved. + * END COPYRIGHT BLOCK **/ +/* + * authdb.c: Functions to aid in user/group database admin + * + * These things leak memory like a sieve. + * + * Ben Polk + * (blame Mike McCool for functions with an MLM) + */ + +#ifdef XP_UNIX +#include +#endif /* WIN32? */ + +#include +#include +#include +#include +#include +#include "base/shexp.h" +#include "base/util.h" +#include "libadminutil/admutil.h" +#include "libadmin/libadmin.h" + +#include "libaccess/nsgmgmt.h" +#include "libaccess/nsumgmt.h" +/* XXX MLM - This shouldn't have to define itself as private. */ +#define __PRIVATE_NSADB +#include "libaccess/nsadb.h" +#include "libaccess/nsamgmt.h" +#include "libaccess/aclerror.h" +#include "libaccess/aclbuild.h" +#include "libaccess/acladmin.h" +#include "usrlists.h" + +#define BUF_SIZE 10 + +void list_authdbs(char *fullpath, char *partialpath); + +static char **list; +static int listsize; +static int curentry; + +/* + * Rights we know about. This should be moved out to some + * external location. Perhaps obj.conf? + */ +NSAPI_PUBLIC char *acl_read_rights[] = +{ + "GET", + "HEAD", + "POST", + "INDEX", +#ifdef MCC_PROXY + "CONNECT", +#endif + NULL +}; + +NSAPI_PUBLIC char *acl_write_rights[] = +{ + "PUT", + "DELETE", + "MKDIR", + "RMDIR", + "MOVE", + NULL +}; + + +/* + * passfilter - function returns non-zero if the regular expression + * passed in matches the string passed in. + */ +static int passfilter(char *str, char *regexp) +{ + if (!str) + return 0; /* NULL string never matches */ + else if (!regexp) + return 1; /* NULL regexp matches everything */ + else + return(!shexp_casecmp(str, regexp)); +} + +NSAPI_PUBLIC char **list_auth_dbs(char *fullpath) +{ + list = new_strlist(BUF_SIZE); + listsize = BUF_SIZE; + curentry = 0; + list_authdbs(fullpath, ""); + + return(list); +} + +NSAPI_PUBLIC void output_authdb_selector(char *path, char *element, char *current) { + char **pathlist = list_auth_dbs(path); + int currentnum = -1; + int plen = path ? strlen(path) : 0; + register int x; + + /* + * If the 'current' string begins with the 'path' string, remove the + * 'path' prefix. + */ + if (!strncmp(current, path, plen)) { + current += plen; + if (*current == FILE_PATHSEP) ++current; + } + + if (pathlist[0]) /* Is there at least one database? */ + { + /* Find current selection in list of databases. */ + for(x=0; pathlist[x]; x++) { + if(!strcmp(current, pathlist[x])) { + currentnum = x; + continue; + } + } + +/* BONEHEAD */ + fprintf(stdout, ""); + } else { + fprintf(stdout, "No databases found."); + } +} + +NSAPI_PUBLIC char *get_current_authdb() +{ + char **config = get_adm_config(); + return(STRDUP(config[3])); +} + +NSAPI_PUBLIC void set_current_authdb(char *current) +{ + char **config = get_adm_config(); + config[3] = STRDUP(current); + write_adm_config(config); +} + +void list_authdbs(char *fullpath, char *partialpath) +{ + int stat_good; + struct stat finfo; + char **dirlisting; + char *path = (char *)MALLOC(strlen(fullpath)+strlen(partialpath)+2); + + sprintf(path, "%s%c%s", fullpath, FILE_PATHSEP, partialpath); + if( !(dirlisting = list_directory(path,0))) + return; + else { + register int x; + char *entry, *newppath; + + for(x=0; dirlisting[x]; x++) { + entry = (char *)MALLOC(strlen(path)+strlen(dirlisting[x])+2); + sprintf(entry, "%s%s", path, dirlisting[x]); + +#ifdef XP_UNIX + stat_good = (lstat(entry, &finfo) == -1 ? 0 : 1); +#else /* WIN32 */ + stat_good = (stat(entry, &finfo) == -1 ? 0 : 1); +#endif /* XP_UNIX */ + + if(!stat_good) + continue; + newppath = (char *)MALLOC(strlen(partialpath)+strlen(dirlisting[x])+3); + + if(S_ISDIR(finfo.st_mode)) { + sprintf(newppath, "%s%s", partialpath, dirlisting[x]); + curentry++; + + if(!(curentry < listsize)) { + listsize += BUF_SIZE; + list = grow_strlist(list, listsize); + } + list[curentry-1] = STRDUP(newppath); + list[curentry] = NULL; + } + + FREE(entry); + FREE(newppath); + } + } +} + +/* Get the userdb directory. (V1.x) */ +NSAPI_PUBLIC char *get_userdb_dir(void) +{ + char *userdb; + char line[BIG_LINE]; + +#ifdef USE_ADMSERV + char *tmp = getenv("NETSITE_ROOT"); + + sprintf(line, "%s%cuserdb", tmp, FILE_PATHSEP); +#else + char *tmp = get_mag_var("#ServerRoot"); + + sprintf(line, "%s%cadmin%cuserdb", tmp, FILE_PATHSEP, FILE_PATHSEP); +#endif + userdb = STRDUP(line); + return userdb; +} + +/* Get the httpacl directory. (V2.x) */ +NSAPI_PUBLIC char *get_httpacl_dir(void) +{ + char *httpacl; + char line[BIG_LINE]; + +#ifdef USE_ADMSERV + char *tmp = getenv("NETSITE_ROOT"); + + sprintf(line, "%s%chttpacl", tmp, FILE_PATHSEP); +#else + char *tmp = get_mag_var("#ServerRoot"); + + sprintf(line, "%s%cadmin%chttpacl", tmp, FILE_PATHSEP, FILE_PATHSEP); +#endif + httpacl = STRDUP(line); + return httpacl; +} + +/* Get the authdb directory. (V2.x) */ +NSAPI_PUBLIC char *get_authdb_dir(void) +{ + char *authdb; + char line[BIG_LINE]; + +#ifdef USE_ADMSERV + char *tmp = getenv("NETSITE_ROOT"); + + sprintf(line, "%s%cauthdb", tmp, FILE_PATHSEP); +#else + char *tmp = get_mag_var("#ServerRoot"); + + sprintf(line, "%s%cadmin%cauthdb", tmp, FILE_PATHSEP, FILE_PATHSEP); +#endif + authdb = STRDUP(line); + return authdb; +} +/* + * groupOrUser - function sets its return variable flags + * based on whether the name passed in is + * a user or a group in the specified database. + * It could be both, although the entry form + * are intended to prohibit this. + * Returns: 0 if no error occurs, something else otherwise. + */ +NSAPI_PUBLIC int groupOrUser(char *db_path, char *name, int *is_user, int *is_group) +{ + int rv = 1; + UserObj_t *uoptr; + GroupObj_t *goptr; + void *padb; + + if (name && is_user && is_group) { + *is_user = 0; + *is_group = 0; + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (!rv) { + + rv = nsadbFindByName(NULL, padb, name, AIF_USER, (void **)&uoptr); + if (rv == AIF_USER) { + *is_user = 1; + } + + rv = nsadbFindByName(NULL, padb, name, AIF_GROUP, (void **)&goptr); + if (rv == AIF_GROUP) { + *is_group = 1; + } + + nsadbClose(padb, 0); + } + } + + return rv; +} + +/* + * getfullname - function to get the fullname of a user. + * Return: Returns 0 if it works, something else if it fails. + */ +NSAPI_PUBLIC int getfullname(char *db_path, char *user, char **fullname) { + int rv; + UserObj_t *uoptr; + void *padb; + + if (db_path && user) + { + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv == 0) { + rv = nsadbFindByName(NULL, padb, user, AIF_USER, (void **)&uoptr); + if (rv == AIF_USER) { + *fullname = (uoptr->uo_rname != 0) ? STRDUP((char *)uoptr->uo_rname) + : STRDUP(""); + } + else + rv = 1; + nsadbClose(padb, 0); + } + } + else + rv = 1; + + return rv; +} + +/* + * setfullname - function to set the fullname for the specified user. + * Return: Returns 0 if it works, something else if it fails. + */ +NSAPI_PUBLIC int setfullname(char *db_path, char *user, char *fullname) { + int rv; + UserObj_t *uoptr; + void *padb; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, "Failed To Open Database", + "An error occurred while trying to update " + "the user's fullname in the database."); + } else { + /* See if the user already exists, if so, update it. */ + rv = nsadbFindByName(NULL, padb, user, AIF_USER, (void **)&uoptr); + if (rv == AIF_USER) { + uoptr->uo_rname = (NTS_t)fullname; + } else { + /* User doesn't exist, so we've failed. */ + report_error(SYSTEM_ERROR, user, + "Unable to change this user's fullname, " + "user was not found in the database."); + rv = 1; + } + + if (uoptr) { + rv = nsadbModifyUser(NULL, padb, uoptr); + if (rv < 0) + report_error(SYSTEM_ERROR, user, + "A database error occurred while " + "trying to change the user fullname."); + } + nsadbClose(padb, 0); + } + return rv; +} + +/* Set a user's login name MLM*/ +NSAPI_PUBLIC int setusername(char *db_path, char *user, char *newname) { + int rv; + UserObj_t *uoptr; + void *padb; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, "Failed To Open Database", + "An error occurred while trying to update " + "the user's fullname in the database."); + } else { + /* See if the user already exists, if so, update it. */ + rv = nsadbFindByName(NULL, padb, user, AIF_USER, (void **)&uoptr); + if (rv != AIF_USER) { + /* User doesn't exist, so we've failed. */ + report_error(SYSTEM_ERROR, user, + "Unable to change this user's fullname, " + "user was not found in the database."); + rv = 1; + } + if (uoptr) { + rv = userRename(NULL, ((AuthDB_t *)padb)->adb_userdb, + uoptr, (NTS_t)newname); + + if (rv < 0) + report_error(SYSTEM_ERROR, user, + "A database error occurred while " + "trying to change the login name."); + } + nsadbClose(padb, 0); + } + return rv; +} + +/* + * addusertogroup - function to add a user to a group + * Return: Returns 0 if it works, something else if it fails. + */ +NSAPI_PUBLIC int addusertogroup(char *db_path, char *user, char *group) { + int rv; + UserObj_t *uoptr; + GroupObj_t *goptr; + void *padb; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, "Failed To Open Database", + "An error occurred while trying to add " + "user to a group."); + } else { + /* See if the user and group exist. */ + rv = nsadbFindByName(NULL, padb, group, AIF_GROUP, (void **)&goptr); + rv = nsadbFindByName(NULL, padb, user, AIF_USER, (void **)&uoptr); + if (goptr == 0) { + report_error(INCORRECT_USAGE, group, + "The group was not found."); + } + else if (uoptr == 0) { + report_error(INCORRECT_USAGE, user, + "The user was not found."); + } + else { + rv = nsadbAddUserToGroup(NULL, padb, goptr, uoptr); + } + + nsadbClose(padb, 0); + } + return rv; +} + +/* + * addgrouptogroup - function to add a group to a group + * Return: Returns 0 if it works, something else if it fails. + */ +NSAPI_PUBLIC int addgrouptogroup(char *db_path, char *memgroup, char *group) { + int rv; + GroupObj_t *goptr; + GroupObj_t *mem_goptr; + void *padb; + + if (!strcmp(memgroup, group)) { + report_error(INCORRECT_USAGE, group, + "You can't add a group to itself."); + } + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, "Failed To Open Database", + "An error occurred while trying to add " + "group to a group."); + } else { + /* See if the groups exist. */ + rv = nsadbFindByName(NULL, padb, group, AIF_GROUP, (void **)&goptr); + rv = nsadbFindByName(NULL, + padb, memgroup, AIF_GROUP, (void **)&mem_goptr); + if (goptr == 0) { + report_error(INCORRECT_USAGE, group, + "The target group was not found."); + } + else if (mem_goptr == 0) { + report_error(INCORRECT_USAGE, memgroup, + "The group to add was not found."); + } + else { + rv = nsadbAddGroupToGroup(NULL, padb, goptr, mem_goptr); + } + + nsadbClose(padb, 0); + } + return rv; +} + +/* + * remuserfromgroup - function to remove a user from a group + * Return: Returns 0 if it works, something else if it fails. + */ +NSAPI_PUBLIC int remuserfromgroup(char *db_path, char *user, char *group) { + int rv; + UserObj_t *uoptr; + GroupObj_t *goptr; + void *padb; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, "Failed To Open Database", + "An error occurred while trying to add " + "user to a group."); + } else { + /* See if the user and group exist. */ + rv = nsadbFindByName(NULL, padb, group, AIF_GROUP, (void **)&goptr); + rv = nsadbFindByName(NULL, padb, user, AIF_USER, (void **)&uoptr); + if (goptr == 0) { + report_error(SYSTEM_ERROR, group, + "The group was not found."); + } + else if (uoptr == 0) { + report_error(SYSTEM_ERROR, user, + "The user was not found."); + } + else { + rv = nsadbRemUserFromGroup(NULL, padb, goptr, uoptr); + if (rv) + report_error(SYSTEM_ERROR, "Error taking out user", + "An error occured trying to take " + "the user out of the group."); + } + + nsadbClose(padb, 0); + } + return rv; +} + +/* + * remgroupfromgroup - function to remove a group to a group + * Return: Returns 0 if it works, something else if it fails. + */ +NSAPI_PUBLIC int remgroupfromgroup(char *db_path, char *memgroup, char *group) { + int rv; + GroupObj_t *goptr; + GroupObj_t *mem_goptr; + void *padb; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, "Failed To Open Database", + "An error occurred while trying to remove " + "a group from a group."); + } else { + /* See if the groups exist. */ + rv = nsadbFindByName(NULL, padb, group, AIF_GROUP, (void **)&goptr); + rv = nsadbFindByName(NULL, + padb, memgroup, AIF_GROUP, (void **)&mem_goptr); + if (goptr == 0) { + report_error(SYSTEM_ERROR, group, + "The target group was not found."); + } + else if (mem_goptr == 0) { + report_error(SYSTEM_ERROR, memgroup, + "The group to remove was not found."); + } + else { + rv = nsadbRemGroupFromGroup(NULL, padb, goptr, mem_goptr); + } + + nsadbClose(padb, 0); + } + return rv; +} + +/* + * setpw - function to set the password for the specified user. + * Return: Returns 0 if it works, something else if it fails. + */ +NSAPI_PUBLIC int setpw(char *db_path, char *user, char *pwd) { + int rv; + UserObj_t *uoptr = 0; + void *padb; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, "Failed To Open Database", + "An error occurred while trying to add " + "the password to the database."); + } else { + /* See if the user already exists, if so, update it. */ + rv = nsadbFindByName(NULL, padb, user, AIF_USER, (void **)&uoptr); + if (uoptr != 0) { + uoptr->uo_pwd = (NTS_t)STRDUP(pw_enc(pwd)); + } else { + /* User doesn't exist, so we've failed. */ + report_error(SYSTEM_ERROR, user, + "Unable to change this user's password, " + "user was not found in the database."); + rv = 1; + } + + if (uoptr) { + rv = nsadbModifyUser(NULL, padb, uoptr); + if (rv < 0) + report_error(SYSTEM_ERROR, user, + "A database error occurred while " + "trying to change the user password."); + } + nsadbClose(padb, 0); + } + return rv; +} + +/* + * setdbpw - function to set the password on the special user + * who's password is used as the database password. + * If the password passed in is NULL, the user is + * removed or not created. + * If the password is not NULL, then the user will + * be created if needed, and it's password set to + * the one passed in. + * + * Return: Returns 0 if it works, something else if it fails. + */ +NSAPI_PUBLIC int setdbpw(char *db_path, char *pwd) +{ + int rv; + UserObj_t *uoptr = 0; + void *padb; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, "Failed To Open Database", + "An error occurred while trying to add " + "the password to the database."); + } + /* + * If NULL pwd, remove the user if it exists. + */ + else if (pwd == NULL) { + rv = nsadbRemoveUser(NULL, padb, DBPW_USER); + nsadbClose(padb, 0); + + /* + * If we get success(0) or a no such user error(NSAERRNAME) + * we're happy. + */ + if (rv != 0 && rv != NSAERRNAME) { + report_error(SYSTEM_ERROR, "Remove Password Failed", + "An error occurred while trying to remove " + "the password for the database."); + } + } else { + /* See if the user already exists, if so, just update it. */ + rv = nsadbFindByName(NULL, padb, DBPW_USER, AIF_USER, (void **)&uoptr); + if (uoptr == 0) { + /* User doesn't exist, so add it. */ + uoptr = userCreate((NTS_t)DBPW_USER, (NTS_t)pw_enc(pwd), (NTS_t)DBPW_USER); + if (uoptr == 0) { + report_error(SYSTEM_ERROR, "Failed To Update Database", + "An error occurred while trying to add " + "the password to the database."); + rv = 1; + } + else { + rv = nsadbCreateUser(NULL, padb, uoptr); + } + } else { + uoptr->uo_pwd = (NTS_t)STRDUP(pw_enc(pwd)); + rv = nsadbModifyUser(NULL, padb, uoptr); + } + + nsadbClose(padb, 0); + + if (uoptr) { + if (rv < 0) { + report_error(SYSTEM_ERROR, "Failed To Set Database Password", + "An error occurred while trying to save " + "the password in the database."); + rv = 1; + } + userFree(uoptr); + } + } + return rv; +} + +/* + * checkdbpw - Return TRUE if the password is correct, or database + * doesn't have one, because the password user isn't there. + * Return FALSE if required password is not correct. + */ +NSAPI_PUBLIC int checkdbpw(char *db_path, char *pwd) +{ + int rv; + UserObj_t *uoptr = 0; + void *padb; + int fpwOK = 0; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv == 0) { + rv = nsadbFindByName(NULL, padb, DBPW_USER, AIF_USER, (void **)&uoptr); + if (uoptr == 0) { + fpwOK = 1; /* Password userid isn't there, so none required. */ + } else { + if (pwd == NULL) + fpwOK = 0; /* PW user exists, no pw passed in, return false. */ + else { + if (pw_cmp(pwd, (char *)uoptr->uo_pwd)) + fpwOK = 0; /* passwords are different, so return false. */ + else + fpwOK = 1; /* passwords are the same, so return true. */ + } + userFree(uoptr); + } + nsadbClose(padb, 0); + } + return fpwOK; +} + +/* + * Create a link to another CGI: + * val - value text on the link + * targ - name of the CGI to start + * arg - argument to pass to the CGI + */ +void output_cgi_link(char *val, char *trg, char *arg) +{ + char line[BIG_LINE]; + sprintf(line, "%s?%s", trg, arg); + printf("%s", + util_uri_escape(NULL, line), val); +} + +/* + * groupEnumCB - callback function from libaccess group enumerator + */ +static int groupEnumCB (NSErr_t * errp, + void * padb, void *parg, GroupObj_t *goptr) +{ + if (goptr && goptr->go_name && strlen((char *)goptr->go_name)) + ulsAddToList(parg, goptr->go_gid, (char *)goptr->go_name); + + return 0; /* 0: continue enumeration */ +} + +/* + * userEnumCB - callback function from libaccess group enumerator + */ +static int userEnumCB (NSErr_t * errp, + void * padb, void *parg, UserObj_t *uoptr) +{ + if (uoptr && uoptr->uo_name && strlen((char *)uoptr->uo_name)) + ulsAddToList(parg, uoptr->uo_uid, (char *)uoptr->uo_name); + + return 0; /* 0: continue enumeration */ +} + +/* + * idfound - horribly inefficient scan through the idlist table + * returning true if the specified id is found, false + * otherwise. + */ +int idfound(int id, int *idlist, int count) +{ + int i; + for (i = 0; i < count; ++i) { + if (id == idlist[i]) + return 1; + } + return 0; +} + +void output_groups_user_is_in(char *db_path, char *user) +{ + int rv; + UserObj_t *uoptr = 0; + GroupObj_t *goptr = 0; + void *padb; + USI_t *gidlist; + int i; + int id; + char *group; + char *gname; + int groupCount; + char line[BIG_LINE]; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, db_path, + "Failed to open database while trying " + "to list group membership."); + } else { + /* See if the user exists. */ + rv = nsadbFindByName(NULL, padb, user, AIF_USER, (void **)&uoptr); + if (uoptr == 0) { + /* User doesn't exist, so we've failed. */ + report_error(SYSTEM_ERROR, user, + "Unable to find user when trying to " + "list group membership."); + rv = 1; + } else { + groupCount = UILCOUNT(&uoptr->uo_groups); + if (groupCount > 0) { + void *DirectlyInList; + void *IndirectlyInList; + ulsAlloc(&DirectlyInList); + ulsAlloc(&IndirectlyInList); + + gidlist = UILLIST(&uoptr->uo_groups); + for (i = 0; i < groupCount; ++i) { + rv = nsadbIdToName(NULL, + padb, gidlist[i], AIF_GROUP, &gname); + if (rv >= 0) { + rv = nsadbFindByName(NULL, padb, gname, AIF_GROUP, + (void **)&goptr); + } + if (goptr != 0) { + if (goptr->go_name && strlen((char *)goptr->go_name)) { + if (idfound(uoptr->uo_uid, + (int*)UILLIST(&goptr->go_users), + UILCOUNT(&goptr->go_users))) { + ulsAddToList(DirectlyInList, goptr->go_gid, + (char *)goptr->go_name); + } + else { + ulsAddToList(IndirectlyInList, goptr->go_gid, + (char *)goptr->go_name); + } + } + groupFree(goptr); + goptr = 0; + } + } + ulsSortName(DirectlyInList); + ulsGetCount(DirectlyInList, &groupCount); + for (i=0; i"); + printf("Member of %s", group); + sprintf(line, "group=%s", group); + output_cgi_link("Edit Group", "grped", line); + printf(""); + sprintf(line, "remfromgrp_but=1&memuser=%s&group=%s", + user, group); + output_cgi_link("Remove from Group", "grped", line); + printf("\n"); + } + } + ulsSortName(IndirectlyInList); + ulsGetCount(IndirectlyInList, &groupCount); + for (i=0; i"); + printf("Indirect member of %s", group); + sprintf(line, "group=%s", group); + output_cgi_link("Edit Group", "grped", group); + printf(""); + sprintf(line, "addtogrp_but=1&memuser=%s&group=%s", + user, group); + output_cgi_link("Add to Group", "grped", line); + printf("\n"); + } + } + ulsFree(&DirectlyInList); + ulsFree(&IndirectlyInList); + } + } + } + return; +} + +/* + * output a table with the groups the user isn't a member of + */ +void output_nonmembership(char *db_path, char *user) +{ + int rv; + UserObj_t *uoptr = 0; + void *padb; + USI_t *gidlist; + int i; + int id; + char *group; + int groupCount; + char line[BIG_LINE]; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, db_path, + "Failed to open database while trying " + "to list group membership."); + } else { + rv = nsadbFindByName(NULL, padb, user, AIF_USER, (void **)&uoptr); + if (uoptr == 0) { + report_error(SYSTEM_ERROR, user, + "Unable to find user when trying to " + "list group membership."); + rv = 1; + } else { + void *sortList; + + ulsAlloc(&sortList); + rv = nsadbEnumerateGroups(NULL, padb, + (void *)sortList, groupEnumCB); + + ulsSortName(sortList); + ulsGetCount(sortList, &groupCount); + + if (groupCount > 0) { + gidlist = UILLIST(&uoptr->uo_groups); + for (i=0; iuo_groups))){ + printf(""); + printf("Not a member of %s", group); + sprintf(line, "group=%s", group); + output_cgi_link("Edit Group", "grped", line); + printf(""); + sprintf(line, "addtogrp_but=1&memuser=%s&group=%s", + user, group); + output_cgi_link("Add to Group", "grped", line); + printf("\n"); + } + } + } + ulsFree(&sortList); + userFree(uoptr); + } + } + return; +} + +/* + * output_group_membership - output a table showing which + * groups a user is in. + */ +void output_group_membership(char *db_path, char *user) +{ + printf("\n"); + output_groups_user_is_in(db_path, user); + output_nonmembership(db_path, user); + printf("
\n"); + printf("%s group membership:", user); + printf("
\n"); +} + +void output_grpgroup_membership(char *db_path, char *group, char *filter) +{ + int rv; + GroupObj_t *goptr = 0; + void *padb; + USI_t *gidlist; + int i; + int id; + char *gname; + char *memgroup; + int groupCount; + char line[BIG_LINE]; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, db_path, + "Failed to open database while trying " + "to list group membership."); + } else { + /* See if the group exists. */ + rv = nsadbFindByName(NULL, padb, group, AIF_GROUP, (void **)&goptr); + if (goptr == 0) { + /* Group doesn't exist, so we've failed. */ + report_error(SYSTEM_ERROR, group, + "Unable to find group when trying to " + "list group membership."); + rv = 1; + } else { + groupCount = UILCOUNT(&goptr->go_groups); + if (groupCount > 0) { + void *sortList; + ulsAlloc(&sortList); + + printf("\n"); + gidlist = UILLIST(&goptr->go_groups); + for (i = 0; i < groupCount; ++i) { + rv = nsadbIdToName(NULL, + padb, gidlist[i], AIF_GROUP, &gname); + if ((rv >= 0) && (gname != 0) && (strlen(gname) != 0)) { + ulsAddToList(sortList, gidlist[i], gname); + } + } + ulsSortName(sortList); + ulsGetCount(sortList, &groupCount); + for (i=0; i\n"); + } + } + printf("
\n"); + printf("%s has these group members:", group); + printf("
"); + printf("%s", memgroup); + sprintf(line, "group=%s", memgroup); + output_cgi_link("Edit Group", "grped", line); + printf(""); + sprintf(line, "remfromgrp_but=1&memgroup=%s&group=%s", + memgroup, group); + output_cgi_link("Remove from Group", "grped", line); + printf("
\n"); + ulsFree(&sortList); + } else { + printf("This group has no group members."); + } + groupFree(goptr); + } + nsadbClose(padb, 0); + } + return; +} + +/* + * Output a table showing the user members of a group. + */ +NSAPI_PUBLIC void output_user_membership(char *db_path, char *group, char *filter) +{ + int rv; + GroupObj_t *goptr = 0; + void *padb; + USI_t *uidlist; + char *user; + int i; + int id; + char *memuser; + int userCount; + char line[BIG_LINE]; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) { + report_error(SYSTEM_ERROR, db_path, + "Failed to open database while trying " + "to list user membership."); + } else { + /* See if the group exists. */ + rv = nsadbFindByName(NULL, padb, group, AIF_GROUP, (void **)&goptr); + if (goptr == 0) { + /* Group doesn't exist, so we've failed. */ + nsadbClose(padb, 0); + report_error(SYSTEM_ERROR, group, + "Unable to find group when trying to " + "list user membership."); + rv = 1; + } else { + userCount = UILCOUNT(&goptr->go_users); + if (userCount > 0) { + void *sortList; + ulsAlloc(&sortList); + + printf("\n"); + uidlist = UILLIST(&goptr->go_users); + for (i = 0; i < userCount; ++i) { + rv = nsadbIdToName(NULL, + padb, uidlist[i], AIF_USER, &user); + if ((rv >= 0) && (user != 0) && (strlen(user) != 0)) { + ulsAddToList(sortList, uidlist[i], user); + } + } + nsadbClose(padb, 0); + ulsSortName(sortList); + ulsGetCount(sortList, &userCount); + for (i=0; i\n"); + } + } + printf("
\n"); + printf("%s has these user members:", group); + printf("
"); + printf("%s", memuser); + sprintf(line, "user=%s", memuser); + output_cgi_link("Edit User", "usred", line); + printf(""); + sprintf(line, "remfromgrp_but=1&memuser=%s&group=%s", + memuser, group); + output_cgi_link("Remove from Group", "grped", line); + printf("
\n"); + ulsFree(&sortList); + } else { + nsadbClose(padb, 0); + printf("This group has no user members."); + } + } + } + return; +} + +/* + * Output a group showing all users. + */ +NSAPI_PUBLIC int output_users_list(char *db_path, char *filter) +{ + int rv; + void *padb; + int i; + int id; + char *user; + int userCount; + char line[BIG_LINE]; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) + report_error(SYSTEM_ERROR, db_path, + "Failed to open database while trying " + "to list users."); + else { + void *sortList; + + ulsAlloc(&sortList); + rv = nsadbEnumerateUsers(NULL, padb, (void *)sortList, userEnumCB); + nsadbClose(padb, 0); + ulsSortName(sortList); + ulsGetCount(sortList, &userCount); + + if (userCount > 0) { + + printf("\n"); + + for (i=0; i\n"); + } + } + printf("
\n"); + printf("User List:"); + printf("
"); + printf("%s", user); + sprintf(line, "user=%s", user); + output_cgi_link("Edit User", "usred", line); + printf("\n"); + output_cgi_link("Remove User", "usrrem", line); + printf("
\n"); + } else { + printf("There are no users in the database."); + } + ulsFree(&sortList); + } + return rv; +} + +/* + * Output a table showing all groups. + */ +NSAPI_PUBLIC int output_groups_list(char *db_path, char *filter) +{ + int rv; + void *padb; + int i; + int id; + char *group; + int groupCount; + char line[BIG_LINE]; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) + report_error(SYSTEM_ERROR, db_path, + "Failed to open database while trying " + "to list groups."); + else { + void *sortList; + + ulsAlloc(&sortList); + rv = nsadbEnumerateGroups(NULL, padb, (void *)sortList, groupEnumCB); + nsadbClose(padb, 0); + ulsSortName(sortList); + ulsGetCount(sortList, &groupCount); + + if (groupCount > 0) { + + printf("\n"); + + for (i=0; i\n"); + } + } + printf("
\n"); + printf("Group List:"); + printf("
"); + printf("%s", group); + sprintf(line, "group=%s", group); + output_cgi_link("Edit Group", "grped", line); + printf(""); + output_cgi_link("Remove Group", "grprem", line); + printf("
\n"); + } else { + printf("There are no groups in the database."); + } + ulsFree(&sortList); + } + return rv; +} + +/* Helper function: Return a uls list of all the groups a user is in. MLM */ +void *_list_user_groups(void *padb, char *user, int group_users) +{ + int rv; + register int i; + UserObj_t *uoptr = 0; + GroupObj_t *ugoptr = 0; + GroupObj_t *goptr = 0; + void *userGroupList = NULL; + int userGroupCount= 0; + USI_t *gidlist; + char *ugname = NULL; + + if(!group_users) { + rv = nsadbFindByName(NULL, padb, user, AIF_USER, (void **)&uoptr); + } else { + rv = nsadbFindByName(NULL, padb, user, AIF_GROUP, (void **)&ugoptr); + } + if ((uoptr == 0) && (ugoptr == 0)) { + /* User doesn't exist, so we've failed. */ + return NULL; + } else { + if(uoptr) { + userGroupCount = UILCOUNT(&uoptr->uo_groups); + } else { + userGroupCount = UILCOUNT(&ugoptr->go_groups); + } + if (userGroupCount > 0) { + ulsAlloc(&userGroupList); + if(uoptr) { + gidlist = UILLIST(&uoptr->uo_groups); + } else { + gidlist = UILLIST(&ugoptr->go_groups); + } + + for (i = 0; i < userGroupCount; ++i) { + rv = nsadbIdToName(NULL, padb, + gidlist[i], AIF_GROUP, &ugname); + + if (rv >= 0) { + rv = nsadbFindByName(NULL, padb, ugname, AIF_GROUP, + (void **)&goptr); + } + if (goptr != 0) { + if (goptr->go_name && strlen((char *)goptr->go_name)) { + if(uoptr) { + if (idfound(uoptr->uo_uid, + (int*)UILLIST(&goptr->go_users), + UILCOUNT(&goptr->go_users))) { + ulsAddToList(userGroupList, goptr->go_gid, + (char *)goptr->go_name); + } + } else { + ulsAddToList(userGroupList, goptr->go_gid, + (char *)goptr->go_name); + } + } + groupFree(goptr); + goptr = 0; + } + } + } + } + return userGroupList; +} + +/* Output a selector box, with name "name", and make it a multiple + * selector box if multiple=1. */ +/* If user is non-null, then if it's a multiple selector, correctly highlight + * the groups the user is in. + * If group_user is 1, then the variable "user" refers to a *group* as + * a member, rather than a user. + * Highlight the item "highlight" regardless of membership (as long as + * it's non-NULL.) MLM */ +NSAPI_PUBLIC void output_group_selector(char *db_path, int group_user, + char *user, + char *highlight, char *except, + char *name, int none, int multiple) +{ + int rv; + void *padb; + int i, j, isselected; + int id; + char *group; + int groupCount; + void *userGroupList = NULL; + int userGroupCount= 0; + char *ugname = NULL; + + rv = nsadbOpen(NULL, db_path, 0, &padb); + if (rv < 0) + report_error(SYSTEM_ERROR, db_path, + "Failed to open database while trying " + "to list groups."); + else { + void *sortList; + + ulsAlloc(&sortList); + rv = nsadbEnumerateGroups(NULL, padb, (void *)sortList, groupEnumCB); + + if((multiple) && (user)) { + userGroupList=_list_user_groups(padb, user, group_user); + if(userGroupList) { + ulsSortName(userGroupList); + ulsGetCount(userGroupList, &userGroupCount); + } + } + nsadbClose(padb, 0); + ulsSortName(sortList); + ulsGetCount(sortList, &groupCount); + + if (groupCount > 0) { + /* Make a pulldown if we can. If the size is bigger than the + * overflow value, make it a box to hack around the fact that + * the X Navigator can't scroll pulldown lists. */ + if((multiple) || (groupCount > SELECT_OVERFLOW)) { + printf("", name); + } + if((!multiple) && (none)) { + printf("