aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/rdist
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/rdist')
-rw-r--r--usr.bin/rdist/docmd.c2
-rw-r--r--usr.bin/rdist/expand.c2
-rw-r--r--usr.bin/rdist/rdist.14
-rw-r--r--usr.bin/rdist/server.c95
4 files changed, 77 insertions, 26 deletions
diff --git a/usr.bin/rdist/docmd.c b/usr.bin/rdist/docmd.c
index b99d12609f83..e73c1b7afc17 100644
--- a/usr.bin/rdist/docmd.c
+++ b/usr.bin/rdist/docmd.c
@@ -36,6 +36,7 @@ static char sccsid[] = "@(#)docmd.c 5.8 (Berkeley) 3/1/91";
#endif /* not lint */
#include "defs.h"
+#include <stdlib.h>
#include <setjmp.h>
#include <netdb.h>
@@ -506,6 +507,7 @@ notify(file, rhost, to, lmod)
* Create a pipe to mailling program.
*/
(void)sprintf(buf, "%s -oi -t", _PATH_SENDMAIL);
+ unsetenv("IFS");
pf = popen(buf, "w");
if (pf == NULL) {
error("notify: \"%s\" failed\n", _PATH_SENDMAIL);
diff --git a/usr.bin/rdist/expand.c b/usr.bin/rdist/expand.c
index d3c0e9e7a964..69889b755078 100644
--- a/usr.bin/rdist/expand.c
+++ b/usr.bin/rdist/expand.c
@@ -58,7 +58,7 @@ char *entp;
char **sortbase;
char *index();
-int argcmp();
+static int argcmp();
#define sort() qsort((char *)sortbase, &eargv[eargc] - sortbase, \
sizeof(*sortbase), argcmp), sortbase = &eargv[eargc]
diff --git a/usr.bin/rdist/rdist.1 b/usr.bin/rdist/rdist.1
index 42e200d463f0..11a17b58ede4 100644
--- a/usr.bin/rdist/rdist.1
+++ b/usr.bin/rdist/rdist.1
@@ -139,7 +139,7 @@ link itself.
.It Fl i
Ignore unresolved links.
.Nm Rdist
-will normally try to maintain the link structure of files being transfered
+will normally try to maintain the link structure of files being transferred
and warn the user if all the links cannot be found.
.It Fl m Ar host
Limit which machines are to be updated. Multiple
@@ -287,7 +287,7 @@ unless the destination name is of the format ``login@host".
The
.Ic notify
command is used to mail the list of files updated (and any errors
-that may have occured) to the listed names.
+that may have occurred) to the listed names.
If no `@' appears in the name, the destination host is appended to
the name
(e.g., name1@host, name2@host, ...).
diff --git a/usr.bin/rdist/server.c b/usr.bin/rdist/server.c
index ca953222102c..4939e7c8c351 100644
--- a/usr.bin/rdist/server.c
+++ b/usr.bin/rdist/server.c
@@ -637,13 +637,19 @@ query(name)
{
struct stat stb;
- if (catname)
+ if (catname) {
+ if (tp - target + 1 + strlen(name) + 1 > sizeof(target)) {
+ errno = EINVAL;
+ goto err;
+ }
(void) sprintf(tp, "/%s", name);
+ }
if (lstat(target, &stb) < 0) {
if (errno == ENOENT)
(void) write(rem, "N\n", 2);
else
+ err:
error("%s:%s: %s\n", host, target, strerror(errno));
*tp = '\0';
return;
@@ -760,7 +766,7 @@ recvf(cmd, type)
errno = ENOTDIR;
} else if (errno == ENOENT && (mkdir(target, mode) == 0 ||
chkparent(target) == 0 && mkdir(target, mode) == 0)) {
- if (chog(target, owner, group, mode) == 0)
+ if (fchog(-1, target, owner, group, mode) == 0)
ack();
return;
}
@@ -819,6 +825,9 @@ recvf(cmd, type)
goto fixup;
}
+ if (stat(target, &stb) != 0)
+ stb.st_atime = 0;
+
if ((f = creat(new, mode)) < 0) {
if (errno != ENOENT || chkparent(new) < 0 ||
(f = creat(new, mode)) < 0)
@@ -852,14 +861,15 @@ recvf(cmd, type)
wrerr++;
}
}
- (void) close(f);
if (response() < 0) {
err();
+ (void) close(f);
(void) unlink(new);
return;
}
if (wrerr) {
error("%s:%s: %s\n", host, new, strerror(errno));
+ (void) close(f);
(void) unlink(new);
return;
}
@@ -872,6 +882,7 @@ recvf(cmd, type)
if ((f2 = fopen(new, "r")) == NULL) {
badn:
error("%s:%s: %s\n", host, new, strerror(errno));
+ (void) close(f);
(void) unlink(new);
return;
}
@@ -879,6 +890,7 @@ recvf(cmd, type)
if (c == EOF) {
(void) fclose(f1);
(void) fclose(f2);
+ (void) close(f);
(void) unlink(new);
ack();
return;
@@ -887,6 +899,7 @@ recvf(cmd, type)
(void) fclose(f2);
if (opts & VERIFY) {
differ:
+ (void) close(f);
(void) unlink(new);
buf[0] = '\0';
(void) sprintf(buf + 1, "need to update: %s\n",target);
@@ -895,20 +908,13 @@ recvf(cmd, type)
}
}
- /*
- * Set last modified time
- */
- tvp[0].tv_sec = stb.st_atime; /* old atime from target */
- tvp[0].tv_usec = 0;
- tvp[1].tv_sec = mtime;
- tvp[1].tv_usec = 0;
- if (utimes(new, tvp) < 0) {
- note("%s:utimes failed %s: %s\n", host, new, strerror(errno));
- }
- if (chog(new, owner, group, mode) < 0) {
+ if (fchog(f, new, owner, group, mode) < 0) {
+ (void) close(f);
(void) unlink(new);
return;
}
+ (void) close(f);
+
fixup:
if (rename(new, target) < 0) {
badt:
@@ -916,6 +922,20 @@ badt:
(void) unlink(new);
return;
}
+
+ if (type == S_IFREG) {
+ /*
+ * Set last modified time
+ */
+ tvp[0].tv_sec = stb.st_atime; /* old atime from target */
+ tvp[0].tv_usec = 0;
+ tvp[1].tv_sec = mtime;
+ tvp[1].tv_usec = 0;
+ if (utimes(target, tvp) < 0) {
+ note("%s:utimes failed %s: %s\n", host, target, strerror(errno));
+ }
+ }
+
if (opts & COMPARE) {
buf[0] = '\0';
(void) sprintf(buf + 1, "updated %s\n", target);
@@ -1011,12 +1031,12 @@ chkparent(name)
/*
* Change owner, group and mode of file.
*/
-chog(file, owner, group, mode)
+fchog(fd, file, owner, group, mode)
char *file, *owner, *group;
int mode;
{
register int i;
- int uid, gid;
+ int uid, gid, ret;
extern char user[];
extern int userid;
@@ -1032,6 +1052,9 @@ chog(file, owner, group, mode)
mode &= ~04000;
uid = 0;
}
+ else
+ note("%s:%s: unknown login name",
+ host, owner);
} else
uid = pw->pw_uid;
} else
@@ -1040,16 +1063,20 @@ chog(file, owner, group, mode)
gid = atoi(group + 1);
goto ok;
}
- } else if ((mode & 04000) && strcmp(user, owner) != 0)
+ } else if ((mode & 04000) && strcmp(user, owner) != 0) {
+ note("%s:%s not owner, clearing setuid", host, user);
mode &= ~04000;
+ }
gid = -1;
if (gr == NULL || strcmp(group, gr->gr_name) != 0) {
if ((*group == ':' && (getgrgid(gid = atoi(group + 1)) == NULL))
|| ((gr = getgrnam(group)) == NULL)) {
if (mode & 02000) {
- note("%s:%s: unknown group", host, group);
+ note("%s:%s: unknown group, clearing setgid", host, group);
mode &= ~02000;
}
+ else
+ note("%s:%s: unknown group", host, group);
} else
gid = gr->gr_gid;
} else
@@ -1058,16 +1085,38 @@ chog(file, owner, group, mode)
if (gr) for (i = 0; gr->gr_mem[i] != NULL; i++)
if (!(strcmp(user, gr->gr_mem[i])))
goto ok;
+ note("%s:%s not in group %s, clearing setgid", host, user, group);
mode &= ~02000;
gid = -1;
}
ok:
- if (chown(file, uid, gid) < 0 ||
- (mode & 07000) && chmod(file, mode) < 0) {
- note("%s: chown or chmod failed: file %s: %s",
- host, file, strerror(errno));
+ if (getuid() != 0)
+ uid = -1;
+ if ( (uid != -1 || gid != -1)
+ && ( fd != -1 && fchown(fd, uid, gid) < 0
+ || fd == -1 && chown(file, uid, gid) < 0
+ )
+ ) {
+ if (mode & 04000) {
+ note("%s:chown failed, clearing setuid", host);
+ mode &= ~04000;
+ }
+ if (mode & 02000) {
+ note("%s:chown failed, clearing setgid", host);
+ mode &= ~02000;
+ }
}
- return(0);
+ ret = 0;
+ if (mode & 07000) {
+ if ( fd != -1 && fchmod(fd, mode) < 0
+ || fd == -1 && chmod(file, mode) < 0
+ ) {
+ ret = -1;
+ note("%s:chmod failed: file %s: %s",
+ host, file, strerror(errno));
+ }
+ }
+ return(ret);
}
/*