X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Futil%2Fnetatalk_conf.c;h=26406e668e624b4b60b8ddc0f7b1405dfc4554ae;hb=98ada4ea7939f7559444be02961c4edb612f44f8;hp=1bfa3a94c5a15778da2bfa92fcce3a25ca024306;hpb=fb751e80c0bc12c35675fbf1434ceecb4aad47cb;p=netatalk.git diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 1bfa3a94..26406e66 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -772,6 +772,10 @@ static struct vol *creatvol(AFPObj *obj, volume->v_flags |= AFPVOL_NOV2TOEACONV; if (getoption_bool(obj->iniconfig, section, "follow symlinks", preset, 0)) volume->v_flags |= AFPVOL_FOLLOWSYM; + if (getoption_bool(obj->iniconfig, section, "spotlight", preset, obj->options.flags & OPTION_SPOTLIGHT_VOL)) { + volume->v_flags |= AFPVOL_SPOTLIGHT; + obj->options.flags |= OPTION_SPOTLIGHT; + } if (getoption_bool(obj->iniconfig, section, "preexec close", preset, 0)) volume->v_preexec_close = 1; @@ -801,6 +805,8 @@ static struct vol *creatvol(AFPObj *obj, volume->v_ad_options |= ADVOL_INVDOTS; if ((volume->v_flags & AFPVOL_FOLLOWSYM)) volume->v_ad_options |= ADVOL_FOLLO_SYML; + if ((volume->v_flags & AFPVOL_RO)) + volume->v_ad_options |= ADVOL_RO; /* Mac to Unix conversion flags*/ if ((volume->v_flags & AFPVOL_EILSEQ)) @@ -916,16 +922,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 */ @@ -1323,6 +1329,9 @@ int load_volumes(AFPObj *obj) LOG(log_debug, logtype_afpd, "load_volumes: BEGIN"); + if (obj->uid) + pwent = getpwuid(obj->uid); + if (Volumes) { if (!volfile_changed(&obj->options)) goto EC_CLEANUP; @@ -1330,6 +1339,15 @@ int load_volumes(AFPObj *obj) for (vol = Volumes; vol; vol = vol->v_next) { vol->v_deleted = 1; } + if (obj->uid) { + become_root(); + ret = set_groups(obj, pwent); + unbecome_root(); + if (ret != 0) { + LOG(log_error, logtype_afpd, "load_volumes: set_groups: %s", strerror(errno)); + EC_FAIL; + } + } } else { LOG(log_debug, logtype_afpd, "load_volumes: no volumes yet"); EC_ZERO_LOG( lstat(obj->options.configfile, &st) ); @@ -1354,9 +1372,6 @@ int load_volumes(AFPObj *obj) break; } - if (obj->uid) - pwent = getpwuid(obj->uid); - if (obj->iniconfig) iniparser_freedict(obj->iniconfig); LOG(log_debug, logtype_afpd, "load_volumes: loading: %s", obj->options.configfile); @@ -1432,6 +1447,56 @@ struct vol *getvolbyvid(const uint16_t vid ) return( vol ); } +/* + * get username by path + * + * getvolbypath() assumes that the user home directory has the same name as the username. + * If that is not true, getuserbypath() is called and tries to retrieve the username + * from the directory owner, checking its validity. + * + * @param path (r) absolute volume path + * @returns NULL if no match is found, pointer to username if successfull + * + */ +static char *getuserbypath(const char *path) +{ + EC_INIT; + struct stat sbuf; + struct passwd *pwd; + char *hdir = NULL; + + LOG(log_debug, logtype_afpd, "getuserbypath(\"%s\")", path); + + /* does folder exists? */ + if (stat(path, &sbuf) != 0) + EC_FAIL; + + /* get uid of dir owner */ + if ((pwd = getpwuid(sbuf.st_uid)) == NULL) + EC_FAIL; + + /* does user home directory exists? */ + if (stat(pwd->pw_dir, &sbuf) != 0) + EC_FAIL; + + /* resolve and remove symlinks */ + if ((hdir = realpath_safe(pwd->pw_dir)) == NULL) + EC_FAIL; + + /* handle subdirectories, path = */ + if (strncmp(path, hdir, strlen(hdir)) != 0) + EC_FAIL; + + LOG(log_debug, logtype_afpd, "getuserbypath: match user: %s, home: %s, realhome: %s", + pwd->pw_name, pwd->pw_dir, hdir); + +EC_CLEANUP: + if (hdir) + free(hdir); + if (ret != 0) + return NULL; + return pwd->pw_name; +} /*! * Search volume by path, creating user home vols as necessary * @@ -1447,6 +1512,9 @@ struct vol *getvolbyvid(const uint16_t vid ) * (3) If there is, match "path" with "basedir regex" to get the user home parent dir * (4) Built user home path by appending the basedir matched in (3) and appending the username * (5) The next path element then is the username + * (5b) getvolbypath() assumes that the user home directory has the same name as the username. + * If that is not true, getuserbypath() is called and tries to retrieve the username + * from the directory owner, checking its validity * (6) Append [Homes]->path subdirectory if defined * (7) Create volume * @@ -1539,6 +1607,14 @@ struct vol *getvolbypath(AFPObj *obj, const char *path) subpath = prw; strlcat(tmpbuf, user, MAXPATHLEN); + if (getpwnam(user) == NULL) { + /* (5b) */ + char *tuser; + if ((tuser = getuserbypath(tmpbuf)) != NULL) { + free(user); + user = strdup(tuser); + } + } strlcpy(obj->username, user, MAXUSERLEN); strlcat(tmpbuf, "/", MAXPATHLEN); @@ -1622,6 +1698,12 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->configfile = AFPObj->cmdlineconfigfile ? strdup(AFPObj->cmdlineconfigfile) : strdup(_PATH_CONFDIR "afp.conf"); options->sigconffile = strdup(_PATH_STATEDIR "afp_signature.conf"); options->uuidconf = strdup(_PATH_STATEDIR "afp_voluuid.conf"); +#ifdef HAVE_TRACKER_SPARQL + options->slmod_path = strdup(_PATH_AFPDUAMPATH "slmod_sparql.so"); +#endif +#ifdef HAVE_TRACKER_RDF + options->slmod_path = strdup(_PATH_AFPDUAMPATH "slmod_rdf.so"); +#endif options->flags = OPTION_UUID | AFPObj->cmdlineflags; if ((config = iniparser_load(AFPObj->options.configfile)) == NULL) @@ -1639,8 +1721,6 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->flags |= OPTION_NOZEROCONF; if (iniparser_getboolean(config, INISEC_GLOBAL, "advertise ssh", 0)) options->flags |= OPTION_ANNOUNCESSH; - if (iniparser_getboolean(config, INISEC_GLOBAL, "map acls", 1)) - options->flags |= OPTION_ACL2MACCESS; if (iniparser_getboolean(config, INISEC_GLOBAL, "close vol", 0)) options->flags |= OPTION_CLOSEVOL; if (!iniparser_getboolean(config, INISEC_GLOBAL, "client polling", 0)) @@ -1649,8 +1729,12 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->flags |= OPTION_NOSENDFILE; if (iniparser_getboolean(config, INISEC_GLOBAL, "solaris share reservations", 1)) options->flags |= OPTION_SHARE_RESERV; + if (iniparser_getboolean(config, INISEC_GLOBAL, "afpstats", 0)) + options->flags |= OPTION_DBUS_AFPSTATS; if (iniparser_getboolean(config, INISEC_GLOBAL, "afp read locks", 0)) options->flags |= OPTION_AFP_READ_LOCK; + if (iniparser_getboolean(config, INISEC_GLOBAL, "spotlight", 0)) + options->flags |= OPTION_SPOTLIGHT_VOL; if (!iniparser_getboolean(config, INISEC_GLOBAL, "save password", 1)) options->passwdbits |= PASSWD_NOSAVE; if (iniparser_getboolean(config, INISEC_GLOBAL, "set password", 0)) @@ -1668,6 +1752,7 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->k5service = iniparser_getstrdup(config, INISEC_GLOBAL, "k5 service", NULL); options->k5realm = iniparser_getstrdup(config, INISEC_GLOBAL, "k5 realm", NULL); options->listen = iniparser_getstrdup(config, INISEC_GLOBAL, "afp listen", NULL); + options->interfaces = iniparser_getstrdup(config, INISEC_GLOBAL, "afp interfaces", NULL); options->ntdomain = iniparser_getstrdup(config, INISEC_GLOBAL, "nt domain", NULL); options->addomain = iniparser_getstrdup(config, INISEC_GLOBAL, "ad domain", NULL); options->ntseparator = iniparser_getstrdup(config, INISEC_GLOBAL, "nt separator", NULL); @@ -1687,6 +1772,18 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->sleep = iniparser_getint (config, INISEC_GLOBAL, "sleep time", 10); options->disconnected = iniparser_getint (config, INISEC_GLOBAL, "disconnect time",24); + p = iniparser_getstring(config, INISEC_GLOBAL, "map acls", "rights"); + if (STRCMP(p, ==, "rights")) + options->flags |= OPTION_ACL2MACCESS; + else if (STRCMP(p, ==, "mode")) + options->flags |= OPTION_ACL2MODE | OPTION_ACL2MACCESS; + else { + if (STRCMP(p, !=, "none")) { + LOG(log_error, logtype_afpd, "bad ACL mapping option: %s, defaulting to 'rights'", p); + options->flags |= OPTION_ACL2MACCESS; + } + } + if ((p = iniparser_getstring(config, INISEC_GLOBAL, "hostname", NULL))) { EC_NULL_LOG( options->hostname = strdup(p) ); } else { @@ -1857,6 +1954,8 @@ void afp_config_free(AFPObj *obj) CONFIG_ARG_FREE(obj->options.k5realm); if (obj->options.listen) CONFIG_ARG_FREE(obj->options.listen); + if (obj->options.interfaces) + CONFIG_ARG_FREE(obj->options.interfaces); if (obj->options.ntdomain) CONFIG_ARG_FREE(obj->options.ntdomain); if (obj->options.addomain) @@ -1877,6 +1976,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.slmod_path) + CONFIG_ARG_FREE(obj->options.slmod_path); if (obj->options.unixcodepage) CONFIG_ARG_FREE(obj->options.unixcodepage);