1 /* callin.c
2 Check a login name and password against the UUCP password file.
3
4 Copyright (C) 1992, 1993, 1995, 2002 Ian Lance Taylor
5
6 This file is part of the Taylor UUCP uuconf library.
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public License
10 as published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21
22 The author of the program may be contacted at ian@airs.com.
23 */
24
25 #include "uucnfi.h"
26
27 #if USE_RCS_ID
28 const char _uuconf_callin_rcsid[] = "$FreeBSD$";
29 #endif
30
31 #include <errno.h>
32
33 static int ipcheck P((pointer pglobal, int argc, char **argv,
34 pointer pvar, pointer pinfo));
35
36 struct sinfo
37 {
38 int (*pcmpfn) P((int, pointer, const char *));
39 pointer pinfo;
40 boolean ffound;
41 boolean fmatched;
42 };
43
44 /* Check a login name and password against the UUCP password file.
45 This looks at the Taylor UUCP password file, but will work even if
46 uuconf_taylor_init was not called. It accepts either spaces or
47 colons as field delimiters. */
48
49 int
uuconf_callin(pglobal,pcmpfn,pinfo)50 uuconf_callin (pglobal, pcmpfn, pinfo)
51 pointer pglobal;
52 int (*pcmpfn) P((int, pointer, const char *));
53 pointer pinfo;
54 {
55 struct sglobal *qglobal = (struct sglobal *) pglobal;
56 int iret;
57 char **pz;
58 struct uuconf_cmdtab as[1];
59 struct sinfo s;
60 char *zline;
61 size_t cline;
62
63 /* If we have no password file names, fill in the default name. */
64 if (qglobal->qprocess->pzpwdfiles == NULL)
65 {
66 char ab[sizeof NEWCONFIGLIB + sizeof PASSWDFILE - 1];
67
68 memcpy ((pointer) ab, (pointer) NEWCONFIGLIB,
69 sizeof NEWCONFIGLIB - 1);
70 memcpy ((pointer) (ab + sizeof NEWCONFIGLIB - 1), (pointer) PASSWDFILE,
71 sizeof PASSWDFILE);
72 iret = _uuconf_iadd_string (qglobal, ab, TRUE, FALSE,
73 &qglobal->qprocess->pzpwdfiles,
74 qglobal->pblock);
75 if (iret != UUCONF_SUCCESS)
76 return iret;
77 }
78
79 as[0].uuconf_zcmd = NULL;
80
81 s.pcmpfn = pcmpfn;
82 s.pinfo = pinfo;
83 s.ffound = FALSE;
84 s.fmatched = FALSE;
85
86 zline = NULL;
87 cline = 0;
88
89 iret = UUCONF_SUCCESS;
90
91 for (pz = qglobal->qprocess->pzpwdfiles; *pz != NULL; pz++)
92 {
93 FILE *e;
94
95 e = fopen (*pz, "r");
96 if (e == NULL)
97 {
98 if (FNO_SUCH_FILE ())
99 continue;
100 qglobal->ierrno = errno;
101 iret = UUCONF_FOPEN_FAILED | UUCONF_ERROR_ERRNO;
102 break;
103 }
104
105 qglobal->ilineno = 0;
106
107 iret = UUCONF_SUCCESS;
108
109 while (getline (&zline, &cline, e) > 0)
110 {
111 char *z0, *z1;
112
113 ++qglobal->ilineno;
114
115 /* We have a few hacks to make Unix style passwd files work.
116 1) We turn the first two colon characters into spaces.
117 2) If the colon characters are adjacent, we assume there
118 is no password, and we skip the entry.
119 3) If the password between colon characters contains a
120 space, we assume that it has been disabled, and we
121 skip the entry. */
122 z0 = strchr (zline, ':');
123 if (z0 != NULL)
124 {
125 *z0 = ' ';
126 z1 = strchr (z0, ':');
127 if (z1 != NULL)
128 {
129 if (z1 - z0 == 1)
130 continue;
131 *z1 = '\0';
132 if (strchr (z0 + 1, ' ') != NULL)
133 continue;
134 }
135 }
136 iret = uuconf_cmd_line (pglobal, zline, as, (pointer) &s,
137 ipcheck, 0, (pointer) NULL);
138 if ((iret & UUCONF_CMDTABRET_EXIT) != 0)
139 {
140 iret &=~ UUCONF_CMDTABRET_EXIT;
141 if (iret != UUCONF_SUCCESS)
142 iret |= UUCONF_ERROR_LINENO;
143 break;
144 }
145
146 iret = UUCONF_SUCCESS;
147 }
148
149 (void) fclose (e);
150
151 if (iret != UUCONF_SUCCESS || s.ffound)
152 break;
153 }
154
155 if (zline != NULL)
156 free ((pointer) zline);
157
158 if (iret != UUCONF_SUCCESS)
159 {
160 qglobal->zfilename = *pz;
161 iret |= UUCONF_ERROR_FILENAME;
162 }
163 else if (! s.ffound || ! s.fmatched)
164 iret = UUCONF_NOT_FOUND;
165
166 return iret;
167 }
168
169 /* This is called on each line of the file. It checks to see if the
170 login name from the file is the one we are looking for. If it is,
171 it sets ffound, and then sets fmatched according to whether the
172 password matches or not. */
173
174 static int
ipcheck(pglobal,argc,argv,pvar,pinfo)175 ipcheck (pglobal, argc, argv, pvar, pinfo)
176 pointer pglobal ATTRIBUTE_UNUSED;
177 int argc;
178 char **argv;
179 pointer pvar ATTRIBUTE_UNUSED;
180 pointer pinfo;
181 {
182 struct sinfo *q = (struct sinfo *) pinfo;
183
184 if (argc != 2)
185 return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
186
187 if (! (*q->pcmpfn) (0, q->pinfo, argv[0]))
188 return UUCONF_CMDTABRET_CONTINUE;
189
190 q->ffound = TRUE;
191 q->fmatched = (*q->pcmpfn) (1, q->pinfo, argv[1]) != 0;
192
193 return UUCONF_CMDTABRET_EXIT;
194 }
195