Explanation on chown(1) POSIX spec

chownposix

The POSIX spec for the chown utility mentions in its rationale section about the chown user:group syntax (formerly chown user.group) (emphasis mine):

The 4.3 BSD method of specifying both owner and group was included in this volume of POSIX.1-2008 because:

  • There are cases where the desired end condition could not be achieved using the chgrp and chown (that only changed the user ID) utilities. (If the current owner is not a member of the desired group and the desired owner is not a member of the current group, the chown() function could fail unless both owner and group are changed at the same time.)

I thought the user:group syntax was a convenience thing. Now the above implies there are things you can do with chown user:group that you can't with chgrp group; chown user

Now that text doesn't make sense to me. In 4.3BSD, only root could change the owner a file so in any case there's no restriction in what he can do.

SysV and a few other systems allow (or used to allow) the owner of a file to change the user and group of a file to anything, but even in those system, that text above doesn't make sense to me. OK, if one does do a chown someone-else the-file, one cannot do chgrp something-else the-file afterwards because one is no longer the owner of the file, but there's nothing preventing him/her from doing the chgrp first (staying the owner of the file) and chown after, and that's not what the text above is exactly saying.

I don't understand what the and the desired owner is not a member of the current group has to do with the problem.

So what are the conditions for which the chown() function could fail unless both owner and group are changed at the same time, and on what system?

Best Answer

The Microsoft Interix Unix subsystem (now retired) for its NT kernel dealt a little differently with user and group permissions than some others do:

User and group information is stored in the Security Access database. Both users and groups are stored in the same database, but group and user names must be unique; no group can have a user's name and vice versa. (This database replaces the /etc/passwd and /etc/groups files in UNIX.) Users and groups are created using the appropriate Windows methodology (User Manager, Active Directory Users and Computers, or Local Users and Groups) or with the Win32 net user command. (Example shell scripts to create and remove users are included in the directory /usr/examples/admin.) Users can belong to many groups.

Here are some more specific manual excerpts:

In Windows, either a user or a group can own an object. This is different from UNIX, in which only a user owns an object.

Windows identifies all users and groups internally by using a security identifier (SID). A hashing algorithm generates SID values that are unique; no two users or groups will have the same SID.

Users and groups that have permission to access an object are identified by their SID. All objects that can be secured by Windows have a discretionary access control list (DACL), which consists of separate entries called access control entries (ACEs). An ACE includes two important pieces of information: a user or group SID, and a description of how much access the individual user or group has to an object.

CHGRP

...Change the group ID for the file ... the user invoking chgrp(1) must belong to the specified group and be the owner of the file, or have appropriate privileges.

CHOWN

...The owner and group operands are both optional; however, one must be specified. If the group operand is specified, it must be preceded by a colon (:).

The owner can be specified by either a numeric user ID or a user name. If a user name is also a numeric user ID, the operand is used as a user name. The group can be either a numeric group ID or a group name. If a group name is also a numeric group ID, the operand is used as a group name.

For security reasons, the ownership of a file can be altered only by a process with appropriate privileges.

As I read it that means that if your user account belongs to a Windows group with sufficient privileges to modify a file's permissions that is owned by that group, then it is possible to effectively chgrp that file outside your user account's control. This amounts to lesser control than you might have with chown and explicit user:group parameters. In that context without the possibility of declaring user: and :group you never could achieve the same results as otherwise.

Here is a link to a detailed look at how Interix interacts with Windows ACLs with a focus on how such knowledge might apply to Samba file-systems on other Unix variants.

Here is a link to a now obsolete Solaris document describing the tunable rstchown which...

Indicates whether the POSIX semantics for the chown(2) system call are in effect...

Apparently, if the parameter is set to a value of 0...

...turning off POSIX semantics opens the potential for various security holes. It also opens the possibility of a user changing ownership of a file to another user and being unable to retrieve the file back without intervention from the user or the system administrator.

Such an option does not invalidate Solaris's POSIX conformance. Just that it is an option at all qualifies it as conformant:

Although all implementations conforming to POSIX.1-2008 support all the features described below, there may be system-dependent or file system-dependent configuration procedures that can remove or modify any or all of these features. Such configurations should not be made if strict compliance is required.

The following symbolic constants shall be defined with a value other than -1. If a constant is defined with the value zero, applications should use the sysconf(), pathconf(), or fpathconf() functions, or the getconf utility, to determine which features are present on the system at that time or for the particular pathname in question.

_POSIX_CHOWN_RESTRICTED

The use of chown() is restricted to a process with appropriate privileges, and to changing the group ID of a file only to the effective group ID of the process or to one of its supplementary group IDs.

The chown() system function - which is the documented system call made by both the chown and chgrp shell utilities - is specified to fail for numerous reasons. Among them:

EACCES Search permission is denied on a component of the path prefix.

ELOOP A loop exists in symbolic links encountered during resolution of the path argument.

EPERM The effective user ID does not match the owner of the file, or the calling process does not have appropriate privileges and _POSIX_CHOWN_RESTRICTED indicates that such privilege is required.

The behavior of granting permissions modification rights to non-root users has never been unique to Solaris, however. There is very excellent - if somewhat dated - coverage of Unix file permissions in this forum post in which the author states:

Originally, Unix allowed a file owner to give away a file. A file's owner could change the owner to someone else. There was no way for a non-root user to undo this operation... BSD [later] removed chown from non-root users ...[in part because]... it implemented disk quotas which could limit how much disk space a user could have in a filesystem... Naughty users could give away large files to sneek past the quotas.

Today, it is not easy to say if a non-root can chown a file. Many versions of Unix allow both behaviors...

Another good - and more recent - mailing-list post quotes this and continues:

The default with most OS's is for chown to be restricted to root only. And there is a consensus that it should stay this way for security considerations. If a non-root user does change the owner of a file and any execute bit is on, the SUID and SGID bits must be cleared. This may or may not happen with root.

I think that last paragraph says it nicely.

That article also references CAP_CHOWN to control that facility on Linux (that should only affect the POSIX_CHOWN_RESTRICTED behavior). There is also the CAP_FOWNER capability, that's a little different in behavior.

And as you point out in 2003:

Note that at least on HPUX, you can change the owner of your files (to root for instance) even if you're not a priviledged user...

...which depended upon a configuration setprivgroup parameter.

In any case in which a non-root user can manipulate file-permissions it is conceivable, as is mentioned in the rationale quoted in your question, that a user might chown a file which that user owns so that it is owned by another user. If the file's group ownership and the chowning user's groups do not align then the user would no longer be capable of modifying that file.

In this scenario chown then chgrp would fail as the user would no longer have permissions to alter that file's permissions, whereas chown user:group - so long as group is among the user's own - would succeed.

There are probably numerous other niche situations that might result similarly, which might include directory sticky and/or setgid bits, file-system and/or implementation-specific access-control lists. This thread is interesting, for instance. The countless permutations are far beyond my own feeble grasp - which is why this answer is wikied. If you're reading this, you believe it is worth improving, and you believe you know how - please do.

There is also extensive documentation on the various possible effects of file permissions, tree traversal, and symbolic links that might effect a similar failure with regards to -Recursive chown applications here:

From POSIX XRAT section headings Third and Fourth Domains :

Generally, users specifying the option for a file hierarchy traversal wish to operate on a single, physical hierarchy, and therefore symbolic links, which may reference files outside of the hierarchy, are ignored. For example, chown owner file is a different operation from the same command with the -R option specified. In this example, the behavior of the command chown owner file is described here, while the behavior of the command chown -R owner file is described in the third and fourth domains.

...There is a security issue with defaulting to a logical walk. Historically, the command chown -R user file has been safe for the superuser because setuid and setgid bits were lost when the ownership of the file was changed. If the walk were logical, changing ownership would no longer be safe because a user might have inserted a symbolic link pointing to any file in the tree. Again, this would necessitate the addition of an option to the commands doing hierarchy traversal to not indirect through the symbolic links, and historical scripts doing recursive walks would instantly become security problems. While this is mostly an issue for system administrators, it is preferable to not have different defaults for different classes of users.

...

In 4.3 BSD, chgrp during tree traversal changed the group of the symbolic link, not the target. Symbolic links in 4.4 BSD did not have owner, group, mode, or other standard UNIX system file attributes.

And from the POSIX chgrp page proper there is this which points to a possible incomplete -Recursive action, or at least to what used to be:

The System V and BSD versions use different exit status codes. Some implementations used the exit status as a count of the number of errors that occurred; this practice is unworkable since it can overflow the range of valid exit status values. The standard developers chose to mask these by specifying only 0 and >0 as exit values.

Related Question