f8ea25c05a9c0590581e482acc3e5896816c1c5b
[idzebra-moved-to-github.git] / util / passwddb.c
1 /* $Id: passwddb.c,v 1.9 2004-12-13 20:51:34 adam Exp $
2    Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
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 #ifdef WIN32
25 #else
26 #include <unistd.h>
27 #endif
28 #include <string.h>
29 #include <stdio.h>
30
31 #ifndef USE_CRYPT
32 #define USE_CRYPT 0
33 #endif
34
35 #if USE_CRYPT
36 #include <crypt.h>
37 #endif
38
39 #include <yaz/log.h>
40 #include <yaz/xmalloc.h>
41
42 #include <passwddb.h>
43
44 struct passwd_entry {
45         char *name;
46         char *des;
47         struct passwd_entry *next;
48 };
49
50 struct passwd_db {
51         struct passwd_entry *entries;
52 };
53
54 Passwd_db passwd_db_open (void)
55 {
56         struct passwd_db *p = (struct passwd_db *) xmalloc (sizeof(*p));
57         p->entries = 0;
58         return p;
59 }
60
61 static int get_entry (const char **p, char *dst, int max)
62 {       
63         int i = 0;
64         while ((*p)[i] != ':' && (*p)[i])
65                 i++;
66         if (i >= max)
67                 i = max-1;
68         if (i)
69                 memcpy (dst, *p, i);
70         dst[i] = '\0';
71         *p += i;
72         if (*p)
73                 (*p)++;
74         return i;
75 }
76
77 int passwd_db_file (Passwd_db db, const char *fname)
78 {
79         FILE *f;
80         char buf[1024];
81         f = fopen (fname, "r");
82         if (!f)
83                 return -1;
84         while (fgets (buf, sizeof(buf)-1, f))
85         {
86                 struct passwd_entry *pe;
87                 char name[128];
88                 char des[128];
89                 char *p;
90                 const char *cp = buf;
91                 if ((p = strchr (buf, '\n')))
92                         *p = '\0';
93                 get_entry (&cp, name, 128);
94                 get_entry (&cp, des, 128);
95
96                 pe = (struct passwd_entry *) xmalloc (sizeof(*pe));
97                 pe->name = xstrdup (name);
98                 pe->des = xstrdup (des);
99                 pe->next = db->entries;
100                 db->entries = pe;
101         }
102         fclose (f);
103         return 0;
104 }
105
106 void passwd_db_close (Passwd_db db)
107 {
108         struct passwd_entry *pe = db->entries;
109         while (pe)
110         {
111                 struct passwd_entry *pe_next = pe->next;
112         
113                 xfree (pe->name);
114                 xfree (pe->des);
115                 xfree (pe);
116                 pe = pe_next;
117         }
118         xfree (db);
119 }
120
121 void passwd_db_show (Passwd_db db)
122 {
123         struct passwd_entry *pe;
124         for (pe = db->entries; pe; pe = pe->next)
125                 yaz_log (YLOG_LOG,"%s:%s", pe->name, pe->des);
126 }
127
128 int passwd_db_auth (Passwd_db db, const char *user, const char *pass)
129 {
130         struct passwd_entry *pe;
131 #if USE_CRYPT
132         char salt[3];
133         const char *des_try;
134 #endif
135         for (pe = db->entries; pe; pe = pe->next)
136                 if (user && !strcmp (user, pe->name))
137                         break;
138         if (!pe)
139                 return -1;
140 #if USE_CRYPT
141         if (strlen (pe->des) < 3)
142                 return -3;
143         if (!pass)
144             return -2;
145         memcpy (salt, pe->des, 2);
146         salt[2] = '\0'; 
147         des_try = crypt (pass, salt);
148         if (strcmp (des_try, pe->des))
149                 return -2;
150 #else
151         if (strcmp (pe->des, pass))
152                 return -2;
153 #endif
154         return 0;       
155 }
156