Added authentication check facility to zebra.
[idzebra-moved-to-github.git] / util / passwddb.c
1
2 #include <unistd.h>
3 #include <string.h>
4 #include <stdio.h>
5
6 #if USE_CRYPT
7 #include <crypt.h>
8 #endif
9
10 #include <log.h>
11 #include <xmalloc.h>
12
13 #include <passwddb.h>
14
15 struct passwd_entry {
16         char *name;
17         char *des;
18         struct passwd_entry *next;
19 };
20
21 struct passwd_db {
22         struct passwd_entry *entries;
23 };
24
25 Passwd_db passwd_db_open (void)
26 {
27         struct passwd_db *p = xmalloc (sizeof(*p));
28         p->entries = 0;
29         return p;
30 }
31
32 static int get_entry (const char **p, char *dst, int max)
33 {       
34         int i = 0;
35         while ((*p)[i] != ':' && (*p)[i])
36                 i++;
37         if (i >= max)
38                 i = max-1;
39         if (i)
40                 memcpy (dst, *p, i);
41         dst[i] = '\0';
42         *p += i;
43         if (*p)
44                 (*p)++;
45         return i;
46 }
47
48 int passwd_db_file (Passwd_db db, const char *fname)
49 {
50         FILE *f;
51         char buf[1024];
52         f = fopen (fname, "r");
53         if (!f)
54                 return -1;
55         while (fgets (buf, sizeof(buf)-1, f))
56         {
57                 struct passwd_entry *pe;
58                 char name[128];
59                 char des[128];
60                 char *p;
61                 const char *cp = buf;
62                 if ((p = strchr (buf, '\n')))
63                         *p = '\0';
64                 get_entry (&cp, name, 128);
65                 get_entry (&cp, des, 128);
66
67                 pe = xmalloc (sizeof(*pe));
68                 pe->name = xstrdup (name);
69                 pe->des = xstrdup (des);
70                 pe->next = db->entries;
71                 db->entries = pe;
72         }
73         fclose (f);
74         return 0;
75 }
76
77 void passwd_db_close (Passwd_db db)
78 {
79         struct passwd_entry *pe = db->entries;
80         while (pe)
81         {
82                 struct passwd_entry *pe_next = pe->next;
83         
84                 xfree (pe->name);
85                 xfree (pe->des);
86                 xfree (pe);
87                 pe = pe_next;
88         }
89         xfree (db);
90 }
91
92 void passwd_db_show (Passwd_db db)
93 {
94         struct passwd_entry *pe;
95         for (pe = db->entries; pe; pe = pe->next)
96                 logf (LOG_LOG,"%s:%s", pe->name, pe->des);
97 }
98
99 int passwd_db_auth (Passwd_db db, const char *user, const char *pass)
100 {
101         struct passwd_entry *pe;
102 #if USE_CRYPT
103         char salt[3];
104         const char *des_try;
105 #endif
106         for (pe = db->entries; pe; pe = pe->next)
107                 if (user && !strcmp (user, pe->name))
108                         break;
109         if (!pe)
110                 return -1;
111 #if USE_CRYPT
112         if (strlen (pe->des) < 3)
113                 return -3;
114         if (!pass)
115             return -2;
116         memcpy (salt, pe->des, 2);
117         salt[2] = '\0'; 
118         des_try = crypt (pass, salt);
119         if (strcmp (des_try, pe->des))
120                 return -2;
121 #else
122         if (strcmp (pe->des, pass))
123                 return -2;
124 #endif
125         return 0;       
126 }
127