Changes in 2.0.5
================
+* NEW: afpd: Time Machine support with new volume option "tm".
* FIX: papd: Remove variable expansion for BSD printers. Fixes CVE-2008-5718.
* FIX: afpd: .AppleDxxx folders were user accessible if option 'usedots'
was set
# requested perm
#
# miscellaneous options [syntax: options:option1,option2]:
+# tm -> enable TimeMachine support
# prodos -> make compatible with appleII clients.
# crlf -> enable crlf translation for TEXT files.
# noadouble -> don't create .AppleDouble unless a resource
/*
- * $Id: directory.c,v 1.71.2.4.2.15.2.13 2009-09-01 12:34:38 franklahm Exp $
+ * $Id: directory.c,v 1.71.2.4.2.15.2.14 2009-09-07 11:35:04 franklahm Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
return err;
}
+int afp_syncdir(obj, ibuf, ibuflen, rbuf, rbuflen )
+AFPObj *obj _U_;
+char *ibuf, *rbuf _U_;
+int ibuflen _U_, *rbuflen;
+{
+#ifdef HAVE_DIRFD
+ DIR *dp;
+#endif
+ int dfd;
+ struct vol *vol;
+ struct dir *dir;
+ u_int32_t did;
+ u_int16_t vid;
+
+ *rbuflen = 0;
+ ibuf += 2;
+
+ memcpy( &vid, ibuf, sizeof( vid ));
+ ibuf += sizeof( vid );
+ if (NULL == (vol = getvolbyvid( vid )) ) {
+ return( AFPERR_PARAM );
+ }
+
+ memcpy( &did, ibuf, sizeof( did ));
+ ibuf += sizeof( did );
+
+ /*
+ * Here's the deal:
+ * if it's CNID 2 our only choice to meet the specs is call sync.
+ * For any other CNID just sync that dir. To my knowledge the
+ * intended use of FPSyncDir is to sync the volume so all we're
+ * ever going to see here is probably CNID 2. Anyway, we' prepared.
+ */
+
+ if ( ntohl(did) == 2 ) {
+ sync();
+ } else {
+ if (NULL == ( dir = dirlookup( vol, did )) ) {
+ return afp_errno; /* was AFPERR_NOOBJ */
+ }
+
+ if (movecwd( vol, dir ) < 0 )
+ return ( AFPERR_NOOBJ );
+
+ /*
+ * Assuming only OSens that have dirfd also may require fsyncing directories
+ * in order to flush metadata e.g. Linux.
+ */
+
+#ifdef HAVE_DIRFD
+ if (NULL == ( dp = opendir( "." )) ) {
+ switch( errno ) {
+ case ENOENT :
+ return( AFPERR_NOOBJ );
+ case EACCES :
+ return( AFPERR_ACCESS );
+ default :
+ return( AFPERR_PARAM );
+ }
+ }
+
+ LOG(log_debug, logtype_afpd, "afp_syncdir: dir: '%s'", dir->d_u_name);
+
+ dfd = dirfd( dp );
+ if ( fsync ( dfd ) < 0 )
+ LOG(log_error, logtype_afpd, "afp_syncdir(%s): %s",
+ dir->d_u_name, strerror(errno) );
+ closedir(dp); /* closes dfd too */
+#endif
+
+ if ( -1 == (dfd = open(vol->ad_path(".", ADFLAGS_DIR), O_RDWR))) {
+ switch( errno ) {
+ case ENOENT:
+ return( AFPERR_NOOBJ );
+ case EACCES:
+ return( AFPERR_ACCESS );
+ default:
+ return( AFPERR_PARAM );
+ }
+ }
+
+ LOG(log_debug, logtype_afpd, "afp_syncdir: ad-file: '%s'",
+ vol->ad_path(".", ADFLAGS_DIR) );
+
+ if ( fsync(dfd) < 0 )
+ LOG(log_error, logtype_afpd, "afp_syncdir(%s): %s",
+ vol->ad_path(dir->d_u_name, ADFLAGS_DIR), strerror(errno) );
+ close(dfd);
+ }
+
+ return ( AFP_OK );
+}
+
int afp_createdir(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
/*
- * $Id: directory.h,v 1.13.2.4.2.2.2.1 2008-11-25 15:16:32 didg Exp $
+ * $Id: directory.h,v 1.13.2.4.2.2.2.2 2009-09-07 11:35:04 franklahm Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
extern int afp_closedir __P((AFPObj *, char *, int, char *, int *));
extern int afp_mapid __P((AFPObj *, char *, int, char *, int *));
extern int afp_mapname __P((AFPObj *, char *, int, char *, int *));
+extern int afp_syncdir __P((AFPObj *, char *, int, char *, int *));
/* from enumerate.c */
extern int afp_enumerate __P((AFPObj *, char *, unsigned int, char *, unsigned int *));
/*
- * $Id: fork.c,v 1.51.2.2.2.10.2.6 2008-11-25 15:16:33 didg Exp $
+ * $Id: fork.c,v 1.51.2.2.2.10.2.7 2009-09-07 11:35:04 franklahm Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
return( AFP_OK );
}
+/*
+ FIXME
+ There is a lot to tell about fsync, fdatasync, F_FULLFSYNC.
+ fsync(2) on OSX is implemented differently than on other platforms.
+ see: http://mirror.linux.org.au/pub/linux.conf.au/2007/video/talks/278.pdf.
+ */
+int afp_syncfork(obj, ibuf, ibuflen, rbuf, rbuflen )
+ AFPObj *obj _U_;
+ char *ibuf, *rbuf _U_;
+ int ibuflen _U_, *rbuflen;
+{
+ struct ofork *ofork;
+ u_int16_t ofrefnum;
+
+ *rbuflen = 0;
+ ibuf += 2;
+
+ memcpy(&ofrefnum, ibuf, sizeof(ofrefnum));
+ ibuf += sizeof( ofrefnum );
+
+ if (NULL == ( ofork = of_find( ofrefnum )) ) {
+ LOG(log_error, logtype_afpd, "afpd_syncfork: of_find(%d) could not locate fork", ofrefnum );
+ return( AFPERR_PARAM );
+ }
+
+ if ( flushfork( ofork ) < 0 ) {
+ LOG(log_error, logtype_afpd, "flushfork(%s): %s", of_name(ofork), strerror(errno) );
+ return AFPERR_MISC;
+ }
+
+ return( AFP_OK );
+}
+
/* this is very similar to closefork */
int flushfork( ofork )
struct ofork *ofork;
/*
- * $Id: fork.h,v 1.8.6.2.2.3 2008-11-25 15:16:33 didg Exp $
+ * $Id: fork.h,v 1.8.6.2.2.4 2009-09-07 11:35:04 franklahm Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
extern int afp_bytelock_ext __P((AFPObj *, char *, int, char *, int *));
extern int afp_read_ext __P((AFPObj *, char *, int, char *, int *));
extern int afp_write_ext __P((AFPObj *, char *, int, char *, int *));
+extern int afp_syncfork __P((AFPObj *, char *, int, char *, int *));
#endif
/*
- * $Id: switch.c,v 1.12.8.1 2005-09-27 10:40:41 didg Exp $
+ * $Id: switch.c,v 1.12.8.2 2009-09-07 11:35:04 franklahm Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, /* 64 - 71 */
NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, /* 72 - 79 */
+ NULL, NULL, afp_syncdir, afp_syncfork, /* 72 - 79 */
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, /* 80 - 87 */
NULL, NULL, NULL, NULL,
/*
- * $Id: volume.c,v 1.51.2.7.2.33.2.24 2009-03-26 11:53:32 franklahm Exp $
+ * $Id: volume.c,v 1.51.2.7.2.33.2.25 2009-09-07 11:35:04 franklahm Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
{AFPVOL_NODEV, "NODEV"}, /* always use 0 for device number in cnid calls */
{AFPVOL_EILSEQ, "ILLEGALSEQ"}, /* encode illegal sequence */
{AFPVOL_CACHE, "CACHEID"}, /* Use adouble v2 CNID caching, default don't use it */
+ {AFPVOL_TM, "TM"}, /* Set "kSupportsTMLockSteal" is volume attributes */
{0, NULL}
};
options[VOLOPT_FLAGS].i_value |= AFPVOL_EILSEQ;
else if (strcasecmp(p, "cachecnid") == 0)
options[VOLOPT_FLAGS].i_value |= AFPVOL_CACHE;
+ else if (strcasecmp(p, "tm") == 0)
+ options[VOLOPT_FLAGS].i_value |= AFPVOL_TM;
p = strtok(NULL, ",");
}
ashort |= VOLPBIT_ATTR_CATSEARCH;
if (afp_version >= 30) {
ashort |= VOLPBIT_ATTR_UTF8;
- if (vol->v_flags & AFPVOL_UNIX_PRIV)
- ashort |= VOLPBIT_ATTR_UNIXPRIV;
+ if (vol->v_flags & AFPVOL_UNIX_PRIV)
+ ashort |= VOLPBIT_ATTR_UNIXPRIV;
+ if (vol->v_flags & AFPVOL_TM)
+ ashort |= VOLPBIT_ATTR_TM;
}
ashort = htons(ashort);
memcpy(data, &ashort, sizeof( ashort ));
/*
- * $Id: volume.h,v 1.19.2.5.2.7.2.5 2009-01-28 05:37:58 didg Exp $
+ * $Id: volume.h,v 1.19.2.5.2.7.2.6 2009-09-07 11:35:05 franklahm Exp $
*
* Copyright (c) 1990,1994 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#define AFPVOL_CACHE (1 << 21) /* Use adouble v2 CNID caching, default don't use it */
#define AFPVOL_INV_DOTS (1 << 22) /* dots files are invisible */
+#define AFPVOL_TM (1 << 23) /* Supports TimeMachine */
/* FPGetSrvrParms options */
#define AFPSRVR_CONFIGINFO (1 << 0)
#define VOLPBIT_ATTR_UNIXPRIV (1 << 5)
#define VOLPBIT_ATTR_UTF8 (1 << 6)
#define VOLPBIT_ATTR_NONETUID (1 << 7)
+#define VOLPBIT_ATTR_TM (1 << 13)
#define VOLPBIT_ATTR 0
#define VOLPBIT_SIG 1
/* version 3.1 */
#define AFP_ENUMERATE_EXT2 68
+#define AFP_SYNCDIR 78
+#define AFP_SYNCFORK 79
#define AFP_ZZZ 122
-
#endif