/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ #include "mail.h" #ifdef SVR4 #include #endif /* * mail [ -ehpPqrtw ] [-x debuglevel] [ -f file ] [ -F user(s) ] * mail -T file persons * mail [ -tw ] [ -m messagetype ] persons * rmail [ -tw ] persons */ int main(int argc, char **argv) { register int i; char *cptr, *p; struct stat statb; static char pn[] = "main"; extern char **environ; int env_var_idx, next_slot_idx; int tmpfd = -1; #ifdef SVR4 (void) setlocale(LC_ALL, ""); #endif /* fix here for bug #1086130 - security hole */ /* skip over the LD_* env variable */ env_var_idx = 0; next_slot_idx = 0; while (environ[env_var_idx] != NULL) { environ[next_slot_idx] = environ[env_var_idx]; if (strncmp(environ[env_var_idx], "LD_", 3)) { next_slot_idx++; } env_var_idx++; } environ[next_slot_idx] = NULL; #ifdef SIGCONT #ifdef SVR4 { struct sigaction nsig; nsig.sa_handler = SIG_DFL; sigemptyset(&nsig.sa_mask); nsig.sa_flags = SA_RESTART; (void) sigaction(SIGCONT, &nsig, (struct sigaction *)0); } #else sigset(SIGCONT, SIG_DFL); #endif #endif /* * Strip off path name of this command for use in messages */ if ((program = strrchr(argv[0], '/')) != NULL) { program++; } else { program = argv[0]; } /* Close all file descriptors except stdin, stdout & stderr */ closefrom(STDERR_FILENO + 1); /* * Get group id for mail, exit if none exists */ if ((grpptr = getgrnam("mail")) == NULL) { errmsg(E_GROUP, ""); exit(1); } else { mailgrp = grpptr->gr_gid; } /* * Save the *id for later use. */ my_uid = getuid(); my_gid = getgid(); my_euid = geteuid(); my_egid = getegid(); /* * What command (rmail or mail)? */ if (strcmp(program, "rmail") == SAME) { ismail = FALSE; } /* * Parse the command line and adjust argc and argv * to compensate for any options */ i = parse(argc, argv); argv += (i - 1); argc -= (i - 1); /* block a potential security hole */ if (flgT && (my_euid != 0)) { setgid(my_gid); Tout(pn, "Setgid unset\n"); } if (debug == 0) { /* If not set as an invocation option, check for system-wide */ /* global flag */ char *xp = xgetenv("DEBUG"); if (xp != (char *)NULL) { debug = atoi(xp); if (debug < 0) { /* Keep trace file even if successful */ keepdbgfile = -1; debug = -debug; } } } if (debug > 0) { strcpy(dbgfname, "/tmp/MLDBGXXXXXX"); if ((tmpfd = mkstemp(dbgfname)) == -1) { fprintf(stderr, "%s: can't open debugging file '%s'\n", program, dbgfname); exit(13); } if ((dbgfp = fdopen(tmpfd, "w")) == (FILE *)NULL) { fprintf(stderr, "%s: can't open debugging file '%s'\n", program, dbgfname); (void) close(tmpfd); exit(13); } setbuf(dbgfp, NULL); fprintf(dbgfp, "main(): debugging level == %d\n", debug); fprintf(dbgfp, "main(): trace file ='%s': kept %s\n", dbgfname, ((keepdbgfile < 0) ? "on success or failure." : "only on failure.")); } if (!ismail && (goerr > 0 || !i)) { Dout(pn, 11, "!ismail, goerr=%d, i=%d\n", goerr, i); if (goerr > 0) { errmsg(E_SYNTAX, "Usage: rmail [-wt] person(s)"); } if (!i) { errmsg(E_SYNTAX, "At least one user must be specified"); } Dout(pn, 11, "exiting!\n"); done(0); } umsave = umask(7); uname(&utsn); if ((p = xgetenv("CLUSTER")) != (char *)NULL) { /* * We are not who we appear... */ thissys = p; } else { thissys = utsn.nodename; } Dout(pn, 11, "thissys = '%s', uname = '%s'\n", thissys, utsn.nodename); failsafe = xgetenv("FAILSAFE"); if (failsafe) Dout(pn, 11, "failsafe processing enabled to %s\n", failsafe); /* * Use environment variables */ home = getenv("HOME"); if (!home || !*home) { home = "."; } my_name[0] = '\0'; pwd = getpwuid(my_uid); if (pwd) (void) strlcpy(my_name, pwd->pw_name, sizeof (my_name)); /* If root, use LOGNAME if set */ if (my_uid == 0) { /* If root, use LOGNAME if set */ if (((cptr = getenv("LOGNAME")) != NULL) && (strlen(cptr) != 0)) { (void) strlcpy(my_name, cptr, sizeof (my_name)); } } Dout(pn, 11, "my_name = '%s'\n", my_name); /* * Catch signals for cleanup */ if (setjmp(sjbuf)) { done(0); } for (i = SIGINT; i < SIGCLD; i++) { setsig(i, delete); } setsig(SIGHUP, sig_done); setsig(SIGTERM, sig_done); cksaved(my_name); /* * Rmail is always invoked to send mail */ Dout(pn, 11, "ismail=%d, argc=%d\n", ismail, argc); if (ismail && (argc == 1)) { sending = FALSE; printmail(); } else { sending = TRUE; sendmail(argc, argv); } done(0); }