f3727282cd80840f5e1e3ae2e63452516196cda5
[idzebra-moved-to-github.git] / util / passwddb.c
1 /* $Id: passwddb.c,v 1.11 2005-05-12 10:10:32 adam Exp $
2    Copyright (C) 1995-2005
3    Index Data ApS
4
5 This file is part of the Zebra server.
6
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra.  If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.
21 */
22
23
24 #if HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27
28 #include <string.h>
29 #include <stdio.h>
30
31 #if HAVE_CRYPT_H
32 #include <crypt.h>
33 #endif
34
35 #include <yaz/log.h>
36 #include <yaz/xmalloc.h>
37
38 #include <passwddb.h>
39
40 struct passwd_entry {
41     char *name;
42     char *des;
43     struct passwd_entry *next;
44 };
45
46 struct passwd_db {
47     struct passwd_entry *entries;
48 };
49
50 Passwd_db passwd_db_open (void)
51 {
52     struct passwd_db *p = (struct passwd_db *) xmalloc (sizeof(*p));
53     p->entries = 0;
54     return p;
55 }
56
57 static int get_entry (const char **p, char *dst, int max)
58 {       
59     int i = 0;
60     while ((*p)[i] != ':' && (*p)[i])
61         i++;
62     if (i >= max)
63         i = max-1;
64     if (i)
65         memcpy (dst, *p, i);
66     dst[i] = '\0';
67     *p += i;
68     if (*p)
69         (*p)++;
70     return i;
71 }
72
73 int passwd_db_file (Passwd_db db, const char *fname)
74 {
75     FILE *f;
76     char buf[1024];
77     f = fopen (fname, "r");
78     if (!f)
79         return -1;
80     while (fgets (buf, sizeof(buf)-1, f))
81     {
82         struct passwd_entry *pe;
83         char name[128];
84         char des[128];
85         char *p;
86         const char *cp = buf;
87         if ((p = strchr (buf, '\n')))
88             *p = '\0';
89         get_entry (&cp, name, 128);
90         get_entry (&cp, des, 128);
91
92         pe = (struct passwd_entry *) xmalloc (sizeof(*pe));
93         pe->name = xstrdup (name);
94         pe->des = xstrdup (des);
95         pe->next = db->entries;
96         db->entries = pe;
97     }
98     fclose (f);
99     return 0;
100 }
101
102 void passwd_db_close (Passwd_db db)
103 {
104     struct passwd_entry *pe = db->entries;
105     while (pe)
106     {
107         struct passwd_entry *pe_next = pe->next;
108         
109         xfree (pe->name);
110         xfree (pe->des);
111         xfree (pe);
112         pe = pe_next;
113     }
114     xfree (db);
115 }
116
117 void passwd_db_show (Passwd_db db)
118 {
119     struct passwd_entry *pe;
120     for (pe = db->entries; pe; pe = pe->next)
121         yaz_log (YLOG_LOG,"%s:%s", pe->name, pe->des);
122 }
123
124 int passwd_db_auth (Passwd_db db, const char *user, const char *pass)
125 {
126     struct passwd_entry *pe;
127 #if HAVE_CRYPT_H
128     char salt[3];
129     const char *des_try;
130 #endif
131     for (pe = db->entries; pe; pe = pe->next)
132         if (user && !strcmp (user, pe->name))
133             break;
134     if (!pe)
135         return -1;
136 #if HAVE_CRYPT_H
137     if (strlen (pe->des) < 3)
138         return -3;
139     if (!pass)
140         return -2;
141     memcpy (salt, pe->des, 2);
142     salt[2] = '\0';     
143     des_try = crypt (pass, salt);
144     if (strcmp (des_try, pe->des))
145         return -2;
146 #else
147     if (strcmp (pe->des, pass))
148         return -2;
149 #endif
150     return 0;   
151 }
152