is wrong resulting in corrupt resource forks after the
conversion. Bug #568.
* FIX: ad: fix for bug #563 broke ad file utilities, bug #570.
+* NEW: afpd: new advanced option controlling permissions and ACLs,
+ from FR #93
Changes in 3.1.2
================
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>chmod request = <replaceable>preserve (default) | ignore | simple</replaceable>
+ <type>(G/V)</type></term>
+
+ <listitem>
+ <para>Advanced permission control that deals with ACLs.</para>
+
+ <itemizedlist>
+ <listitem><para>
+ <option>ignore</option> - UNIX chmod() requests are completely ignored
+ </para></listitem>
+ <listitem><para>
+ <option>preserve</option> - preserve ZFS ACEs for
+ named users and groups or POSIX ACL group mask
+ </para></listitem>
+ <listitem><para>
+ <option>simple</option> - just to a chmod() as
+ requested without any extra steps
+ </para></listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>close vol = <replaceable>BOOLEAN</replaceable> (default:
<emphasis>no</emphasis>) <type>(G)</type></term>
}
if (S_ISDIR(st.st_mode)) {
- if ( chmod_acl( modbuf, (DIRBITS | mode)) < 0 && errno != EPERM ) {
+ if (ochmod(modbuf,
+ DIRBITS | mode,
+ &st,
+ vol_syml_opt(vol) | vol_chmod_opt(vol)
+ ) < 0 && errno != EPERM) {
LOG(log_error, logtype_afpd, "setdeskmode: chmod %s: %s",fullpathname(modbuf), strerror(errno) );
}
- } else if ( chmod_acl( modbuf, mode & ~EXEC_MODE ) < 0 && errno != EPERM ) {
+ } else if (ochmod(modbuf,
+ mode & ~EXEC_MODE,
+ &st,
+ vol_syml_opt(vol) | vol_chmod_opt(vol)
+ ) < 0 && errno != EPERM) {
LOG(log_error, logtype_afpd, "setdeskmode: chmod %s: %s",fullpathname(modbuf), strerror(errno) );
}
}
closedir( sub );
/* XXX: need to preserve special modes */
- if ( chmod_acl( deskp->d_name, (DIRBITS | mode)) < 0 && errno != EPERM ) {
+ if (ochmod(deskp->d_name,
+ DIRBITS | mode,
+ NULL,
+ vol_syml_opt(vol) | vol_chmod_opt(vol)
+ ) < 0 && errno != EPERM) {
LOG(log_error, logtype_afpd, "setdeskmode: chmod %s: %s",fullpathname(deskp->d_name), strerror(errno) );
}
}
EC_FAIL;
}
/* XXX: need to preserve special modes */
- if ( chmod_acl(bdata(dtpath), (DIRBITS | mode)) < 0 && errno != EPERM ) {
+ if (ochmod(bdata(dtpath),
+ DIRBITS | mode,
+ NULL,
+ vol_syml_opt(vol) | vol_chmod_opt(vol)
+ ) < 0 && errno != EPERM) {
LOG(log_error, logtype_afpd, "setdeskmode: chmod %s: %s", bdata(dtpath), strerror(errno));
}
LOG(log_debug, logtype_afpd, "setdirunixmode('%s', mode:%04o) {v_dperm:%04o}",
fullpathname(name), mode, vol->v_dperm);
- mode |= vol->v_dperm;
+ mode |= (vol->v_dperm | DIRBITS) & ~vol->v_umask;
if (dir_rx_set(mode)) {
/* extending right? dir first then .AppleDouble in rf_setdirmode */
- if (chmod_acl(name, (DIRBITS | mode) & ~vol->v_umask) < 0 )
+ if (ochmod(name, mode, NULL,
+ vol_syml_opt(vol) | vol_chmod_opt(vol)
+ ) < 0)
return -1;
}
if (vol->vfs->vfs_setdirunixmode(vol, name, mode, NULL) < 0) {
return -1 ;
}
if (!dir_rx_set(mode)) {
- if (chmod_acl(name, (DIRBITS | mode) & ~vol->v_umask) < 0 )
+ if (ochmod(name, mode, NULL,
+ vol_syml_opt(vol) | vol_chmod_opt(vol)
+ ) < 0)
return -1;
}
return 0;
#ifdef HAVE_ACLS
#define O_NETATALK_ACL (O_NOFOLLOW << 1)
+#define O_IGNORE (O_NOFOLLOW << 2)
#ifdef HAVE_SOLARIS_ACLS
#include <sys/acl.h>
#define AFPVOL_USTATFS (1<<3)
#define AFPVOL_UQUOTA (1<<4)
-/*
- Flags that alter volume behaviour.
- Keep in sync with libatalk/util/volinfo.c
-*/
#define AFPVOL_NOV2TOEACONV (1 << 5) /* no adouble:v2 to adouble:ea conversion */
#define AFPVOL_SPOTLIGHT (1 << 6) /* Index volume for Spotlight searches */
#define AFPVOL_RO (1 << 8) /* read-only volume */
+#define AFPVOL_CHMOD_PRESERVE_ACL (1 << 9) /* try to preserve ACLs */
+#define AFPVOL_CHMOD_IGNORE (1 << 10) /* try to preserve ACLs */
#define AFPVOL_NOSTAT (1 << 16) /* advertise the volume even if we can't stat() it
* maybe because it will be mounted later in preexec */
#define AFPVOL_UNIX_PRIV (1 << 17) /* support unix privileges */
#define vol_unix_priv(vol) ((vol)->v_obj->afp_version >= 30 && ((vol)->v_flags & AFPVOL_UNIX_PRIV))
#define vol_inv_dots(vol) (((vol)->v_flags & AFPVOL_INV_DOTS) ? 1 : 0)
#define vol_syml_opt(vol) (((vol)->v_flags & AFPVOL_FOLLOWSYM) ? 0 : O_NOFOLLOW)
+#define vol_chmod_opt(vol) (((vol)->v_flags & AFPVOL_CHMOD_PRESERVE_ACL) ? O_NETATALK_ACL : \
+ ((vol)->v_flags & AFPVOL_CHMOD_IGNORE) ? O_IGNORE : 0)
#endif
}
}
+ val = getoption(obj->iniconfig, section, "chmod request", preset, NULL);
+ if (val == NULL) {
+ val = atalk_iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "chmod request", "preserve");
+ }
+ if (strcasecmp(val, "ignore") == 0) {
+ volume->v_flags |= AFPVOL_CHMOD_IGNORE;
+ } else if (strcasecmp(val, "preserve") == 0) {
+ volume->v_flags |= AFPVOL_CHMOD_PRESERVE_ACL;
+ } else if (strcasecmp(val, "simple") != 0) {
+ LOG(log_warning, logtype_afpd, "unknown 'chmod request' setting: '%s', using default", val);
+ volume->v_flags |= AFPVOL_CHMOD_PRESERVE_ACL;
+ }
+
/*
* Handle read-only behaviour. semantics:
* 1) neither the rolist nor the rwlist exist -> rw
#include <atalk/unix.h>
#include <atalk/compat.h>
#include <atalk/errchk.h>
+#include <atalk/acl.h>
/* close all FDs >= a specified value */
static void closeall(int fd)
* Options description:
* O_NOFOLLOW: don't chmod() symlinks, do nothing, return 0
* O_NETATALK_ACL: call chmod_acl() instead of chmod()
+ * O_IGNORE: ignore chmod() request, directly return 0
*/
int ochmod(char *path, mode_t mode, const struct stat *st, int options)
{
struct stat sb;
+ if (options & O_IGNORE)
+ return 0;
+
if (!st) {
if (lstat(path, &sb) != 0)
return -1;
mode |= st->st_mode & ~mask; /* keep other bits from previous mode */
- if (ochmod((char *)name, mode & ~vol->v_umask, st, vol_syml_opt(vol) | O_NETATALK_ACL) < 0 && errno != EPERM ) {
+ if (ochmod((char *)name,
+ mode & ~vol->v_umask,
+ st,
+ vol_syml_opt(vol) | vol_chmod_opt(vol)
+ ) < 0 && errno != EPERM ) {
return -1;
}
return 0;
const char *adouble = vol->ad_path(name, ADFLAGS_DIR );
if (dir_rx_set(mode)) {
- if (chmod_acl(ad_dir(adouble), (DIRBITS | mode) & ~vol->v_umask) < 0 )
+ if (ochmod(ad_dir(adouble),
+ (DIRBITS | mode) & ~vol->v_umask,
+ st,
+ vol_syml_opt(vol) | vol_chmod_opt(vol)
+ ) < 0)
return -1;
}
return -1;
if (!dir_rx_set(mode)) {
- if (chmod_acl(ad_dir(adouble), (DIRBITS | mode) & ~vol->v_umask) < 0 )
+ if (ochmod(ad_dir(adouble),
+ (DIRBITS | mode) & ~vol->v_umask,
+ st,
+ vol_syml_opt(vol) | vol_chmod_opt(vol)
+ ) < 0)
return -1 ;
}
return 0;
const char *adouble_p = ad_dir(adouble);
if (dir_rx_set(mode)) {
- if (chmod_acl(ad_dir(adouble), (DIRBITS | mode) & ~vol->v_umask) < 0)
+ if (ochmod(ad_dir(adouble),
+ (DIRBITS | mode) & ~vol->v_umask,
+ st,
+ vol_syml_opt(vol) | vol_chmod_opt(vol)
+ ) < 0)
return -1;
}
return -1;
if (!dir_rx_set(mode)) {
- if (chmod_acl(ad_dir(adouble), (DIRBITS | mode) & ~vol->v_umask) < 0)
+ if (ochmod(ad_dir(adouble),
+ (DIRBITS | mode) & ~vol->v_umask,
+ st,
+ vol_syml_opt(vol) | vol_chmod_opt(vol)
+ ) < 0)
return -1 ;
}
return 0;
.\" Title: afp.conf
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 09 Feb 2013
+.\" Date: 05 Jun 2014
.\" Manual: @NETATALK_VERSION@
.\" Source: @NETATALK_VERSION@
.\" Language: English
.\"
-.TH "AFP\&.CONF" "5" "09 Feb 2013" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.TH "AFP\&.CONF" "5" "05 Jun 2014" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
\fBbasedir regex = /home\fR
.RE
.PP
+chmod request = \fIpreserve (default) | ignore | simple\fR \fB(V)\fR
+.RS 4
+Advanced permission control that deals with ACLs\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+
+\fBignore\fR
+\- UNIX chmod() requests are completely ignored
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+
+\fBpreserve\fR
+\- preserve ZFS ACEs for named users and groups or POSIX ACL group mask
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+
+\fBsimple\fR
+\- just to a chmod() as requested without any extra steps
+.RE
+.RE
+.PP
close vol = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
.RS 4
Whether to close volumes possibly opened by clients when they\*(Aqre removed from the configuration and the configuration is reloaded\&.
Impose a limit on the number of results queried from Tracker via SPARQL queries\&.
.RE
.PP
-spotlight = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
+spotlight = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)/(V)\fR
.RS 4
Whether to enable Spotlight searches\&. Note: once the global option is enabled, any volume that is not enabled won\*(Aqt be searchable at all\&. See also
\fIdbus daemon\fR