Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #433 from proftpd/facl-use-have-access
Now that we have a refactored pr_fs_have_access() function, we can up…
  • Loading branch information
Castaglia committed Feb 26, 2017
2 parents 0ba0882 + 95f3785 commit 31b6a22
Showing 1 changed file with 11 additions and 87 deletions.
98 changes: 11 additions & 87 deletions modules/mod_facl.c
@@ -1,6 +1,6 @@
/*
* ProFTPD - FTP server daemon
* Copyright (c) 2004-2016 The ProFTPD Project team
* Copyright (c) 2004-2017 The ProFTPD Project team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -62,87 +62,21 @@ static int is_errno_eperm(int xerrno) {
return 0;
}

/* Copied directory from src/fsio.c, since these functions are not
* accessible outside of that file.
*/
static int sys_access(pr_fs_t *fs, const char *path, int mode, uid_t uid,
static int facl_access(pr_fs_t *fs, const char *path, int mode, uid_t uid,
gid_t gid, array_header *suppl_gids) {
mode_t mask;
struct stat st;

pr_fs_clear_cache2(path);
if (pr_fsio_stat(path, &st) < 0) {
return -1;
}

/* Root always succeeds. */
if (uid == PR_ROOT_UID) {
return 0;
}

/* Initialize mask to reflect the permission bits that are applicable for
* the given user. mask contains the user-bits if the user ID equals the
* ID of the file owner. mask contains the group bits if the group ID
* belongs to the group of the file. mask will always contain the other
* bits of the permission bits.
*/
mask = S_IROTH|S_IWOTH|S_IXOTH;

if (st.st_uid == uid) {
mask |= S_IRUSR|S_IWUSR|S_IXUSR;
}

/* Check the current group, as well as all supplementary groups.
* Fortunately, we have this information cached, so accessing it is
* almost free.
*/
if (st.st_gid == gid) {
mask |= S_IRGRP|S_IWGRP|S_IXGRP;

} else {
if (suppl_gids) {
register unsigned int i = 0;

for (i = 0; i < suppl_gids->nelts; i++) {
if (st.st_gid == ((gid_t *) suppl_gids->elts)[i]) {
mask |= S_IRGRP|S_IWGRP|S_IXGRP;
break;
}
}
}
}

mask &= st.st_mode;

/* Perform requested access checks. */
if (mode & R_OK) {
if (!(mask & (S_IRUSR|S_IRGRP|S_IROTH))) {
errno = EACCES;
return -1;
}
}

if (mode & W_OK) {
if (!(mask & (S_IWUSR|S_IWGRP|S_IWOTH))) {
errno = EACCES;
return -1;
}
}

if (mode & X_OK) {
if (!(mask & (S_IXUSR|S_IXGRP|S_IXOTH))) {
errno = EACCES;
return -1;
}
}

/* F_OK already checked by checking the return value of stat. */
return 0;
return pr_fs_have_access(&st, mode, uid, gid, suppl_gids);
}

static int sys_faccess(pr_fh_t *fh, int mode, uid_t uid, gid_t gid,
static int facl_faccess(pr_fh_t *fh, int mode, uid_t uid, gid_t gid,
array_header *suppl_gids) {
return sys_access(fh->fh_fs, fh->fh_path, mode, uid, gid, suppl_gids);
return facl_access(fh->fh_fs, fh->fh_path, mode, uid, gid, suppl_gids);
}

#if defined(HAVE_BSD_POSIX_ACL) || \
Expand Down Expand Up @@ -1065,12 +999,7 @@ static int facl_fsio_access(pr_fs_t *fs, const char *path, int mode,
pr_trace_msg(trace_channel, 3, "ACL retrieval operation not supported "
"for '%s', falling back to normal access check", path);

/* Fall back to the custom access() function defined in src/fsio.
* Since that sys_access() function there is not public, we have
* to duplicate the code. For now, that is, until a more clean
* arrangement can be found.
*/
if (sys_access(fs, path, mode, uid, gid, suppl_gids) < 0) {
if (facl_access(fs, path, mode, uid, gid, suppl_gids) < 0) {
xerrno = errno;

pr_trace_msg(trace_channel, 6, "normal access check for '%s' "
Expand Down Expand Up @@ -1100,7 +1029,7 @@ static int facl_fsio_access(pr_fs_t *fs, const char *path, int mode,
pr_trace_msg(trace_channel, 3, "ACL retrieval operation not supported "
"for '%s', falling back to normal access check", path);

if (sys_access(fs, path, mode, uid, gid, suppl_gids) < 0) {
if (facl_access(fs, path, mode, uid, gid, suppl_gids) < 0) {
xerrno = errno;

pr_trace_msg(trace_channel, 6, "normal access check for '%s' "
Expand Down Expand Up @@ -1141,7 +1070,7 @@ static int facl_fsio_access(pr_fs_t *fs, const char *path, int mode,
pr_trace_msg(trace_channel, 3, "ACL retrieval operation not supported "
"for '%s', falling back to normal access check", path);

if (sys_access(fs, path, mode, uid, gid, suppl_gids) < 0) {
if (facl_access(fs, path, mode, uid, gid, suppl_gids) < 0) {
xerrno = errno;

pr_trace_msg(trace_channel, 6, "normal access check for '%s' "
Expand Down Expand Up @@ -1205,12 +1134,7 @@ static int facl_fsio_faccess(pr_fh_t *fh, int mode, uid_t uid, gid_t gid,
pr_trace_msg(trace_channel, 3, "ACL retrieval operation not supported "
"for '%s', falling back to normal access check", fh->fh_path);

/* Fall back to the custom faccess() function defined in src/fsio.
* Since that sys_faccess() function there is not public, we have
* to duplicate the code. For now, that is, until a more clean
* arrangement can be found.
*/
if (sys_faccess(fh, mode, uid, gid, suppl_gids) < 0) {
if (facl_faccess(fh, mode, uid, gid, suppl_gids) < 0) {
xerrno = errno;

pr_trace_msg(trace_channel, 6, "normal access check for '%s' "
Expand Down Expand Up @@ -1240,7 +1164,7 @@ static int facl_fsio_faccess(pr_fh_t *fh, int mode, uid_t uid, gid_t gid,
pr_trace_msg(trace_channel, 3, "ACL retrieval operation not supported "
"for '%s', falling back to normal access check", fh->fh_path);

if (sys_faccess(fh, mode, uid, gid, suppl_gids) < 0) {
if (facl_faccess(fh, mode, uid, gid, suppl_gids) < 0) {
xerrno = errno;

pr_trace_msg(trace_channel, 6, "normal access check for '%s' "
Expand Down Expand Up @@ -1278,7 +1202,7 @@ static int facl_fsio_faccess(pr_fh_t *fh, int mode, uid_t uid, gid_t gid,
pr_trace_msg(trace_channel, 3, "ACL retrieval operation not supported "
"for '%s', falling back to normal access check", fh->fh_path);

if (sys_faccess(fh, mode, uid, gid, suppl_gids) < 0) {
if (facl_faccess(fh, mode, uid, gid, suppl_gids) < 0) {
xerrno = errno;

pr_trace_msg(trace_channel, 6, "normal access check for '%s' "
Expand Down

0 comments on commit 31b6a22

Please sign in to comment.