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

(-)./msdosfs_vnops.c (-4 / +23 lines)
Lines 171-180 Link Here
171
	error = uniqdosname(pdep, cnp, ndirent.de_Name);
171
	error = uniqdosname(pdep, cnp, ndirent.de_Name);
172
	if (error)
172
	if (error)
173
		goto bad;
173
		goto bad;
174
174
175
	ndirent.de_Attributes = (ap->a_vap->va_mode & VWRITE) ?
175
	ndirent.de_Attributes = ((ap->a_vap->va_mode & VWRITE) ?
176
				ATTR_ARCHIVE : ATTR_ARCHIVE | ATTR_READONLY;
176
				ATTR_ARCHIVE : ATTR_ARCHIVE | ATTR_READONLY) |
177
				((ap->a_vap->va_flags & SF_IMMUTABLE) ?
178
				ATTR_SYSTEM : 0);
177
	ndirent.de_LowerCase = 0;
179
	ndirent.de_LowerCase = 0;
178
	ndirent.de_StartCluster = 0;
180
	ndirent.de_StartCluster = 0;
179
	ndirent.de_FileSize = 0;
181
	ndirent.de_FileSize = 0;
180
	ndirent.de_dev = pdep->de_dev;
182
	ndirent.de_dev = pdep->de_dev;
Lines 275-282 Link Here
275
			break;
277
			break;
276
		}
278
		}
277
	}
279
	}
278
280
281
	/* System (SF_IMMUTABLE) files cannot be written by anyone. */
282
	if ((mode & VEXEC) && (dep->de_Attributes & ATTR_SYSTEM))
283
		return EPERM;
284
279
	return (vaccess(vp->v_type, file_mode, pmp->pm_uid, pmp->pm_gid,
285
	return (vaccess(vp->v_type, file_mode, pmp->pm_uid, pmp->pm_gid,
280
	    ap->a_mode, ap->a_cred, NULL));
286
	    ap->a_mode, ap->a_cred, NULL));
281
}
287
}
282
288
Lines 333-341 Link Here
333
	} else {
339
	} else {
334
		vap->va_atime = vap->va_mtime;
340
		vap->va_atime = vap->va_mtime;
335
		vap->va_ctime = vap->va_mtime;
341
		vap->va_ctime = vap->va_mtime;
336
	}
342
	}
337
	vap->va_flags = 0;
343
	vap->va_flags = (dep->de_Attributes & ATTR_SYSTEM) ? SF_IMMUTABLE : 0;
338
	if ((dep->de_Attributes & ATTR_ARCHIVE) == 0)
344
	if ((dep->de_Attributes & ATTR_ARCHIVE) == 0)
339
		vap->va_flags |= SF_ARCHIVED;
345
		vap->va_flags |= SF_ARCHIVED;
340
	vap->va_gen = 0;
346
	vap->va_gen = 0;
341
	vap->va_blocksize = pmp->pm_bpcluster;
347
	vap->va_blocksize = pmp->pm_bpcluster;
Lines 384-391 Link Here
384
		    vap->va_uid, vap->va_gid);
390
		    vap->va_uid, vap->va_gid);
385
#endif
391
#endif
386
		return (EINVAL);
392
		return (EINVAL);
387
	}
393
	}
394
	/* Check for immutability and securelevel */
395
	if ((dep->de_Attributes & ATTR_SYSTEM) && (securelevel > 0))
396
		return EPERM;
397
	/* Set appropriate flags */
388
	if (vap->va_flags != VNOVAL) {
398
	if (vap->va_flags != VNOVAL) {
389
		if (vp->v_mount->mnt_flag & MNT_RDONLY)
399
		if (vp->v_mount->mnt_flag & MNT_RDONLY)
390
			return (EROFS);
400
			return (EROFS);
391
		if (cred->cr_uid != pmp->pm_uid &&
401
		if (cred->cr_uid != pmp->pm_uid &&
Lines 401-412 Link Here
401
		 * users to attempt to set SF_SETTABLE bits or anyone to
411
		 * users to attempt to set SF_SETTABLE bits or anyone to
402
		 * set unsupported bits.  However, we ignore attempts to
412
		 * set unsupported bits.  However, we ignore attempts to
403
		 * set ATTR_ARCHIVE for directories `cp -pr' from a more
413
		 * set ATTR_ARCHIVE for directories `cp -pr' from a more
404
		 * sensible file system attempts it a lot.
414
		 * sensible file system attempts it a lot.
415
		 *
416
		 * An exception with regards to the SF_SETTABLE bits, is
417
		 * SF_IMMUTABLE, which we map to ATTR_SYSTEM.
405
		 */
418
		 */
406
		if (cred->cr_uid != 0) {
419
		if (cred->cr_uid != 0) {
407
			if (vap->va_flags & SF_SETTABLE)
420
			if (vap->va_flags & (SF_SETTABLE^SF_IMMUTABLE))
408
				return EPERM;
421
				return EPERM;
422
			if (vap->va_flags & SF_IMMUTABLE)
423
				dep->de_Attributes |= ATTR_SYSTEM;
424
			else
425
				dep->de_Attributes &= ~ATTR_SYSTEM;
409
		}
426
		}
410
		if (vap->va_flags & ~SF_ARCHIVED)
427
		if (vap->va_flags & ~SF_ARCHIVED)
411
			return EOPNOTSUPP;
428
			return EOPNOTSUPP;
412
		if (vap->va_flags & SF_ARCHIVED)
429
		if (vap->va_flags & SF_ARCHIVED)
Lines 414-421 Link Here
414
		else if (!(dep->de_Attributes & ATTR_DIRECTORY))
431
		else if (!(dep->de_Attributes & ATTR_DIRECTORY))
415
			dep->de_Attributes |= ATTR_ARCHIVE;
432
			dep->de_Attributes |= ATTR_ARCHIVE;
416
		dep->de_flag |= DE_MODIFIED;
433
		dep->de_flag |= DE_MODIFIED;
417
	}
434
	}
435
	if (dep->de_Attributes & ATTR_SYSTEM)
436
		return EPERM;
418
437
419
	if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
438
	if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
420
		uid_t uid;
439
		uid_t uid;
421
		gid_t gid;
440
		gid_t gid;

Return to bug 21807