diff options
Diffstat (limited to 'usr.bin/rdist')
| -rw-r--r-- | usr.bin/rdist/docmd.c | 2 | ||||
| -rw-r--r-- | usr.bin/rdist/expand.c | 2 | ||||
| -rw-r--r-- | usr.bin/rdist/rdist.1 | 4 | ||||
| -rw-r--r-- | usr.bin/rdist/server.c | 95 |
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); } /* |
