source: trunk/athena/etc/mkcred/mkcred.c @ 13858

Revision 13858, 4.1 KB checked in by tb, 25 years ago (diff)
configure.in: Check for <db.h> and <ndbm.h>. Makefile.in: Include @DEFS@ in the compile commands. mkcred.c: Include the correct db header depending on configure test results.
Line 
1/* Copyright 1998 by the Massachusetts Institute of Technology.
2 *
3 * Permission to use, copy, modify, and distribute this
4 * software and its documentation for any purpose and without
5 * fee is hereby granted, provided that the above copyright
6 * notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting
8 * documentation, and that the name of M.I.T. not be used in
9 * advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission.
11 * M.I.T. makes no representations about the suitability of
12 * this software for any purpose.  It is provided "as is"
13 * without express or implied warranty.
14 */
15
16/* mkcred: used to compile credentials files for knfs mountd */
17
18static const char rcsid[] = "$Id: mkcred.c,v 1.2 1999-11-07 22:25:17 tb Exp $";
19
20#include <sys/param.h>
21#include <sys/types.h>
22#include <sys/fcntl.h>
23#include <sys/stat.h>
24#include <limits.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28
29#if defined (HAVE_DB_H) && !defined (HAVE_NDBM_H)
30#define DB_DBM_HSEARCH 1
31#include <db.h>
32#elif defined (HAVE_NDBM_H)
33#include <ndbm.h>
34#else
35#error Cannot find a suitable database header
36#endif
37
38void add_cred(DBM *db, char *str);
39int read_line(FILE *fp, char **buf, int *bufsize);
40
41int main(int argc, char **argv)
42{
43  FILE *f;
44  DBM *db;
45  char *line = NULL;
46  int bufsize, status;
47
48  if (argc != 2)
49    {
50      fprintf(stderr, "Usage: mkcred filename\n");
51      exit(1);
52    }
53
54  f = fopen(argv[1], "r");
55  if (!f)
56    {
57      fprintf(stderr, "mkcred: Can't open %s for reading\n", argv[1]);
58      exit(1);
59    }
60
61  db = dbm_open(argv[1], O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
62  if (!db)
63    {
64      fprintf(stderr, "mkcred: Can't create database files.\n");
65      exit(1);
66    }
67
68  while ((status = read_line(f, &line, &bufsize)) == 0)
69    add_cred(db, line);
70
71  dbm_close(db);
72
73  if (status == -1)
74    {
75      fprintf(stderr, "mkcred: Error reading input file.\n");
76      exit(1);
77    }
78
79  return 0;
80}
81
82struct ucred {
83  uid_t uid;
84  gid_t gid;
85  int glen;
86  gid_t gids[NGROUPS_MAX];
87};
88
89void add_cred(DBM *db, char *str)
90{
91  char *name, *p;
92  struct ucred u;
93  datum k, d;
94  int i;
95  int code;
96
97  name = strtok(str, ":");
98  if (!name)
99    goto err;
100  p = strtok(NULL, ":");
101  if (!p)
102    goto err;
103  u.uid = strtoul(p, &p, 10);
104  if (*p)
105    goto err;
106  p = strtok(NULL, ":");
107  if (!p)
108    goto err;
109  u.gid = strtoul(p, &p, 10);
110  if (*p)
111    goto err;
112
113  for(i = 0, p = strtok(NULL, ":"); i < NGROUPS_MAX && p; i++)
114    {     
115      u.gids[i] = strtoul(p, &p, 10);
116      if (*p)
117        goto err;
118      p = strtok(NULL, ":");
119    }
120
121  u.glen = i+1;
122
123  k.dptr = name;
124  k.dsize = strlen(name);
125  d.dptr = (char *) &u;
126  d.dsize = sizeof(u);
127  code = dbm_store(db, k, d, DBM_REPLACE);
128  if (code != 0)
129    {
130      fprintf(stderr, "mkcred: Could not store info for %s\n", name);
131      exit(1);
132    }
133  return;
134
135err:
136  fprintf(stderr, "mkcred: Error parsing entry '%s'\n", str);
137  exit(1);
138}
139
140/* read_line's contract is to read a line from a file into a
141 * dynamically allocated buffer, zeroing the trailing newline if there
142 * is one. The calling routine may call read_line multiple times with
143 * the same buf and bufsize pointers; *buf will be reallocated and
144 * *bufsize adjusted as appropriate. The initial value of *buf should
145 * be NULL. After the calling routine is done reading lines, it should
146 * free *buf. This function returns 0 if a line was successfully read,
147 * 1 if the file ended, and -1 if there was an I/O error or if it ran
148 * out of memory.
149 */
150
151int read_line(FILE *fp, char **buf, int *bufsize)
152{
153  char *newbuf;
154  int offset = 0, len;
155
156  if (*buf == NULL)
157    {
158      *buf = malloc(128);
159      if (!*buf)
160        return -1;
161      *bufsize = 128;
162    }
163
164  while (1)
165    {
166      if (!fgets(*buf + offset, *bufsize - offset, fp))
167        return (offset != 0) ? 0 : (ferror(fp)) ? -1 : 1;
168      len = offset + strlen(*buf + offset);
169      if ((*buf)[len - 1] == '\n')
170        {
171          (*buf)[len - 1] = 0;
172          return 0;
173        }
174      offset = len;
175
176      /* Allocate more space. */
177      newbuf = realloc(*buf, *bufsize * 2);
178      if (!newbuf)
179        return -1;
180      *buf = newbuf;
181      *bufsize *= 2;
182    }
183}
Note: See TracBrowser for help on using the repository browser.