#include <string.h>
#include <limits.h>
#include <pwd.h>
+#include <grp.h>
#include "common.h"
-enum {
- FLAG_TYPEMASK = 0x03,
- USER_TYPE_NORMAL = 0x00,
- USER_TYPE_COKE = 0x01,
- USER_TYPE_WHEEL = 0x02,
- USER_TYPE_GOD = 0x03
-};
+#define USE_UNIX_GROUPS 1
// === PROTOTYPES ===
static int GetUnixID(const char *Username);
FILE *gBank_File;
// === CODE ===
+static int Bank_int_WriteEntry(int ID)
+{
+ if( ID < 0 || ID >= giBank_NumUsers ) {
+ return -1;
+ }
+
+ // Commit to file
+ fseek(gBank_File, ID*sizeof(gaBank_Users[0]), SEEK_SET);
+ fwrite(&gaBank_Users[ID], sizeof(gaBank_Users[0]), 1, gBank_File);
+
+ return 0;
+}
+
int Bank_GetUserByName(const char *Username)
{
int i, uid;
return gaBank_Users[ID].Balance;
}
-int Bank_AlterUserBalance(int ID, int Delta)
+int Bank_GetUserFlags(int ID)
{
- // Sanity
if( ID < 0 || ID >= giBank_NumUsers )
return -1;
- // Update
- gaBank_Users[ID].Balance += Delta;
+ // root
+ if( gaBank_Users[ID].UnixID == 0 ) {
+ gaBank_Users[ID].Flags |= USER_FLAG_WHEEL|USER_FLAG_COKE;
+ }
- // Commit
- fseek(gBank_File, ID*sizeof(gaBank_Users[0]), SEEK_SET);
- fwrite(&gaBank_Users[ID], sizeof(gaBank_Users[0]), 1, gBank_File);
+ #if USE_UNIX_GROUPS
+ // TODO: Implement checking the PAM groups and status instead, then
+ // fall back on the database. (and update if there is a difference)
+ if( gaBank_Users[ID].UnixID > 0 )
+ {
+ struct passwd *pwd;
+ struct group *grp;
+ int i;
+
+ // Get username
+ pwd = getpwuid( gaBank_Users[ID].UnixID );
+
+ // Check for additions to the "coke" group
+ grp = getgrnam("coke");
+ if( grp ) {
+ for( i = 0; grp->gr_mem[i]; i ++ )
+ {
+ if( strcmp(grp->gr_mem[i], pwd->pw_name) == 0 ) {
+ gaBank_Users[ID].Flags |= USER_FLAG_COKE;
+ break ;
+ }
+ }
+ }
+
+ // Check for additions to the "wheel" group
+ grp = getgrnam("wheel");
+ if( grp ) {
+ for( i = 0; grp->gr_mem[i]; i ++ )
+ {
+ if( strcmp(grp->gr_mem[i], pwd->pw_name) == 0 ) {
+ gaBank_Users[ID].Flags |= USER_FLAG_WHEEL;
+ break ;
+ }
+ }
+ }
+ }
+ #endif
+
+ return gaBank_Users[ID].Flags;
+}
+
+int Bank_SetUserFlags(int ID, int Mask, int Value)
+{
+ // Sanity
+ if( ID < 0 || ID >= giBank_NumUsers )
+ return -1;
+
+ // Silently ignore changes to root and meta accounts
+ if( gaBank_Users[ID].UnixID <= 0 ) return 0;
+
+ gaBank_Users[ID].Flags &= ~Mask;
+ gaBank_Users[ID].Flags |= Value;
+
+ Bank_int_WriteEntry(ID);
return 0;
}
-int Bank_SetUserBalance(int ID, int Value)
+int Bank_AlterUserBalance(int ID, int Delta)
{
// Sanity
if( ID < 0 || ID >= giBank_NumUsers )
return -1;
// Update
- gaBank_Users[ID].Balance = Value;
-
- // Commit
- fseek(gBank_File, ID*sizeof(gaBank_Users[0]), SEEK_SET);
- fwrite(&gaBank_Users[ID], sizeof(gaBank_Users[0]), 1, gBank_File);
+ gaBank_Users[ID].Balance += Delta;
+
+ Bank_int_WriteEntry(ID);
return 0;
}
int Bank_GetMinAllowedBalance(int ID)
{
+ int flags;
if( ID < 0 || ID >= giBank_NumUsers )
return 0;
- switch( gaBank_Users[ID].Flags & FLAG_TYPEMASK )
- {
- case USER_TYPE_NORMAL: return 0;
- case USER_TYPE_COKE: return -2000;
- case USER_TYPE_WHEEL: return -10000;
- case USER_TYPE_GOD: return INT_MIN;
- default: return 0;
- }
+ flags = Bank_GetUserFlags(ID);
+
+ // Internal accounts have no limit
+ if( (flags & USER_FLAG_INTERNAL) )
+ return INT_MIN;
+
+ // Wheel is allowed to go to -$100
+ if( (flags & USER_FLAG_WHEEL) )
+ return -10000;
+
+ // Coke is allowed to go to -$20
+ if( (flags & USER_FLAG_COKE) )
+ return -2000;
+
+ // For everyone else, no negative
+ return 0;
}
/**
gaBank_Users[giBank_NumUsers].Balance = 0;
gaBank_Users[giBank_NumUsers].Flags = 0;
- if( strcmp(Username, ">liability") == 0 ) {
- gaBank_Users[giBank_NumUsers].Flags = USER_TYPE_GOD; // No minium
+ if( strcmp(Username, COKEBANK_DEBT_ACCT) == 0 ) {
+ gaBank_Users[giBank_NumUsers].Flags = USER_FLAG_INTERNAL;
+ }
+ else if( strcmp(Username, COKEBANK_SALES_ACCT) == 0 ) {
+ gaBank_Users[giBank_NumUsers].Flags = USER_FLAG_INTERNAL;
+ }
+ else if( strcmp(Username, "root") == 0 ) {
+ gaBank_Users[giBank_NumUsers].Flags = USER_FLAG_WHEEL|USER_FLAG_COKE;
}
-
- // Commit to file
- fseek(gBank_File, giBank_NumUsers*sizeof(gaBank_Users[0]), SEEK_SET);
- fwrite(&gaBank_Users[giBank_NumUsers], sizeof(gaBank_Users[0]), 1, gBank_File);
// Increment count
giBank_NumUsers ++;
+
+ Bank_int_WriteEntry(giBank_NumUsers - 1);
return 0;
}
return NULL;
if( gaBank_Users[ID].UnixID == -1 )
- return strdup(">sales");
+ return strdup(COKEBANK_SALES_ACCT);
if( gaBank_Users[ID].UnixID == -2 )
- return strdup(">liability");
+ return strdup(COKEBANK_DEBT_ACCT);
pwd = getpwuid(gaBank_Users[ID].UnixID);
if( !pwd ) return NULL;
{
int uid;
- if( strcmp(Username, ">sales") == 0 ) { // Pseudo account that sales are made into
+ if( strcmp(Username, COKEBANK_SALES_ACCT) == 0 ) { // Pseudo account that sales are made into
uid = -1;
}
- else if( strcmp(Username, ">liability") == 0 ) { // Pseudo acount that money is added from
+ else if( strcmp(Username, COKEBANK_DEBT_ACCT) == 0 ) { // Pseudo acount that money is added from
uid = -2;
}
else {