last_patch63 from vodz: add in crond and crontab applets
This commit is contained in:
parent
44608e9693
commit
f6f7bfb8e0
2
AUTHORS
2
AUTHORS
@ -55,7 +55,7 @@ Glenn McGrath <bug1@optushome.com.au>
|
|||||||
ar, dpkg, dpkg-deb
|
ar, dpkg, dpkg-deb
|
||||||
|
|
||||||
Vladimir Oleynik <dzo@simtreas.ru>
|
Vladimir Oleynik <dzo@simtreas.ru>
|
||||||
cmdedit; ports: ash, stty, traceroute, telnetd, top;
|
cmdedit; ports: ash, crond, stty, traceroute, telnetd, top;
|
||||||
locale, various fixes
|
locale, various fixes
|
||||||
and irreconcilable critic of everything not perfect.
|
and irreconcilable critic of everything not perfect.
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ Glenn McGrath <bug1@netconnect.com.au>
|
|||||||
|
|
||||||
Vladimir Oleynik <dzo@simtreas.ru>
|
Vladimir Oleynik <dzo@simtreas.ru>
|
||||||
|
|
||||||
cmdedit; ports: ash, stty, traceroute, telnetd, top;
|
cmdedit; ports: ash, crond, stty, traceroute, telnetd, top;
|
||||||
locale, various fixes
|
locale, various fixes
|
||||||
and irreconcilable critic of everything not perfect.
|
and irreconcilable critic of everything not perfect.
|
||||||
|
|
||||||
@ -167,4 +167,4 @@ Enrique Zanardi <ezanardi@ull.es>
|
|||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
# $Id: busybox_footer.pod,v 1.6 2002/09/30 20:52:08 andersen Exp $
|
# $Id: busybox_footer.pod,v 1.7 2002/10/22 12:24:56 andersen Exp $
|
||||||
|
@ -56,18 +56,18 @@ terse runtime description of their behavior.
|
|||||||
Currently defined functions include:
|
Currently defined functions include:
|
||||||
|
|
||||||
addgroup, adduser, adjtimex, ar, awk, basename, busybox, cat, chgrp,
|
addgroup, adduser, adjtimex, ar, awk, basename, busybox, cat, chgrp,
|
||||||
chmod, chown, chroot, chvt, clear, cmp, cp, cpio, cut, date, dc, dd,
|
chmod, chown, chroot, chvt, clear, cmp, cp, cpio, crond, crontab, cut,
|
||||||
deallocvt, deluser, df, dirname, dmesg, dos2unix, dpkg, dpkg-deb, du,
|
date, dc, dd, deallocvt, deluser, df, dirname, dmesg, dos2unix, dpkg,
|
||||||
dumpkmap, dutmp, echo, expr, false, fbset, fdflush, find, free,
|
dpkg-deb, du, dumpkmap, dutmp, echo, expr, false, fbset, fdflush, find,
|
||||||
freeramdisk, fsck.minix, getopt, getty, grep, gunzip, gzip, halt, head,
|
free, freeramdisk, fsck.minix, getopt, getty, grep, gunzip, gzip, halt,
|
||||||
hostid, hostname, id, ifconfig, init, insmod, kill, killall, klogd, length,
|
head, hostid, hostname, id, ifconfig, init, insmod, kill, killall, klogd,
|
||||||
ln, loadacm, loadfont, loadkmap, logger, logname, ls, lsmod, makedevs,
|
length, ln, loadacm, loadfont, loadkmap, logger, logname, ls, lsmod,
|
||||||
md5sum, mkdir, mkfifo, mkfs.minix, mknod, mkswap, mktemp, more, mount, mt,
|
makedevs, md5sum, mkdir, mkfifo, mkfs.minix, mknod, mkswap, mktemp, more,
|
||||||
mv, nc, netstat, nslookup, ping, pivot_root, poweroff, printf, ps, pwd,
|
mount, mt, mv, nc, netstat, nslookup, ping, pivot_root, poweroff, printf,
|
||||||
rdate, readlink, reboot, renice, reset, rm, rmdir, rmmod, route, rpm2cpio,
|
ps, pwd, rdate, readlink, reboot, renice, reset, rm, rmdir, rmmod, route,
|
||||||
sed, setkeycodes, sh, sleep, sort, stty, swapoff, swapon, sync, syslogd,
|
rpm2cpio, sed, setkeycodes, sh, sleep, sort, stty, swapoff, swapon, sync,
|
||||||
tail, tar, tee, telnet, telnetd, test, tftp, time, top, touch, tr, true,
|
syslogd, tail, tar, tee, telnet, telnetd, test, tftp, time, top, touch, tr,
|
||||||
tty, umount, uname, uniq, unix2dos, update, uptime, usleep, uudecode,
|
true, tty, umount, uname, uniq, unix2dos, update, uptime, usleep, uudecode,
|
||||||
uuencode, watchdog, wc, wget, which, whoami, xargs, yes, zcat, [
|
uuencode, watchdog, wc, wget, which, whoami, xargs, yes, zcat, [
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
@ -107,6 +107,12 @@
|
|||||||
#ifdef CONFIG_CPIO
|
#ifdef CONFIG_CPIO
|
||||||
APPLET(cpio, cpio_main, _BB_DIR_BIN, _BB_SUID_NEVER)
|
APPLET(cpio, cpio_main, _BB_DIR_BIN, _BB_SUID_NEVER)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef BB_CROND
|
||||||
|
APPLET(crond, crond_main, _BB_DIR_USR_SBIN)
|
||||||
|
#endif
|
||||||
|
#ifdef BB_CRONTAB
|
||||||
|
APPLET(crontab, crontab_main, _BB_DIR_USR_BIN)
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_CUT
|
#ifdef CONFIG_CUT
|
||||||
APPLET(cut, cut_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
|
APPLET(cut, cut_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
|
||||||
#endif
|
#endif
|
||||||
|
@ -186,6 +186,30 @@
|
|||||||
"\tu\t\tunconditional overwrite\n" \
|
"\tu\t\tunconditional overwrite\n" \
|
||||||
"\tF\t\tinput from file"
|
"\tF\t\tinput from file"
|
||||||
|
|
||||||
|
#define crond_trivial_usage \
|
||||||
|
"-d[#] -c <crondir> -f -b"
|
||||||
|
#define crond_full_usage \
|
||||||
|
"\t-d [#] -l [#] -S -L logfile -f -b -c dir\n" \
|
||||||
|
"\t-d num\tdebug level\n" \
|
||||||
|
"\t-l num\tlog level (8 - default)\n" \
|
||||||
|
"\t-S\tlog to syslod (defualt)\n" \
|
||||||
|
"\t-L file\tlog to file\n" \
|
||||||
|
"\t-f\trun in fordeground\n" \
|
||||||
|
"\t-b\trun in background (default)\n" \
|
||||||
|
"\t-c dir\tworking dir"
|
||||||
|
|
||||||
|
#define crontab_trivial_usage \
|
||||||
|
"crontab [-c dir] {file|-}|[-u|-l|-e|-d user]"
|
||||||
|
#define crontab_full_usage \
|
||||||
|
"\tfile <opts> replace crontab from file\n" \
|
||||||
|
"\t- <opts> replace crontab from stdin\n" \
|
||||||
|
"\t-u user specify user\n" \
|
||||||
|
"\t-l [user] list crontab for user\n" \
|
||||||
|
"\t-e [user] edit crontab for user\n" \
|
||||||
|
"\t-d [user] delete crontab for user\n" \
|
||||||
|
"\t-c dir specify crontab directory"
|
||||||
|
|
||||||
|
|
||||||
#define cut_trivial_usage \
|
#define cut_trivial_usage \
|
||||||
"[OPTION]... [FILE]..."
|
"[OPTION]... [FILE]..."
|
||||||
#define cut_full_usage \
|
#define cut_full_usage \
|
||||||
|
@ -25,6 +25,8 @@ endif
|
|||||||
|
|
||||||
MISCUTILS-y:=
|
MISCUTILS-y:=
|
||||||
MISCUTILS-$(CONFIG_ADJTIMEX) += adjtimex.o
|
MISCUTILS-$(CONFIG_ADJTIMEX) += adjtimex.o
|
||||||
|
MISCUTILS-$(CONFIG_CROND) += crond.o
|
||||||
|
MISCUTILS-$(CONFIG_CRONTAB) += crontab.o
|
||||||
MISCUTILS-$(CONFIG_DC) += dc.o
|
MISCUTILS-$(CONFIG_DC) += dc.o
|
||||||
MISCUTILS-$(CONFIG_DUTMP) += dutmp.o
|
MISCUTILS-$(CONFIG_DUTMP) += dutmp.o
|
||||||
MISCUTILS-$(CONFIG_MAKEDEVS) += makedevs.o
|
MISCUTILS-$(CONFIG_MAKEDEVS) += makedevs.o
|
||||||
|
@ -7,6 +7,8 @@ mainmenu_option next_comment
|
|||||||
comment 'Miscellaneous Utilities'
|
comment 'Miscellaneous Utilities'
|
||||||
|
|
||||||
bool 'adjtimex' CONFIG_ADJTIMEX
|
bool 'adjtimex' CONFIG_ADJTIMEX
|
||||||
|
bool 'crond' CONFIG_CROND
|
||||||
|
bool 'crontab' CONFIG_CRONTAB
|
||||||
bool 'dc' CONFIG_DC
|
bool 'dc' CONFIG_DC
|
||||||
bool 'dutmp' CONFIG_DUTMP
|
bool 'dutmp' CONFIG_DUTMP
|
||||||
bool 'makedevs' CONFIG_MAKEDEVS
|
bool 'makedevs' CONFIG_MAKEDEVS
|
||||||
|
1146
miscutils/crond.c
Normal file
1146
miscutils/crond.c
Normal file
File diff suppressed because it is too large
Load Diff
393
miscutils/crontab.c
Normal file
393
miscutils/crontab.c
Normal file
@ -0,0 +1,393 @@
|
|||||||
|
/*
|
||||||
|
* CRONTAB
|
||||||
|
*
|
||||||
|
* usually setuid root, -c option only works if getuid() == geteuid()
|
||||||
|
*
|
||||||
|
* Copyright 1994 Matthew Dillon (dillon@apollo.west.oic.com)
|
||||||
|
* May be distributed under the GNU General Public License
|
||||||
|
*
|
||||||
|
* Vladimir Oleynik <dzo@simtreas.ru> (C) 2002 to be used in busybox
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
|
#ifndef CRONTABS
|
||||||
|
#define CRONTABS "/var/spool/cron/crontabs"
|
||||||
|
#endif
|
||||||
|
#ifndef TMPDIR
|
||||||
|
#define TMPDIR "/var/spool/cron"
|
||||||
|
#endif
|
||||||
|
#ifndef CRONUPDATE
|
||||||
|
#define CRONUPDATE "cron.update"
|
||||||
|
#endif
|
||||||
|
#ifndef PATH_VI
|
||||||
|
#define PATH_VI "/usr/bin/vi" /* location of vi */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "busybox.h"
|
||||||
|
|
||||||
|
static const char *CDir = CRONTABS;
|
||||||
|
|
||||||
|
static void EditFile(const char *user, const char *file);
|
||||||
|
static int GetReplaceStream(const char *user, const char *file);
|
||||||
|
static int ChangeUser(const char *user, short dochdir);
|
||||||
|
|
||||||
|
int
|
||||||
|
crontab_main(int ac, char **av)
|
||||||
|
{
|
||||||
|
enum { NONE, EDIT, LIST, REPLACE, DELETE } option = NONE;
|
||||||
|
const struct passwd *pas;
|
||||||
|
const char *repFile = NULL;
|
||||||
|
int repFd = 0;
|
||||||
|
int i;
|
||||||
|
char caller[256]; /* user that ran program */
|
||||||
|
int UserId;
|
||||||
|
|
||||||
|
UserId = getuid();
|
||||||
|
if ((pas = getpwuid(UserId)) == NULL)
|
||||||
|
perror_msg_and_die("getpwuid");
|
||||||
|
|
||||||
|
strncpy(caller, pas->pw_name, sizeof(caller));
|
||||||
|
|
||||||
|
i = 1;
|
||||||
|
if (ac > 1) {
|
||||||
|
if (av[1][0] == '-' && av[1][1] == 0) {
|
||||||
|
option = REPLACE;
|
||||||
|
++i;
|
||||||
|
} else if (av[1][0] != '-') {
|
||||||
|
option = REPLACE;
|
||||||
|
++i;
|
||||||
|
repFile = av[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < ac; ++i) {
|
||||||
|
char *ptr = av[i];
|
||||||
|
|
||||||
|
if (*ptr != '-')
|
||||||
|
break;
|
||||||
|
ptr += 2;
|
||||||
|
|
||||||
|
switch(ptr[-1]) {
|
||||||
|
case 'l':
|
||||||
|
if (ptr[-1] == 'l')
|
||||||
|
option = LIST;
|
||||||
|
/* fall through */
|
||||||
|
case 'e':
|
||||||
|
if (ptr[-1] == 'e')
|
||||||
|
option = EDIT;
|
||||||
|
/* fall through */
|
||||||
|
case 'd':
|
||||||
|
if (ptr[-1] == 'd')
|
||||||
|
option = DELETE;
|
||||||
|
/* fall through */
|
||||||
|
case 'u':
|
||||||
|
if (i + 1 < ac && av[i+1][0] != '-') {
|
||||||
|
++i;
|
||||||
|
if (getuid() == geteuid()) {
|
||||||
|
pas = getpwnam(av[i]);
|
||||||
|
if (pas) {
|
||||||
|
UserId = pas->pw_uid;
|
||||||
|
} else {
|
||||||
|
error_msg_and_die("user %s unknown", av[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error_msg_and_die("only the superuser may specify a user");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
if (getuid() == geteuid()) {
|
||||||
|
CDir = (*ptr) ? ptr : av[++i];
|
||||||
|
} else {
|
||||||
|
error_msg_and_die("-c option: superuser only");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
i = ac;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i != ac || option == NONE)
|
||||||
|
show_usage();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get password entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((pas = getpwuid(UserId)) == NULL)
|
||||||
|
perror_msg_and_die("getpwuid");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there is a replacement file, obtain a secure descriptor to it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (repFile) {
|
||||||
|
repFd = GetReplaceStream(caller, repFile);
|
||||||
|
if (repFd < 0)
|
||||||
|
error_msg_and_die("unable to read replacement file");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change directory to our crontab directory
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (chdir(CDir) < 0)
|
||||||
|
perror_msg_and_die("cannot change dir to %s", CDir);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle options as appropriate
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch(option) {
|
||||||
|
case LIST:
|
||||||
|
{
|
||||||
|
FILE *fi;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
if ((fi = fopen(pas->pw_name, "r"))) {
|
||||||
|
while (fgets(buf, sizeof(buf), fi) != NULL)
|
||||||
|
fputs(buf, stdout);
|
||||||
|
fclose(fi);
|
||||||
|
} else {
|
||||||
|
error_msg("no crontab for %s", pas->pw_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EDIT:
|
||||||
|
{
|
||||||
|
FILE *fi;
|
||||||
|
int fd;
|
||||||
|
int n;
|
||||||
|
char tmp[128];
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
snprintf(tmp, sizeof(tmp), TMPDIR "/crontab.%d", getpid());
|
||||||
|
if ((fd = open(tmp, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0600)) >= 0) {
|
||||||
|
chown(tmp, getuid(), getgid());
|
||||||
|
if ((fi = fopen(pas->pw_name, "r"))) {
|
||||||
|
while ((n = fread(buf, 1, sizeof(buf), fi)) > 0)
|
||||||
|
write(fd, buf, n);
|
||||||
|
}
|
||||||
|
EditFile(caller, tmp);
|
||||||
|
remove(tmp);
|
||||||
|
lseek(fd, 0L, 0);
|
||||||
|
repFd = fd;
|
||||||
|
} else {
|
||||||
|
error_msg_and_die("unable to create %s", tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
option = REPLACE;
|
||||||
|
/* fall through */
|
||||||
|
case REPLACE:
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
char path[1024];
|
||||||
|
int fd;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
snprintf(path, sizeof(path), "%s.new", pas->pw_name);
|
||||||
|
if ((fd = open(path, O_CREAT|O_TRUNC|O_EXCL|O_APPEND|O_WRONLY, 0600)) >= 0) {
|
||||||
|
while ((n = read(repFd, buf, sizeof(buf))) > 0) {
|
||||||
|
write(fd, buf, n);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
rename(path, pas->pw_name);
|
||||||
|
} else {
|
||||||
|
error_msg("unable to create %s/%s", CDir, buf);
|
||||||
|
}
|
||||||
|
close(repFd);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DELETE:
|
||||||
|
remove(pas->pw_name);
|
||||||
|
break;
|
||||||
|
case NONE:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bump notification file. Handle window where crond picks file up
|
||||||
|
* before we can write our entry out.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (option == REPLACE || option == DELETE) {
|
||||||
|
FILE *fo;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
while ((fo = fopen(CRONUPDATE, "a"))) {
|
||||||
|
fprintf(fo, "%s\n", pas->pw_name);
|
||||||
|
fflush(fo);
|
||||||
|
if (fstat(fileno(fo), &st) != 0 || st.st_nlink != 0) {
|
||||||
|
fclose(fo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fclose(fo);
|
||||||
|
/* loop */
|
||||||
|
}
|
||||||
|
if (fo == NULL) {
|
||||||
|
error_msg("unable to append to %s/%s", CDir, CRONUPDATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
GetReplaceStream(const char *user, const char *file)
|
||||||
|
{
|
||||||
|
int filedes[2];
|
||||||
|
int pid;
|
||||||
|
int fd;
|
||||||
|
int n;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
if (pipe(filedes) < 0) {
|
||||||
|
perror("pipe");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
if ((pid = fork()) < 0) {
|
||||||
|
perror("fork");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
if (pid > 0) {
|
||||||
|
/*
|
||||||
|
* PARENT
|
||||||
|
*/
|
||||||
|
|
||||||
|
close(filedes[1]);
|
||||||
|
if (read(filedes[0], buf, 1) != 1) {
|
||||||
|
close(filedes[0]);
|
||||||
|
filedes[0] = -1;
|
||||||
|
}
|
||||||
|
return(filedes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CHILD
|
||||||
|
*/
|
||||||
|
|
||||||
|
close(filedes[0]);
|
||||||
|
|
||||||
|
if (ChangeUser(user, 0) < 0)
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
fd = open(file, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
error_msg("unable to open %s", file);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
buf[0] = 0;
|
||||||
|
write(filedes[1], buf, 1);
|
||||||
|
while ((n = read(fd, buf, sizeof(buf))) > 0) {
|
||||||
|
write(filedes[1], buf, n);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
EditFile(const char *user, const char *file)
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
if ((pid = fork()) == 0) {
|
||||||
|
/*
|
||||||
|
* CHILD - change user and run editor
|
||||||
|
*/
|
||||||
|
char *ptr;
|
||||||
|
char visual[1024];
|
||||||
|
|
||||||
|
if (ChangeUser(user, 1) < 0)
|
||||||
|
exit(0);
|
||||||
|
if ((ptr = getenv("VISUAL")) == NULL || strlen(ptr) > 256)
|
||||||
|
ptr = PATH_VI;
|
||||||
|
|
||||||
|
snprintf(visual, sizeof(visual), "%s %s", ptr, file);
|
||||||
|
execl("/bin/sh", "/bin/sh", "-c", visual, NULL);
|
||||||
|
perror("exec");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
if (pid < 0) {
|
||||||
|
/*
|
||||||
|
* PARENT - failure
|
||||||
|
*/
|
||||||
|
perror_msg_and_die("fork");
|
||||||
|
}
|
||||||
|
wait4(pid, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
log(const char *ctl, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
va_start(va, ctl);
|
||||||
|
vsnprintf(buf, sizeof(buf), ctl, va);
|
||||||
|
syslog(LOG_NOTICE, "%s",buf );
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ChangeUser(const char *user, short dochdir)
|
||||||
|
{
|
||||||
|
struct passwd *pas;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtain password entry and change privilages
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((pas = getpwnam(user)) == 0) {
|
||||||
|
log("failed to get uid for %s", user);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
setenv("USER", pas->pw_name, 1);
|
||||||
|
setenv("HOME", pas->pw_dir, 1);
|
||||||
|
setenv("SHELL", "/bin/sh", 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change running state to the user in question
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (initgroups(user, pas->pw_gid) < 0) {
|
||||||
|
log("initgroups failed: %s %m", user);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
if (setregid(pas->pw_gid, pas->pw_gid) < 0) {
|
||||||
|
log("setregid failed: %s %d", user, pas->pw_gid);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
if (setreuid(pas->pw_uid, pas->pw_uid) < 0) {
|
||||||
|
log("setreuid failed: %s %d", user, pas->pw_uid);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
if (dochdir) {
|
||||||
|
if (chdir(pas->pw_dir) < 0) {
|
||||||
|
if (chdir(TMPDIR) < 0) {
|
||||||
|
log("chdir failed: %s %s", user, pas->pw_dir);
|
||||||
|
log("chdir failed: %s " TMPDIR, user);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(pas->pw_uid);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user