]> err.no Git - backuppcd/blob - backuppcd-auth.c
Import gnulib stuff
[backuppcd] / backuppcd-auth.c
1 #include "compat.h"
2 #include <stdio.h>
3 #include "backuppcd-auth.h"
4
5 struct bpcd_auth_userinfo;
6 struct bpcd_auth_userinfo {
7         const char *username;
8         const char *passhash;
9         backuppc_privs_t privs;
10         struct bpcd_auth_userinfo *_next;
11 };
12
13 struct bpcd_auth_userinfo *userlist = NULL;
14
15 #ifdef HAVE_LIBCONFIG
16 static int bpcd_auth_opt_user(const char *shortvar, const char *var, const char *arguments, const char *value, lc_flags_t flags, void *extra) {
17         struct bpcd_auth_userinfo *newnode;
18         char *valcopy_s, *valcopy;
19         char *privstr;
20
21         newnode = malloc(sizeof(*newnode));
22         if (newnode == NULL) {
23                 return -1;
24         }
25
26         valcopy_s = valcopy = strdup(value);
27
28         newnode->username = strsep(&valcopy, " ,\t");
29         if (newnode->username == NULL) {
30                 free(valcopy_s);
31                 free(newnode);
32                 fprintf(stderr, "error: usage: USER <Username> <Password> <Privilegs>\n");
33                 return -1;
34         }
35
36         newnode->passhash = strsep(&valcopy, " ,\t");
37         if (newnode->passhash == NULL) {
38                 free(valcopy_s);
39                 free(newnode);
40                 fprintf(stderr, "error: usage: USER <Username> <Password> <Privilegs>\n");
41                 return -1;
42         }
43
44         privstr = strsep(&valcopy, " ,\t");
45         if (privstr == NULL) {
46                 free(valcopy_s);
47                 free(newnode);
48                 fprintf(stderr, "error: usage: USER <Username> <Password> <Privilegs>\n");
49                 return -1;
50         }
51
52         if (strlen(newnode->passhash) != 40) {
53                 free(valcopy_s);
54                 free(newnode);
55                 fprintf(stderr, "error: Password hash must be exactly 40 charectars long.\n");
56                 return -1;
57         }
58
59         if (strcasecmp(privstr, "Read") == 0) {
60                 newnode->privs = BPC_PRIV_READ;
61         } else if (strcasecmp(privstr, "Write") == 0) {
62                 newnode->privs = BPC_PRIV_WRITE;
63         } else if (strcasecmp(privstr, "ReadWrite") == 0) {
64                 newnode->privs = BPC_PRIV_RDWR;
65         } else if (strcasecmp(privstr, "RD") == 0) {
66                 newnode->privs = BPC_PRIV_READ;
67         } else if (strcasecmp(privstr, "WR") == 0) {
68                 newnode->privs = BPC_PRIV_WRITE;
69         } else if (strcasecmp(privstr, "RDWR") == 0) {
70                 newnode->privs = BPC_PRIV_RDWR;
71         } else if (strcasecmp(privstr, "r") == 0) {
72                 newnode->privs = BPC_PRIV_READ;
73         } else if (strcasecmp(privstr, "w") == 0) {
74                 newnode->privs = BPC_PRIV_WRITE;
75         } else if (strcasecmp(privstr, "rw") == 0) {
76                 newnode->privs = BPC_PRIV_RDWR;
77         } else {
78                 free(valcopy_s);
79                 free(newnode);
80                 fprintf(stderr, "error: usage: Privileges must be one of: READ, WRITE, or READWRITE\n");
81                 return -1
82         }
83
84         newnode->_next = userlist;
85         userlist = newnode;
86
87         return 0;
88 }
89 #endif
90
91 void bpcd_auth_init(void) {
92 #ifdef HAVE_LIBCONFIG
93         lc_register_callback("User", 'u', LC_VAR_STRING, bpcd_auth_opt_user, NULL);
94 #endif
95         return;
96 }
97
98 backuppc_privs_t bpcd_auth_verify(const char *username, const char *passhash, uint32_t address) {
99         struct bpcd_auth_userinfo *tmp;
100
101         for (tmp = userlist; tmp; tmp = tmp->_next) {
102
103                 /*
104                  * Should the username be case-sensitive ? (XXX)
105                  */
106                 if (strcasecmp(tmp->username, username) == 0) {
107                         if (strcasecmp(tmp->passhash, passhash) == 0) {
108                                 return(tmp->privs);
109                         } else {
110                                 return(BPC_PRIV_ERROR);
111                         }
112                 }
113         }
114
115         return(BPC_PRIV_ERROR);
116 }