Browse Source

check metadata on chown/chmod errors when cloning

pull/372/head
Antonio SJ Musumeci 8 years ago
parent
commit
492d895632
  1. 56
      src/fs_base_chmod.hpp
  2. 65
      src/fs_base_chown.hpp
  3. 4
      src/fs_clonefile.cpp
  4. 4
      src/fs_clonepath.cpp

56
src/fs_base_chmod.hpp

@ -21,6 +21,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#include "fs_base_stat.hpp"
#define MODE_BITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
namespace fs namespace fs
{ {
static static
@ -49,6 +53,58 @@ namespace fs
{ {
return ::fchmod(fd,st.st_mode); return ::fchmod(fd,st.st_mode);
} }
static
inline
int
chmod_check_on_error(const std::string &path,
const mode_t mode)
{
int rv;
rv = fs::chmod(path,mode);
if(rv == -1)
{
int error;
struct stat st;
error = errno;
rv = fs::stat(path,st);
if(rv == -1)
return -1;
if((st.st_mode & MODE_BITS) != (mode & MODE_BITS))
return (errno=error,-1);
}
return 0;
}
static
inline
int
fchmod_check_on_error(const int fd,
const struct stat &st)
{
int rv;
rv = fs::fchmod(fd,st);
if(rv == -1)
{
int error;
struct stat tmpst;
error = errno;
rv = fs::fstat(fd,tmpst);
if(rv == -1)
return -1;
if((st.st_mode & MODE_BITS) != (tmpst.st_mode & MODE_BITS))
return (errno=error,-1);
}
return 0;
}
} }
#endif #endif

65
src/fs_base_chown.hpp

@ -25,6 +25,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "fs_base_stat.hpp"
namespace fs namespace fs
{ {
static static
@ -56,6 +58,15 @@ namespace fs
return ::lchown(path.c_str(),uid,gid); return ::lchown(path.c_str(),uid,gid);
} }
static
inline
int
lchown(const std::string &path,
const struct stat &st)
{
return fs::lchown(path,st.st_uid,st.st_gid);
}
static static
inline inline
int int
@ -74,6 +85,60 @@ namespace fs
{ {
return fs::fchown(fd,st.st_uid,st.st_gid); return fs::fchown(fd,st.st_uid,st.st_gid);
} }
static
inline
int
lchown_check_on_error(const std::string &path,
const struct stat &st)
{
int rv;
rv = fs::lchown(path,st);
if(rv == -1)
{
int error;
struct stat tmpst;
error = errno;
rv = fs::lstat(path,tmpst);
if(rv == -1)
return -1;
if((st.st_uid != tmpst.st_uid) ||
(st.st_gid != tmpst.st_gid))
return (errno=error,-1);
}
return 0;
}
static
inline
int
fchown_check_on_error(const int fd,
const struct stat &st)
{
int rv;
rv = fs::fchown(fd,st);
if(rv == -1)
{
int error;
struct stat tmpst;
error = errno;
rv = fs::fstat(fd,tmpst);
if(rv == -1)
return -1;
if((st.st_uid != tmpst.st_uid) ||
(st.st_gid != tmpst.st_gid))
return (errno=error,-1);
}
return 0;
}
} }
#endif #endif

4
src/fs_clonefile.cpp

@ -176,11 +176,11 @@ namespace fs
if((rv == -1) && !ignorable_error(errno)) if((rv == -1) && !ignorable_error(errno))
return -1; return -1;
rv = fs::fchown(fdout,stin);
rv = fs::fchown_check_on_error(fdout,stin);
if(rv == -1) if(rv == -1)
return -1; return -1;
rv = fs::fchmod(fdout,stin);
rv = fs::fchmod_check_on_error(fdout,stin);
if(rv == -1) if(rv == -1)
return -1; return -1;

4
src/fs_clonepath.cpp

@ -82,7 +82,7 @@ namespace fs
if(errno != EEXIST) if(errno != EEXIST)
return -1; return -1;
rv = fs::chmod(topath,st.st_mode);
rv = fs::chmod_check_on_error(topath,st.st_mode);
if(rv == -1) if(rv == -1)
return -1; return -1;
} }
@ -96,7 +96,7 @@ namespace fs
if((rv == -1) && !ignorable_error(errno)) if((rv == -1) && !ignorable_error(errno))
return -1; return -1;
rv = fs::chown(topath,st);
rv = fs::lchown_check_on_error(topath,st);
if(rv == -1) if(rv == -1)
return -1; return -1;

Loading…
Cancel
Save