]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
Add minimal fchownat and fchmodat implementations.
authorDarren Tucker <dtucker@dtucker.net>
Fri, 18 Jan 2019 00:09:01 +0000 (11:09 +1100)
committerDarren Tucker <dtucker@dtucker.net>
Fri, 18 Jan 2019 00:09:01 +0000 (11:09 +1100)
Fixes builds on at least OS X Lion, NetBSD 6 and Solaris 10.

configure.ac
openbsd-compat/bsd-misc.c
openbsd-compat/bsd-misc.h

index 2d1dafdee136b96ff08b0a105f3d2fc50186cc7e..8e92d15999f8374c53667a080ee78b9813b9d8d5 100644 (file)
@@ -1719,7 +1719,9 @@ AC_CHECK_FUNCS([ \
        errx \
        explicit_bzero \
        fchmod \
+       fchmodat \
        fchown \
+       fchownat \
        flock \
        freeaddrinfo \
        freezero \
index 4bae96548270ee5ef191d071cfd28b2779af1f3a..d3a41df50651fc7828a49af2ba60bbb435be409e 100644 (file)
@@ -154,6 +154,64 @@ utimensat(int fd, const char *path, const struct timespec times[2],
 }
 #endif
 
+#ifndef HAVE_FCHOWNAT
+/*
+ * A limited implementation of fchownat() that only implements the
+ * functionality used by OpenSSH, currently only AT_FDCWD and
+ * AT_SYMLINK_NOFOLLOW.
+ */
+int
+fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
+{
+       int ret, oflags = O_WRONLY;
+
+       if (fd != AT_FDCWD) {
+               errno = ENOSYS;
+               return -1;
+       }
+# ifndef HAVE_FCHOWN
+       return chown(pathname, owner, group);
+# else
+       if (flag & AT_SYMLINK_NOFOLLOW)
+               oflags |= O_NOFOLLOW;
+       if ((fd = open(path, oflags)) == -1)
+               return -1;
+       ret = fchown(fd, owner, group);
+       close(fd);
+       return ret;
+# endif
+}
+#endif
+
+#ifndef HAVE_FCHMODAT
+/*
+ * A limited implementation of fchmodat() that only implements the
+ * functionality used by OpenSSH, currently only AT_FDCWD and
+ * AT_SYMLINK_NOFOLLOW.
+ */
+int
+fchmodat(int fd, const char *path, mode_t mode, int flag)
+{
+       int ret, oflags = O_WRONLY;
+
+       if (fd != AT_FDCWD) {
+               errno = ENOSYS;
+               return -1;
+       }
+# ifndef HAVE_FCHMOD
+       return chown(pathname, owner, group);
+# else
+       if (flag & AT_SYMLINK_NOFOLLOW)
+               oflags |= O_NOFOLLOW;
+       if ((fd = open(path, oflags)) == -1)
+               return -1;
+       ret = fchmod(fd, mode);
+       close(fd);
+       return ret;
+# endif
+}
+#endif
+
 #ifndef HAVE_TRUNCATE
 int truncate(const char *path, off_t length)
 {
index 584c2b5ef5e5a1d5c7cf0d19a738d0e7ee3d4063..cb158cd5c16bcfd8ab65935d669410520f5c36eb 100644 (file)
@@ -72,6 +72,18 @@ int utimes(char *, struct timeval *);
 int utimensat(int, const char *, const struct timespec[2], int);
 #endif
 
+#ifndef AT_FDCWD
+# define AT_FDCWD (-2)
+#endif
+
+#ifndef HAVE_FCHMODAT
+int fchmodat(int, const char *, mode_t, int);
+#endif
+
+#ifndef HAVE_FCHOWNAT
+int fchownat(int, const char *, uid_t, gid_t, int);
+#endif
+
 #ifndef HAVE_TRUNCATE
 int truncate (const char *, off_t);
 #endif /* HAVE_TRUNCATE */