X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Futil%2Fnetatalk_conf.c;h=a08ddebd44dafacaf84a7d8b87fc735e627392a3;hb=be799718387d2e6029cccee369b25ba85bb2fade;hp=39a725c2905e2b5bd82087248c0f413f30ef448e;hpb=33c70ce1349f3e7fcbc5776785f34f3bd89f1d92;p=netatalk.git diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 39a725c2..a08ddebd 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -170,26 +170,28 @@ static char *get_vol_uuid(const AFPObj *obj, const char *volname) As we can't check (requires write access) on ro-volumes, we switch ea:auto volumes that are options:ro to ea:none. */ +#define EABUFSZ 4 static int do_check_ea_support(const struct vol *vol) { int haseas; - char eaname[] = {"org.netatalk.supports-eas.XXXXXX"}; + const char *eaname = "org.netatalk.has-Extended-Attributes"; const char *eacontent = "yes"; + char buf[EABUFSZ]; - if ((vol->v_flags & AFPVOL_RO) == AFPVOL_RO) { - LOG(log_note, logtype_afpd, "read-only volume '%s', can't test for EA support, assuming yes", vol->v_localname); + if (sys_lgetxattr(vol->v_path, eaname, buf, EABUFSZ) != -1) return 1; - } - mktemp(eaname); + if (vol->v_flags & AFPVOL_RO) { + LOG(log_debug, logtype_afpd, "read-only volume '%s', can't test for EA support, assuming yes", vol->v_localname); + return 1; + } become_root(); - if ((sys_setxattr(vol->v_path, eaname, eacontent, 4, 0)) == 0) { - sys_removexattr(vol->v_path, eaname); + if ((sys_setxattr(vol->v_path, eaname, eacontent, strlen(eacontent) + 1, 0)) == 0) { haseas = 1; } else { - LOG(log_warning, logtype_afpd, "volume \"%s\" does not support Extended Attributes or read-only volume root", + LOG(log_warning, logtype_afpd, "volume \"%s\" does not support Extended Attributes or read-only volume", vol->v_localname); haseas = 0; } @@ -202,25 +204,14 @@ static int do_check_ea_support(const struct vol *vol) static void check_ea_support(struct vol *vol) { int haseas; - char eaname[] = {"org.netatalk.supports-eas.XXXXXX"}; - const char *eacontent = "yes"; haseas = do_check_ea_support(vol); if (vol->v_vfs_ea == AFPVOL_EA_AUTO) { - if ((vol->v_flags & AFPVOL_RO) == AFPVOL_RO) { - LOG(log_info, logtype_afpd, "read-only volume '%s', can't test for EA support, disabling EAs", vol->v_localname); - vol->v_vfs_ea = AFPVOL_EA_NONE; - return; - } - - if (haseas) { + if (haseas) vol->v_vfs_ea = AFPVOL_EA_SYS; - } else { - LOG(log_warning, logtype_afpd, "volume \"%s\" does not support Extended Attributes, using ea:ad instead", - vol->v_localname); - vol->v_vfs_ea = AFPVOL_EA_AD; - } + else + vol->v_vfs_ea = AFPVOL_EA_NONE; } if (vol->v_adouble == AD_VERSION_EA) { @@ -571,8 +562,8 @@ static struct vol *creatvol(AFPObj *obj, { EC_INIT; struct vol *volume = NULL; - int suffixlen, vlen, tmpvlen, u8mvlen, macvlen; - char tmpname[AFPVOL_U8MNAMELEN+1]; + int i, suffixlen, vlen, tmpvlen, u8mvlen, macvlen; + char *tmpname; ucs2_t u8mtmpname[(AFPVOL_U8MNAMELEN+1)*2], mactmpname[(AFPVOL_MACNAMELEN+1)*2]; char suffix[6]; /* max is #FFFF */ uint16_t flags; @@ -651,9 +642,14 @@ static struct vol *creatvol(AFPObj *obj, else EC_NULL( volume->v_maccodepage = strdup(obj->options.maccodepage) ); + vlen = strlen(name); + tmpname = strdup(name); + for(i = 0; i < vlen; i++) + if(tmpname[i] == '/') tmpname[i] = ':'; + bstring dbpath; EC_NULL_LOG( val = iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "vol dbpath", _PATH_STATEDIR "CNID/") ); - EC_NULL_LOG( dbpath = bformat("%s/%s/", val, name) ); + EC_NULL_LOG( dbpath = bformat("%s/%s/", val, tmpname) ); EC_NULL_LOG( volume->v_dbpath = strdup(bdata(dbpath)) ); bdestroy(dbpath); @@ -752,7 +748,7 @@ static struct vol *creatvol(AFPObj *obj, if (getoption_bool(obj->iniconfig, section, "acls", preset, 1)) volume->v_flags |= AFPVOL_ACLS; #endif - if (!getoption_bool(obj->iniconfig, section, "convert adouble", preset, 1)) + if (!getoption_bool(obj->iniconfig, section, "convert appledouble", preset, 1)) volume->v_flags |= AFPVOL_NOV2TOEACONV; if (getoption_bool(obj->iniconfig, section, "preexec close", preset, 0)) @@ -765,12 +761,15 @@ static struct vol *creatvol(AFPObj *obj, * 1) neither the rolist nor the rwlist exist -> rw * 2) rolist exists -> ro if user is in it. * 3) rwlist exists -> ro unless user is in it. + * 4) cnid scheme = last -> ro forcibly. */ if (pwd) { if (accessvol(obj, getoption(obj->iniconfig, section, "rolist", preset, NULL), pwd->pw_name) == 1 || accessvol(obj, getoption(obj->iniconfig, section, "rwlist", preset, NULL), pwd->pw_name) == 0) volume->v_flags |= AFPVOL_RO; } + if (0 == strcmp(volume->v_cnidscheme, "last")) + volume->v_flags |= AFPVOL_RO; if ((volume->v_flags & AFPVOL_NODEV)) volume->v_ad_options |= ADVOL_NODEV; @@ -801,12 +800,9 @@ static struct vol *creatvol(AFPObj *obj, /* because v_vid has not been decided yet. */ suffixlen = sprintf(suffix, "#%X", lastvid + 1 ); - - vlen = strlen( name ); - /* Unicode Volume Name */ /* Firstly convert name from unixcharset to UTF8-MAC */ - flags = CONV_IGNORE; + flags = CONV_IGNORE | CONV_ALLOW_SLASH; tmpvlen = convert_charset(obj->options.unixcharset, CH_UTF8_MAC, 0, name, vlen, tmpname, AFPVOL_U8MNAMELEN, &flags); if (tmpvlen <= 0) { strcpy(tmpname, "???"); @@ -816,7 +812,7 @@ static struct vol *creatvol(AFPObj *obj, /* Do we have to mangle ? */ if ( (flags & CONV_REQMANGLE) || (tmpvlen > obj->options.volnamelen)) { if (tmpvlen + suffixlen > obj->options.volnamelen) { - flags = CONV_FORCE; + flags = CONV_FORCE | CONV_ALLOW_SLASH; tmpvlen = convert_charset(obj->options.unixcharset, CH_UTF8_MAC, 0, name, vlen, tmpname, obj->options.volnamelen - suffixlen, &flags); tmpname[tmpvlen >= 0 ? tmpvlen : 0] = 0; } @@ -832,7 +828,7 @@ static struct vol *creatvol(AFPObj *obj, /* Maccharset Volume Name */ /* Firsty convert name from unixcharset to maccharset */ - flags = CONV_IGNORE; + flags = CONV_IGNORE | CONV_ALLOW_SLASH; tmpvlen = convert_charset(obj->options.unixcharset, obj->options.maccharset, 0, name, vlen, tmpname, AFPVOL_U8MNAMELEN, &flags); if (tmpvlen <= 0) { strcpy(tmpname, "???"); @@ -842,7 +838,7 @@ static struct vol *creatvol(AFPObj *obj, /* Do we have to mangle ? */ if ( (flags & CONV_REQMANGLE) || (tmpvlen > AFPVOL_MACNAMELEN)) { if (tmpvlen + suffixlen > AFPVOL_MACNAMELEN) { - flags = CONV_FORCE; + flags = CONV_FORCE | CONV_ALLOW_SLASH; tmpvlen = convert_charset(obj->options.unixcharset, obj->options.maccharset, 0, @@ -897,16 +893,16 @@ static struct vol *creatvol(AFPObj *obj, initvol_vfs(volume); /* get/store uuid from file in afpd master*/ - if (!(pwd) && (volume->v_flags & AFPVOL_TM)) { - char *uuid = get_vol_uuid(obj, volume->v_localname); - if (!uuid) { - LOG(log_error, logtype_afpd, "Volume '%s': couldn't get UUID", - volume->v_localname); - } else { - volume->v_uuid = uuid; - LOG(log_debug, logtype_afpd, "Volume '%s': UUID '%s'", - volume->v_localname, volume->v_uuid); - } + become_root(); + char *uuid = get_vol_uuid(obj, volume->v_localname); + unbecome_root(); + if (!uuid) { + LOG(log_error, logtype_afpd, "Volume '%s': couldn't get UUID", + volume->v_localname); + } else { + volume->v_uuid = uuid; + LOG(log_debug, logtype_afpd, "Volume '%s': UUID '%s'", + volume->v_localname, volume->v_uuid); } /* no errors shall happen beyond this point because the cleanup would mess the volume chain up */ @@ -1031,6 +1027,10 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) LOG(log_warning, logtype_afpd, "home name must contain $u."); p = "$u's home"; } + if (strchr(p, ':') != NULL) { + LOG(log_warning, logtype_afpd, "home name must not contain \":\"."); + p = "$u's home"; + } strlcpy(tmp, p, MAXPATHLEN); } else { strlcpy(tmp, secname, AFPVOL_U8MNAMELEN); @@ -1339,7 +1339,7 @@ struct vol *getvolbypath(AFPObj *obj, const char *path) subpath = prw; strlcat(tmpbuf, user, MAXPATHLEN); - strlcat(obj->username, user, MAXUSERLEN); + strlcpy(obj->username, user, MAXUSERLEN); strlcat(tmpbuf, "/", MAXPATHLEN); /* (6) */ @@ -1432,8 +1432,6 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) /* "server options" boolean options */ if (!iniparser_getboolean(config, INISEC_GLOBAL, "zeroconf", 1)) options->flags |= OPTION_NOZEROCONF; - if (iniparser_getboolean(config, INISEC_GLOBAL, "icon", 0)) - options->flags |= OPTION_CUSTOMICON; if (iniparser_getboolean(config, INISEC_GLOBAL, "advertise ssh", 0)) options->flags |= OPTION_ANNOUNCESSH; if (iniparser_getboolean(config, INISEC_GLOBAL, "map acls", 1)) @@ -1543,7 +1541,7 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) /* unix charset is in [G] only */ if (!(p = iniparser_getstring(config, INISEC_GLOBAL, "unix charset", NULL))) { options->unixcodepage = strdup("UTF8"); - charset_names[CH_UNIX] = strdup("UTF8"); + set_charset_name(CH_UNIX, "UTF8"); } else { if (strcasecmp(p, "LOCALE") == 0) { #if defined(CODESET) @@ -1559,7 +1557,7 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) p = strdup("UTF8"); } options->unixcodepage = strdup(p); - charset_names[CH_UNIX] = strdup(p); + set_charset_name(CH_UNIX, p); } options->unixcharset = CH_UNIX; LOG(log_debug, logtype_afpd, "Global unix charset is %s", options->unixcodepage); @@ -1578,13 +1576,13 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) /* mac charset is in [G] and [V] */ if (!(p = iniparser_getstring(config, INISEC_GLOBAL, "mac charset", NULL))) { options->maccodepage = strdup("MAC_ROMAN"); - charset_names[CH_MAC] = strdup("MAC_ROMAN"); + set_charset_name(CH_MAC, "MAC_ROMAN"); } else { if (strncasecmp(p, "MAC", 3) != 0) { LOG(log_warning, logtype_afpd, "Is '%s' really mac charset? ", p); } options->maccodepage = strdup(p); - charset_names[CH_MAC] = strdup(p); + set_charset_name(CH_MAC, p); } options->maccharset = CH_MAC; LOG(log_debug, logtype_afpd, "Global mac charset is %s", options->maccodepage);