summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1995-08-21 12:34:18 +0000
committerache <ache@FreeBSD.org>1995-08-21 12:34:18 +0000
commit5a4e23dc5e4476a191d16d27970855bb02ff5acf (patch)
tree63312f0019250a621432b4314e4af8075173791e /libexec
parentc41493511aa516cc3de8d2e4a850bb6087862137 (diff)
downloadFreeBSD-src-5a4e23dc5e4476a191d16d27970855bb02ff5acf.zip
FreeBSD-src-5a4e23dc5e4476a191d16d27970855bb02ff5acf.tar.gz
Upgrade to 2.9
Diffstat (limited to 'libexec')
-rw-r--r--libexec/atrun/LEGAL29
-rw-r--r--libexec/atrun/Makefile5
-rw-r--r--libexec/atrun/atrun.c172
-rw-r--r--libexec/atrun/gloadavg.c69
-rw-r--r--libexec/atrun/gloadavg.h29
5 files changed, 236 insertions, 68 deletions
diff --git a/libexec/atrun/LEGAL b/libexec/atrun/LEGAL
new file mode 100644
index 0000000..92b1b49
--- /dev/null
+++ b/libexec/atrun/LEGAL
@@ -0,0 +1,29 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+
+Sorry for the long wait, but there still were a few things to
+be ironed out in at, which I've finally done :-)
+
+The FreeBSD team does have my permission to use at, version 2.9,
+under the BSD license.
+
+You'll find it on sunsite.unc.edu's Incoming, hopefully; the
+md5 checksum is
+
+3ba2ca3c0e87e1a04feae2c6c1376b0d at-2.9.tgz
+
+Best regards
+ Thomas
+- --
+Thomas Koenig, Thomas.Koenig@ciw.uni-karlsruhe.de, ig25@dkauni2.bitnet.
+The joy of engineering is to find a straight line on a double
+logarithmic diagram.
+
+-----BEGIN PGP SIGNATURE-----
+Version: 2.6.2i
+
+iQCVAwUBMCjVrPBu+cbJcKCVAQFNiQP/dpWP57s/E8plVGUD3zfgOXDmKUvg8U7a
+VwRzJrIMuSgnSJs0wkpvcomc3NLicipfX7hhWLh/xatPM2YbF7O5HZoNdvWvexD2
+1Y67zJ+0HFb1mPnSBOrS5RFiQAe3KqmGec6E14Rih/qNoFQZBVRFXZ4xxuwP+0Rs
+e2U+TVTUz6A=
+=TvyW
+-----END PGP SIGNATURE-----
diff --git a/libexec/atrun/Makefile b/libexec/atrun/Makefile
index cb69fd1..96d415b 100644
--- a/libexec/atrun/Makefile
+++ b/libexec/atrun/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.1 1994/01/05 01:02:56 nate Exp $
+# $Id: Makefile,v 1.3 1995/08/10 04:06:52 ache Exp $
MAINSRC= ${.CURDIR}/../../usr.bin/at
@@ -6,13 +6,14 @@ MAINSRC= ${.CURDIR}/../../usr.bin/at
PROG= atrun
MAN8= atrun.8
+SRCS= atrun.c gloadavg.c
BINDIR= $(ATLIB_DIR)
MANSRC= .
CLEANFILES += ${MAN8}
MANDEPEND = ${MAN8}
-CFLAGS+= -I$(MAINSRC)
+CFLAGS+= -I$(MAINSRC) -I{$.CURDIR}
${MAN8}: atrun.man
sed -e \
diff --git a/libexec/atrun/atrun.c b/libexec/atrun/atrun.c
index 3ae9ee7..9bd7aca 100644
--- a/libexec/atrun/atrun.c
+++ b/libexec/atrun/atrun.c
@@ -1,4 +1,4 @@
-/*
+/*
* atrun.c - run jobs queued by at; run with root privileges.
* Copyright (C) 1993, 1994 Thomas Koenig
*
@@ -14,7 +14,7 @@
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
@@ -42,17 +42,15 @@
#include <time.h>
#include <unistd.h>
#include <syslog.h>
-#ifndef __FreeBSD__
-#include <getopt.h>
-#else
+#ifdef __FreeBSD__
#include <paths.h>
+#else
+#include <getopt.h>
#endif
/* Local headers */
-#ifndef __FreeBSD__
#include "gloadavg.h"
-#endif
#define MAIN
#include "privs.h"
@@ -73,29 +71,19 @@
/* File scope variables */
static char *namep;
-static char rcsid[] = "$Id: atrun.c,v 1.3 1995/04/12 19:21:43 ache Exp $";
+static char rcsid[] = "$Id: atrun.c,v 1.5 1995/08/10 04:06:53 ache Exp $";
static debug = 0;
-/* Local functions */
-static void
-perr(const char *a)
-{
- if (debug)
- {
- perror(a);
- }
- else
- syslog(LOG_ERR, "%s: %m", a);
-
- exit(EXIT_FAILURE);
-}
+void perr(const char *a);
+/* Local functions */
static int
write_string(int fd, const char* a)
{
return write(fd, a, strlen(a));
}
+#undef DEBUG_FORK
#ifdef DEBUG_FORK
static pid_t
myfork()
@@ -124,10 +112,12 @@ run_file(const char *filename, uid_t uid, gid_t gid)
char *mailname = NULL;
FILE *stream;
int send_mail = 0;
- struct stat buf;
+ struct stat buf, lbuf;
off_t size;
struct passwd *pentry;
int fflags;
+ long nuid;
+ long ngid;
PRIV_START
@@ -142,8 +132,8 @@ run_file(const char *filename, uid_t uid, gid_t gid)
pid = fork();
if (pid == -1)
perr("Cannot fork");
-
- else if (pid > 0)
+
+ else if (pid != 0)
return;
/* Let's see who we mail to. Hopefully, we can read it from
@@ -156,7 +146,7 @@ run_file(const char *filename, uid_t uid, gid_t gid)
{
syslog(LOG_ERR,"Userid %lu not found - aborting job %s",
(unsigned long) uid, filename);
- exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
PRIV_START
@@ -170,32 +160,63 @@ run_file(const char *filename, uid_t uid, gid_t gid)
if ((fd_in = dup(fileno(stream))) <0)
perr("Error duplicating input file descriptor");
+ if (fstat(fd_in, &buf) == -1)
+ perr("Error in fstat of input file descriptor");
+
+ if (lstat(filename, &lbuf) == -1)
+ perr("Error in fstat of input file");
+
+ if (S_ISLNK(lbuf.st_mode)) {
+ syslog(LOG_ERR,"Symbolic link encountered in job %s - aborting",
+ filename);
+ exit(EXIT_FAILURE);
+ }
+ if ((lbuf.st_dev != buf.st_dev) || (lbuf.st_ino != buf.st_ino) ||
+ (lbuf.st_uid != buf.st_uid) || (lbuf.st_gid != buf.st_gid) ||
+ (lbuf.st_size!=buf.st_size)) {
+ syslog(LOG_ERR,"Somebody changed files from under us for job %s - "
+ "aborting",filename);
+ exit(EXIT_FAILURE);
+ }
+ if (buf.st_nlink > 1) {
+ syslog(LOG_ERR,"Someboy is trying to run a linked script for job %s",
+ filename);
+ exit(EXIT_FAILURE);
+ }
if ((fflags = fcntl(fd_in, F_GETFD)) <0)
perr("Error in fcntl");
fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC);
- if (fscanf(stream, "#! /bin/sh\n# mail %8s %d", mailbuf, &send_mail) == 2)
+ if (fscanf(stream, "#!/bin/sh\n# atrun uid=%ld gid=%ld\n# mail %8s %d",
+ &nuid, &ngid, mailbuf, &send_mail) != 4)
{
- mailname = mailbuf;
- pentry = getpwnam(mailname);
- if (pentry == NULL || pentry->pw_uid != uid) {
- syslog(LOG_ERR,"Userid %lu mismatch name %s - aborting job %s",
- (unsigned long) uid, mailname, filename);
- exit(EXIT_FAILURE);
- }
+ syslog(LOG_ERR,"File %s is in wrong format - aborting",
+ filename);
+ exit(EXIT_FAILURE);
}
- else
- {
- mailname = pentry->pw_name;
+ if (mailbuf[0] == '-') {
+ syslog(LOG_ERR,"illegal mail name %s in %s",mailbuf,filename);
+ exit(EXIT_FAILURE);
+ }
+ mailname = mailbuf;
+ if (nuid != uid) {
+ syslog(LOG_ERR,"Job %s - userid %d does not match file uid %d",
+ filename, nuid, uid);
+ exit(EXIT_FAILURE);
+ }
+ if (ngid != gid) {
+ syslog(LOG_ERR,"Job %s - groupid %d does not match file gid %d",
+ filename, ngid, gid);
+ exit(EXIT_FAILURE);
}
fclose(stream);
if (chdir(ATSPOOL_DIR) < 0)
perr("Cannot chdir to " ATSPOOL_DIR);
-
+
/* Create a file to hold the output of the job we are about to run.
* Write the mail header.
- */
+ */
if((fd_out=open(filename,
O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR)) < 0)
perr("Cannot create output file");
@@ -209,7 +230,7 @@ run_file(const char *filename, uid_t uid, gid_t gid)
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
-
+
pid = fork();
if (pid < 0)
perr("Error in fork");
@@ -245,8 +266,9 @@ run_file(const char *filename, uid_t uid, gid_t gid)
PRIV_START
nice(tolower(queue) - 'a');
-
- chdir(pentry->pw_dir);
+
+ if (chdir(pentry->pw_dir))
+ chdir("/");
if (initgroups(pentry->pw_name,pentry->pw_gid))
perr("Cannot delete saved userids");
@@ -258,7 +280,7 @@ run_file(const char *filename, uid_t uid, gid_t gid)
perr("Cannot set user id");
if(execle("/bin/sh","sh",(char *) NULL, nenvp) != 0)
- perr("Exec failed");
+ perr("Exec failed for /bin/sh");
PRIV_END
}
@@ -277,7 +299,21 @@ run_file(const char *filename, uid_t uid, gid_t gid)
unlink(filename);
if ((buf.st_size != size) || send_mail)
- {
+ {
+ PRIV_START
+
+ if (chdir(pentry->pw_dir))
+ chdir("/");
+
+ if (initgroups(pentry->pw_name,pentry->pw_gid))
+ perr("Cannot delete saved userids");
+
+ if (setgid(gid) < 0)
+ perr("Cannot change group");
+
+ if (setuid(uid) < 0)
+ perr("Cannot set user id");
+
#ifdef __FreeBSD__
execl(_PATH_SENDMAIL, "sendmail", "-F", "Atrun Service",
"-odi", "-oem",
@@ -285,13 +321,29 @@ run_file(const char *filename, uid_t uid, gid_t gid)
#else
execl(MAIL_CMD, MAIL_CMD, mailname, (char *) NULL);
#endif
- perr("Exec failed");
+ perr("Exec failed for mail command");
+
+ PRIV_END
}
exit(EXIT_SUCCESS);
}
/* Global functions */
+/* Needed in gloadavg.c */
+void
+perr(const char *a)
+{
+ if (debug)
+ {
+ perror(a);
+ }
+ else
+ syslog(LOG_ERR, "%s: %m", a);
+
+ exit(EXIT_FAILURE);
+}
+
int
main(int argc, char *argv[])
{
@@ -309,6 +361,7 @@ main(int argc, char *argv[])
struct dirent *dirent;
struct stat buf;
unsigned long ctm;
+ unsigned long jobno;
char queue;
time_t now, run_time;
char batch_name[] = "Z2345678901234";
@@ -332,7 +385,7 @@ main(int argc, char *argv[])
{
switch (c)
{
- case 'l':
+ case 'l':
if (sscanf(optarg, "%lf", &load_avg) != 1)
perr("garbled option -l");
if (load_avg <= 0.)
@@ -375,31 +428,28 @@ main(int argc, char *argv[])
batch_uid = (uid_t) -1;
batch_gid = (gid_t) -1;
- while ((dirent = readdir(spool)) != NULL)
- {
+ while ((dirent = readdir(spool)) != NULL) {
if (stat(dirent->d_name,&buf) != 0)
perr("Cannot stat in " ATJOB_DIR);
/* We don't want directories
*/
- if (!S_ISREG(buf.st_mode))
+ if (!S_ISREG(buf.st_mode))
continue;
- if (sscanf(dirent->d_name,"%c%8lx",&queue,&ctm) != 2)
+ if (sscanf(dirent->d_name,"%c%5lx%8lx",&queue,&jobno,&ctm) != 3)
continue;
run_time = (time_t) ctm*60;
- if ((S_IXUSR & buf.st_mode) && (run_time <=now))
- {
- if (isupper(queue) && (strcmp(batch_name,dirent->d_name) > 0))
- {
+ if ((S_IXUSR & buf.st_mode) && (run_time <=now)) {
+ if (isupper(queue) && (strcmp(batch_name,dirent->d_name) > 0)) {
run_batch = 1;
strncpy(batch_name, dirent->d_name, sizeof(batch_name));
batch_uid = buf.st_uid;
batch_gid = buf.st_gid;
}
-
+
/* The file is executable and old enough
*/
if (islower(queue))
@@ -412,18 +462,8 @@ main(int argc, char *argv[])
}
/* run the single batch file, if any
*/
-#ifndef __FreeBSD__
- if (run_batch && (gloadavg() < load_avg)) {
-#else
- if (run_batch) {
- double la;
-
- if (getloadavg(&la, 1) != 1)
- perr("Error in getloadavg");
- if (la < load_avg)
-#endif
- run_file(batch_name, batch_uid, batch_gid);
- }
+ if (run_batch && (gloadavg() < load_avg))
+ run_file(batch_name, batch_uid, batch_gid);
closelog();
exit(EXIT_SUCCESS);
diff --git a/libexec/atrun/gloadavg.c b/libexec/atrun/gloadavg.c
new file mode 100644
index 0000000..6e996f0
--- /dev/null
+++ b/libexec/atrun/gloadavg.c
@@ -0,0 +1,69 @@
+/*
+ * gloadavg.c - get load average for Linux
+ * Copyright (C) 1993 Thomas Koenig
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author(s) may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __FreeBSD__
+#define _POSIX_SOURCE 1
+
+/* System Headers */
+
+#include <stdio.h>
+#else
+#include <stdlib.h>
+#endif
+
+/* Local headers */
+
+#include "gloadavg.h"
+
+/* File scope variables */
+
+static char rcsid[] = "$Id: gloadavg.c,v 1.2 1995/08/10 04:06:54 ache Exp $";
+
+/* Global functions */
+
+double
+gloadavg(void)
+/* return the current load average as a floating point number, or <0 for
+ * error
+ */
+{
+ double result;
+#ifndef __FreeBSD__
+ FILE *fp;
+
+ if((fp=fopen(PROC_DIR "loadavg","r")) == NULL)
+ result = -1.0;
+ else
+ {
+ if(fscanf(fp,"%lf",&result) != 1)
+ result = -1.0;
+ fclose(fp);
+ }
+#else
+ if (getloadavg(&result, 1) != 1)
+ perr("Error in getloadavg");
+#endif
+ return result;
+}
diff --git a/libexec/atrun/gloadavg.h b/libexec/atrun/gloadavg.h
new file mode 100644
index 0000000..c7e2c2c
--- /dev/null
+++ b/libexec/atrun/gloadavg.h
@@ -0,0 +1,29 @@
+/*
+ * gloadavg.h - header for atrun(8)
+ * Copyright (C) 1993 Thomas Koenig
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author(s) may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+double gloadavg(void);
+#if 0
+static char atrun_h_rcsid[] = "$Id: gloadavg.h,v 1.2 1995/08/10 04:06:55 ache Exp $";
+#endif
OpenPOWER on IntegriCloud