diff options
Diffstat (limited to 'cpukit/httpd/um.c')
-rw-r--r-- | cpukit/httpd/um.c | 1415 |
1 files changed, 1415 insertions, 0 deletions
diff --git a/cpukit/httpd/um.c b/cpukit/httpd/um.c new file mode 100644 index 0000000000..ce9e171c01 --- /dev/null +++ b/cpukit/httpd/um.c @@ -0,0 +1,1415 @@ +/* + * um.c -- User Management + * + * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. + * + * See the file "license.txt" for usage and redistribution license requirements + * + * $Id$ + */ + +/******************************** Description *********************************/ +/* + * User Management routines for adding/deleting/changing users and groups + * Also, routines for determining user access + */ + +/********************************* Includes ***********************************/ + +#include "um.h" +#include "emfdb.h" +#include "webs.h" + +/********************************** Defines ***********************************/ + +#define UM_DB_FILENAME T("um.xml") +#define UM_TXT_FILENAME T("umconfig.txt") + +/* + * Table names + */ +#define UM_USER_TABLENAME T("users") +#define UM_GROUP_TABLENAME T("groups") +#define UM_ACCESS_TABLENAME T("access") + +/* + * Column names + */ +#define UM_NAME T("name") +#define UM_PASS T("password") +#define UM_GROUP T("group") +#define UM_PROT T("prot") +#define UM_DISABLE T("disable") +#define UM_METHOD T("method") +#define UM_PRIVILEGE T("priv") +#define UM_SECURE T("secure") + +/* + * XOR encryption mask + * Note: This string should be modified for individual sites + * in order to enhance user password security. + */ +#define UM_XOR_ENCRYPT T("*j7a(L#yZ98sSd5HfSgGjMj8;Ss;d)(*&^#@$a2s0i3g") + +/******************************** Local Data **********************************/ + +#ifdef UEMF +/* + * User table definition + */ +#define NUMBER_OF_USER_COLUMNS 5 + +char_t *userColumnNames[NUMBER_OF_USER_COLUMNS] = { + UM_NAME, UM_PASS, UM_GROUP, UM_PROT, UM_DISABLE +}; + +int userColumnTypes[NUMBER_OF_USER_COLUMNS] = { + T_STRING, T_STRING, T_STRING, T_INT, T_INT +}; + +dbTable_t userTable = { + UM_USER_TABLENAME, + NUMBER_OF_USER_COLUMNS, + userColumnNames, + userColumnTypes, + 0, + NULL +}; + +/* + * Group table definition + */ +#define NUMBER_OF_GROUP_COLUMNS 5 + +char_t *groupColumnNames[NUMBER_OF_GROUP_COLUMNS] = { + UM_NAME, UM_PRIVILEGE, UM_METHOD, UM_PROT, UM_DISABLE +}; + +int groupColumnTypes[NUMBER_OF_GROUP_COLUMNS] = { + T_STRING, T_INT, T_INT, T_INT, T_INT +}; + +dbTable_t groupTable = { + UM_GROUP_TABLENAME, + NUMBER_OF_GROUP_COLUMNS, + groupColumnNames, + groupColumnTypes, + 0, + NULL +}; + +/* + * Access Limit table definition + */ +#define NUMBER_OF_ACCESS_COLUMNS 4 + +char_t *accessColumnNames[NUMBER_OF_ACCESS_COLUMNS] = { + UM_NAME, UM_METHOD, UM_SECURE, UM_GROUP +}; + +int accessColumnTypes[NUMBER_OF_ACCESS_COLUMNS] = { + T_STRING, T_INT, T_INT, T_STRING +}; + +dbTable_t accessTable = { + UM_ACCESS_TABLENAME, + NUMBER_OF_ACCESS_COLUMNS, + accessColumnNames, + accessColumnTypes, + 0, + NULL +}; +#endif /* #ifdef UEMF */ + +/* + * Database Identifier returned from dbOpen() + */ +static int didUM = -1; + +/* + * Configuration database persist filename + */ +static char_t *saveFilename = NULL; + +static int umOpenCount = 0; /* count of apps using this module */ + +/*************************** Forward Declarations *****************************/ + +static bool_t umCheckName(char_t *name); + +/*********************************** Code *************************************/ +/* + * umOpen() registers the UM tables in the fake emf-database + */ + +int umOpen() +{ + if (++umOpenCount != 1) { + return didUM; + } +/* + * Do not initialize if intialization has already taken place + */ + if (didUM == -1) { + didUM = dbOpen(UM_USER_TABLENAME, UM_DB_FILENAME, NULL, 0); +#ifdef UEMF + dbRegisterDBSchema(&userTable); + dbRegisterDBSchema(&groupTable); + dbRegisterDBSchema(&accessTable); +#endif + } + + if (saveFilename == NULL) { + saveFilename = bstrdup(B_L, UM_TXT_FILENAME); + } + + return didUM; +} + +/******************************************************************************/ +/* + * umClose() frees up the UM tables in the fake emf-database + */ + +void umClose() +{ + if (--umOpenCount > 0) { + return; + } +/* + * Do not close if intialization has not taken place + */ + if (didUM != -1) { + dbClose(didUM); + didUM = -1; + } + + if (saveFilename != NULL) { + bfree(B_L, saveFilename); + saveFilename = NULL; + } +} + +/******************************************************************************/ +/* + * umCommit() persists all of the UM tables + */ + +int umCommit(char_t *filename) +{ + if (filename && *filename) { + if (saveFilename != NULL) { + bfree(B_L, saveFilename); + } + + saveFilename = bstrdup(B_L, filename); + } + + a_assert (saveFilename && *saveFilename); + trace(3, T("UM: Writing User Configuration to file <%s>\n"), + saveFilename); + + return dbSave(didUM, saveFilename, 0); +} + +/******************************************************************************/ +/* + * umRestore() loads up the UM tables with persisted data + */ + +int umRestore(char_t *filename) +{ + if (filename && *filename) { + if (saveFilename != NULL) { + bfree(B_L, saveFilename); + } + + saveFilename = bstrdup(B_L, filename); + } + + a_assert(saveFilename && *saveFilename); + + trace(3, T("UM: Loading User Configuration from file <%s>\n"), + saveFilename); + +/* + * First empty the database, otherwise we wind up with duplicates! + */ + dbZero(didUM); + return dbLoad(didUM, saveFilename, 0); +} + +/******************************************************************************/ +/* + * Encrypt/Decrypt a text string. + * Returns the number of characters encrypted. + */ + +static int umEncryptString(char_t *textString) +{ + char_t *enMask; + char_t enChar; + int numChars; + + a_assert(textString); + + enMask = UM_XOR_ENCRYPT; + numChars = 0; + + while (*textString) { + enChar = *textString ^ *enMask; +/* + * Do not produce encrypted text with embedded linefeeds or tabs. + * Simply use existing character. + */ + if (enChar && !gisspace(enChar)) + *textString = enChar; +/* + * Increment all pointers. + */ + enMask++; + textString++; + numChars++; +/* + * Wrap encryption mask pointer if at end of length. + */ + if (*enMask == '\0') { + enMask = UM_XOR_ENCRYPT; + } + } + + return numChars; +} + +/******************************************************************************/ +/* + * umGetFirstRowData() - return a pointer to the first non-blank key value + * in the given column for the given table. + */ + +static char_t *umGetFirstRowData(char_t *tableName, char_t *columnName) +{ + char_t *columnData; + int row; + int check; + + a_assert(tableName && *tableName); + a_assert(columnName && *columnName); + + row = 0; +/* + * Move through table until we retrieve the first row with non-null + * column data. + */ + columnData = NULL; + while ((check = dbReadStr(didUM, tableName, columnName, row++, + &columnData)) == 0 || (check == DB_ERR_ROW_DELETED)) { + if (columnData && *columnData) { + return columnData; + } + } + + return NULL; +} + +/******************************************************************************/ +/* + * umGetNextRowData() - return a pointer to the first non-blank + * key value following the given one. + */ + +static char_t *umGetNextRowData(char_t *tableName, char_t *columnName, + char_t *keyLast) +{ + char_t *key; + int row; + int check; + + a_assert(tableName && *tableName); + a_assert(columnName && *columnName); + a_assert(keyLast && *keyLast); +/* + * Position row counter to row where the given key value was found + */ + row = 0; + key = NULL; + + while ((((check = dbReadStr(didUM, tableName, columnName, row++, + &key)) == 0) || (check == DB_ERR_ROW_DELETED)) && + ((key == NULL) || (gstrcmp(key, keyLast) != 0))) { + } +/* + * If the last key value was not found, return NULL + */ + if (!key || gstrcmp(key, keyLast) != 0) { + return NULL; + } +/* + * Move through table until we retrieve the next row with a non-null key + */ + while (((check = dbReadStr(didUM, tableName, columnName, row++, &key)) + == 0) || (check == DB_ERR_ROW_DELETED)) { + if (key && *key && (gstrcmp(key, keyLast) != 0)) { + return key; + } + } + + return NULL; +} + +/******************************************************************************/ +/* + * umAddUser() - Adds a user to the "users" table. + */ + +int umAddUser(char_t *user, char_t *pass, char_t *group, + bool_t prot, bool_t disabled) +{ + int row; + char_t *password; + + a_assert(user && *user); + a_assert(pass && *pass); + a_assert(group && *group); + + trace(3, T("UM: Adding User <%s>\n"), user); + +/* + * Do not allow duplicates + */ + if (umUserExists(user)) { + return UM_ERR_DUPLICATE; + } + +/* + * Make sure user name and password contain valid characters + */ + if (!umCheckName(user)) { + return UM_ERR_BAD_NAME; + } + + if (!umCheckName(pass)) { + return UM_ERR_BAD_PASSWORD; + } + +/* + * Make sure group exists + */ + if (!umGroupExists(group)) { + return UM_ERR_NOT_FOUND; + } + +/* + * Now create the user record + */ + row = dbAddRow(didUM, UM_USER_TABLENAME); + + if (row < 0) { + return UM_ERR_GENERAL; + } + + if (dbWriteStr(didUM, UM_USER_TABLENAME, UM_NAME, row, user) != 0) { + return UM_ERR_GENERAL; + } + + password = bstrdup(B_L, pass); + umEncryptString(password); + dbWriteStr(didUM, UM_USER_TABLENAME, UM_PASS, row, password); + bfree(B_L, password); + dbWriteStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, group); + dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, prot); + dbWriteInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, disabled); + + return 0; +} + +/******************************************************************************/ +/* + * umDeleteUser() - remove a user from the "users" table + */ + +int umDeleteUser(char_t *user) +{ + int row; + + a_assert(user && *user); + trace(3, T("UM: Deleting User <%s>\n"), user); +/* + * Check to see if user is delete-protected + */ + if (umGetUserProtected(user)) { + return UM_ERR_PROTECTED; + } + +/* + * If found, delete the user from the database + */ + if ((row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0)) >= 0) { + return dbDeleteRow(didUM, UM_USER_TABLENAME, row); + } + + return UM_ERR_NOT_FOUND; +} + +/******************************************************************************/ +/* + * umGetFirstUser() - Returns the user ID of the first user found in the + * "users" table. + */ + +char_t *umGetFirstUser() +{ + return umGetFirstRowData(UM_USER_TABLENAME, UM_NAME); +} + +/******************************************************************************/ +/* + * umGetNextUser() Returns the next user found in the "users" table after + * the given user. + */ + +char_t *umGetNextUser(char_t *userLast) +{ + return umGetNextRowData(UM_USER_TABLENAME, UM_NAME, userLast); +} + +/******************************************************************************/ +/* + * umUserExists() Returns TRUE if userid exists. + */ + +bool_t umUserExists(char_t *user) +{ + a_assert(user && *user); + + if (dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0) >= 0) { + return TRUE; + } else { + return FALSE; + } +} + +/******************************************************************************/ +/* + * umGetUserPassword() returns a de-crypted copy of the user password + */ + +char_t *umGetUserPassword(char_t *user) +{ + char_t *password; + int row; + + a_assert(user && *user); + + password = NULL; + row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); + + if (row >= 0) { + char_t *pass = NULL; + dbReadStr(didUM, UM_USER_TABLENAME, UM_PASS, row, &pass); +/* + * Decrypt password + * Note, this function returns a copy of the password, which must + * be deleted at some time in the future. + */ + password = bstrdup(B_L, pass); + umEncryptString(password); + } + + return password; +} + +/******************************************************************************/ +/* + * umSetUserPassword() updates the user password in the user "table" after + * encrypting the given password + */ + +int umSetUserPassword(char_t *user, char_t *pass) +{ + int row, nRet; + char_t *password; + + a_assert(user && *user); + a_assert(pass && *pass); + trace(3, T("UM: Attempting to change the password for user <%s>\n"), user); +/* + * Find the row of the user + */ + if ((row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0)) < 0) { + return UM_ERR_NOT_FOUND; + } + + password = bstrdup(B_L, pass); + umEncryptString(password); + nRet = dbWriteStr(didUM, UM_USER_TABLENAME, UM_PASS, row, password); + bfree(B_L, password); + + return nRet; +} + +/******************************************************************************/ +/* + * umGetUserGroup() returns the name of the user group + */ + +char_t *umGetUserGroup(char_t *user) +{ + char_t *group; + int row; + + a_assert(user && *user); + group = NULL; +/* + * Find the row of the user + */ + row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); + + if (row >= 0) { + dbReadStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, &group); + } + + return group; +} + +/******************************************************************************/ +/* + * umSetUserGroup() Sets the name of the user group for the user + */ + +int umSetUserGroup(char_t *user, char_t *group) +{ + int row; + + a_assert(user && *user); + a_assert(group && *group); +/* + * Find the row of the user + */ + row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); + + if (row >= 0) { + return dbWriteStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, group); + } else { + return UM_ERR_NOT_FOUND; + } +} + +/******************************************************************************/ +/* + * umGetUserEnabled() - returns if the user is enabled + * Returns FALSE if the user is not found. + */ + +bool_t umGetUserEnabled(char_t *user) +{ + int disabled, row; + + a_assert(user && *user); + + disabled = 1; +/* + * Find the row of the user + */ + row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); + + if (row >= 0) { + dbReadInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, &disabled); + } + + return (bool_t)!disabled; +} + +/******************************************************************************/ +/* + * umSetUserEnabled() Enables/disables the user + */ +int umSetUserEnabled(char_t *user, bool_t enabled) +{ + int row; + + a_assert(user && *user); +/* + * Find the row of the user + */ + row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); + if (row >= 0) { + return dbWriteInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, !enabled); + } else { + return UM_ERR_NOT_FOUND; + } +} + +/******************************************************************************/ +/* + * umGetUserProtected() - determine deletability of user + */ + +bool_t umGetUserProtected(char_t *user) +{ + int protect, row; + + a_assert(user && *user); +/* + * Find the row of the user + */ + row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); + protect = FALSE; + + if (row >= 0) { + dbReadInt(didUM, UM_USER_TABLENAME, UM_PROT, row, &protect); + } + + return (bool_t)protect; +} + +/******************************************************************************/ +/* + * umSetUserProtected() sets the delete protection for the user + */ +int umSetUserProtected(char_t *user, bool_t protect) +{ + int row; + + a_assert(user && *user); +/* + * Find the row of the user + */ + row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0); + + if (row >= 0) { + return dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, protect); + } else { + return UM_ERR_NOT_FOUND; + } +} + + +/******************************************************************************/ +/* + * umAddGroup() adds a group to the "Group" table + */ + +int umAddGroup(char_t *group, short priv, accessMeth_t am, + bool_t prot, bool_t disabled) +{ + int row; + + a_assert(group && *group); + trace(3, T("UM: Adding group <%s>\n"), group); + +/* + * Do not allow duplicates + */ + if (umGroupExists(group)) { + return UM_ERR_DUPLICATE; + } + +/* + * Only allow valid characters in key field + */ + if (!umCheckName(group)) { + return UM_ERR_BAD_NAME; + } + +/* + * Add a new row to the table + */ + if ((row = dbAddRow(didUM, UM_GROUP_TABLENAME)) < 0) { + return UM_ERR_GENERAL; + } + +/* + * Write the key field + */ + if (dbWriteStr(didUM, UM_GROUP_TABLENAME, UM_NAME, row, group) != 0) { + return UM_ERR_GENERAL; + } + +/* + * Write the remaining fields + */ + dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, priv); + dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int) am); + dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, prot); + dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, disabled); + + return 0; +} + +/******************************************************************************/ +/* + * umDeleteGroup() - Delete a user group, if not protected + */ + +int umDeleteGroup(char_t *group) +{ + int row; + + a_assert(group && *group); + trace(3, T("UM: Deleting Group <%s>\n"), group); + +/* + * Check to see if the group is in use + */ + if (umGetGroupInUse(group)) { + return UM_ERR_IN_USE; + } + +/* + * Check to see if the group is delete-protected + */ + if (umGetGroupProtected(group)) { + return UM_ERR_PROTECTED; + } + +/* + * Find the row of the group to delete + */ + if ((row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0)) < 0) { + return UM_ERR_NOT_FOUND; + } + + return dbDeleteRow(didUM, UM_GROUP_TABLENAME, row); +} + +/******************************************************************************/ +/* + * umGroupExists() returns TRUE if group exists, FALSE otherwise + */ + +bool_t umGroupExists(char_t *group) +{ + a_assert(group && *group); + + if (dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0) >= 0) { + return TRUE; + } else { + return FALSE; + } +} + + +/******************************************************************************/ +/* + * umGetGroupInUse() returns TRUE if the group is referenced by a user or by + * an access limit. + */ + +bool_t umGetGroupInUse(char_t *group) +{ + a_assert(group && *group); + +/* + * First, check the user table + */ + if (dbSearchStr(didUM, UM_USER_TABLENAME, UM_GROUP, group, 0) >= 0) { + return TRUE; + } + +/* + * Second, check the access limit table + */ + if (dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, group, 0) >= 0) { + return TRUE; + } + + return FALSE; +} + + +/******************************************************************************/ +/* + * umGetFirstGroup() - return a pointer to the first non-blank group name + */ + +char_t *umGetFirstGroup() +{ + return umGetFirstRowData(UM_GROUP_TABLENAME, UM_NAME); +} + +/******************************************************************************/ +/* + * umGetNextGroup() - return a pointer to the first non-blank group name + * following the given group name + */ + +char_t *umGetNextGroup(char_t *groupLast) +{ + return umGetNextRowData(UM_GROUP_TABLENAME, UM_NAME, groupLast); +} + +/******************************************************************************/ +/* + * Returns the default access method to use for a given group + */ + +accessMeth_t umGetGroupAccessMethod(char_t *group) +{ + int am, row; + + a_assert(group && *group); + row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); + + if (row >= 0) { + dbReadInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int *)&am); + } else { + am = AM_INVALID; + } + + return (accessMeth_t) am; +} + +/******************************************************************************/ +/* + * Set the default access method to use for a given group + */ + +int umSetGroupAccessMethod(char_t *group, accessMeth_t am) +{ + int row; + + a_assert(group && *group); + row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); + + if (row >= 0) { + return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int) am); + } else { + return UM_ERR_NOT_FOUND; + } +} + +/******************************************************************************/ +/* + * Returns the privilege mask for a given group + */ + +short umGetGroupPrivilege(char_t *group) +{ + int privilege, row; + + a_assert(group && *group); + privilege = -1; + row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); + + if (row >= 0) { + dbReadInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, &privilege); + } + + return (short) privilege; +} + +/******************************************************************************/ +/* + * Set the privilege mask for a given group + */ + +int umSetGroupPrivilege(char_t *group, short privilege) +{ + int row; + + a_assert(group && *group); + row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); + + if (row >= 0) { + return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, + (int)privilege); + } else { + return UM_ERR_NOT_FOUND; + } +} + +/******************************************************************************/ +/* + * Returns the enabled setting for a given group. + * Returns FALSE if group is not found. + */ + +bool_t umGetGroupEnabled(char_t *group) +{ + int disabled, row; + + a_assert(group && *group); + row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); + disabled = 1; + + if (row >= 0) { + dbReadInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, &disabled); + } + + return (bool_t) !disabled; +} + +/******************************************************************************/ +/* + * Sets the enabled setting for a given group. + */ + +int umSetGroupEnabled(char_t *group, bool_t enabled) +{ + int row; + + a_assert(group && *group); + row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); + + if (row >= 0) { + return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, + (int) !enabled); + } else { + return UM_ERR_NOT_FOUND; + } +} + +/******************************************************************************/ +/* + * Returns the protected setting for a given group + * Returns FALSE if user is not found + */ + +bool_t umGetGroupProtected(char_t *group) +{ + int protect, row; + + a_assert(group && *group); + + protect = 0; + row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); + if (row >= 0) { + dbReadInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, &protect); + } + + return (bool_t) protect; +} + +/******************************************************************************/ +/* + * Sets the protected setting for a given group + */ + +int umSetGroupProtected(char_t *group, bool_t protect) +{ + int row; + + a_assert(group && *group); + row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0); + + if (row >= 0) { + return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, + (int) protect); + } else { + return UM_ERR_NOT_FOUND; + } +} + + +/******************************************************************************/ +/* + * umAddAccessLimit() adds an access limit to the "access" table + */ + +int umAddAccessLimit(char_t *url, accessMeth_t am, short secure, char_t *group) +{ + int row; + + a_assert(url && *url); + trace(3, T("UM: Adding Access Limit for <%s>\n"), url); + +/* + * Do not allow duplicates + */ + if (umAccessLimitExists(url)) { + return UM_ERR_DUPLICATE; + } + +/* + * Add a new row to the table + */ + if ((row = dbAddRow(didUM, UM_ACCESS_TABLENAME)) < 0) { + return UM_ERR_GENERAL; + } + +/* + * Write the key field + */ + if(dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, row, url) < 0) { + return UM_ERR_GENERAL; + } + +/* + * Write the remaining fields + */ + dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, (int)am); + dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, (int)secure); + dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, group); + + return 0; +} + +/******************************************************************************/ +/* + * umDeleteAccessLimit() + */ + +int umDeleteAccessLimit(char_t *url) +{ + int row; + + a_assert(url && *url); + trace(3, T("UM: Deleting Access Limit for <%s>\n"), url); +/* + * Find the row of the access limit to delete + */ + if ((row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0)) < 0) { + return UM_ERR_NOT_FOUND; + } + + return dbDeleteRow(didUM, UM_ACCESS_TABLENAME, row); +} + +/******************************************************************************/ +/* + * umGetFirstGroup() - return a pointer to the first non-blank access limit + */ + +char_t *umGetFirstAccessLimit() +{ + return umGetFirstRowData(UM_ACCESS_TABLENAME, UM_NAME); +} + +/******************************************************************************/ +/* + * umGetNextAccessLimit() - return a pointer to the first non-blank + * access limit following the given one + */ + +char_t *umGetNextAccessLimit(char_t *urlLast) +{ + return umGetNextRowData(UM_ACCESS_TABLENAME, UM_NAME, urlLast); +} + +/******************************************************************************/ +/* + * umAccessLimitExists() returns TRUE if this access limit exists + */ + +bool_t umAccessLimitExists(char_t *url) +{ + a_assert(url && *url); + + if (dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0) < 0) { + return FALSE; + } else { + return TRUE; + } +} + +/******************************************************************************/ +/* + * umGetAccessLimit() returns the Access Method for the URL + */ + +accessMeth_t umGetAccessLimitMethod(char_t *url) +{ + int am, row; + + am = (int) AM_INVALID; + row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); + + if (row >= 0) { + dbReadInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, &am); + } + + return (accessMeth_t) am; +} + +/******************************************************************************/ +/* + * umSetAccessLimitMethod() - set Access Method for Access Limit + */ + +int umSetAccessLimitMethod(char_t *url, accessMeth_t am) +{ + int row; + + a_assert(url && *url); + row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); + + if (row >= 0) { + return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, (int) am); + } else { + return UM_ERR_NOT_FOUND; + } +} + +/******************************************************************************/ +/* + * umGetAccessLimitSecure() - returns secure switch for access limit + */ + +short umGetAccessLimitSecure(char_t *url) +{ + int secure, row; + + a_assert(url && *url); + secure = -1; + row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); + + if (row >= 0) { + dbReadInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, &secure); + } + + return (short)secure; +} + +/******************************************************************************/ +/* + * umSetAccessLimitSecure() - sets the secure flag for the URL + */ + +int umSetAccessLimitSecure(char_t *url, short secure) +{ + int row; + + a_assert(url && *url); + row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); + + if (row >= 0) { + return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, + (int)secure); + } else { + return UM_ERR_NOT_FOUND; + } +} + +/******************************************************************************/ +/* + * umGetAccessLimitGroup() - returns the user group of the access limit + */ + +char_t *umGetAccessLimitGroup(char_t *url) +{ + char_t *group; + int row; + + a_assert(url && *url); + group = NULL; + row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); + + if (row >= 0) { + dbReadStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, &group); + } + + return group; +} + +/******************************************************************************/ +/* + * umSetAccessLimitGroup() - sets the user group for the access limit. + */ + +int umSetAccessLimitGroup(char_t *url, char_t *group) +{ + int row; + + a_assert(url && *url); + row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0); + + if (row >= 0) { + return dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, group); + } else { + return UM_ERR_NOT_FOUND; + } +} + +/******************************************************************************/ +/* + * Returns the access limit to use for a given URL, by checking for URLs up + * the directory tree. Creates a new string that must be deleted. + */ + +char_t *umGetAccessLimit(char_t *url) +{ + char_t *urlRet, *urlCheck, *lastChar; + int len; + + a_assert(url && *url); + urlRet = NULL; + urlCheck = bstrdup(B_L, url); + a_assert(urlCheck); + len = gstrlen(urlCheck); +/* + * Scan back through URL to see if there is a "parent" access limit + */ + while (len && !urlRet) { + if (umAccessLimitExists(urlCheck)) { + urlRet = bstrdup(B_L, urlCheck); + } else { +/* + * Trim the end portion of the URL to the previous directory marker + */ + lastChar = urlCheck + len; + lastChar--; + + while ((lastChar >= urlCheck) && ((*lastChar == '/') || + (*lastChar == '\\'))) { + *lastChar = 0; + lastChar--; + } + + while ((lastChar >= urlCheck) && (*lastChar != '/') && + (*lastChar != '\\')) { + *lastChar = 0; + lastChar--; + } + + len = gstrlen(urlCheck); + } + } + bfree (B_L, urlCheck); + + return urlRet; +} + +/******************************************************************************/ +/* + * Returns the access method to use for a given URL + */ + +accessMeth_t umGetAccessMethodForURL(char_t *url) +{ + accessMeth_t amRet; + char_t *urlHavingLimit, *group; + + urlHavingLimit = umGetAccessLimit(url); + if (urlHavingLimit) { + group = umGetAccessLimitGroup(urlHavingLimit); + + if (group && *group) { + amRet = umGetGroupAccessMethod(group); + } else { + amRet = umGetAccessLimitMethod(urlHavingLimit); + } + + bfree(B_L, urlHavingLimit); + } else { + amRet = AM_FULL; + } + + return amRet; +} + +/******************************************************************************/ +/* + * Returns TRUE if user can access URL + */ + +bool_t umUserCanAccessURL(char_t *user, char_t *url) +{ + accessMeth_t amURL; + char_t *group, *usergroup, *urlHavingLimit; + short priv; + + a_assert(user && *user); + a_assert(url && *url); + +/* + * Make sure user exists + */ + if (!umUserExists(user)) { + return FALSE; + } + +/* + * Make sure user is enabled + */ + if (!umGetUserEnabled(user)) { + return FALSE; + } + +/* + * Make sure user has sufficient privileges (any will do) + */ + usergroup = umGetUserGroup(user); + priv = umGetGroupPrivilege(usergroup); + if (priv == 0) { + return FALSE; + } + +/* + * Make sure user's group is enabled + */ + if (!umGetGroupEnabled(usergroup)) { + return FALSE; + } + +/* + * The access method of the user group must not be AM_NONE + */ + if (umGetGroupAccessMethod(usergroup) == AM_NONE) { + return FALSE; + } + +/* + * Check to see if there is an Access Limit for this URL + */ + urlHavingLimit = umGetAccessLimit(url); + if (urlHavingLimit) { + amURL = umGetAccessLimitMethod(urlHavingLimit); + group = umGetAccessLimitGroup(urlHavingLimit); + bfree(B_L, urlHavingLimit); + } else { +/* + * If there isn't an access limit for the URL, user has full access + */ + return TRUE; + } + +/* + * If the access method for the URL is AM_NONE then + * the file "doesn't exist". + */ + if (amURL == AM_NONE) { + return FALSE; + } + +/* + * If Access Limit has a group specified, then the user must be a + * member of that group + */ + if (group && *group) { + if (usergroup && (gstrcmp(group, usergroup) != 0)) { + return FALSE; + } + } + +/* + * Otherwise, user can access the URL + */ + return TRUE; +} + +/******************************************************************************/ +/* + * Returns TRUE if given name has only valid chars + */ + +static bool_t umCheckName(char_t *name) +{ + a_assert(name && *name); + + if (name && *name) { + while (*name) { + if (gisspace(*name)) { + return FALSE; + } + + name++; + } + + return TRUE; + } + + return FALSE; +} + +/******************************************************************************/ |