summaryrefslogtreecommitdiffstats
path: root/uidmap.c
diff options
context:
space:
mode:
authorSimon Rettberg2018-11-14 14:37:31 +0100
committerSimon Rettberg2018-11-14 14:37:31 +0100
commit8b8ed36516e9a40df6ac9ac46ab355fee0e5b5f0 (patch)
treeb0267df71f0807319e7e80cf18a27dde1382cc90 /uidmap.c
parentStarted work on proxy-side uid generation/tracking (diff)
downloadldadp-8b8ed36516e9a40df6ac9ac46ab355fee0e5b5f0.tar.gz
ldadp-8b8ed36516e9a40df6ac9ac46ab355fee0e5b5f0.tar.xz
ldadp-8b8ed36516e9a40df6ac9ac46ab355fee0e5b5f0.zip
Support generating uidNumbers on proxy
Diffstat (limited to 'uidmap.c')
-rw-r--r--uidmap.c85
1 files changed, 42 insertions, 43 deletions
diff --git a/uidmap.c b/uidmap.c
index 8315be2..a1cb9f7 100644
--- a/uidmap.c
+++ b/uidmap.c
@@ -9,10 +9,6 @@
#include <stdio.h>
#include <unistd.h>
-static struct hashmap _numToName, _nameToNum;
-static BOOL _initDone = FALSE;
-static const char *_saveFileName = NULL;
-
static const uint16_t MAGIC = 1234;
static const int64_t MAX_AGE = 86400 * 2; // 2 days
#define MAX_NAME_LEN 1024
@@ -27,7 +23,7 @@ struct user
int64_t lastUse;
};
-static void insertTime(const struct string *name, const uint32_t number, const int64_t lastUse)
+static void insertTime(struct uidmap *uidmap, const struct string *name, const uint32_t number, const int64_t lastUse)
{
uint8_t *buffer = malloc(sizeof(struct user) + sizeof(struct string) + name->l);
struct user *u = (struct user*)buffer;
@@ -39,18 +35,18 @@ static void insertTime(const struct string *name, const uint32_t number, const i
u->name = s;
u->number = number;
u->lastUse = lastUse;
- if (name_hashmap_put(&_nameToNum, u->name, u) != u) {
+ if (name_hashmap_put(uidmap->nameToNum, u->name, u) != u) {
plog(DEBUG_WARNING, "[uidmap] Collision when inserting %.*s by name (%"PRIu32")", (int)s->l, s->s, number);
}
- if (number_hashmap_put(&_numToName, &u->number, u) != u) {
+ if (number_hashmap_put(uidmap->numToName, &u->number, u) != u) {
plog(DEBUG_WARNING, "[uidmap] Collision when inserting %.*s by number (%"PRIu32")", (int)s->l, s->s, number);
}
// TODO: Leak
}
-static void insert(const struct string *name, const uint32_t number)
+static void insert(struct uidmap *uidmap, const struct string *name, const uint32_t number)
{
- insertTime(name, number, time(NULL));
+ insertTime(uidmap, name, number, time(NULL));
}
static int uint32_compare(const void *a, const void *b)
@@ -84,7 +80,7 @@ static size_t string_hash(const void *key)
return hash;
}
-uint32_t uidmap_getNumberForName(const struct string *name)
+uint32_t uidmap_getNumberForName(struct uidmap *uidmap, const struct string *name)
{
// Try string matching
char buf[name->l];
@@ -93,7 +89,7 @@ uint32_t uidmap_getNumberForName(const struct string *name)
buf[i] = tolower(name->s[i]);
}
// Get
- struct user *u = name_hashmap_get(&_nameToNum, &lower);
+ struct user *u = name_hashmap_get(uidmap->nameToNum, &lower);
if (u != NULL) {
u->lastUse = time(NULL);
return u->number;
@@ -101,10 +97,10 @@ uint32_t uidmap_getNumberForName(const struct string *name)
// Not known yet - try numeric
uint32_t asNumber = parseUInt32(name);
if (asNumber >= 2000) {
- u = number_hashmap_get(&_numToName, &asNumber);
+ u = number_hashmap_get(uidmap->numToName, &asNumber);
if (u == NULL) {
// No collision, use name as number
- insert(&lower, asNumber);
+ insert(uidmap, &lower, asNumber);
return asNumber;
}
plog(DEBUG_WARNING, "%.*s is numeric (%u) but collides", (int)name->l, name->s, asNumber);
@@ -116,49 +112,52 @@ uint32_t uidmap_getNumberForName(const struct string *name)
}
for (;;) {
//plog(DEBUG_WARNING, "Using number %u for %.*s", asNumber, (int)name->l, name->s);
- u = number_hashmap_get(&_numToName, &asNumber);
+ u = number_hashmap_get(uidmap->numToName, &asNumber);
if (u == NULL)
break;
do {
asNumber = rand() + 2000;
} while (asNumber < 2000);
}
- insert(&lower, asNumber);
+ insert(uidmap, &lower, asNumber);
return asNumber;
}
-const struct string *uidmap_getNameForNumber(const uint32_t number)
+const struct string *uidmap_getNameForNumber(struct uidmap *uidmap, const struct string *numberString)
{
- struct user *u = number_hashmap_get(&_numToName, &number);
+ uint32_t number = parseUInt32(numberString);
+ if (number < 2000)
+ return NULL;
+ struct user *u = number_hashmap_get(uidmap->numToName, &number);
if (u == NULL)
return NULL;
u->lastUse = time(NULL);
return u->name;
}
-void uidmap_init(const char *fileName)
+void uidmap_init(struct uidmap *uidmap)
{
- if (_initDone)
+ if (uidmap->nameToNum != NULL)
return;
- _initDone = TRUE;
- hashmap_init(&_numToName, uint32_hash, uint32_compare, 0);
- hashmap_init(&_nameToNum, string_hash, string_compare, 0);
- if (fileName == NULL)
+ uidmap->numToName = calloc(2, sizeof(struct hashmap));
+ uidmap->nameToNum = uidmap->numToName + 1;
+ hashmap_init(uidmap->numToName, uint32_hash, uint32_compare, 0);
+ hashmap_init(uidmap->nameToNum, string_hash, string_compare, 0);
+ if (uidmap->fileName == NULL)
return;
- // We have a filename, remember it and try to load DB
- _saveFileName = strdup(fileName);
- FILE *fh = fopen(_saveFileName, "rb");
+ // We have a filename, try to load DB
+ FILE *fh = fopen(uidmap->fileName, "rb");
if (fh == NULL)
return;
fseek(fh, 0, SEEK_END);
const int fsize = ftell(fh);
fseek(fh, 0, SEEK_SET);
- if (fsize > 0) {
+ if (fsize > 0) { // Guess required map size
const size_t entries = (size_t)fsize / 25;
- hashmap_destroy(&_numToName);
- hashmap_destroy(&_nameToNum);
- hashmap_init(&_numToName, uint32_hash, uint32_compare, entries);
- hashmap_init(&_nameToNum, string_hash, string_compare, entries);
+ hashmap_destroy(uidmap->numToName);
+ hashmap_destroy(uidmap->nameToNum);
+ hashmap_init(uidmap->numToName, uint32_hash, uint32_compare, entries);
+ hashmap_init(uidmap->nameToNum, string_hash, string_compare, entries);
}
// Not endian safe, do not copy file around...
uint16_t len = 0;
@@ -196,38 +195,38 @@ void uidmap_init(const char *fileName)
lastUse = now;
// Add
name.l = len;
- insertTime(&name, uidNumber, lastUse);
+ insertTime(uidmap, &name, uidNumber, lastUse);
loaded++;
}
fclose(fh);
- plog(DEBUG_INFO, "Loaded %d entries from %s", loaded, _saveFileName);
+ plog(DEBUG_INFO, "Loaded %d entries from %s", loaded, uidmap->fileName);
}
-void uidmap_cleanupSave()
+void uidmap_cleanupSave(struct uidmap *uidmap)
{
- if (!_initDone)
+ if (uidmap->nameToNum == NULL)
return;
FILE *fh = NULL;
- if (_saveFileName != NULL) {
- fh = fopen(_saveFileName, "wb");
+ if (uidmap->fileName != NULL) {
+ fh = fopen(uidmap->fileName, "wb");
if (fh != NULL) {
if (fwrite(&MAGIC, sizeof(MAGIC), 1, fh) != 1) {
- plog(DEBUG_WARNING, "Cannot write magic to %s", _saveFileName);
+ plog(DEBUG_WARNING, "Cannot write magic to %s", uidmap->fileName);
fclose(fh);
fh = NULL;
}
}
}
const int64_t deadline = time(NULL) - MAX_AGE;
- struct hashmap_iter *it = hashmap_iter(&_nameToNum);
+ struct hashmap_iter *it = hashmap_iter(uidmap->nameToNum);
struct user *u = NULL;
int saved = 0, removed = 0;
uint16_t len;
while (it != NULL) {
u = name_hashmap_iter_get_data(it);
if (u->lastUse < deadline) {
- it = hashmap_iter_remove(&_nameToNum, it);
- if (number_hashmap_remove(&_numToName, &u->number) != u) {
+ it = hashmap_iter_remove(uidmap->nameToNum, it);
+ if (number_hashmap_remove(uidmap->numToName, &u->number) != u) {
plog(DEBUG_WARNING, "Could not remove user from numToName that was in nameToNum");
}
free(u);
@@ -242,14 +241,14 @@ void uidmap_cleanupSave()
|| fwrite(&u->number, sizeof(u->number), 1, fh) != 1
|| fwrite(u->name->s, len, 1, fh) != 1
) {
- plog(DEBUG_WARNING, "Could not write record to %s", _saveFileName);
+ plog(DEBUG_WARNING, "Could not write record to %s", uidmap->fileName);
fclose(fh);
fh = NULL;
} else {
saved++;
}
}
- it = hashmap_iter_next(&_nameToNum, it);
+ it = hashmap_iter_next(uidmap->nameToNum, it);
}
if (fh != NULL) {
fsync(fileno(fh));