|
|
1.1 root 1: /* rdperm.c
2: Read the HDB Permissions file.
3:
4: Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA.
21:
22: The author of the program may be contacted at [email protected] or
23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
24: */
25:
26: #include "uucnfi.h"
27:
28: #if USE_RCS_ID
29: const char _uuconf_rdperm_rcsid[] = "$Id: rdperm.c,v 1.1 93/07/30 08:07:29 bin Exp Locker: bin $";
30: #endif
31:
32: #include <errno.h>
33: #include <ctype.h>
34:
35: static int ihcolon P((pointer pglobal, int argc, char **argv, pointer pvar,
36: pointer pinfo));
37: static int ihsendfiles P((pointer pglobal, int argc, char **argv,
38: pointer pvar, pointer pinfo));
39: static int ihunknownperm P((pointer pglobal, int argc, char **argv,
40: pointer pvar, pointer pinfo));
41: static int ihadd_norw P((struct sglobal *qglobal, char ***ppz, char **pzno));
42:
43: /* These routines reads in the HDB Permissions file. We store the
44: entries in a linked list of shpermissions structures, so we only
45: have to actually read the file once. */
46:
47: /* This command table and static structure are used to parse a line
48: from Permissions. The entries are parsed as follows:
49:
50: Multiple strings separated by colons: LOGNAME, MACHINE, READ,
51: WRITE, NOREAD, NOWRITE, COMMANDS, VALIDATE, ALIAS.
52:
53: Boolean values: REQUEST, CALLBACK.
54:
55: Simple strings: MYNAME, PUBDIR.
56:
57: "Yes" or "call": SENDFILES.
58:
59: The NOREAD and NOWRITE entries are merged into the READ and WRITE
60: entries, rather than being permanently stored. They are handled
61: specially in the uuconf_cmdtab table. */
62:
63: static const struct cmdtab_offset asHperm_cmds[] =
64: {
65: { "NOREAD", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, ihcolon },
66: { "NOWRITE", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, ihcolon },
67: { "LOGNAME", UUCONF_CMDTABTYPE_FN | 2,
68: offsetof (struct shpermissions, pzlogname), ihcolon },
69: { "MACHINE", UUCONF_CMDTABTYPE_FN | 2,
70: offsetof (struct shpermissions, pzmachine), ihcolon },
71: { "REQUEST", UUCONF_CMDTABTYPE_BOOLEAN,
72: offsetof (struct shpermissions, frequest), NULL },
73: { "SENDFILES", UUCONF_CMDTABTYPE_FN | 2,
74: offsetof (struct shpermissions, fsendfiles), ihsendfiles },
75: { "READ", UUCONF_CMDTABTYPE_FN | 2,
76: offsetof (struct shpermissions, pzread), ihcolon },
77: { "WRITE", UUCONF_CMDTABTYPE_FN | 2,
78: offsetof (struct shpermissions, pzwrite), ihcolon },
79: { "CALLBACK", UUCONF_CMDTABTYPE_BOOLEAN,
80: offsetof (struct shpermissions, fcallback), NULL },
81: { "COMMANDS", UUCONF_CMDTABTYPE_FN | 2,
82: offsetof (struct shpermissions, pzcommands), ihcolon },
83: { "VALIDATE", UUCONF_CMDTABTYPE_FN | 2,
84: offsetof (struct shpermissions, pzvalidate), ihcolon },
85: { "MYNAME", UUCONF_CMDTABTYPE_STRING,
86: offsetof (struct shpermissions, zmyname), NULL },
87: { "PUBDIR", UUCONF_CMDTABTYPE_STRING,
88: offsetof (struct shpermissions, zpubdir), NULL },
89: { "ALIAS", UUCONF_CMDTABTYPE_FN | 2,
90: offsetof (struct shpermissions, pzalias), ihcolon },
91: { NULL, 0, 0, NULL }
92: };
93:
94: #define CHPERM_CMDS (sizeof asHperm_cmds / sizeof asHperm_cmds[0])
95:
96: /* Actually read the Permissions file into a linked list of
97: structures. */
98:
99: int
100: _uuconf_ihread_permissions (qglobal)
101: struct sglobal *qglobal;
102: {
103: char *zperm;
104: FILE *e;
105: int iret;
106: struct uuconf_cmdtab as[CHPERM_CMDS];
107: char **pznoread, **pznowrite;
108: struct shpermissions shperm;
109: char *zline;
110: size_t cline;
111: char **pzsplit;
112: size_t csplit;
113: int cchars;
114: struct shpermissions *qlist, **pq;
115:
116: if (qglobal->qprocess->fhdb_read_permissions)
117: return UUCONF_SUCCESS;
118:
119: zperm = (char *) uuconf_malloc (qglobal->pblock,
120: (sizeof OLDCONFIGLIB
121: + sizeof HDB_PERMISSIONS - 1));
122: if (zperm == NULL)
123: {
124: qglobal->ierrno = errno;
125: return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
126: }
127:
128: memcpy ((pointer) zperm, (pointer) OLDCONFIGLIB,
129: sizeof OLDCONFIGLIB - 1);
130: memcpy ((pointer) (zperm + sizeof OLDCONFIGLIB - 1),
131: (pointer) HDB_PERMISSIONS, sizeof HDB_PERMISSIONS);
132:
133: e = fopen (zperm, "r");
134: if (e == NULL)
135: {
136: uuconf_free (qglobal->pblock, zperm);
137: qglobal->qprocess->fhdb_read_permissions = TRUE;
138: return UUCONF_SUCCESS;
139: }
140:
141: _uuconf_ucmdtab_base (asHperm_cmds, CHPERM_CMDS, (char *) &shperm, as);
142: as[0].uuconf_pvar = (pointer) &pznoread;
143: as[1].uuconf_pvar = (pointer) &pznowrite;
144:
145: zline = NULL;
146: cline = 0;
147: pzsplit = NULL;
148: csplit = 0;
149:
150: qlist = NULL;
151: pq = &qlist;
152:
153: qglobal->ilineno = 0;
154:
155: iret = UUCONF_SUCCESS;
156:
157: while ((cchars = _uuconf_getline (qglobal, &zline, &cline, e)) > 0)
158: {
159: int centries;
160: struct shpermissions *qnew;
161: int i;
162:
163: ++qglobal->ilineno;
164:
165: --cchars;
166: if (zline[cchars] == '\n')
167: zline[cchars] = '\0';
168: if (isspace (BUCHAR (zline[0])) || zline[0] == '#')
169: continue;
170:
171: centries = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit);
172: if (centries < 0)
173: {
174: qglobal->ierrno = errno;
175: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
176: break;
177: }
178:
179: if (centries == 0)
180: continue;
181:
182: shperm.pzlogname = (char **) &_uuconf_unset;
183: shperm.pzmachine = (char **) &_uuconf_unset;
184: shperm.frequest = -1;
185: shperm.fsendfiles = -1;
186: shperm.pzread = (char **) &_uuconf_unset;
187: shperm.pzwrite = (char **) &_uuconf_unset;
188: shperm.fcallback = -1;
189: shperm.pzcommands = (char **) &_uuconf_unset;
190: shperm.pzvalidate = (char **) &_uuconf_unset;
191: shperm.zmyname = (char *) &_uuconf_unset;
192: shperm.zpubdir = (char *) &_uuconf_unset;
193: shperm.pzalias = (char **) &_uuconf_unset;
194: pznoread = (char **) &_uuconf_unset;
195: pznowrite = (char **) &_uuconf_unset;
196:
197: for (i = 0; i < centries; i++)
198: {
199: char *zeq;
200: char *azargs[2];
201:
202: zeq = strchr (pzsplit[i], '=');
203: if (zeq == NULL)
204: {
205: iret = UUCONF_SYNTAX_ERROR;
206: qglobal->qprocess->fhdb_read_permissions = TRUE;
207: break;
208: }
209: *zeq = '\0';
210:
211: azargs[0] = pzsplit[i];
212: azargs[1] = zeq + 1;
213:
214: iret = uuconf_cmd_args (qglobal, 2, azargs, as, (pointer) NULL,
215: ihunknownperm, 0, qglobal->pblock);
216: if ((iret & UUCONF_CMDTABRET_KEEP) != 0)
217: {
218: iret &=~ UUCONF_CMDTABRET_KEEP;
219:
220: if (uuconf_add_block (qglobal->pblock, zline) != 0)
221: {
222: qglobal->ierrno = errno;
223: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
224: break;
225: }
226:
227: zline = NULL;
228: cline = 0;
229: }
230: if ((iret & UUCONF_CMDTABRET_EXIT) != 0)
231: {
232: iret &=~ UUCONF_CMDTABRET_EXIT;
233: break;
234: }
235: }
236:
237: if (iret != UUCONF_SUCCESS)
238: break;
239:
240: if (shperm.pzmachine == (char **) &_uuconf_unset
241: && shperm.pzlogname == (char **) &_uuconf_unset)
242: {
243: iret = UUCONF_SYNTAX_ERROR;
244: qglobal->qprocess->fhdb_read_permissions = TRUE;
245: break;
246: }
247:
248: /* Attach any NOREAD or NOWRITE entries to the corresponding
249: READ or WRITE entries in the format expected for the
250: pzlocal_receive, etc., fields in uuconf_system. */
251: if (pznoread != NULL)
252: {
253: iret = ihadd_norw (qglobal, &shperm.pzread, pznoread);
254: if (iret != UUCONF_SUCCESS)
255: break;
256: uuconf_free (qglobal->pblock, pznoread);
257: }
258:
259: if (pznowrite != NULL)
260: {
261: iret = ihadd_norw (qglobal, &shperm.pzwrite, pznowrite);
262: if (iret != UUCONF_SUCCESS)
263: break;
264: uuconf_free (qglobal->pblock, pznowrite);
265: }
266:
267: qnew = ((struct shpermissions *)
268: uuconf_malloc (qglobal->pblock,
269: sizeof (struct shpermissions)));
270: if (qnew == NULL)
271: {
272: qglobal->ierrno = errno;
273: iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
274: break;
275: }
276:
277: *qnew = shperm;
278: *pq = qnew;
279: pq = &qnew->qnext;
280: *pq = NULL;
281: }
282:
283: (void) fclose (e);
284:
285: if (zline != NULL)
286: free ((pointer) zline);
287: if (pzsplit != NULL)
288: free ((pointer) pzsplit);
289:
290: if (iret == UUCONF_SUCCESS)
291: {
292: qglobal->qprocess->qhdb_permissions = qlist;
293: qglobal->qprocess->fhdb_read_permissions = TRUE;
294: }
295: else
296: {
297: qglobal->zfilename = zperm;
298: iret |= UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
299: }
300:
301: return iret;
302: }
303:
304: /* Split the argument into colon separated strings, and assign a NULL
305: terminated array of strings to pvar. */
306:
307: /*ARGSUSED*/
308: static int
309: ihcolon (pglobal, argc, argv, pvar, pinfo)
310: pointer pglobal;
311: int argc;
312: char **argv;
313: pointer pvar;
314: pointer pinfo;
315: {
316: struct sglobal *qglobal = (struct sglobal *) pglobal;
317: char ***ppz = (char ***) pvar;
318: char **pzsplit;
319: size_t csplit;
320: int centries;
321: int i;
322: int iret;
323:
324: *ppz = NULL;
325:
326: pzsplit = NULL;
327: csplit = 0;
328:
329: centries = _uuconf_istrsplit (argv[1], ':', &pzsplit, &csplit);
330: if (centries < 0)
331: {
332: qglobal->ierrno = errno;
333: return (UUCONF_MALLOC_FAILED
334: | UUCONF_ERROR_ERRNO
335: | UUCONF_CMDTABRET_EXIT);
336: }
337:
338: if (centries == 0)
339: {
340: if (pzsplit != NULL)
341: free ((pointer) pzsplit);
342: return UUCONF_CMDTABRET_CONTINUE;
343: }
344:
345: iret = UUCONF_SUCCESS;
346:
347: for (i = 0; i < centries; i++)
348: {
349: iret = _uuconf_iadd_string (qglobal, pzsplit[i], FALSE, FALSE,
350: ppz, qglobal->pblock);
351: if (iret != UUCONF_SUCCESS)
352: {
353: iret |= UUCONF_CMDTABRET_EXIT;
354: break;
355: }
356: }
357:
358: free ((pointer) pzsplit);
359:
360: return UUCONF_CMDTABRET_KEEP;
361: }
362:
363: /* Handle the SENDFILES parameter, which can take "yes" or "call" or
364: "no" as an argument. The string "call" is equivalent to "no". */
365:
366: /*ARGSUSED*/
367: static int
368: ihsendfiles (pglobal, argc, argv, pvar, pinfo)
369: pointer pglobal;
370: int argc;
371: char **argv;
372: pointer pvar;
373: pointer pinfo;
374: {
375: int *pi = (int *) pvar;
376:
377: switch (argv[1][0])
378: {
379: case 'C':
380: case 'c':
381: case 'N':
382: case 'n':
383: *pi = FALSE;
384: break;
385: case 'Y':
386: case 'y':
387: *pi = TRUE;
388: break;
389: default:
390: return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
391: }
392:
393: return UUCONF_CMDTABRET_CONTINUE;
394: }
395:
396: /* If there is an unknown Permissions entry, return a syntax error.
397: This should probably be more clever. */
398:
399: /*ARGSUSED*/
400: static int
401: ihunknownperm (pglobal, argc, argv, pvar, pinfo)
402: pointer pglobal;
403: int argc;
404: char **argv;
405: pointer pvar;
406: pointer pinfo;
407: {
408: return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
409: }
410:
411: /* Add a NOREAD or NOWRITE entry to a READ or WRITE entry. */
412:
413: static int
414: ihadd_norw (qglobal, ppz, pzno)
415: struct sglobal *qglobal;
416: char ***ppz;
417: char **pzno;
418: {
419: register char **pz;
420:
421: if (pzno == (char **) &_uuconf_unset)
422: return UUCONF_SUCCESS;
423:
424: for (pz = pzno; *pz != NULL; pz++)
425: {
426: size_t csize;
427: char *znew;
428: int iret;
429:
430: csize = strlen (*pz) + 1;
431: znew = (char *) uuconf_malloc (qglobal->pblock, csize + 1);
432: if (znew == NULL)
433: {
434: qglobal->ierrno = errno;
435: return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
436: }
437: znew[0] = '!';
438: memcpy ((pointer) (znew + 1), (pointer) *pz, csize);
439: iret = _uuconf_iadd_string (qglobal, znew, FALSE, FALSE, ppz,
440: qglobal->pblock);
441: if (iret != UUCONF_SUCCESS)
442: return iret;
443: }
444:
445: return UUCONF_SUCCESS;
446: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.