Deleted Added
sdiff udiff text old ( 71348 ) new ( 90795 )
full compact
1/*
2 * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
4 * Copyright (c) 1992 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 *
12 */
13
14#include <sm/gen.h>
15
16SM_IDSTR(copyright,
17"@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\
18 All rights reserved.\n\
19 Copyright (c) 1992 Eric P. Allman. All rights reserved.\n\
20 Copyright (c) 1992, 1993\n\
21 The Regents of the University of California. All rights reserved.\n")
22
23SM_IDSTR(id, "@(#)$Id: makemap.c,v 8.175 2001/12/28 22:44:01 ca Exp $")
24
25/* $FreeBSD: head/contrib/sendmail/makemap/makemap.c 90795 2002-02-17 21:58:34Z gshapiro $ */
26
27#include <sys/types.h>
28#ifndef ISC_UNIX
29# include <sys/file.h>
30#endif /* ! ISC_UNIX */
31#include <ctype.h>
32#include <stdlib.h>
33#include <unistd.h>

--- 7 unchanged lines hidden (view full) ---

41
42uid_t RealUid;
43gid_t RealGid;
44char *RealUserName;
45uid_t RunAsUid;
46uid_t RunAsGid;
47char *RunAsUserName;
48int Verbose = 2;
49bool DontInitGroups = false;
50uid_t TrustedUid = 0;
51BITMAP256 DontBlameSendmail;
52
53#define BUFSIZE 1024
54#define ISSEP(c) (sep == '\0' ? isascii(c) && isspace(c) : (c) == sep)
55
56static void
57usage(progname)
58 char *progname;
59{
60 /* XXX break the usage output into multiple lines? it's too long */
61 sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
62 "Usage: %s [-C cffile] [-N] [-c cachesize] [-d] [-e] [-f] [-l] [-o] [-r] [-s] [-t delimiter] [-u] [-v] type mapname\n",
63 progname);
64#if _FFR_COMMENT_CHAR
65 /* add -D comment-char */
66#endif /* _FFR_COMMENT_CHAR */
67 exit(EX_USAGE);
68}
69
70int
71main(argc, argv)
72 int argc;
73 char **argv;
74{
75 char *progname;
76 char *cfile;
77 bool inclnull = false;
78 bool notrunc = false;
79 bool allowreplace = false;
80 bool allowempty = false;
81 bool verbose = false;
82 bool foldcase = true;
83 bool unmake = false;
84 char sep = '\0';
85 char comment = '#';
86 int exitstat;
87 int opt;
88 char *typename = NULL;
89 char *mapname = NULL;
90 unsigned int lineno;
91 int st;
92 int mode;
93 int smode;
94 int putflags = 0;
95 long sff = SFF_ROOTOK|SFF_REGONLY;
96 struct passwd *pw;
97 SMDB_DATABASE *database;
98 SMDB_CURSOR *cursor;
99 SMDB_DBENT db_key, db_val;
100 SMDB_DBPARAMS params;
101 SMDB_USER_INFO user_info;
102 char ibuf[BUFSIZE];
103#if HASFCHOWN
104 SM_FILE_T *cfp;
105 char buf[MAXLINE];
106#endif /* HASFCHOWN */
107 static char rnamebuf[MAXNAME]; /* holds RealUserName */
108 extern char *optarg;
109 extern int optind;
110
111 memset(&params, '\0', sizeof params);
112 params.smdbp_cache_size = 1024 * 1024;
113
114 progname = strrchr(argv[0], '/');
115 if (progname != NULL)
116 progname++;
117 else
118 progname = argv[0];
119 cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
120
121 clrbitmap(DontBlameSendmail);
122 RunAsUid = RealUid = getuid();
123 RunAsGid = RealGid = getgid();
124 pw = getpwuid(RealUid);
125 if (pw != NULL)
126 (void) sm_strlcpy(rnamebuf, pw->pw_name, sizeof rnamebuf);
127 else
128 (void) sm_snprintf(rnamebuf, sizeof rnamebuf,
129 "Unknown UID %d", (int) RealUid);
130 RunAsUserName = RealUserName = rnamebuf;
131 user_info.smdbu_id = RunAsUid;
132 user_info.smdbu_group_id = RunAsGid;
133 (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
134 SMDB_MAX_USER_NAME_LEN);
135
136#define OPTIONS "C:D:Nc:deflorst:uv"
137 while ((opt = getopt(argc, argv, OPTIONS)) != -1)
138 {
139 switch (opt)
140 {
141 case 'C':
142 cfile = optarg;
143 break;
144
145 case 'N':
146 inclnull = true;
147 break;
148
149 case 'c':
150 params.smdbp_cache_size = atol(optarg);
151 break;
152
153 case 'd':
154 params.smdbp_allow_dup = true;
155 break;
156
157 case 'e':
158 allowempty = true;
159 break;
160
161 case 'f':
162 foldcase = false;
163 break;
164
165#if _FFR_COMMENT_CHAR
166 case 'D':
167 comment = *optarg;
168 break;
169#endif /* _FFR_COMMENT_CHAR */
170
171 case 'l':
172 smdb_print_available_types();
173 exit(EX_OK);
174 break;
175
176 case 'o':
177 notrunc = true;
178 break;
179
180 case 'r':
181 allowreplace = true;
182 break;
183
184 case 's':
185 setbitn(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail);
186 setbitn(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail);
187 setbitn(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail);
188 setbitn(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail);
189 break;
190
191 case 't':
192 if (optarg == NULL || *optarg == '\0')
193 {
194 sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
195 "Invalid separator\n");
196 break;
197 }
198 sep = *optarg;
199 break;
200
201 case 'u':
202 unmake = true;
203 break;
204
205 case 'v':
206 verbose = true;
207 break;
208
209 default:
210 usage(progname);
211 /* NOTREACHED */
212 }
213 }
214

--- 14 unchanged lines hidden (view full) ---

229 else
230 {
231 typename = argv[0];
232 mapname = argv[1];
233 }
234
235#if HASFCHOWN
236 /* Find TrustedUser value in sendmail.cf */
237 if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY,
238 NULL)) == NULL)
239 {
240 sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "makemap: %s: %s",
241 cfile, sm_errstring(errno));
242 exit(EX_NOINPUT);
243 }
244 while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL)
245 {
246 register char *b;
247
248 if ((b = strchr(buf, '\n')) != NULL)
249 *b = '\0';
250
251 b = buf;
252 switch (*b++)

--- 9 unchanged lines hidden (view full) ---

262 continue;
263 if (isascii(*b) && isdigit(*b))
264 TrustedUid = atoi(b);
265 else
266 {
267 TrustedUid = 0;
268 pw = getpwnam(b);
269 if (pw == NULL)
270 (void) sm_io_fprintf(smioerr,
271 SM_TIME_DEFAULT,
272 "TrustedUser: unknown user %s\n", b);
273 else
274 TrustedUid = pw->pw_uid;
275 }
276
277# ifdef UID_MAX
278 if (TrustedUid > UID_MAX)
279 {
280 (void) sm_io_fprintf(smioerr,
281 SM_TIME_DEFAULT,
282 "TrustedUser: uid value (%ld) > UID_MAX (%ld)",
283 (long) TrustedUid,
284 (long) UID_MAX);
285 TrustedUid = 0;
286 }
287# endif /* UID_MAX */
288 break;
289 }
290
291
292 default:
293 continue;
294 }
295 }
296 (void) sm_io_close(cfp, SM_TIME_DEFAULT);
297#endif /* HASFCHOWN */
298
299 if (!params.smdbp_allow_dup && !allowreplace)
300 putflags = SMDBF_NO_OVERWRITE;
301
302 if (unmake)
303 {
304 mode = O_RDONLY;

--- 15 unchanged lines hidden (view full) ---

320 errno = smdb_open_database(&database, mapname, mode, smode, sff,
321 typename, &user_info, &params);
322 if (errno != SMDBE_OK)
323 {
324 char *hint;
325
326 if (errno == SMDBE_UNSUPPORTED_DB_TYPE &&
327 (hint = smdb_db_definition(typename)) != NULL)
328 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
329 "%s: Need to recompile with -D%s for %s support\n",
330 progname, hint, typename);
331 else
332 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
333 "%s: error opening type %s map %s: %s\n",
334 progname, typename, mapname,
335 sm_errstring(errno));
336 exit(EX_CANTCREAT);
337 }
338
339 (void) database->smdb_sync(database, 0);
340
341 if (!unmake && geteuid() == 0 && TrustedUid != 0)
342 {
343 errno = database->smdb_set_owner(database, TrustedUid, -1);
344 if (errno != SMDBE_OK)
345 {
346 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
347 "WARNING: ownership change on %s failed %s",
348 mapname, sm_errstring(errno));
349 }
350 }
351
352 /*
353 ** Copy the data
354 */
355
356 exitstat = EX_OK;
357 if (unmake)
358 {
359 errno = database->smdb_cursor(database, &cursor, 0);
360 if (errno != SMDBE_OK)
361 {
362
363 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
364 "%s: cannot make cursor for type %s map %s\n",
365 progname, typename, mapname);
366 exit(EX_SOFTWARE);
367 }
368
369 memset(&db_key, '\0', sizeof db_key);
370 memset(&db_val, '\0', sizeof db_val);
371
372 for (lineno = 0; ; lineno++)
373 {
374 errno = cursor->smdbc_get(cursor, &db_key, &db_val,
375 SMDB_CURSOR_GET_NEXT);
376 if (errno != SMDBE_OK)
377 break;
378
379 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
380 "%.*s\t%.*s\n",
381 (int) db_key.size,
382 (char *) db_key.data,
383 (int) db_val.size,
384 (char *)db_val.data);
385
386 }
387 (void) cursor->smdbc_close(cursor);
388 }
389 else
390 {
391 lineno = 0;
392 while (sm_io_fgets(smioin, SM_TIME_DEFAULT, ibuf, sizeof ibuf)
393 != NULL)
394 {
395 register char *p;
396
397 lineno++;
398
399 /*
400 ** Parse the line.
401 */
402
403 p = strchr(ibuf, '\n');
404 if (p != NULL)
405 *p = '\0';
406 else if (!sm_io_eof(smioin))
407 {
408 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
409 "%s: %s: line %u: line too long (%ld bytes max)\n",
410 progname, mapname, lineno,
411 (long) sizeof ibuf);
412 exitstat = EX_DATAERR;
413 continue;
414 }
415
416 if (ibuf[0] == '\0' || ibuf[0] == comment)
417 continue;
418 if (sep == '\0' && isascii(ibuf[0]) && isspace(ibuf[0]))
419 {
420 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
421 "%s: %s: line %u: syntax error (leading space)\n",
422 progname, mapname, lineno);
423 exitstat = EX_DATAERR;
424 continue;
425 }
426
427 memset(&db_key, '\0', sizeof db_key);
428 memset(&db_val, '\0', sizeof db_val);
429 db_key.data = ibuf;
430
431 for (p = ibuf; *p != '\0' && !(ISSEP(*p)); p++)
432 {
433 if (foldcase && isascii(*p) && isupper(*p))
434 *p = tolower(*p);
435 }
436 db_key.size = p - ibuf;
437 if (inclnull)
438 db_key.size++;
439
440 if (*p != '\0')
441 *p++ = '\0';
442 while (*p != '\0' && ISSEP(*p))
443 p++;
444 if (!allowempty && *p == '\0')
445 {
446 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
447 "%s: %s: line %u: no RHS for LHS %s\n",
448 progname, mapname, lineno,
449 (char *) db_key.data);
450 exitstat = EX_DATAERR;
451 continue;
452 }
453
454 db_val.data = p;
455 db_val.size = strlen(p);
456 if (inclnull)
457 db_val.size++;
458
459 /*
460 ** Do the database insert.
461 */
462
463 if (verbose)
464 {
465 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
466 "key=`%s', val=`%s'\n",
467 (char *) db_key.data,
468 (char *) db_val.data);
469 }
470
471 errno = database->smdb_put(database, &db_key, &db_val,
472 putflags);
473 switch (errno)
474 {
475 case SMDBE_KEY_EXIST:
476 st = 1;

--- 5 unchanged lines hidden (view full) ---

482
483 default:
484 st = -1;
485 break;
486 }
487
488 if (st < 0)
489 {
490 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
491 "%s: %s: line %u: key %s: put error: %s\n",
492 progname, mapname, lineno,
493 (char *) db_key.data,
494 sm_errstring(errno));
495 exitstat = EX_IOERR;
496 }
497 else if (st > 0)
498 {
499 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
500 "%s: %s: line %u: key %s: duplicate key\n",
501 progname, mapname,
502 lineno,
503 (char *) db_key.data);
504 exitstat = EX_DATAERR;
505 }
506 }
507 }
508
509 /*
510 ** Now close the database.
511 */
512
513 errno = database->smdb_close(database);
514 if (errno != SMDBE_OK)
515 {
516 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
517 "%s: close(%s): %s\n",
518 progname, mapname, sm_errstring(errno));
519 exitstat = EX_IOERR;
520 }
521 smdb_free_database(database);
522
523 exit(exitstat);
524
525 /* NOTREACHED */
526 return exitstat;
527}