chown(2) System Calls Manual chown(2) chown, fchown, lchown, fchownat - C (libc, -lc) #include int chown(const char *path, uid_t owner, gid_t group); int fchown(int fd, uid_t owner, gid_t group); int lchown(const char *path, uid_t owner, gid_t group); #include /* of AT_* */ #include int fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags); glibc (. feature_test_macros(7)): fchown(), lchown(): /* glibc 2.12: */ _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 500 || /* Glibc <= 2.19: */ _BSD_SOURCE fchownat(): glibc 2.10: _POSIX_C_SOURCE >= 200809L glibc 2.10: _ATFILE_SOURCE . chown(), fchown() lchown() , : o chown() changes the ownership of the file specified by path, which is dereferenced if it is a symbolic link. o fchown() , fd. o lchown() chown() , . (Linux: CAP_CHOWN) . , . (Linux: CAP_CHOWN) . owner group -1, . , S_ISUID S_ISGID POSIX , chown() ; Linux Linux 2.2.13, root . (. ., S_IXGRP) S_ISGID , chown(). ( ), . fchownat() fchownat() chown(), , . If path is relative, then it is interpreted relative to the directory referred to by the file descriptor dirfd (rather than relative to the current working directory of the calling process, as is done by chown() for a relative pathname). If path is relative and dirfd is the special value AT_FDCWD, then path is interpreted relative to the current working directory of the calling process (like chown()). If path is absolute, then dirfd is ignored. flags , (OR) ; AT_EMPTY_PATH ( Linux 2.6.39) If path is an empty string, operate on the file referred to by dirfd (which may have been obtained using the open(2) O_PATH flag). In this case, dirfd can refer to any type of file, not just a directory. If dirfd is AT_FDCWD, the call operates on the current working directory. This flag is Linux-specific; define _GNU_SOURCE to obtain its definition. AT_SYMLINK_NOFOLLOW If path is a symbolic link, do not dereference it: instead operate on the link itself, like lchown(). (By default, fchownat() dereferences symbolic links, like chown().) openat(2) fchownat(). 0. -1, errno . , . chown() . EACCES - (. path_resolution(7).) EBADF (fchown()) fd . EBADF (fchownat()) path is relative but dirfd is neither AT_FDCWD nor a valid file descriptor. EFAULT path . EINVAL (fchownat()) flags. EIO (fchown()) (inode) /. ELOOP path . ENAMETOOLONG path . ENOENT . ENOMEM . ENOTDIR . ENOTDIR (fchownat()) path is relative and dirfd is a file descriptor referring to a file other than a directory. EPERM (. ), / . EPERM (immutable) ( FS_IOC_SETFLAGS(2const)). EROFS , . 4.4BSD ( , ). POSIX.1-2008. chown() fchown() lchown() 4.4BSD, SVr4, POSIX.1-2001. fchownat() POSIX.1-2008. Linux 2.6.16, glibc 2.4. (, open(2) mkdir(2)), ID . , , set-group-ID . mount(8) -o grpid ( -o bsdgroups) -o nogrpid ( -o sysvgroups), : o -o grpid, . o -o nogrpid set-group-ID, GID . o -o nogrpid set-group-ID, . Linux 4.12, -o grpid -o nogrpid ext2, ext3, ext4 XFS. , , -o nogrpid. glibc On older kernels where fchownat() is unavailable, the glibc wrapper function falls back to the use of chown() and lchown(). When path is relative, glibc constructs a pathname based on the symbolic link in /proc/self/fd that corresponds to the dirfd argument. NFS chown() NFS, UID. , , , chown() . , . chown(), fchown() lchown() Linux 16- . Linux 2.4 chown32(), fchown32() lchown32(), 32- . glibc chown(), fchown() lchown() . Before Linux 2.1.81 (except 2.1.46), chown() did not follow symbolic links. Since Linux 2.1.81, chown() does follow symbolic links, and there is a new system call lchown() that does not follow symbolic links. Since Linux 2.1.86, this new call (that has the same semantics as the old chown()) has got the same syscall number, and chown() got the newly introduced number. , , , . ID, ( ID getpwnam(3), ). #include #include #include #include #include int main(int argc, char *argv[]) { char *endptr; uid_t uid; struct passwd *pwd; if (argc != 3 || argv[1][0] == '\0') { fprintf(stderr, "%s \n", argv[0]); exit(EXIT_FAILURE); } uid = strtol(argv[1], &endptr, 10); /* Allow a numeric string */ if (*endptr != '\0') { /* Was not pure numeric string */ pwd = getpwnam(argv[1]); /* Try getting UID for username */ if (pwd == NULL) { perror("getpwnam"); exit(EXIT_FAILURE); } uid = pwd->pw_uid; } if (chown(argv[2], uid, -1) == -1) { perror("chown"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } chgrp(1), chown(1), chmod(2), flock(2), path_resolution(7), symlink(7) () Azamat Hackimov , Dmitriy S. Seregin , Dmitry Bolkhovskikh , Katrin Kutepova , Yuri Kozlov , Kirill Rekhov ; GNU (GNU General Public License - GPL, 3 ) , - . - , , () () () <>. Linux 6.15 17 2025 . chown(2)