return 0;
}
+/* error here means it's not ad ._ adouble:osx file and thus we return 1 */
+int ad_valid_header_osx(const char *path)
+{
+ EC_INIT;
+ int fd;
+ struct adouble adosx;
+ char *buf = &adosx.ad_data[0];
+ ssize_t header_len;
+
+ EC_NEG1( fd = open(path, O_RDONLY) );
+
+ /* read the header */
+ EC_NEG1( header_len = read(fd, buf, AD_DATASZ_OSX) );
+
+ if (header_len < AD_HEADER_LEN)
+ EC_FAIL;
+
+ memcpy(&adosx.ad_magic, buf, sizeof(adosx.ad_magic));
+ memcpy(&adosx.ad_version, buf + ADEDOFF_VERSION, sizeof(adosx.ad_version));
+ adosx.ad_magic = ntohl(adosx.ad_magic);
+ adosx.ad_version = ntohl(adosx.ad_version);
+
+ if ((adosx.ad_magic != AD_MAGIC) || (adosx.ad_version != AD_VERSION2)) {
+ LOG(log_error, logtype_afpd, "ad_valid_header_osx: not an adouble:ox file");
+ EC_FAIL;
+ }
+
+EC_CLEANUP:
+ if (ret != 0)
+ return 1;
+ return 0;
+}
+
/* Read an ._ file, only uses the resofork, finderinfo is taken from EA */
static int ad_header_read_osx(const char *path _U_, struct adouble *ad, const struct stat *hst)
{
#include <arpa/inet.h>
#include <inttypes.h>
#include <time.h>
+#include <regex.h>
#include <atalk/afp.h>
#include <atalk/util.h>
continue;
if (STRCMP(secname, ==, INISEC_HOMES)) {
have_uservol = 1;
- if (obj->username[0] == 0)
+ if (!obj->uid)
/* not an AFP session, but cnid daemon, dbd or ad util */
continue;
- if ((p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "basedir", NULL)) == NULL)
- continue;
- strlcpy(tmp, p, MAXPATHLEN);
- strlcat(tmp, "/", MAXPATHLEN);
- strlcat(tmp, obj->username, MAXPATHLEN);
+ strlcpy(tmp, pwent->pw_dir, MAXPATHLEN);
strlcat(tmp, "/", MAXPATHLEN);
if (p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL))
strlcat(tmp, p, MAXPATHLEN);
char tmpbuf[MAXPATHLEN + 1];
const char *secname, *basedir, *p = NULL, *subpath = NULL, *subpathconfig;
char *user = NULL, *prw;
+ int regexerr = -1;
+ static regex_t reg;
+ regmatch_t match[1];
LOG(log_debug, logtype_afpd, "getvolbypath(\"%s\")", path);
/* might be a user home, check for that and create a volume if yes */
if (!have_uservol)
- EC_FAIL;
+ EC_FAIL_LOG("getvolbypath(\"%s\"): no volume for path", path);
int secnum = iniparser_getnsec(obj->iniconfig);
}
if (STRCMP(secname, !=, INISEC_HOMES))
- EC_FAIL;
-
- EC_NULL_LOG( basedir = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "basedir", NULL) );
+ EC_FAIL_LOG("getvolbypath(\"%s\"): no volume for path", path);
+ EC_NULL_LOG( basedir = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "basedir regex", NULL) );
LOG(log_debug, logtype_afpd, "getvolbypath: user home section: '%s', basedir: '%s'", secname, basedir);
- if (strncmp(path, basedir, strlen(basedir)) != 0)
- EC_FAIL;
+ if (regexerr != 0 && (regexerr = regcomp(®, basedir, REG_EXTENDED)) != 0) {
+ char errbuf[1024];
+ regerror(regexerr, ®, errbuf, sizeof(errbuf));
+ printf("error: %s\n", errbuf);
+ EC_FAIL_LOG("getvolbypath(\"%s\"): bad basedir regex: %s", errbuf);
+ }
+
+ if (regexec(®, path, 1, match, 0) == REG_NOMATCH)
+ EC_FAIL_LOG("getvolbypath(\"%s\"): no volume for path", path);
+
+ if (match[0].rm_eo - match[0].rm_so > MAXPATHLEN)
+ EC_FAIL_LOG("getvolbypath(\"%s\"): path too long", path);
+
+ strncpy(tmpbuf, path + match[0].rm_so, match[0].rm_eo - match[0].rm_so);
+ tmpbuf[match[0].rm_eo - match[0].rm_so] = 0;
+
+ LOG(log_debug, logtype_afpd, "getvolbypath: basedir regex: '%s', basedir match: \"%s\"",
+ basedir, tmpbuf);
- strlcpy(tmpbuf, basedir, MAXPATHLEN);
strlcat(tmpbuf, "/", MAXPATHLEN);
p = path + strlen(basedir);