View | Details | Raw Unified | Return to bug 20646
Collapse All | Expand All

(-)mysrc/bin/cp/cp.c (-1 / +1 lines)
Lines 388-394 Link Here
388
                         * umask; arguably wrong, but it's been that way
388
                         * umask; arguably wrong, but it's been that way
389
                         * forever.
389
                         * forever.
390
			 */
390
			 */
391
			if (pflag && setfile(curr->fts_statp, 0))
391
			if (pflag && setfile(curr->fts_statp, 0, 1))
392
				badcp = rval = 1;
392
				badcp = rval = 1;
393
			else if (dne)
393
			else if (dne)
394
				(void)chmod(to.p_path,
394
				(void)chmod(to.p_path,
(-)mysrc/bin/cp/extern.h (-1 / +1 lines)
Lines 51-56 Link Here
51
int	copy_file __P((FTSENT *, int));
51
int	copy_file __P((FTSENT *, int));
52
int	copy_link __P((FTSENT *, int));
52
int	copy_link __P((FTSENT *, int));
53
int	copy_special __P((struct stat *, int));
53
int	copy_special __P((struct stat *, int));
54
int	setfile __P((struct stat *, int));
54
int	setfile __P((struct stat *, int, int));
55
void	usage __P((void));
55
void	usage __P((void));
56
__END_DECLS
56
__END_DECLS
(-)mysrc/bin/cp/utils.c (-23 / +44 lines)
Lines 176-182 Link Here
176
	 * to remove it if we created it and its length is 0.
176
	 * to remove it if we created it and its length is 0.
177
	 */
177
	 */
178
178
179
	if (pflag && setfile(fs, to_fd))
179
	/* do not copy flags at this time, or the next (f)chmod() fails */
180
	if (pflag && setfile(fs, to_fd, 0))
180
		rval = 1;
181
		rval = 1;
181
	/*
182
	/*
182
	 * If the source was setuid or setgid, lose the bits unless the
183
	 * If the source was setuid or setgid, lose the bits unless the
Lines 194-199 Link Here
194
			rval = 1;
195
			rval = 1;
195
		}
196
		}
196
	}
197
	}
198
199
	/* setfile() again, just for the file flags */
200
	if (pflag && setfile(fs, to_fd, 2))
201
		rval = 1;
202
197
	(void)close(from_fd);
203
	(void)close(from_fd);
198
	if (close(to_fd)) {
204
	if (close(to_fd)) {
199
		warn("%s", to.p_path);
205
		warn("%s", to.p_path);
Lines 239-245 Link Here
239
		warn("mkfifo: %s", to.p_path);
245
		warn("mkfifo: %s", to.p_path);
240
		return (1);
246
		return (1);
241
	}
247
	}
242
	return (pflag ? setfile(from_stat, 0) : 0);
248
	return (pflag ? setfile(from_stat, 0, 1) : 0);
243
}
249
}
244
250
245
int
251
int
Lines 255-268 Link Here
255
		warn("mknod: %s", to.p_path);
261
		warn("mknod: %s", to.p_path);
256
		return (1);
262
		return (1);
257
	}
263
	}
258
	return (pflag ? setfile(from_stat, 0) : 0);
264
	return (pflag ? setfile(from_stat, 0, 1) : 0);
259
}
265
}
260
266
261
267
262
int
268
int
263
setfile(fs, fd)
269
setfile(fs, fd, setflags)
264
	register struct stat *fs;
270
	register struct stat *fs;
265
	int fd;
271
	int fd, setflags;
272
	/* values for setflags:
273
	   0 - do not touch fd's flags;
274
	   1 - set fd's flags to match fs's flags;
275
	   2 - ONLY set fd's flags to fs's flags, do nothing more
276
277
	   the only reason for setflags to be 2 is in copy_file()
278
	   after the set[ug]id fixup; this would be better if
279
	   the fixup itself were moved here.
280
	*/
266
{
281
{
267
	static struct timeval tv[2];
282
	static struct timeval tv[2];
268
	struct stat ts;
283
	struct stat ts;
Lines 292-319 Link Here
292
	 * the mode; current BSD behavior is to remove all setuid bits on
307
	 * the mode; current BSD behavior is to remove all setuid bits on
293
	 * chown.  If chown fails, lose setuid/setgid bits.
308
	 * chown.  If chown fails, lose setuid/setgid bits.
294
	 */
309
	 */
295
	if (!gotstat || fs->st_uid != ts.st_uid || fs->st_gid != ts.st_gid)
310
296
		if (fd ? fchown(fd, fs->st_uid, fs->st_gid) :
311
	/* Oops. Are we called *after* the copy_file() set[ug]id fixup? */
297
		    chown(to.p_path, fs->st_uid, fs->st_gid)) {
312
	if (setflags != 2) {
298
			if (errno != EPERM) {
313
		if (!gotstat || fs->st_uid != ts.st_uid || fs->st_gid != ts.st_gid)
314
			if (fd ? fchown(fd, fs->st_uid, fs->st_gid) :
315
					chown(to.p_path, fs->st_uid, fs->st_gid)) {
316
				if (errno != EPERM) {
317
					warn("chown: %s", to.p_path);
318
					rval = 1;
319
				}
320
				fs->st_mode &= ~(S_ISUID | S_ISGID);
321
			}
322
		
323
		if (!gotstat || fs->st_mode != ts.st_mode)
324
			if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) {
299
				warn("chown: %s", to.p_path);
325
				warn("chown: %s", to.p_path);
300
				rval = 1;
326
				rval = 1;
301
			}
327
			}
302
			fs->st_mode &= ~(S_ISUID | S_ISGID);
328
	}
303
		}
304
305
	if (!gotstat || fs->st_mode != ts.st_mode)
306
		if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) {
307
			warn("chown: %s", to.p_path);
308
			rval = 1;
309
		}
310
329
311
	if (!gotstat || fs->st_flags != ts.st_flags)
330
	if (setflags) {
312
		if (fd ?
331
		if (!gotstat || fs->st_flags != ts.st_flags)
313
		    fchflags(fd, fs->st_flags) : chflags(to.p_path, fs->st_flags)) {
332
			if (fd ?
314
			warn("chflags: %s", to.p_path);
333
					fchflags(fd, fs->st_flags) : chflags(to.p_path, fs->st_flags)) {
315
			rval = 1;
334
				warn("chflags: %s", to.p_path);
316
		}
335
				rval = 1;
336
			}
337
	}
317
338
318
	return (rval);
339
	return (rval);
319
}
340
}

Return to bug 20646