2 * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
4 * Copyright (c) 1983 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
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.
17 "@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\
18 All rights reserved.\n\
19 Copyright (c) 1983 Eric P. Allman. All rights reserved.\n\
20 Copyright (c) 1988, 1993\n\
21 The Regents of the University of California. All rights reserved.\n")
23 SM_IDSTR(id
, "@(#)$Id: praliases.c,v 8.93 2001/09/11 04:05:07 gshapiro Exp $")
25 #include <sys/types.h>
30 # undef EX_OK /* unistd.h may have another use for this */
37 #endif /* ! NOT_SENDMAIL */
38 #include <sendmail/sendmail.h>
39 #include <sendmail/pathnames.h>
40 #include <libsmdb/smdb.h>
42 static void praliases
__P((char *, int, char **));
51 bool DontInitGroups
= false;
53 BITMAP256 DontBlameSendmail
;
55 # define DELIMITERS " ,/"
56 # define PATH_SEPARATOR ':'
64 char *filename
= NULL
;
67 char afilebuf
[MAXLINE
];
70 static char rnamebuf
[MAXNAME
];
74 clrbitmap(DontBlameSendmail
);
75 RunAsUid
= RealUid
= getuid();
76 RunAsGid
= RealGid
= getgid();
77 pw
= getpwuid(RealUid
);
80 if (strlen(pw
->pw_name
) > MAXNAME
- 1)
81 pw
->pw_name
[MAXNAME
] = 0;
82 sm_snprintf(rnamebuf
, sizeof rnamebuf
, "%s", pw
->pw_name
);
85 (void) sm_snprintf(rnamebuf
, sizeof rnamebuf
,
86 "Unknown UID %d", (int) RealUid
);
87 RunAsUserName
= RealUserName
= rnamebuf
;
89 cfile
= getcfname(0, 0, SM_GET_SENDMAIL_CF
, NULL
);
90 while ((ch
= getopt(argc
, argv
, "C:f:")) != -1)
101 (void) sm_io_fprintf(smioerr
, SM_TIME_DEFAULT
,
102 "usage: praliases [-C cffile] [-f aliasfile]\n");
109 if (filename
!= NULL
)
111 praliases(filename
, argc
, argv
);
115 if ((cfp
= sm_io_open(SmFtStdio
, SM_TIME_DEFAULT
, cfile
, SM_IO_RDONLY
,
118 (void) sm_io_fprintf(smioerr
, SM_TIME_DEFAULT
,
119 "praliases: %s: %s\n", cfile
,
120 sm_errstring(errno
));
124 while (sm_io_fgets(cfp
, SM_TIME_DEFAULT
, buf
, sizeof(buf
)) != NULL
)
126 register char *b
, *p
;
128 b
= strchr(buf
, '\n');
135 case 'O': /* option -- see if alias file */
136 if (sm_strncasecmp(b
, " AliasFile", 10) == 0 &&
137 !(isascii(b
[10]) && isalnum(b
[10])))
139 /* new form -- find value */
143 while (isascii(*++b
) && isspace(*b
))
146 else if (*b
++ != 'A')
148 /* something else boring */
152 /* this is the A or AliasFile option -- save it */
153 if (sm_strlcpy(afilebuf
, b
, sizeof afilebuf
) >=
156 (void) sm_io_fprintf(smioerr
, SM_TIME_DEFAULT
,
157 "praliases: AliasFile filename too long: %.30s\n",
159 (void) sm_io_close(cfp
, SM_TIME_DEFAULT
);
164 for (p
= b
; p
!= NULL
; )
166 while (isascii(*p
) && isspace(*p
))
172 p
= strpbrk(p
, DELIMITERS
);
174 /* find end of spec */
179 for (; *p
!= '\0'; p
++)
182 ** Don't break into a quoted
188 else if (*p
== ',' && !quoted
)
192 /* No more alias specs follow */
195 /* chop trailing whitespace */
196 while (isascii(*p
) &&
209 /* chop trailing whitespace */
210 while (isascii(*e
) &&
217 praliases(b
, argc
, argv
);
224 (void) sm_io_close(cfp
, SM_TIME_DEFAULT
);
231 praliases(filename
, argc
, argv
)
240 SMDB_DATABASE
*database
= NULL
;
241 SMDB_CURSOR
*cursor
= NULL
;
242 SMDB_DBENT db_key
, db_value
;
243 SMDB_DBPARAMS params
;
244 SMDB_USER_INFO user_info
;
246 colon
= strchr(filename
, PATH_SEPARATOR
);
250 db_type
= SMDB_TYPE_DEFAULT
;
259 /* clean off arguments */
262 while (isascii(*db_name
) && isspace(*db_name
))
267 while (*db_name
!= '\0' &&
268 !(isascii(*db_name
) && isspace(*db_name
)))
272 /* Skip non-file based DB types */
273 if (db_type
!= NULL
&& *db_type
!= '\0')
275 if (db_type
!= SMDB_TYPE_DEFAULT
&&
276 strcmp(db_type
, "hash") != 0 &&
277 strcmp(db_type
, "btree") != 0 &&
278 strcmp(db_type
, "dbm") != 0)
280 sm_io_fprintf(smioerr
, SM_TIME_DEFAULT
,
281 "praliases: Skipping non-file based alias type %s\n",
287 if (*db_name
== '\0' || (db_type
!= NULL
&& *db_type
== '\0'))
291 (void) sm_io_fprintf(smioerr
, SM_TIME_DEFAULT
,
292 "praliases: illegal alias specification: %s\n", filename
);
296 memset(¶ms
, '\0', sizeof params
);
297 params
.smdbp_cache_size
= 1024 * 1024;
299 user_info
.smdbu_id
= RunAsUid
;
300 user_info
.smdbu_group_id
= RunAsGid
;
301 (void) sm_strlcpy(user_info
.smdbu_name
, RunAsUserName
,
302 SMDB_MAX_USER_NAME_LEN
);
304 result
= smdb_open_database(&database
, db_name
, O_RDONLY
, 0,
305 SFF_ROOTOK
, db_type
, &user_info
, ¶ms
);
306 if (result
!= SMDBE_OK
)
308 sm_io_fprintf(smioerr
, SM_TIME_DEFAULT
,
309 "praliases: %s: open: %s\n",
310 db_name
, sm_errstring(result
));
316 memset(&db_key
, '\0', sizeof db_key
);
317 memset(&db_value
, '\0', sizeof db_value
);
319 result
= database
->smdb_cursor(database
, &cursor
, 0);
320 if (result
!= SMDBE_OK
)
322 (void) sm_io_fprintf(smioerr
, SM_TIME_DEFAULT
,
323 "praliases: %s: set cursor: %s\n", db_name
,
324 sm_errstring(result
));
328 while ((result
= cursor
->smdbc_get(cursor
, &db_key
, &db_value
,
329 SMDB_CURSOR_GET_NEXT
)) ==
333 /* skip magic @:@ entry */
334 if (db_key
.size
== 2 &&
335 db_key
.data
[0] == '@' &&
336 db_key
.data
[1] == '\0' &&
337 db_value
.size
== 2 &&
338 db_value
.data
[0] == '@' &&
339 db_value
.data
[1] == '\0')
343 (void) sm_io_fprintf(smioout
, SM_TIME_DEFAULT
,
346 (char *) db_key
.data
,
348 (char *) db_value
.data
);
351 if (result
!= SMDBE_OK
&& result
!= SMDBE_LAST_ENTRY
)
353 (void) sm_io_fprintf(smioerr
, SM_TIME_DEFAULT
,
354 "praliases: %s: get value at cursor: %s\n",
355 db_name
, sm_errstring(result
));
359 else for (; *argv
!= NULL
; ++argv
)
363 memset(&db_key
, '\0', sizeof db_key
);
364 memset(&db_value
, '\0', sizeof db_value
);
366 db_key
.size
= strlen(*argv
);
367 get_res
= database
->smdb_get(database
, &db_key
, &db_value
, 0);
368 if (get_res
== SMDBE_NOT_FOUND
)
371 get_res
= database
->smdb_get(database
, &db_key
,
374 if (get_res
== SMDBE_OK
)
376 (void) sm_io_fprintf(smioout
, SM_TIME_DEFAULT
,
379 (char *) db_key
.data
,
381 (char *) db_value
.data
);
384 (void) sm_io_fprintf(smioout
, SM_TIME_DEFAULT
,
386 (char *)db_key
.data
);
391 (void) cursor
->smdbc_close(cursor
);
392 if (database
!= NULL
)
393 (void) database
->smdb_close(database
);