#include "config.h"
#endif /* HAVE_CONFIG_H */
-
+#include <unistd.h>
+#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#ifdef STDC_HEADERS
#include <string.h>
-#endif
#include <sys/param.h>
#include <atalk/adouble.h>
#include <atalk/logger.h>
#include <atalk/volinfo.h>
#include <atalk/volume.h>
+#include <atalk/compat.h>
#ifdef CNID_DB
#include <atalk/cnid.h>
#endif /* CNID_DB*/
{AFPVOL_USEDOTS, "USEDOTS"}, /* use real dots */
{AFPVOL_LIMITSIZE, "LIMITSIZE"}, /* limit size for older macs */
{AFPVOL_MAPASCII, "MAPASCII"}, /* map the ascii range as well */
- {AFPVOL_DROPBOX, "DROPBOX"}, /* dropkludge dropbox support */
{AFPVOL_NOFILEID, "NOFILEID"}, /* don't advertise createid resolveid and deleteid calls */
{AFPVOL_NOSTAT, "NOSTAT"}, /* advertise the volume even if we can't stat() it
* maybe because it will be mounted later in preexec */
}
break;
case CNID_DBPATH:
- if ((vol->v_dbpath = strdup(value)) == NULL) {
- fprintf (stderr, "strdup: %s", strerror(errno));
- return -1;
- }
+ if ((vol->v_dbpath = malloc(MAXPATHLEN+1)) == NULL)
+ return -1;
+ strcpy(vol->v_dbpath, value);
break;
case ADOUBLE_VER:
if (strcasecmp(value, "v2") == 0) {
char volinfofile[MAXPATHLEN];
char buf[MAXPATHLEN];
struct flock lock;
- int fd;
+ int fd, len;
FILE *fp;
if ( !path || !vol)
return -1;
if ((vol->v_path = strdup(volinfofile)) == NULL ) {
- fprintf (stderr, "strdup: %s", strerror(errno));
+ fprintf (stderr, "strdup: %s", strerror(errno));
return (-1);
}
+ /* Remove trailing slashes */
+ len = strlen(vol->v_path);
+ while (len && (vol->v_path[len-1] == '/')) {
+ vol->v_path[len-1] = 0;
+ len--;
+ }
+
strlcat(volinfofile, ".AppleDesktop/", sizeof(volinfofile));
strlcat(volinfofile, VOLINFOFILE, sizeof(volinfofile));
if ((vol->v_flags & AFPVOL_INV_DOTS))
vol->v_ad_options |= ADVOL_INVDOTS;
+ vol->retaincount = 1;
+
fclose(fp);
return 0;
}
+/*!
+ * Allocate a struct volinfo object for refcounting usage with retain and close, and
+ * call loadvolinfo with it
+ */
+struct volinfo *allocvolinfo(char *path)
+{
+ struct volinfo *p = malloc(sizeof(struct volinfo));
+ if (p == NULL)
+ return NULL;
+
+ if (loadvolinfo(path, p) == -1)
+ return NULL;
+
+ p->malloced = 1;
+
+ return p;
+}
+
+void retainvolinfo(struct volinfo *vol)
+{
+ vol->retaincount++;
+}
+
+/*!
+ * Decrement retain count, free resources when retaincount reaches 0
+ */
+int closevolinfo(struct volinfo *volinfo)
+{
+ if (volinfo->retaincount <= 0)
+ abort();
+
+ volinfo->retaincount--;
+
+ if (volinfo->retaincount == 0) {
+ free(volinfo->v_name); volinfo->v_name = NULL;
+ free(volinfo->v_path); volinfo->v_path = NULL;
+ free(volinfo->v_cnidscheme); volinfo->v_cnidscheme = NULL;
+ free(volinfo->v_dbpath); volinfo->v_dbpath = NULL;
+ free(volinfo->v_volcodepage); volinfo->v_volcodepage = NULL;
+ free(volinfo->v_maccodepage); volinfo->v_maccodepage = NULL;
+ free(volinfo->v_dbd_host); volinfo->v_dbd_host = NULL;
+ free(volinfo->v_dbd_port); volinfo->v_dbd_port = NULL;
+ if (volinfo->malloced) {
+ volinfo->malloced = 0;
+ free(volinfo);
+ }
+ }
+
+ return 0;
+}
+
/*
* Save the volume options to a file, used by shell utilities. Writing the file
* everytime a volume is opened is unnecessary, but it shouldn't hurt much.
*/
int savevolinfo(const struct vol *vol, const char *Cnid_srv, const char *Cnid_port)
{
+ uid_t process_uid;
char buf[16348];
char item[MAXPATHLEN];
int fd;
strlcat (item, "/.AppleDesktop/", sizeof(item));
strlcat (item, VOLINFOFILE, sizeof(item));
- if ((fd = open( item, O_RDWR | O_CREAT , 0666)) <0 ) {
- LOG(log_debug, logtype_afpd,"Error opening %s: %s", item, strerror(errno));
+ process_uid = geteuid();
+ if (process_uid) {
+ if (seteuid(0) == -1) {
+ process_uid = 0;
+ }
+ }
+
+ if ((fd = open(item, O_RDWR | O_CREAT , 0666)) <0 ) {
+ LOG(log_debug, logtype_default,"Error opening %s: %s", item, strerror(errno));
+ if (process_uid) {
+ if (seteuid(process_uid) == -1) {
+ LOG(log_error, logtype_default, "can't seteuid back %s", strerror(errno));
+ exit(EXITERR_SYS);
+ }
+ }
return (-1);
}
+ if (process_uid) {
+ if (seteuid(process_uid) == -1) {
+ LOG(log_error, logtype_default, "can't seteuid back %s", strerror(errno));
+ exit(EXITERR_SYS);
+ }
+ }
+
/* try to get a lock */
lock.l_start = 0;
lock.l_whence = SEEK_SET;
/* ignore, other process already writing the file */
return 0;
} else {
- LOG(log_error, logtype_cnid, "savevoloptions: cannot get lock: %s", strerror(errno));
+ LOG(log_error, logtype_default, "savevoloptions: cannot get lock: %s", strerror(errno));
return (-1);
}
}
strlcat(buf, item, sizeof(buf));
if (strlen(buf) >= sizeof(buf)-1)
- LOG(log_debug, logtype_afpd,"Error writing .volinfo file: buffer too small, %s", buf);
+ LOG(log_debug, logtype_default, "Error writing .volinfo file: buffer too small, %s", buf);
if (write( fd, buf, strlen(buf)) < 0 || ftruncate(fd, strlen(buf)) < 0 ) {
- LOG(log_debug, logtype_afpd,"Error writing .volinfo file: %s", strerror(errno));
+ LOG(log_debug, logtype_default, "Error writing .volinfo file: %s", strerror(errno));
}
lock.l_type = F_UNLCK;