From 8086e405be87facbc266aa65eb7c070a392df919 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 26 Jun 2013 15:20:41 +0200 Subject: [PATCH] New global/volume option "ignored attributes" Can be used to ignore Finder locks by setting "ignored attributes = all". From FR#80. --- NEWS | 1 + doc/manpages/man5/afp.conf.5.xml | 15 +++++++++++++++ etc/afpd/directory.c | 4 +++- etc/afpd/file.c | 10 ++++++---- etc/afpd/filedir.c | 2 +- include/atalk/globals.h | 1 + include/atalk/volume.h | 1 + libatalk/util/netatalk_conf.c | 18 ++++++++++++++++++ man/man5/afp.conf.5.in | 10 ++++++++++ 9 files changed, 56 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index c8674455..101fc751 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ Changes in 3.0.5 ================ * FIX: Fix a crash when using pam_winbind. Fixes bug #516. +* NEW: New global/volume option "ignored attributes" Changes in 3.0.4 ================ diff --git a/doc/manpages/man5/afp.conf.5.xml b/doc/manpages/man5/afp.conf.5.xml index a09eec5b..0115b897 100644 --- a/doc/manpages/man5/afp.conf.5.xml +++ b/doc/manpages/man5/afp.conf.5.xml @@ -867,6 +867,21 @@ + + ignored attributes = all | nowrite | nodelete | norename + (G)/(V) + + + Speficy a set of file and directory attributes that shall + be ignored by the server, all includes all + the other options. + In OS X when the Finder sets a lock on a file/directory or you + set the BSD uchg flag in the Terminal, all three attributes are + used. Thus in order to ignore the Finder lock/BSD uchg flag, add + set ignored attributes = all. + + + mimic model = model (G) diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index b7dc0701..0bbfade2 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -1478,6 +1478,7 @@ int getdirparams(const AFPObj *obj, ashort = htons(ATTRBIT_INVISIBLE); } else ashort = 0; + ashort &= ~htons(vol->v_ignattr); memcpy( data, &ashort, sizeof( ashort )); data += sizeof( ashort ); break; @@ -1866,6 +1867,7 @@ int setdirparams(struct vol *vol, struct path *path, uint16_t d_bitmap, char *bu ad_getattr(&ad, &bshort); oshort = bshort; if ( ntohs( ashort ) & ATTRBIT_SETCLR ) { + ashort &= ~htons(vol->v_ignattr); bshort |= htons( ntohs( ashort ) & ~ATTRBIT_SETCLR ); } else { bshort &= ~ashort; @@ -2295,7 +2297,7 @@ int deletecurdir(struct vol *vol) ad_getattr(&ad, &ashort); ad_close(&ad, ADFLAGS_HF); - if ((ashort & htons(ATTRBIT_NODELETE))) { + if (!(vol->v_ignattr & ATTRBIT_NODELETE) && (ashort & htons(ATTRBIT_NODELETE))) { return AFPERR_OLOCK; } } diff --git a/etc/afpd/file.c b/etc/afpd/file.c index be1fafe5..daaa84a5 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -377,6 +377,7 @@ int getmetadata(const AFPObj *obj, ashort = htons(ATTRBIT_INVISIBLE); } else ashort = 0; + ashort &= ~htons(vol->v_ignattr); #if 0 /* FIXME do we want a visual clue if the file is read only */ @@ -1022,6 +1023,7 @@ int setfilparams(const AFPObj *obj, struct vol *vol, ad_getattr(adp, &bshort); oshort = bshort; if ( ntohs( ashort ) & ATTRBIT_SETCLR ) { + ashort &= ~htons(vol->v_ignattr); bshort |= htons( ntohs( ashort ) & ~ATTRBIT_SETCLR ); } else { bshort &= ~ashort; @@ -1526,7 +1528,7 @@ done: WRITE lock on read only file. */ -static int check_attrib(struct adouble *adp) +static int check_attrib(const struct vol *vol, struct adouble *adp) { uint16_t bshort = 0; @@ -1534,10 +1536,10 @@ uint16_t bshort = 0; /* * Does kFPDeleteInhibitBit (bit 8) set? */ - if ((bshort & htons(ATTRBIT_NODELETE))) { + if (!(vol->v_ignattr & ATTRBIT_NODELETE) && (bshort & htons(ATTRBIT_NODELETE))) { return AFPERR_OLOCK; } - if ((bshort & htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN))) { + if ((bshort & htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN))) { return AFPERR_BUSY; } return 0; @@ -1562,7 +1564,7 @@ int deletefile(const struct vol *vol, int dirfd, char *file, int checkAttrib) * ad_open would create a 0 byte resource fork */ if ( ad_metadataat(dirfd, file, ADFLAGS_CHECK_OF, &ad) == 0 ) { - if ((err = check_attrib(&ad))) { + if ((err = check_attrib(vol, &ad))) { ad_close(&ad, ADFLAGS_HF | ADFLAGS_CHECK_OF); return err; } diff --git a/etc/afpd/filedir.c b/etc/afpd/filedir.c index 8feac755..234a26e5 100644 --- a/etc/afpd/filedir.c +++ b/etc/afpd/filedir.c @@ -302,7 +302,7 @@ static int moveandrename(struct vol *vol, ad_getattr(adp, &bshort); ad_close(adp, ADFLAGS_HF); - if ((bshort & htons(ATTRBIT_NORENAME))) { + if (!(vol->v_ignattr & ATTRBIT_NORENAME) && (bshort & htons(ATTRBIT_NORENAME))) { rc = AFPERR_OLOCK; goto exit; } diff --git a/include/atalk/globals.h b/include/atalk/globals.h index b2456013..d863df0c 100644 --- a/include/atalk/globals.h +++ b/include/atalk/globals.h @@ -117,6 +117,7 @@ struct afp_options { char *logfile; char *mimicmodel; char *adminauthuser; + char *ignored_attr; struct afp_volume_name volfile; }; diff --git a/include/atalk/volume.h b/include/atalk/volume.h index b185f994..c850c20d 100644 --- a/include/atalk/volume.h +++ b/include/atalk/volume.h @@ -98,6 +98,7 @@ struct vol { int v_preexec_close; char *v_uuid; /* For TimeMachine zeroconf record */ int v_qfd; + uint32_t v_ignattr; /* AFP attributes that shall be ignored */ }; /* load_volumes() flags */ diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index fdc80d63..29e37161 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -778,6 +778,21 @@ static struct vol *creatvol(AFPObj *obj, if (getoption_bool(obj->iniconfig, section, "root preexec close", preset, 0)) volume->v_root_preexec_close = 1; + if ((val = getoption(obj->iniconfig, section, "ignored attributes", preset, obj->options.ignored_attr))) { + if (strstr(val, "all")) { + volume->v_ignattr |= ATTRBIT_NOWRITE | ATTRBIT_NORENAME | ATTRBIT_NODELETE; + } + if (strstr(val, "nowrite")) { + volume->v_ignattr |= ATTRBIT_NOWRITE; + } + if (strstr(val, "norename")) { + volume->v_ignattr |= ATTRBIT_NORENAME; + } + if (strstr(val, "nodelete")) { + volume->v_ignattr |= ATTRBIT_NODELETE; + } + } + /* * Handle read-only behaviour. semantics: * 1) neither the rolist nor the rwlist exist -> rw @@ -1746,6 +1761,7 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->ntseparator = atalk_iniparser_getstrdup(config, INISEC_GLOBAL, "nt separator", NULL); options->mimicmodel = atalk_iniparser_getstrdup(config, INISEC_GLOBAL, "mimic model", NULL); options->adminauthuser = atalk_iniparser_getstrdup(config, INISEC_GLOBAL, "admin auth user",NULL); + options->ignored_attr = atalk_iniparser_getstrdup(config, INISEC_GLOBAL, "ignored attributes", NULL); options->connections = atalk_iniparser_getint (config, INISEC_GLOBAL, "max connections",200); options->passwdminlen = atalk_iniparser_getint (config, INISEC_GLOBAL, "passwd minlen", 0); options->tickleval = atalk_iniparser_getint (config, INISEC_GLOBAL, "tickleval", 30); @@ -1964,6 +1980,8 @@ void afp_config_free(AFPObj *obj) CONFIG_ARG_FREE(obj->options.Cnid_port); if (obj->options.fqdn) CONFIG_ARG_FREE(obj->options.fqdn); + if (obj->options.ignored_attr) + CONFIG_ARG_FREE(obj->options.ignored_attr); if (obj->options.unixcodepage) CONFIG_ARG_FREE(obj->options.unixcodepage); diff --git a/man/man5/afp.conf.5.in b/man/man5/afp.conf.5.in index 90ac57ac..d9a2304c 100644 --- a/man/man5/afp.conf.5.in +++ b/man/man5/afp.conf.5.in @@ -566,6 +566,16 @@ Sets a message to be displayed when clients logon to the server\&. The message s and should be quoted\&. Extended characters are allowed\&. .RE .PP +ignored attributes = \fIall | nowrite | nodelete | norename\fR \fB(G)/(V)\fR +.RS 4 +Speficy a set of file and directory attributes that shall be ignored by the server, +all +includes all the other options\&. +.sp +In OS X when the Finder sets a lock on a file/directory or you set the BSD uchg flag in the Terminal, all three attributes are used\&. Thus in order to ignore the Finder lock/BSD uchg flag, add set +\fIignored attributes = all\fR\&. +.RE +.PP mimic model = \fImodel\fR \fB(G)\fR .RS 4 Specifies the icon model that appears on clients\&. Defaults to off\&. Note that afpd must support Zeroconf\&. Examples: RackMac (same as Xserve), PowerBook, PowerMac, Macmini, iMac, MacBook, MacBookPro, MacBookAir, MacPro, AppleTV1,1, AirPort\&. -- 2.39.2