Remove the need for rdist(1) to run setuid, thus completely closing any
possibility of a security hole. It now does what rdist-6 does, and calls /usr/bin/rsh if not running as root. There are NO protocol changes, this is 100% compatable with the old rdist, except that it does not need setuid root privs. However, there are some minor differences to the base rdist-6 code in that if it is being run by root, it will call rcmd(3) directly rather than piping everything through rsh(1). This is a little more efficient as it doesn't involve context switching on pipe reads/writes. Also, the -P option was added from rdist-6.1.2, which allows an alternative rsh program to be specified, such as ssh. Note that it requires the fixes to the ssh port to disable the unconditional USE_PIPES option that was recently added. The rcmd(3) optimisation is disabled if a non-rsh program is speficied.
This commit is contained in:
parent
b05a2d987d
commit
fb9e3ade6c
@ -2,11 +2,15 @@
|
||||
|
||||
PROG= rdist
|
||||
CFLAGS+=-I${.CURDIR}
|
||||
SRCS= docmd.c expand.c lookup.c main.c server.c
|
||||
SRCS= docmd.c expand.c lookup.c main.c rshrcmd.c server.c
|
||||
OBJS+= gram.o
|
||||
BINOWN= root
|
||||
BINMODE=4555
|
||||
INSTALLFLAGS=-fschg
|
||||
CLEANFILES=y.tab.h
|
||||
|
||||
# To use the old method, which requires setuid-root and all the baggage and
|
||||
# security holes that goes with it, uncomment:
|
||||
# CFLAGS+= -DDIRECT_RCMD
|
||||
# BINOWN= root
|
||||
# BINMODE=4555
|
||||
# INSTALLFLAGS=-fschg
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -105,6 +105,13 @@
|
||||
|
||||
#define ALLOC(x) (struct x *) malloc(sizeof(struct x))
|
||||
|
||||
/*
|
||||
* RSH Time Out interval (in seconds).
|
||||
* Should be long enough to allow rsh to even the slowest hosts.
|
||||
*/
|
||||
#define RTIMEOUT 180
|
||||
|
||||
|
||||
struct namelist { /* for making lists of strings */
|
||||
char *n_name;
|
||||
struct namelist *n_next;
|
||||
@ -150,6 +157,7 @@ extern struct passwd *pw; /* pointer to static area used by getpwent */
|
||||
extern struct group *gr; /* pointer to static area used by getgrent */
|
||||
extern char host[]; /* host name of master copy */
|
||||
extern char buf[BUFSIZ]; /* general purpose buffer */
|
||||
extern char *path_rsh; /* rsh command to use */
|
||||
|
||||
int any __P((int, char *));
|
||||
char *colon __P((char *));
|
||||
@ -178,3 +186,4 @@ void prnames __P((struct namelist *));
|
||||
void server __P((void));
|
||||
void yyerror __P((char *));
|
||||
int yyparse __P((void));
|
||||
int rshrcmd __P((char **, u_short, char *, char *, char *, int *));
|
||||
|
@ -34,7 +34,7 @@
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "From: @(#)docmd.c 8.1 (Berkeley) 6/9/93";*/
|
||||
static const char rcsid[] =
|
||||
"$Id: docmd.c,v 1.3 1995/05/30 06:33:02 rgrimes Exp $";
|
||||
"$Id: docmd.c,v 1.4 1996/07/12 04:00:13 nate Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "defs.h"
|
||||
@ -56,6 +56,7 @@ static void dodcolon __P((char **,
|
||||
struct namelist *, char *, struct subcmd *));
|
||||
static void notify __P((char *, char *, struct namelist *, time_t));
|
||||
static void rcmptime __P((struct stat *));
|
||||
static int remotecmd __P((char *, char *, char *, char *));
|
||||
|
||||
/*
|
||||
* Do the commands in cmds (initialized by yyparse).
|
||||
@ -129,7 +130,7 @@ doarrow(filev, files, rhost, cmds)
|
||||
int n, ddir, opts = options;
|
||||
|
||||
if (debug)
|
||||
printf("doarrow(%x, %s, %x)\n", files, rhost, cmds);
|
||||
printf("doarrow(%p, %s, %p)\n", files, rhost, cmds);
|
||||
|
||||
if (files == NULL) {
|
||||
error("no files to be updated\n");
|
||||
@ -194,6 +195,54 @@ doarrow(filev, files, rhost, cmds)
|
||||
}
|
||||
}
|
||||
|
||||
static int remotecmd(rhost, luser, ruser, cmd)
|
||||
char *rhost;
|
||||
char *luser, *ruser;
|
||||
char *cmd;
|
||||
{
|
||||
int desc;
|
||||
static int port = -1;
|
||||
|
||||
if (debug) {
|
||||
printf("local user = %s remote user = %s\n", luser, ruser);
|
||||
printf("Remote command = '%s'\n", cmd);
|
||||
}
|
||||
|
||||
(void) fflush(stdout);
|
||||
(void) fflush(stderr);
|
||||
(void) signal(SIGALRM, cleanup);
|
||||
(void) alarm(RTIMEOUT);
|
||||
|
||||
if (geteuid() == 0 && strcmp(path_rsh, _PATH_RSH) == 0) {
|
||||
if (debug)
|
||||
printf("I am root, therefore direct rcmd\n");
|
||||
|
||||
(void) signal(SIGPIPE, cleanup);
|
||||
|
||||
if (port < 0) {
|
||||
struct servent *sp;
|
||||
|
||||
if ((sp = getservbyname("shell", "tcp")) == NULL)
|
||||
fatal("shell/tcp: unknown service");
|
||||
port = sp->s_port;
|
||||
}
|
||||
|
||||
desc = rcmd(&rhost, port, luser, ruser, cmd, 0);
|
||||
} else {
|
||||
if (debug)
|
||||
printf("Remote shell command = '%s'\n", path_rsh);
|
||||
(void) signal(SIGPIPE, SIG_IGN);
|
||||
desc = rshrcmd(&rhost, -1, luser, ruser, cmd, 0);
|
||||
if (desc > 0)
|
||||
(void) signal(SIGPIPE, cleanup);
|
||||
}
|
||||
|
||||
(void) alarm(0);
|
||||
|
||||
return(desc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a connection to the rdist server on the machine rhost.
|
||||
*/
|
||||
@ -207,7 +256,9 @@ makeconn(rhost)
|
||||
char tuser[20];
|
||||
int n;
|
||||
extern char user[];
|
||||
#if defined(DIRECT_RCMD)
|
||||
extern int userid;
|
||||
#endif
|
||||
|
||||
if (debug)
|
||||
printf("makeconn(%s)\n", rhost);
|
||||
@ -251,9 +302,13 @@ makeconn(rhost)
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
#if defined(DIRECT_RCMD)
|
||||
seteuid(0);
|
||||
rem = rcmd(&rhost, port, user, ruser, buf, 0);
|
||||
seteuid(userid);
|
||||
#else
|
||||
rem = remotecmd(rhost, user, ruser, buf);
|
||||
#endif
|
||||
if (rem < 0)
|
||||
return(0);
|
||||
cp = buf;
|
||||
@ -463,7 +518,7 @@ rcmptime(st)
|
||||
int len;
|
||||
|
||||
if (debug)
|
||||
printf("rcmptime(%x)\n", st);
|
||||
printf("rcmptime(%p)\n", st);
|
||||
|
||||
if ((d = opendir(target)) == NULL) {
|
||||
error("%s: %s\n", target, strerror(errno));
|
||||
@ -471,7 +526,7 @@ rcmptime(st)
|
||||
}
|
||||
otp = tp;
|
||||
len = tp - target;
|
||||
while (dp = readdir(d)) {
|
||||
while ((dp = readdir(d))) {
|
||||
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
|
||||
continue;
|
||||
if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {
|
||||
@ -481,7 +536,7 @@ rcmptime(st)
|
||||
tp = otp;
|
||||
*tp++ = '/';
|
||||
cp = dp->d_name;
|
||||
while (*tp++ = *cp++)
|
||||
while ((*tp++ = *cp++))
|
||||
;
|
||||
tp--;
|
||||
cmptime(target);
|
||||
|
@ -91,7 +91,7 @@ expand(list, wh)
|
||||
char *argvbuf[GAVSIZ];
|
||||
|
||||
if (debug) {
|
||||
printf("expand(%x, %d)\nlist = ", list, wh);
|
||||
printf("expand(%p, %d)\nlist = ", list, wh);
|
||||
prnames(list);
|
||||
}
|
||||
|
||||
@ -217,7 +217,7 @@ expstr(s)
|
||||
cp1 = pw->pw_dir;
|
||||
s = cp;
|
||||
}
|
||||
for (cp = path; *cp++ = *cp1++; )
|
||||
for (cp = path; (*cp++ = *cp1++); )
|
||||
;
|
||||
tpathp = pathp = cp - 1;
|
||||
} else {
|
||||
@ -451,7 +451,7 @@ amatch(s, p)
|
||||
case '[':
|
||||
ok = 0;
|
||||
lc = 077777;
|
||||
while (cc = *p++) {
|
||||
while ((cc = *p++)) {
|
||||
if (cc == ']') {
|
||||
if (ok)
|
||||
break;
|
||||
@ -534,7 +534,7 @@ smatch(s, p)
|
||||
case '[':
|
||||
ok = 0;
|
||||
lc = 077777;
|
||||
while (cc = *p++) {
|
||||
while ((cc = *p++)) {
|
||||
if (cc == ']') {
|
||||
if (ok)
|
||||
break;
|
||||
@ -592,10 +592,10 @@ Cat(s1, s2)
|
||||
eargv[eargc - 1] = s = malloc(len);
|
||||
if (s == NULL)
|
||||
fatal("ran out of memory\n");
|
||||
while (*s++ = *s1++ & TRIM)
|
||||
while ((*s++ = *s1++ & TRIM))
|
||||
;
|
||||
s--;
|
||||
while (*s++ = *s2++ & TRIM)
|
||||
while ((*s++ = *s2++ & TRIM))
|
||||
;
|
||||
}
|
||||
|
||||
@ -655,12 +655,12 @@ exptilde(buf, file)
|
||||
*s3 = '/';
|
||||
s2 = pw->pw_dir;
|
||||
}
|
||||
for (s1 = buf; *s1++ = *s2++; )
|
||||
for (s1 = buf; (*s1++ = *s2++); )
|
||||
;
|
||||
s2 = --s1;
|
||||
if (s3 != NULL) {
|
||||
s2++;
|
||||
while (*s1++ = *s3++)
|
||||
while ((*s1++ = *s3++))
|
||||
;
|
||||
}
|
||||
return(s2);
|
||||
|
@ -171,8 +171,8 @@ cmd: INSTALL options opt_namelist SM = {
|
||||
char errbuf[_POSIX2_LINE_MAX];
|
||||
|
||||
for (nl = $2; nl != NULL; nl = nl->n_next) {
|
||||
if (val = regcomp(&rx, nl->n_name,
|
||||
REG_EXTENDED)) {
|
||||
if ((val = regcomp(&rx, nl->n_name,
|
||||
REG_EXTENDED))) {
|
||||
regerror(val, &rx, errbuf,
|
||||
sizeof errbuf);
|
||||
yyerror(errbuf);
|
||||
@ -477,7 +477,7 @@ makestr(str)
|
||||
str = cp = malloc(strlen(s = str) + 1);
|
||||
if (cp == NULL)
|
||||
fatal("ran out of memory\n");
|
||||
while (*cp++ = *s++)
|
||||
while ((*cp++ = *s++))
|
||||
;
|
||||
return(str);
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ define(name)
|
||||
{
|
||||
register char *cp, *s;
|
||||
register struct namelist *nl;
|
||||
struct namelist *value;
|
||||
struct namelist *value = NULL;
|
||||
|
||||
if (debug)
|
||||
printf("define(%s)\n", name);
|
||||
@ -129,7 +129,7 @@ lookup(name, action, value)
|
||||
char buf[256];
|
||||
|
||||
if (debug)
|
||||
printf("lookup(%s, %d, %x)\n", name, action, value);
|
||||
printf("lookup(%s, %d, %p)\n", name, action, value);
|
||||
|
||||
n = 0;
|
||||
for (cp = name; *cp; )
|
||||
|
@ -68,6 +68,7 @@ char user[10]; /* user's name */
|
||||
char homedir[128]; /* user's home directory */
|
||||
int userid; /* user's user ID */
|
||||
int groupid; /* user's group ID */
|
||||
char *path_rsh = _PATH_RSH; /* rsh (or equiv command) path */
|
||||
|
||||
struct passwd *pw; /* pointer to static area used by getpwent */
|
||||
struct group *gr; /* pointer to static area used by getgrent */
|
||||
@ -107,6 +108,12 @@ main(argc, argv)
|
||||
iamremote++;
|
||||
else while (*++arg)
|
||||
switch (*arg) {
|
||||
case 'P':
|
||||
if (--argc <= 0)
|
||||
usage();
|
||||
path_rsh = *++argv;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (--argc <= 0)
|
||||
usage();
|
||||
@ -222,8 +229,9 @@ main(argc, argv)
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
printf("Usage: rdist [-nqbhirvwyD] [-f distfile] [-d var=value] [-m host] [file ...]\n");
|
||||
printf("or: rdist [-nqbhirvwyD] -c source [...] machine[:dest]\n");
|
||||
printf("Usage: rdist [-nqbhirvwyD] [-P /path/to/rsh ] [-f distfile] [-d var=value]\n");
|
||||
printf(" [-m host] [file ...]\n");
|
||||
printf("or: rdist [-nqbhirvwyD] [-P /path/to/rsh ] -c source [...] machine[:dest]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -237,7 +245,7 @@ docmdargs(nargs, args)
|
||||
{
|
||||
register struct namelist *nl, *prev;
|
||||
register char *cp;
|
||||
struct namelist *files, *hosts;
|
||||
struct namelist *files = NULL, *hosts;
|
||||
struct subcmd *cmds;
|
||||
char *dest;
|
||||
static struct namelist tnl = { NULL, NULL };
|
||||
|
@ -36,3 +36,4 @@
|
||||
#include <paths.h>
|
||||
|
||||
#define _PATH_RDIST "rdist"
|
||||
#define _PATH_RSH "/usr/bin/rsh"
|
||||
|
@ -40,12 +40,14 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm rdist
|
||||
.Op Fl nqbRhivwy
|
||||
.Op Fl P Ar rshcmd
|
||||
.Op Fl f Ar distfile
|
||||
.Op Fl d Ar var=value
|
||||
.Op Fl m Ar host
|
||||
.Op Ar name ...
|
||||
.Nm rdist
|
||||
.Op Fl nqbRhivwy
|
||||
.Op Fl P Ar rshcmd
|
||||
.Fl c
|
||||
.Ar name ...
|
||||
.Oo login@ Oc Ns Ar host Ns Op :dest
|
||||
@ -118,9 +120,13 @@ The equivalent distfile is as follows.
|
||||
Options common to both forms:
|
||||
.Pp
|
||||
.Bl -tag -width Ic
|
||||
.It Fl b
|
||||
Binary comparison. Perform a binary comparison and update files if they differ
|
||||
rather than comparing dates and sizes.
|
||||
.It Fl P Ar rshcmd
|
||||
Alternative program to provide
|
||||
.Xr rsh 1 -like
|
||||
transport to the remote server. It must provide a binary-transparent path
|
||||
to the remote server, and must have a command argument syntax that is
|
||||
compatable with
|
||||
.Xr rsh 1 .
|
||||
.It Fl d Ar var=value
|
||||
Define
|
||||
.Ar var
|
||||
|
124
usr.bin/rdist/rshrcmd.c
Normal file
124
usr.bin/rdist/rshrcmd.c
Normal file
@ -0,0 +1,124 @@
|
||||
|
||||
/*
|
||||
* This is an rcmd() replacement originally by
|
||||
* Chris Siebenmann <cks@utcc.utoronto.ca>.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char RCSid[] =
|
||||
"$Id: rshrcmd.c,v 1.7 1995/12/12 00:20:55 mcooper Exp $";
|
||||
#endif
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#if !defined(DIRECT_RCMD)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *
|
||||
xbasename(s)
|
||||
char *s;
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = strrchr(s, '/');
|
||||
if (ret && ret[1])
|
||||
return (ret + 1);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is a replacement rcmd() function that uses the rsh(1c)
|
||||
* program in place of a direct rcmd() function call so as to
|
||||
* avoid having to be root.
|
||||
*/
|
||||
int
|
||||
rshrcmd(ahost, port, luser, ruser, cmd, fd2p)
|
||||
char **ahost;
|
||||
u_short port;
|
||||
char *luser, *ruser, *cmd;
|
||||
int *fd2p;
|
||||
{
|
||||
int cpid;
|
||||
struct hostent *hp;
|
||||
int sp[2];
|
||||
|
||||
/* insure that we are indeed being used as we thought. */
|
||||
if (fd2p != 0)
|
||||
return -1;
|
||||
/* validate remote hostname. */
|
||||
hp = gethostbyname(*ahost);
|
||||
if (hp == 0) {
|
||||
error("%s: unknown host", *ahost);
|
||||
return -1;
|
||||
}
|
||||
/* *ahost = hp->h_name; *//* This makes me nervous. */
|
||||
|
||||
/* get a socketpair we'll use for stdin and stdout. */
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0) {
|
||||
error("socketpair(AF_UNIX, SOCK_STREAM, 0) failed: %s.",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
cpid = fork();
|
||||
if (cpid < 0) {
|
||||
error("fork failed: %s.", strerror(errno));
|
||||
return -1; /* error. */
|
||||
}
|
||||
if (cpid == 0) {
|
||||
/* child. we use sp[1] to be stdin/stdout, and close
|
||||
sp[0]. */
|
||||
(void) close(sp[0]);
|
||||
if (dup2(sp[1], 0) < 0 || dup2(0,1) < 0 || dup2(0, 2) < 0) {
|
||||
error("dup2 failed: %s.", strerror(errno));
|
||||
_exit(255);
|
||||
}
|
||||
/* fork again to lose parent. */
|
||||
cpid = fork();
|
||||
if (cpid < 0) {
|
||||
error("fork to lose parent failed: %s.", strerror(errno));
|
||||
_exit(255);
|
||||
}
|
||||
if (cpid > 0)
|
||||
_exit(0);
|
||||
/* in grandchild here. */
|
||||
|
||||
/*
|
||||
* If we are rdist'ing to "localhost" as the same user
|
||||
* as we are, then avoid running remote shell for efficiency.
|
||||
*/
|
||||
if (strcmp(*ahost, "localhost") == 0 &&
|
||||
strcmp(luser, ruser) == 0) {
|
||||
execlp(_PATH_BSHELL, xbasename(_PATH_BSHELL), "-c",
|
||||
cmd, (char *) NULL);
|
||||
error("execlp %s failed: %s.", _PATH_BSHELL, strerror(errno));
|
||||
} else {
|
||||
execlp(path_rsh, xbasename(path_rsh),
|
||||
*ahost, "-l", ruser, cmd, (char *) NULL);
|
||||
error("execlp %s failed: %s.", path_rsh,
|
||||
strerror(errno));
|
||||
}
|
||||
_exit(255);
|
||||
}
|
||||
if (cpid > 0) {
|
||||
/* parent. close sp[1], return sp[0]. */
|
||||
(void) close(sp[1]);
|
||||
/* reap child. */
|
||||
(void) wait(0);
|
||||
return sp[0];
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* !DIRECT_RCMD */
|
@ -371,7 +371,7 @@ sendf(rname, opts)
|
||||
|
||||
otp = tp;
|
||||
len = tp - target;
|
||||
while (dp = readdir(d)) {
|
||||
while ((dp = readdir(d))) {
|
||||
if (!strcmp(dp->d_name, ".") ||
|
||||
!strcmp(dp->d_name, ".."))
|
||||
continue;
|
||||
@ -383,7 +383,7 @@ sendf(rname, opts)
|
||||
tp = otp;
|
||||
*tp++ = '/';
|
||||
cp = dp->d_name;
|
||||
while (*tp++ = *cp++)
|
||||
while ((*tp++ = *cp++))
|
||||
;
|
||||
tp--;
|
||||
sendf(dp->d_name, opts);
|
||||
@ -498,7 +498,7 @@ sendf(rname, opts)
|
||||
} else
|
||||
ack();
|
||||
f = response();
|
||||
if (f < 0 || f == 0 && (opts & COMPARE))
|
||||
if (f < 0 || (f == 0 && (opts & COMPARE)))
|
||||
return;
|
||||
dospecial:
|
||||
for (sc = subcmds; sc != NULL; sc = sc->sc_next) {
|
||||
@ -564,7 +564,7 @@ update(rname, opts, stp)
|
||||
register time_t mtime;
|
||||
|
||||
if (debug)
|
||||
printf("update(%s, %x, %x)\n", rname, opts, stp);
|
||||
printf("update(%s, %x, %p)\n", rname, opts, stp);
|
||||
|
||||
/*
|
||||
* Check to see if the file exists on the remote machine.
|
||||
@ -697,7 +697,7 @@ recvf(cmd, type)
|
||||
int type;
|
||||
{
|
||||
register char *cp;
|
||||
int f, mode, opts, wrerr, olderrno;
|
||||
int f = -1, mode, opts, wrerr, olderrno;
|
||||
off_t i, size;
|
||||
time_t mtime;
|
||||
struct stat stb;
|
||||
@ -761,7 +761,7 @@ recvf(cmd, type)
|
||||
stp[catname] = tp;
|
||||
if (catname++) {
|
||||
*tp++ = '/';
|
||||
while (*tp++ = *cp++)
|
||||
while ((*tp++ = *cp++))
|
||||
;
|
||||
tp--;
|
||||
}
|
||||
@ -783,8 +783,8 @@ recvf(cmd, type)
|
||||
return;
|
||||
}
|
||||
errno = ENOTDIR;
|
||||
} else if (errno == ENOENT && (mkdir(target, mode) == 0 ||
|
||||
chkparent(target) == 0 && mkdir(target, mode) == 0)) {
|
||||
} else if ((errno == ENOENT && mkdir(target, mode) == 0) ||
|
||||
(chkparent(target) == 0 && mkdir(target, mode) == 0)) {
|
||||
if (fchog(-1, target, owner, group, mode) == 0)
|
||||
ack();
|
||||
return;
|
||||
@ -922,7 +922,7 @@ differ: buf[0] = '\0';
|
||||
note("%s: utimes failed %s: %s\n", host, new, strerror(errno));
|
||||
|
||||
if (fchog(f, new, owner, group, mode) < 0) {
|
||||
badnew2: (void) close(f);
|
||||
badnew2: if (f != -1) (void) close(f);
|
||||
(void) unlink(new);
|
||||
return;
|
||||
}
|
||||
@ -1084,10 +1084,10 @@ fchog(fd, file, owner, group, mode)
|
||||
mode &= ~02000;
|
||||
gid = -1;
|
||||
}
|
||||
ok: if (fd != -1 && fchown(fd, uid, gid) < 0 || chown(file, uid, gid) < 0)
|
||||
ok: if ((fd != -1 && fchown(fd, uid, gid) < 0) || chown(file, uid, gid) < 0)
|
||||
note("%s: %s chown: %s", host, file, strerror(errno));
|
||||
else if (mode & 07000 &&
|
||||
(fd != -1 && fchmod(fd, mode) < 0 || chmod(file, mode) < 0))
|
||||
((fd != -1 && fchmod(fd, mode) < 0) || chmod(file, mode) < 0))
|
||||
note("%s: %s chmod: %s", host, file, strerror(errno));
|
||||
return(0);
|
||||
}
|
||||
@ -1204,7 +1204,7 @@ clean(cp)
|
||||
|
||||
otp = tp;
|
||||
len = tp - target;
|
||||
while (dp = readdir(d)) {
|
||||
while ((dp = readdir(d))) {
|
||||
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
|
||||
continue;
|
||||
if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {
|
||||
@ -1215,7 +1215,7 @@ clean(cp)
|
||||
tp = otp;
|
||||
*tp++ = '/';
|
||||
cp = dp->d_name;;
|
||||
while (*tp++ = *cp++)
|
||||
while ((*tp++ = *cp++))
|
||||
;
|
||||
tp--;
|
||||
if (lstat(target, &stb) < 0) {
|
||||
@ -1284,7 +1284,7 @@ removeit(stp)
|
||||
|
||||
otp = tp;
|
||||
len = tp - target;
|
||||
while (dp = readdir(d)) {
|
||||
while ((dp = readdir(d))) {
|
||||
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
|
||||
continue;
|
||||
if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {
|
||||
@ -1295,7 +1295,7 @@ removeit(stp)
|
||||
tp = otp;
|
||||
*tp++ = '/';
|
||||
cp = dp->d_name;;
|
||||
while (*tp++ = *cp++)
|
||||
while ((*tp++ = *cp++))
|
||||
;
|
||||
tp--;
|
||||
if (lstat(target, &stb) < 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user