4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
28
29 /* Copyright (c) 1987, 1988 Microsoft Corporation */
30 /* All Rights Reserved */
31
32 #ifdef lint
33 /* make lint happy */
34 #define __EXTENSIONS__
35 #endif
36
37 #include <sys/contract/process.h>
38 #include <sys/ctfs.h>
39 #include <sys/param.h>
40 #include <sys/resource.h>
41 #include <sys/stat.h>
42 #include <sys/task.h>
43 #include <sys/time.h>
128 #define NOREAD "can't read your crontab file. Resubmit it."
129 #define BADTYPE "crontab or at-job file is not a regular file.\n"
130 #define NOSTDIN "unable to create a standard input file for \
131 one of your crontab commands. \
132 \nThat command was not executed."
133
134 #define NOTALLOWED "you are not authorized to use cron. Sorry."
135 #define STDERRMSG "\n\n********************************************\
136 *****\nCron: The previous message is the \
137 standard output and standard error \
138 \nof one of your cron commands.\n"
139
140 #define STDOUTERR "one of your commands generated output or errors, \
141 but cron was unable to mail you this output.\
142 \nRemember to redirect standard output and standard \
143 error for each of your commands."
144
145 #define CLOCK_DRIFT "clock time drifted backwards after event!\n"
146 #define PIDERR "unexpected pid returned %d (ignored)"
147 #define CRONTABERR "Subject: Your crontab file has an error in it\n\n"
148 #define CRONOUT "Subject: Output from \"cron\" command\n\n"
149 #define MALLOCERR "out of space, cannot create new string\n"
150
151 #define DIDFORK didfork
152 #define NOFORK !didfork
153
154 #define MAILBUFLEN (8*1024)
155 #define LINELIMIT 80
156 #define MAILBINITFREE (MAILBUFLEN - (sizeof (cte_intro) - 1) \
157 - (sizeof (cte_trail1) - 1) - (sizeof (cte_trail2) - 1) - 1)
158
159 #define ERR_CRONTABENT 0 /* error in crontab file entry */
160 #define ERR_UNIXERR 1 /* error in some system call */
161 #define ERR_CANTEXECCRON 2 /* error setting up "cron" job environment */
162 #define ERR_CANTEXECAT 3 /* error setting up "at" job environment */
163 #define ERR_NOTREG 4 /* error not a regular file */
164
165 #define PROJECT "project="
166
167 #define MAX_LOST_CONTRACTS 2048 /* reset if this many failed abandons */
168
2694 }
2695
2696 free_if_unused(p);
2697 }
2698
2699 /*
2700 * Mail stdout and stderr of a job to user. Get uid for real user and become
2701 * that person. We do this so that mail won't come from root since this
2702 * could be a security hole. If failure, quit - don't send mail as root.
2703 */
2704 static void
2705 mail_result(struct usr *p, struct runinfo *pr, size_t filesize)
2706 {
2707 struct passwd *ruser_ids;
2708 FILE *mailpipe;
2709 FILE *st;
2710 struct utsname name;
2711 int nbytes;
2712 char iobuf[BUFSIZ];
2713 char *cmd;
2714
2715 (void) uname(&name);
2716 if ((ruser_ids = getpwnam(p->name)) == NULL)
2717 exit(0);
2718 (void) setuid(ruser_ids->pw_uid);
2719
2720 cmd = xmalloc(strlen(MAIL) + strlen(p->name)+2);
2721 (void) sprintf(cmd, "%s %s", MAIL, p->name);
2722 mailpipe = popen(cmd, "w");
2723 free(cmd);
2724 if (mailpipe == NULL)
2725 exit(127);
2726 (void) fprintf(mailpipe, "To: %s\n", p->name);
2727 if (pr->jobtype == CRONEVENT) {
2728 (void) fprintf(mailpipe, CRONOUT);
2729 (void) fprintf(mailpipe, "Your \"cron\" job on %s\n",
2730 name.nodename);
2731 if (pr->jobname != NULL) {
2732 (void) fprintf(mailpipe, "%s\n\n", pr->jobname);
2733 }
2734 } else {
2735 (void) fprintf(mailpipe, "Subject: Output from \"at\" job\n\n");
2736 (void) fprintf(mailpipe, "Your \"at\" job on %s\n",
2737 name.nodename);
2738 if (pr->jobname != NULL) {
2739 (void) fprintf(mailpipe, "\"%s\"\n\n", pr->jobname);
2740 }
2741 }
2742 /* Tmp. file is fopen'ed w/ "r", secure open */
2743 if (filesize > 0 &&
2744 (st = fopen(pr->outfile, "r")) != NULL) {
2745 (void) fprintf(mailpipe,
2746 "produced the following output:\n\n");
2747 while ((nbytes = fread(iobuf, sizeof (char), BUFSIZ, st)) != 0)
2748 (void) fwrite(iobuf, sizeof (char), nbytes, mailpipe);
2749 (void) fclose(st);
2750 } else {
2751 (void) fprintf(mailpipe, "completed.\n");
2752 }
2753 (void) pclose(mailpipe);
2754 exit(0);
2755 }
2756
2757 static int
2758 msg_wait(long tim)
2759 {
2760 struct message msg;
2761 int cnt;
2762 time_t reftime;
2763 fd_set fds;
2764 struct timespec tout, *toutp;
2765 static int pending_msg;
2766 static time_t pending_reftime;
2767
2768 if (pending_msg) {
2769 process_msg(&msgbuf, pending_reftime);
2770 pending_msg = 0;
2771 return (0);
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 *
25 * Copyright 2013 Joshua M. Clulow <josh@sysmgr.org>
26 */
27
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
30
31 /* Copyright (c) 1987, 1988 Microsoft Corporation */
32 /* All Rights Reserved */
33
34 #ifdef lint
35 /* make lint happy */
36 #define __EXTENSIONS__
37 #endif
38
39 #include <sys/contract/process.h>
40 #include <sys/ctfs.h>
41 #include <sys/param.h>
42 #include <sys/resource.h>
43 #include <sys/stat.h>
44 #include <sys/task.h>
45 #include <sys/time.h>
130 #define NOREAD "can't read your crontab file. Resubmit it."
131 #define BADTYPE "crontab or at-job file is not a regular file.\n"
132 #define NOSTDIN "unable to create a standard input file for \
133 one of your crontab commands. \
134 \nThat command was not executed."
135
136 #define NOTALLOWED "you are not authorized to use cron. Sorry."
137 #define STDERRMSG "\n\n********************************************\
138 *****\nCron: The previous message is the \
139 standard output and standard error \
140 \nof one of your cron commands.\n"
141
142 #define STDOUTERR "one of your commands generated output or errors, \
143 but cron was unable to mail you this output.\
144 \nRemember to redirect standard output and standard \
145 error for each of your commands."
146
147 #define CLOCK_DRIFT "clock time drifted backwards after event!\n"
148 #define PIDERR "unexpected pid returned %d (ignored)"
149 #define CRONTABERR "Subject: Your crontab file has an error in it\n\n"
150 #define MALLOCERR "out of space, cannot create new string\n"
151
152 #define DIDFORK didfork
153 #define NOFORK !didfork
154
155 #define MAILBUFLEN (8*1024)
156 #define LINELIMIT 80
157 #define MAILBINITFREE (MAILBUFLEN - (sizeof (cte_intro) - 1) \
158 - (sizeof (cte_trail1) - 1) - (sizeof (cte_trail2) - 1) - 1)
159
160 #define ERR_CRONTABENT 0 /* error in crontab file entry */
161 #define ERR_UNIXERR 1 /* error in some system call */
162 #define ERR_CANTEXECCRON 2 /* error setting up "cron" job environment */
163 #define ERR_CANTEXECAT 3 /* error setting up "at" job environment */
164 #define ERR_NOTREG 4 /* error not a regular file */
165
166 #define PROJECT "project="
167
168 #define MAX_LOST_CONTRACTS 2048 /* reset if this many failed abandons */
169
2695 }
2696
2697 free_if_unused(p);
2698 }
2699
2700 /*
2701 * Mail stdout and stderr of a job to user. Get uid for real user and become
2702 * that person. We do this so that mail won't come from root since this
2703 * could be a security hole. If failure, quit - don't send mail as root.
2704 */
2705 static void
2706 mail_result(struct usr *p, struct runinfo *pr, size_t filesize)
2707 {
2708 struct passwd *ruser_ids;
2709 FILE *mailpipe;
2710 FILE *st;
2711 struct utsname name;
2712 int nbytes;
2713 char iobuf[BUFSIZ];
2714 char *cmd;
2715 char *lowname = (pr->jobtype == CRONEVENT ? "cron" : "at");
2716
2717 (void) uname(&name);
2718 if ((ruser_ids = getpwnam(p->name)) == NULL)
2719 exit(0);
2720 (void) setuid(ruser_ids->pw_uid);
2721
2722 cmd = xmalloc(strlen(MAIL) + strlen(p->name)+2);
2723 (void) sprintf(cmd, "%s %s", MAIL, p->name);
2724 mailpipe = popen(cmd, "w");
2725 free(cmd);
2726 if (mailpipe == NULL)
2727 exit(127);
2728 (void) fprintf(mailpipe, "To: %s\n", p->name);
2729 (void) fprintf(mailpipe, "Subject: %s <%s@%s> %s\n",
2730 (pr->jobtype == CRONEVENT ? "Cron" : "At"),
2731 p->name, name.nodename, pr->jobname);
2732
2733 /*
2734 * RFC3834 (Section 5) defines the Auto-Submitted header to prevent
2735 * vacation replies, et al, from being sent in response to
2736 * machine-generated mail.
2737 */
2738 (void) fprintf(mailpipe, "Auto-Submitted: auto-generated\n");
2739
2740 /*
2741 * Additional headers for mail filtering and diagnostics:
2742 */
2743 (void) fprintf(mailpipe, "X-Mailer: cron (%s %s)\n", name.sysname,
2744 name.release);
2745 (void) fprintf(mailpipe, "X-Cron-User: %s\n", p->name);
2746 (void) fprintf(mailpipe, "X-Cron-Host: %s\n", name.nodename);
2747 (void) fprintf(mailpipe, "X-Cron-Job-Name: %s\n", pr->jobname);
2748 (void) fprintf(mailpipe, "X-Cron-Job-Type: %s\n", lowname);
2749
2750 /*
2751 * Message Body:
2752 *
2753 * (Temporary file is fopen'ed with "r", secure open.)
2754 */
2755 (void) fprintf(mailpipe, "\n");
2756 if (filesize > 0 &&
2757 (st = fopen(pr->outfile, "r")) != NULL) {
2758 while ((nbytes = fread(iobuf, sizeof (char), BUFSIZ, st)) != 0)
2759 (void) fwrite(iobuf, sizeof (char), nbytes, mailpipe);
2760 (void) fclose(st);
2761 } else {
2762 (void) fprintf(mailpipe, "Job completed with no output.\n");
2763 }
2764 (void) pclose(mailpipe);
2765 exit(0);
2766 }
2767
2768 static int
2769 msg_wait(long tim)
2770 {
2771 struct message msg;
2772 int cnt;
2773 time_t reftime;
2774 fd_set fds;
2775 struct timespec tout, *toutp;
2776 static int pending_msg;
2777 static time_t pending_reftime;
2778
2779 if (pending_msg) {
2780 process_msg(&msgbuf, pending_reftime);
2781 pending_msg = 0;
2782 return (0);
|