24 25#include <sys/types.h> 26#include <ctype.h> 27#include <stdlib.h> 28#include <unistd.h> 29#ifdef EX_OK 30# undef EX_OK /* unistd.h may have another use for this */ 31#endif /* EX_OK */ 32#include <sysexits.h> 33 34 35#ifndef NOT_SENDMAIL 36# define NOT_SENDMAIL 37#endif /* ! NOT_SENDMAIL */ 38#include <sendmail/sendmail.h> 39#include <sendmail/pathnames.h> 40#include <libsmdb/smdb.h> 41 42static void praliases __P((char *, int, char **)); 43 44uid_t RealUid; 45gid_t RealGid; 46char *RealUserName; 47uid_t RunAsUid; 48gid_t RunAsGid; 49char *RunAsUserName; 50int Verbose = 2; 51bool DontInitGroups = false; 52uid_t TrustedUid = 0; 53BITMAP256 DontBlameSendmail; 54 55# define DELIMITERS " ,/" 56# define PATH_SEPARATOR ':' 57 58int 59main(argc, argv) 60 int argc; 61 char **argv; 62{ 63 char *cfile; 64 char *filename = NULL; 65 SM_FILE_T *cfp; 66 int ch; 67 char afilebuf[MAXLINE]; 68 char buf[MAXLINE]; 69 struct passwd *pw; 70 static char rnamebuf[MAXNAME]; 71 extern char *optarg; 72 extern int optind; 73 74 clrbitmap(DontBlameSendmail); 75 RunAsUid = RealUid = getuid(); 76 RunAsGid = RealGid = getgid(); 77 pw = getpwuid(RealUid); 78 if (pw != NULL) 79 { 80 if (strlen(pw->pw_name) > MAXNAME - 1) 81 pw->pw_name[MAXNAME] = 0; 82 sm_snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name); 83 } 84 else 85 (void) sm_snprintf(rnamebuf, sizeof rnamebuf, 86 "Unknown UID %d", (int) RealUid); 87 RunAsUserName = RealUserName = rnamebuf; 88 89 cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL); 90 while ((ch = getopt(argc, argv, "C:f:")) != -1) 91 { 92 switch ((char)ch) { 93 case 'C': 94 cfile = optarg; 95 break; 96 case 'f': 97 filename = optarg; 98 break; 99 case '?': 100 default: 101 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 102 "usage: praliases [-C cffile] [-f aliasfile]" 103 " [key ...]\n"); 104 exit(EX_USAGE); 105 } 106 } 107 argc -= optind; 108 argv += optind; 109 110 if (filename != NULL) 111 { 112 praliases(filename, argc, argv); 113 exit(EX_OK); 114 } 115 116 if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY, 117 NULL)) == NULL) 118 { 119 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 120 "praliases: %s: %s\n", cfile, 121 sm_errstring(errno)); 122 exit(EX_NOINPUT); 123 } 124
| 24 25#include <sys/types.h> 26#include <ctype.h> 27#include <stdlib.h> 28#include <unistd.h> 29#ifdef EX_OK 30# undef EX_OK /* unistd.h may have another use for this */ 31#endif /* EX_OK */ 32#include <sysexits.h> 33 34 35#ifndef NOT_SENDMAIL 36# define NOT_SENDMAIL 37#endif /* ! NOT_SENDMAIL */ 38#include <sendmail/sendmail.h> 39#include <sendmail/pathnames.h> 40#include <libsmdb/smdb.h> 41 42static void praliases __P((char *, int, char **)); 43 44uid_t RealUid; 45gid_t RealGid; 46char *RealUserName; 47uid_t RunAsUid; 48gid_t RunAsGid; 49char *RunAsUserName; 50int Verbose = 2; 51bool DontInitGroups = false; 52uid_t TrustedUid = 0; 53BITMAP256 DontBlameSendmail; 54 55# define DELIMITERS " ,/" 56# define PATH_SEPARATOR ':' 57 58int 59main(argc, argv) 60 int argc; 61 char **argv; 62{ 63 char *cfile; 64 char *filename = NULL; 65 SM_FILE_T *cfp; 66 int ch; 67 char afilebuf[MAXLINE]; 68 char buf[MAXLINE]; 69 struct passwd *pw; 70 static char rnamebuf[MAXNAME]; 71 extern char *optarg; 72 extern int optind; 73 74 clrbitmap(DontBlameSendmail); 75 RunAsUid = RealUid = getuid(); 76 RunAsGid = RealGid = getgid(); 77 pw = getpwuid(RealUid); 78 if (pw != NULL) 79 { 80 if (strlen(pw->pw_name) > MAXNAME - 1) 81 pw->pw_name[MAXNAME] = 0; 82 sm_snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name); 83 } 84 else 85 (void) sm_snprintf(rnamebuf, sizeof rnamebuf, 86 "Unknown UID %d", (int) RealUid); 87 RunAsUserName = RealUserName = rnamebuf; 88 89 cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL); 90 while ((ch = getopt(argc, argv, "C:f:")) != -1) 91 { 92 switch ((char)ch) { 93 case 'C': 94 cfile = optarg; 95 break; 96 case 'f': 97 filename = optarg; 98 break; 99 case '?': 100 default: 101 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 102 "usage: praliases [-C cffile] [-f aliasfile]" 103 " [key ...]\n"); 104 exit(EX_USAGE); 105 } 106 } 107 argc -= optind; 108 argv += optind; 109 110 if (filename != NULL) 111 { 112 praliases(filename, argc, argv); 113 exit(EX_OK); 114 } 115 116 if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY, 117 NULL)) == NULL) 118 { 119 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 120 "praliases: %s: %s\n", cfile, 121 sm_errstring(errno)); 122 exit(EX_NOINPUT); 123 } 124
|
126 { 127 register char *b, *p; 128 129 b = strchr(buf, '\n'); 130 if (b != NULL) 131 *b = '\0'; 132 133 b = buf; 134 switch (*b++) 135 { 136 case 'O': /* option -- see if alias file */ 137 if (sm_strncasecmp(b, " AliasFile", 10) == 0 && 138 !(isascii(b[10]) && isalnum(b[10]))) 139 { 140 /* new form -- find value */ 141 b = strchr(b, '='); 142 if (b == NULL) 143 continue; 144 while (isascii(*++b) && isspace(*b)) 145 continue; 146 } 147 else if (*b++ != 'A') 148 { 149 /* something else boring */ 150 continue; 151 } 152 153 /* this is the A or AliasFile option -- save it */ 154 if (sm_strlcpy(afilebuf, b, sizeof afilebuf) >= 155 sizeof afilebuf) 156 { 157 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 158 "praliases: AliasFile filename too long: %.30s\n", 159 b); 160 (void) sm_io_close(cfp, SM_TIME_DEFAULT); 161 exit(EX_CONFIG); 162 } 163 b = afilebuf; 164 165 for (p = b; p != NULL; ) 166 { 167 while (isascii(*p) && isspace(*p)) 168 p++; 169 if (*p == '\0') 170 break; 171 b = p; 172 173 p = strpbrk(p, DELIMITERS); 174 175 /* find end of spec */ 176 if (p != NULL) 177 { 178 bool quoted = false; 179 180 for (; *p != '\0'; p++) 181 { 182 /* 183 ** Don't break into a quoted 184 ** string. 185 */ 186 187 if (*p == '"') 188 quoted = !quoted; 189 else if (*p == ',' && !quoted) 190 break; 191 } 192 193 /* No more alias specs follow */ 194 if (*p == '\0') 195 { 196 /* chop trailing whitespace */ 197 while (isascii(*p) && 198 isspace(*p) && 199 p > b) 200 p--; 201 *p = '\0'; 202 p = NULL; 203 } 204 } 205 206 if (p != NULL) 207 { 208 char *e = p - 1; 209 210 /* chop trailing whitespace */ 211 while (isascii(*e) && 212 isspace(*e) && 213 e > b) 214 e--; 215 *++e = '\0'; 216 *p++ = '\0'; 217 } 218 praliases(b, argc, argv); 219 } 220 221 default: 222 continue; 223 } 224 } 225 (void) sm_io_close(cfp, SM_TIME_DEFAULT); 226 exit(EX_OK); 227 /* NOTREACHED */ 228 return EX_OK; 229} 230 231static void 232praliases(filename, argc, argv) 233 char *filename; 234 int argc; 235 char **argv; 236{ 237 int result; 238 char *colon; 239 char *db_name; 240 char *db_type; 241 SMDB_DATABASE *database = NULL; 242 SMDB_CURSOR *cursor = NULL; 243 SMDB_DBENT db_key, db_value; 244 SMDB_DBPARAMS params; 245 SMDB_USER_INFO user_info; 246 247 colon = strchr(filename, PATH_SEPARATOR); 248 if (colon == NULL) 249 { 250 db_name = filename; 251 db_type = SMDB_TYPE_DEFAULT; 252 } 253 else 254 { 255 *colon = '\0'; 256 db_name = colon + 1; 257 db_type = filename; 258 } 259 260 /* clean off arguments */ 261 for (;;) 262 { 263 while (isascii(*db_name) && isspace(*db_name)) 264 db_name++; 265 266 if (*db_name != '-') 267 break; 268 while (*db_name != '\0' && 269 !(isascii(*db_name) && isspace(*db_name))) 270 db_name++; 271 } 272 273 /* Skip non-file based DB types */ 274 if (db_type != NULL && *db_type != '\0') 275 { 276 if (db_type != SMDB_TYPE_DEFAULT && 277 strcmp(db_type, "hash") != 0 && 278 strcmp(db_type, "btree") != 0 && 279 strcmp(db_type, "dbm") != 0) 280 { 281 sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 282 "praliases: Skipping non-file based alias type %s\n", 283 db_type); 284 return; 285 } 286 } 287 288 if (*db_name == '\0' || (db_type != NULL && *db_type == '\0')) 289 { 290 if (colon != NULL) 291 *colon = ':'; 292 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 293 "praliases: illegal alias specification: %s\n", filename); 294 goto fatal; 295 } 296 297 memset(¶ms, '\0', sizeof params); 298 params.smdbp_cache_size = 1024 * 1024; 299 300 user_info.smdbu_id = RunAsUid; 301 user_info.smdbu_group_id = RunAsGid; 302 (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName, 303 SMDB_MAX_USER_NAME_LEN); 304 305 result = smdb_open_database(&database, db_name, O_RDONLY, 0, 306 SFF_ROOTOK, db_type, &user_info, ¶ms); 307 if (result != SMDBE_OK) 308 { 309 sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 310 "praliases: %s: open: %s\n", 311 db_name, sm_errstring(result)); 312 goto fatal; 313 } 314 315 if (argc == 0) 316 { 317 memset(&db_key, '\0', sizeof db_key); 318 memset(&db_value, '\0', sizeof db_value); 319 320 result = database->smdb_cursor(database, &cursor, 0); 321 if (result != SMDBE_OK) 322 { 323 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 324 "praliases: %s: set cursor: %s\n", db_name, 325 sm_errstring(result)); 326 goto fatal; 327 } 328 329 while ((result = cursor->smdbc_get(cursor, &db_key, &db_value, 330 SMDB_CURSOR_GET_NEXT)) == 331 SMDBE_OK) 332 { 333#if 0 334 /* skip magic @:@ entry */ 335 if (db_key.size == 2 && 336 db_key.data[0] == '@' && 337 db_key.data[1] == '\0' && 338 db_value.size == 2 && 339 db_value.data[0] == '@' && 340 db_value.data[1] == '\0') 341 continue; 342#endif /* 0 */ 343 344 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 345 "%.*s:%.*s\n", 346 (int) db_key.size, 347 (char *) db_key.data, 348 (int) db_value.size, 349 (char *) db_value.data); 350 } 351 352 if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY) 353 { 354 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 355 "praliases: %s: get value at cursor: %s\n", 356 db_name, sm_errstring(result)); 357 goto fatal; 358 } 359 } 360 else for (; *argv != NULL; ++argv) 361 { 362 int get_res; 363 364 memset(&db_key, '\0', sizeof db_key); 365 memset(&db_value, '\0', sizeof db_value); 366 db_key.data = *argv; 367 db_key.size = strlen(*argv); 368 get_res = database->smdb_get(database, &db_key, &db_value, 0); 369 if (get_res == SMDBE_NOT_FOUND) 370 { 371 db_key.size++; 372 get_res = database->smdb_get(database, &db_key, 373 &db_value, 0); 374 } 375 if (get_res == SMDBE_OK) 376 { 377 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 378 "%.*s:%.*s\n", 379 (int) db_key.size, 380 (char *) db_key.data, 381 (int) db_value.size, 382 (char *) db_value.data); 383 } 384 else 385 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 386 "%s: No such key\n", 387 (char *)db_key.data); 388 } 389 390 fatal: 391 if (cursor != NULL) 392 (void) cursor->smdbc_close(cursor); 393 if (database != NULL) 394 (void) database->smdb_close(database); 395 if (colon != NULL) 396 *colon = ':'; 397 return; 398}
| 126 { 127 register char *b, *p; 128 129 b = strchr(buf, '\n'); 130 if (b != NULL) 131 *b = '\0'; 132 133 b = buf; 134 switch (*b++) 135 { 136 case 'O': /* option -- see if alias file */ 137 if (sm_strncasecmp(b, " AliasFile", 10) == 0 && 138 !(isascii(b[10]) && isalnum(b[10]))) 139 { 140 /* new form -- find value */ 141 b = strchr(b, '='); 142 if (b == NULL) 143 continue; 144 while (isascii(*++b) && isspace(*b)) 145 continue; 146 } 147 else if (*b++ != 'A') 148 { 149 /* something else boring */ 150 continue; 151 } 152 153 /* this is the A or AliasFile option -- save it */ 154 if (sm_strlcpy(afilebuf, b, sizeof afilebuf) >= 155 sizeof afilebuf) 156 { 157 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 158 "praliases: AliasFile filename too long: %.30s\n", 159 b); 160 (void) sm_io_close(cfp, SM_TIME_DEFAULT); 161 exit(EX_CONFIG); 162 } 163 b = afilebuf; 164 165 for (p = b; p != NULL; ) 166 { 167 while (isascii(*p) && isspace(*p)) 168 p++; 169 if (*p == '\0') 170 break; 171 b = p; 172 173 p = strpbrk(p, DELIMITERS); 174 175 /* find end of spec */ 176 if (p != NULL) 177 { 178 bool quoted = false; 179 180 for (; *p != '\0'; p++) 181 { 182 /* 183 ** Don't break into a quoted 184 ** string. 185 */ 186 187 if (*p == '"') 188 quoted = !quoted; 189 else if (*p == ',' && !quoted) 190 break; 191 } 192 193 /* No more alias specs follow */ 194 if (*p == '\0') 195 { 196 /* chop trailing whitespace */ 197 while (isascii(*p) && 198 isspace(*p) && 199 p > b) 200 p--; 201 *p = '\0'; 202 p = NULL; 203 } 204 } 205 206 if (p != NULL) 207 { 208 char *e = p - 1; 209 210 /* chop trailing whitespace */ 211 while (isascii(*e) && 212 isspace(*e) && 213 e > b) 214 e--; 215 *++e = '\0'; 216 *p++ = '\0'; 217 } 218 praliases(b, argc, argv); 219 } 220 221 default: 222 continue; 223 } 224 } 225 (void) sm_io_close(cfp, SM_TIME_DEFAULT); 226 exit(EX_OK); 227 /* NOTREACHED */ 228 return EX_OK; 229} 230 231static void 232praliases(filename, argc, argv) 233 char *filename; 234 int argc; 235 char **argv; 236{ 237 int result; 238 char *colon; 239 char *db_name; 240 char *db_type; 241 SMDB_DATABASE *database = NULL; 242 SMDB_CURSOR *cursor = NULL; 243 SMDB_DBENT db_key, db_value; 244 SMDB_DBPARAMS params; 245 SMDB_USER_INFO user_info; 246 247 colon = strchr(filename, PATH_SEPARATOR); 248 if (colon == NULL) 249 { 250 db_name = filename; 251 db_type = SMDB_TYPE_DEFAULT; 252 } 253 else 254 { 255 *colon = '\0'; 256 db_name = colon + 1; 257 db_type = filename; 258 } 259 260 /* clean off arguments */ 261 for (;;) 262 { 263 while (isascii(*db_name) && isspace(*db_name)) 264 db_name++; 265 266 if (*db_name != '-') 267 break; 268 while (*db_name != '\0' && 269 !(isascii(*db_name) && isspace(*db_name))) 270 db_name++; 271 } 272 273 /* Skip non-file based DB types */ 274 if (db_type != NULL && *db_type != '\0') 275 { 276 if (db_type != SMDB_TYPE_DEFAULT && 277 strcmp(db_type, "hash") != 0 && 278 strcmp(db_type, "btree") != 0 && 279 strcmp(db_type, "dbm") != 0) 280 { 281 sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 282 "praliases: Skipping non-file based alias type %s\n", 283 db_type); 284 return; 285 } 286 } 287 288 if (*db_name == '\0' || (db_type != NULL && *db_type == '\0')) 289 { 290 if (colon != NULL) 291 *colon = ':'; 292 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 293 "praliases: illegal alias specification: %s\n", filename); 294 goto fatal; 295 } 296 297 memset(¶ms, '\0', sizeof params); 298 params.smdbp_cache_size = 1024 * 1024; 299 300 user_info.smdbu_id = RunAsUid; 301 user_info.smdbu_group_id = RunAsGid; 302 (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName, 303 SMDB_MAX_USER_NAME_LEN); 304 305 result = smdb_open_database(&database, db_name, O_RDONLY, 0, 306 SFF_ROOTOK, db_type, &user_info, ¶ms); 307 if (result != SMDBE_OK) 308 { 309 sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 310 "praliases: %s: open: %s\n", 311 db_name, sm_errstring(result)); 312 goto fatal; 313 } 314 315 if (argc == 0) 316 { 317 memset(&db_key, '\0', sizeof db_key); 318 memset(&db_value, '\0', sizeof db_value); 319 320 result = database->smdb_cursor(database, &cursor, 0); 321 if (result != SMDBE_OK) 322 { 323 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 324 "praliases: %s: set cursor: %s\n", db_name, 325 sm_errstring(result)); 326 goto fatal; 327 } 328 329 while ((result = cursor->smdbc_get(cursor, &db_key, &db_value, 330 SMDB_CURSOR_GET_NEXT)) == 331 SMDBE_OK) 332 { 333#if 0 334 /* skip magic @:@ entry */ 335 if (db_key.size == 2 && 336 db_key.data[0] == '@' && 337 db_key.data[1] == '\0' && 338 db_value.size == 2 && 339 db_value.data[0] == '@' && 340 db_value.data[1] == '\0') 341 continue; 342#endif /* 0 */ 343 344 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 345 "%.*s:%.*s\n", 346 (int) db_key.size, 347 (char *) db_key.data, 348 (int) db_value.size, 349 (char *) db_value.data); 350 } 351 352 if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY) 353 { 354 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 355 "praliases: %s: get value at cursor: %s\n", 356 db_name, sm_errstring(result)); 357 goto fatal; 358 } 359 } 360 else for (; *argv != NULL; ++argv) 361 { 362 int get_res; 363 364 memset(&db_key, '\0', sizeof db_key); 365 memset(&db_value, '\0', sizeof db_value); 366 db_key.data = *argv; 367 db_key.size = strlen(*argv); 368 get_res = database->smdb_get(database, &db_key, &db_value, 0); 369 if (get_res == SMDBE_NOT_FOUND) 370 { 371 db_key.size++; 372 get_res = database->smdb_get(database, &db_key, 373 &db_value, 0); 374 } 375 if (get_res == SMDBE_OK) 376 { 377 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 378 "%.*s:%.*s\n", 379 (int) db_key.size, 380 (char *) db_key.data, 381 (int) db_value.size, 382 (char *) db_value.data); 383 } 384 else 385 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 386 "%s: No such key\n", 387 (char *)db_key.data); 388 } 389 390 fatal: 391 if (cursor != NULL) 392 (void) cursor->smdbc_close(cursor); 393 if (database != NULL) 394 (void) database->smdb_close(database); 395 if (colon != NULL) 396 *colon = ':'; 397 return; 398}
|