aboutsummaryrefslogtreecommitdiffstats
path: root/src/usermap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/usermap.c')
-rw-r--r--src/usermap.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/usermap.c b/src/usermap.c
new file mode 100644
index 0000000..b900296
--- /dev/null
+++ b/src/usermap.c
@@ -0,0 +1,123 @@
+
+#include "usermap.h"
+#include "userinfo.h"
+#include <stdlib.h>
+
+struct UserMap {
+ uid_t *user_from;
+ uid_t *user_to;
+ gid_t *group_from;
+ gid_t *group_to;
+ int user_capacity;
+ int group_capacity;
+ int user_size;
+ int group_size;
+};
+
+UserMap *usermap_create()
+{
+ UserMap* map = (UserMap*)malloc(sizeof(UserMap));
+ map->user_from = NULL;
+ map->user_to = NULL;
+ map->group_from = NULL;
+ map->group_to = NULL;
+ map->user_capacity = 0;
+ map->group_capacity = 0;
+ map->user_size = 0;
+ map->group_size = 0;
+ return map;
+}
+
+void usermap_destroy(UserMap *map)
+{
+ free(map->user_from);
+ free(map->user_to);
+ free(map->group_from);
+ free(map->group_to);
+ free(map);
+}
+
+UsermapStatus usermap_add_uid(UserMap *map, uid_t from, uid_t to)
+{
+ int i;
+ if (from == to) {
+ return usermap_status_ok;
+ }
+ if (map->user_size == map->user_capacity) {
+ map->user_capacity *= 2;
+ map->user_from = (uid_t*)realloc(map->user_from, map->user_capacity * sizeof(uid_t));
+ map->user_to = (uid_t*)realloc(map->user_to, map->user_capacity * sizeof(uid_t));
+ }
+ if (usermap_get_uid(map, from) != from) {
+ return usermap_status_duplicate_key;
+ }
+ i = map->user_size;
+ map->user_from[i] = from;
+ map->user_to[i] = to;
+ map->user_size += 1;
+ return usermap_status_ok;
+}
+
+UsermapStatus usermap_add_gid(UserMap *map, gid_t from, gid_t to)
+{
+ int i;
+ if (from == to) {
+ return usermap_status_ok;
+ }
+ if (map->group_size == map->group_capacity) {
+ map->group_capacity *= 2;
+ map->group_from = (gid_t*)realloc(map->group_from, map->group_capacity * sizeof(gid_t));
+ map->group_to = (gid_t*)realloc(map->group_to, map->group_capacity * sizeof(gid_t));
+ }
+ if (usermap_get_gid(map, from) != from) {
+ return usermap_status_duplicate_key;
+ }
+ i = map->group_size;
+ map->group_from[i] = from;
+ map->group_to[i] = to;
+ map->group_size += 1;
+ return usermap_status_ok;
+}
+
+const char* usermap_errorstr(UsermapStatus status)
+{
+ switch (status) {
+ case usermap_status_ok: return "ok";
+ case usermap_status_duplicate_key: return "user mapped twice";
+ default: return "unknown error";
+ }
+}
+
+uid_t usermap_get_uid(UserMap *map, uid_t u)
+{
+ uid_t result = usermap_get_uid_or_none(map, u);
+ return (result != -1 ? result : u);
+}
+
+gid_t usermap_get_gid(UserMap *map, gid_t g)
+{
+ gid_t result = usermap_get_gid_or_none(map, g);
+ return (result != -1 ? result : g);
+}
+
+uid_t usermap_get_uid_or_none(UserMap *map, uid_t u)
+{
+ int i;
+ for (i = 0; i < map->user_size; ++i) {
+ if (map->user_from[i] == u) {
+ return map->user_to[i];
+ }
+ }
+ return -1;
+}
+
+gid_t usermap_get_gid_or_none(UserMap *map, gid_t g)
+{
+ int i;
+ for (i = 0; i < map->group_size; ++i) {
+ if (map->group_from[i] == g) {
+ return map->group_to[i];
+ }
+ }
+ return -1;
+}