>> Ребята! Давайте подсказывайте! Будущее Юникс на карте! Я могу объясниться что я
>> делаю.
> Ты код давай, мы сами объясним. :)
--- ./fs/attr.c.orig 2012-08-26 18:07:47.000000000 +0400
+++ ./fs/attr.c 2012-08-27 15:47:22.000000000 +0400
@@ -45,26 +45,29 @@
return 0;
/* Make sure a caller can chown. */
- if ((ia_valid & ATTR_UID) &&
- (current_fsuid() != inode->i_uid ||
- attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
- return -EPERM;
+ if (ia_valid & ATTR_UID) {
+ if ((current_fsuid() == inode->i_uid) ||
+ capable(CAP_CHOWN))
+ printk(KERN_INFO \
+ "Owner of inode %ld on device %u (device information may be wrong) change from %d to %d\n",\
+ inode->i_ino,MINOR(inode->i_rdev),\
+ inode->i_uid,attr->ia_uid);
+
+ else
+ return -EPERM;
+ }
/* Make sure caller can chgrp. */
- if ((ia_valid & ATTR_GID) &&
- (current_fsuid() != inode->i_uid ||
- (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) &&
- !capable(CAP_CHOWN))
+ if ((ia_valid & ATTR_GID) && !is_owner_or_cap(inode))
return -EPERM;
/* Make sure a caller can chmod. */
if (ia_valid & ATTR_MODE) {
if (!is_owner_or_cap(inode))
return -EPERM;
- /* Also check the setgid bit! */
- if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
- inode->i_gid) && !capable(CAP_FSETID))
- attr->ia_mode &= ~S_ISGID;
+ /*S_ISGID set only for member of inode group*/
+ if ((attr->ia_mode & S_ISGID) && !in_group_p(inode->i_gid))
+ return -EPERM;
}
/* Check for setting the inode time. */
@@ -139,10 +142,15 @@
{
unsigned int ia_valid = attr->ia_valid;
- if (ia_valid & ATTR_UID)
- inode->i_uid = attr->ia_uid;
- if (ia_valid & ATTR_GID)
- inode->i_gid = attr->ia_gid;
+ if (ia_valid & ATTR_UID) {
+ inode->i_uid = attr->ia_uid;
+ inode->i_mode &= ~S_ISUID;
+ inode->i_mode &= ~S_ISGID;
+ }
+ if (ia_valid & ATTR_GID) {
+ inode->i_gid = attr->ia_gid;
+ inode->i_mode &= ~S_ISGID;
+ }
if (ia_valid & ATTR_ATIME)
inode->i_atime = timespec_trunc(attr->ia_atime,
inode->i_sb->s_time_gran);
@@ -152,20 +160,14 @@
if (ia_valid & ATTR_CTIME)
inode->i_ctime = timespec_trunc(attr->ia_ctime,
inode->i_sb->s_time_gran);
- if (ia_valid & ATTR_MODE) {
- umode_t mode = attr->ia_mode;
-
- if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
- mode &= ~S_ISGID;
- inode->i_mode = mode;
- }
+ if (ia_valid & ATTR_MODE)
+ inode->i_mode = attr->ia_mode;
}
EXPORT_SYMBOL(setattr_copy);
int notify_change(struct dentry * dentry, struct iattr * attr)
{
struct inode *inode = dentry->d_inode;
- mode_t mode = inode->i_mode;
int error;
struct timespec now;
unsigned int ia_valid = attr->ia_valid;
@@ -203,21 +205,6 @@
(ia_valid & ATTR_MODE))
BUG();
- if (ia_valid & ATTR_KILL_SUID) {
- if (mode & S_ISUID) {
- ia_valid = attr->ia_valid |= ATTR_MODE;
- attr->ia_mode = (inode->i_mode & ~S_ISUID);
- }
- }
- if (ia_valid & ATTR_KILL_SGID) {
- if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
- if (!(ia_valid & ATTR_MODE)) {
- ia_valid = attr->ia_valid |= ATTR_MODE;
- attr->ia_mode = inode->i_mode;
- }
- attr->ia_mode &= ~S_ISGID;
- }
- }
if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))
return 0;