From: Frank Lahm Date: Tue, 31 Jan 2012 10:58:10 +0000 (+0100) Subject: Add become_root() capability to nfsv4_chmod() X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=97ac9ecbfc8df217c3d0143278ddb7abe50adcf7 Add become_root() capability to nfsv4_chmod() --- diff --git a/include/atalk/unix.h b/include/atalk/unix.h index 05d71059..62303692 100644 --- a/include/atalk/unix.h +++ b/include/atalk/unix.h @@ -43,4 +43,8 @@ extern int unix_rename(int sfd, const char *oldpath, int dfd, const char *newpat extern int copy_file(int sfd, const char *src, const char *dst, mode_t mode); extern int copy_file_fd(int sfd, int dfd); extern int copy_ea(const char *ea, int sfd, const char *src, const char *dst, mode_t mode); + +extern void become_root(void); +extern void unbecome_root(void); + #endif /* ATALK_UNIX_H */ diff --git a/libatalk/acl/unix.c b/libatalk/acl/unix.c index 88cc77d2..0d03488e 100644 --- a/libatalk/acl/unix.c +++ b/libatalk/acl/unix.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef HAVE_SOLARIS_ACLS @@ -234,8 +235,16 @@ int nfsv4_chmod(char *name, mode_t mode) if (chmod(name, mode) != 0) /* (3) */ goto exit; - if ((nnaces = get_nfsv4_acl(name, &nacl)) == -1) /* (4) */ - goto exit; + if ((nnaces = get_nfsv4_acl(name, &nacl)) == -1) {/* (4) */ + if (errno != EACCES) + goto exit; + become_root(); + nnaces = get_nfsv4_acl(name, &nacl); + unbecome_root(); + if (nnaces == -1) + goto exit; + } + if ((nnaces = strip_nontrivial_aces(&nacl, nnaces)) == -1) /* (5) */ goto exit; @@ -243,8 +252,17 @@ int nfsv4_chmod(char *name, mode_t mode) goto exit; if ((ret = acl(name, ACE_SETACL, noaces + nnaces, cacl)) != 0) { - LOG(log_error, logtype_afpd, "nfsv4_chmod: error setting acl: %s", strerror(errno)); - goto exit; + if (errno != EACCES) { + LOG(log_error, logtype_afpd, "nfsv4_chmod: error setting acl: %s", strerror(errno)); + goto exit; + } + become_root(); + ret = acl(name, ACE_SETACL, noaces + nnaces, cacl); + unbecome_root(); + if (ret != 0) { + LOG(log_error, logtype_afpd, "nfsv4_chmod: error setting acl: %s", strerror(errno)); + goto exit; + } } exit: @@ -252,7 +270,7 @@ exit: if (nacl) free(nacl); if (cacl) free(cacl); - LOG(log_debug, logtype_afpd, "nfsv4_chmod(\"%s/%s\", %04o): result: %u", + LOG(log_debug, logtype_afpd, "nfsv4_chmod(\"%s/%s\", %04o): result: %d", getcwdpath(), name, mode, ret); return ret; diff --git a/libatalk/util/unix.c b/libatalk/util/unix.c index 0ac210ec..88371e8a 100644 --- a/libatalk/util/unix.c +++ b/libatalk/util/unix.c @@ -95,6 +95,22 @@ int daemonize(int nochdir, int noclose) return 0; } +static uid_t saved_uid = -1; + +void become_root(void) +{ + saved_uid = geteuid(); + if (seteuid(0) != 0) + AFP_PANIC("Can't seteuid(0)"); +} + +void unbecome_root(void) +{ + if (saved_uid == -1 || seteuid(saved_uid) < 0) + AFP_PANIC("Can't seteuid back"); + saved_uid = -1; +} + /*! * @brief get cwd in static buffer *