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))
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 */
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;
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) );
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);
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
*
* (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
*
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);
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)
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))
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;
if (!iniparser_getboolean(config, INISEC_GLOBAL, "save password", 1))
options->passwdbits |= PASSWD_NOSAVE;
if (iniparser_getboolean(config, INISEC_GLOBAL, "set password", 0))
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);
options->fce_fmodwait = iniparser_getint (config, INISEC_GLOBAL, "fce holdfmod", 60);
options->sleep = iniparser_getint (config, INISEC_GLOBAL, "sleep time", 10);
options->disconnected = iniparser_getint (config, INISEC_GLOBAL, "disconnect time",24);
+ options->tracker_loglevel = iniparser_getint (config, INISEC_GLOBAL, "tracker loglevel", 1);
+
+ 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) );
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)
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);