From d5f8878208f0ab18752aaaa6685495d5eb542e71 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 25 Jul 2013 18:31:11 +0200 Subject: [PATCH] Send optional AFP messages for vetoed files New option "veto messages" can be used to enable sending messages. Then whenever a client tries to access any file or directory with a vetoed name, it will be sent an AFP message indicating the name and the directory. Feature request #81. --- NEWS | 5 +++++ doc/manpages/man5/afp.conf.5.xml | 11 +++++++++++ etc/afpd/directory.c | 8 ++++++++ etc/afpd/messages.c | 13 +++++++++++-- include/atalk/globals.h | 4 ++-- libatalk/util/netatalk_conf.c | 2 ++ man/man5/afp.conf.5.in | 7 +++++++ 7 files changed, 46 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 01a61c95..1c071750 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,11 @@ Changes in 3.0.5 * NEW: New global/volume option "ignored attributes" * FIX: "afp listen" option failed to take IPv6 addresses. Bug #515. * FIX: Fix a possible crash in set_groups. Bug #518. +* NEW: Send optional AFP messages for vetoed files, new option + "veto messages" can be used to enable sending messages. + Then whenever a client tries to access any file or directory + with a vetoed name, it will be sent an AFP message indicating + the name and the directory. From FR #81. Changes in 3.0.4 ================ diff --git a/doc/manpages/man5/afp.conf.5.xml b/doc/manpages/man5/afp.conf.5.xml index e67d651c..48df77b1 100644 --- a/doc/manpages/man5/afp.conf.5.xml +++ b/doc/manpages/man5/afp.conf.5.xml @@ -923,6 +923,17 @@ + + veto message = BOOLEAN (default: + no) (G) + + + Use section as option preset for all + volumes (when set in the [Global] section) or for one volume (when + set in that volume's section). + + + vol dbpath = path (G) diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index 0bbfade2..c1160af2 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -1172,6 +1172,14 @@ struct path *cname(struct vol *vol, struct dir *dir, char **cpath) /* the name is illegal */ LOG(log_info, logtype_afpd, "cname: illegal path: '%s'", ret.u_name); afp_errno = AFPERR_PARAM; + if (vol->v_obj->options.flags & OPTION_VETOMSG) { + bstring message = bformat("Attempt to access vetoed file or directory \"%s\" in directory \"%s\"", + ret.u_name, bdata(dir->d_u_name)); + if (setmessage(bdata(message)) == 0) + /* Client may make multiple attempts, only send the message the first time */ + kill(getpid(), SIGUSR2); + bdestroy(message); + } return NULL; } diff --git a/etc/afpd/messages.c b/etc/afpd/messages.c index 3c85f6a3..5bd965bd 100644 --- a/etc/afpd/messages.c +++ b/etc/afpd/messages.c @@ -27,9 +27,18 @@ static char servermesg[MAXPATHLEN] = ""; static char localized_message[MAXPATHLEN] = ""; -void setmessage(const char *message) +/*! + * Copy AFP message to message buffer + * @param message (r) message to send + * @returns 0 if this message is being set the first time, return 1 if the preceeding + * message was the same + */ +int setmessage(const char *message) { + if (strncmp(message, servermesg, MAXMESGSIZE) == 0) + return 1; strlcpy(servermesg, message, MAXMESGSIZE); + return 0; } void readmessage(AFPObj *obj) @@ -177,6 +186,6 @@ int afp_getsrvrmesg(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, siz *rbuflen += 1; } *rbuflen += outlen; - *message = 0; +// *message = 0; return AFP_OK; } diff --git a/include/atalk/globals.h b/include/atalk/globals.h index d863df0c..61cf247f 100644 --- a/include/atalk/globals.h +++ b/include/atalk/globals.h @@ -48,7 +48,7 @@ #define OPTION_CLOSEVOL (1 << 1) #define OPTION_SERVERNOTIF (1 << 2) #define OPTION_NOSENDFILE (1 << 3) -/* #define OPTION_CUSTOMICON (1 << 4) */ +#define OPTION_VETOMSG (1 << 4) /* whether to send an AFP message for veto file access */ #define OPTION_AFP_READ_LOCK (1 << 5) /* whether to do AFP spec conforming read locks (default: no) */ #define OPTION_ANNOUNCESSH (1 << 6) #define OPTION_UUID (1 << 7) @@ -162,7 +162,7 @@ extern const char *Cnid_port; extern int get_afp_errno (const int param); extern void afp_options_init (struct afp_options *); extern void afp_options_parse_cmdline(AFPObj *obj, int ac, char **av); -extern void setmessage (const char *); +extern int setmessage (const char *); extern void readmessage (AFPObj *); /* afp_util.c */ diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 70e1d6be..4ffbde64 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -1756,6 +1756,8 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->flags |= OPTION_DBUS_AFPSTATS; if (atalk_iniparser_getboolean(config, INISEC_GLOBAL, "afp read locks", 0)) options->flags |= OPTION_AFP_READ_LOCK; + if (atalk_iniparser_getboolean(config, INISEC_GLOBAL, "veto message", 0)) + options->flags |= OPTION_VETOMSG; if (!atalk_iniparser_getboolean(config, INISEC_GLOBAL, "save password", 1)) options->passwdbits |= PASSWD_NOSAVE; if (atalk_iniparser_getboolean(config, INISEC_GLOBAL, "set password", 0)) diff --git a/man/man5/afp.conf.5.in b/man/man5/afp.conf.5.in index 017a6fa4..d9ecb39f 100644 --- a/man/man5/afp.conf.5.in +++ b/man/man5/afp.conf.5.in @@ -595,6 +595,13 @@ solaris share reservations = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR Use share reservations on Solaris\&. Solaris CIFS server uses this too, so this makes a lock coherent multi protocol server\&. .RE .PP +veto message = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR +.RS 4 +Use section +\fBname\fR +as option preset for all volumes (when set in the [Global] section) or for one volume (when set in that volume\*(Aqs section)\&. +.RE +.PP vol dbpath = \fIpath\fR \fB(G)\fR .RS 4 Sets the database information to be stored in path\&. You have to specify a writable location, even if the volume is read only\&. The default is -- 2.39.2