?? um.c
字號:
/*
* 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: um.c,v 1.5 2002/10/24 14:44:50 bporter Exp $
*/
/******************************** 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 qHierarchicalAccess
/*
* user-provided function to allow hierarchical access protection. See below.
* for details.
*/
extern bool_t dmfCanAccess(const char_t* usergroup, const char_t* group);
#endif
#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)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -