/*1* SPDX-License-Identifier: ISC2*3* Copyright (c) 2022 Todd C. Miller <[email protected]>4*5* Permission to use, copy, modify, and distribute this software for any6* purpose with or without fee is hereby granted, provided that the above7* copyright notice and this permission notice appear in all copies.8*9* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES10* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF11* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR12* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES13* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN14* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF15* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.16*/1718#include <config.h>1920#include <fcntl.h>21#include <unistd.h>2223#include <sudo_compat.h>2425#ifndef HAVE_FCHOWNAT26int27sudo_fchownat(int dfd, const char *path, uid_t uid, gid_t gid, int flags)28{29int odfd, ret;3031if (dfd == AT_FDCWD) {32if (flags & AT_SYMLINK_NOFOLLOW)33return lchown(path, uid, gid);34else35return chown(path, uid, gid);36}3738/* Save cwd (cannot use O_PATH on older Linux kernels). */39if ((odfd = open(".", O_RDONLY|O_DIRECTORY)) == -1)40return -1;4142if (fchdir(dfd) == -1) {43close(odfd);44return -1;45}4647if (flags & AT_SYMLINK_NOFOLLOW)48ret = lchown(path, uid, gid);49else50ret = chown(path, uid, gid);5152/* Restore cwd */53if (fchdir(odfd) == -1) {54/* Should not happen */55ret = -1;56}57close(odfd);5859return ret;60}61#endif /* HAVE_FCHOWNAT */626364