PR 46072: netatalk broken with netbsd-6 quotas

Add support for the new libquota. Drop support for the proplib
libquota; it's not worth the configure-time hassle.

Fix some moderately serious bugs in the original/previous libquota
patches; it's clear for example they were never tested with group
quotas.
This commit is contained in:
dholland 2012-05-12 21:53:19 +00:00
parent 551003313c
commit d473661fd0
5 changed files with 191 additions and 68 deletions

View file

@ -1,7 +1,7 @@
# $NetBSD: Makefile,v 1.82 2012/04/17 16:14:54 hauke Exp $
# $NetBSD: Makefile,v 1.83 2012/05/12 21:53:19 dholland Exp $
DISTNAME= netatalk-2.2.1
PKGREVISION= 4
PKGREVISION= 5
CATEGORIES= net print
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE:=netatalk/}
EXTRACT_SUFX= .tar.bz2
@ -42,6 +42,7 @@ CONFIGURE_ARGS+= --enable-netbsd
CONFIGURE_ARGS+= --enable-overwrite
CONFIGURE_ARGS+= --enable-timelord
CONFIGURE_ARGS+= --enable-ddp
CONFIGURE_ARGS+= --enable-quota
CONFIGURE_ARGS+= --libexecdir=${PREFIX}/libexec/netatalk
CONFIGURE_ARGS+= --sbindir=${PREFIX}/libexec/netatalk
CONFIGURE_ARGS+= --with-pkgconfdir=${PKG_SYSCONFDIR}
@ -51,14 +52,6 @@ CONFIGURE_ARGS+= --with-uams-path=${PREFIX}/libexec/netatalk/uams
CONFIGURE_ARGS+= --with-bdb=${BDBBASE}
CONFIGURE_ARGS+= --with-ssl-dir=${BUILDLINK_PREFIX.openssl}
# XXX Waiting for NetBSD quota patches
.if empty(MACHINE_PLATFORM:MNetBSD-5.99.6[2-5]*) && \
empty(MACHINE_PLATFORM:MNetBSD-[6-9]*)
CONFIGURE_ARGS+= --enable-quota
.else
CONFIGURE_ARGS+= --disable-quota
.endif
MAKE_DIRS+= ${PKG_SYSCONFDIR}/msg
SUBST_CLASSES+= paths

View file

@ -1,9 +1,9 @@
$NetBSD: distinfo,v 1.44 2011/12/16 05:21:37 dholland Exp $
$NetBSD: distinfo,v 1.45 2012/05/12 21:53:20 dholland Exp $
SHA1 (netatalk-2.2.1.tar.bz2) = e588b89eced7769f65e213bc4b1b1e4f8035c8b3
RMD160 (netatalk-2.2.1.tar.bz2) = bc55a591fe134d3bf05ca442aa5b5246fd766b8c
Size (netatalk-2.2.1.tar.bz2) = 1227602 bytes
SHA1 (patch-aa) = 20df0964b4fcb934ba2072e0aa7df3b75ada5e77
SHA1 (patch-aa) = 060de5d023c3cc4e8d4e126270f2be69cf8a8913
SHA1 (patch-ac) = 605e87479202cbf093dfbadb25f2972595246d97
SHA1 (patch-ae) = e114085fbe2abf2fb821f2d2737e877c53e7c151
SHA1 (patch-af) = 649be7e50210e6e4156aeff74d3fc0effb90f9f2
@ -17,5 +17,5 @@ SHA1 (patch-ar) = 8c6c6169496b9b2cdec6049d2ee45884d5513d11
SHA1 (patch-au) = 8505351fee21ac1effa4dc620b8006c572b913c1
SHA1 (patch-bj) = abbc2809b6b7fe75ec2d2f8f2fa8d6cd9d6de7b0
SHA1 (patch-bk) = c3fb7c3a42f148171fa99b6121b099dd4998947a
SHA1 (patch-etc_afpd_quota_c) = 0d0a4d5cb8b8f2a9793096b61c326eecc403587c
SHA1 (patch-macros_quota-check.m4) = 40d1e404905398be03aad6d472bf42af920c7b20
SHA1 (patch-etc_afpd_quota_c) = 5005abb6528c0b3160a587fbe9fb285f485e6759
SHA1 (patch-macros_quota-check.m4) = b1484f83a2a6ba5bd50623ab525d5366bb71abaa

View file

@ -1,4 +1,4 @@
$NetBSD: patch-aa,v 1.23 2011/11/29 19:26:28 bouyer Exp $
$NetBSD: patch-aa,v 1.24 2012/05/12 21:53:20 dholland Exp $
--- configure.orig 2011-09-06 13:41:25.000000000 +0200
+++ configure 2011-11-29 18:59:56.000000000 +0100
@ -41760,13 +41760,13 @@ $NetBSD: patch-aa,v 1.23 2011/11/29 19:26:28 bouyer Exp $
+done
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getfsquota in -lquota" >&5
+$as_echo_n "checking for getfsquota in -lquota... " >&6; }
+if test "${ac_cv_lib_quota_getfsquota+set}" = set; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for quota_open in -lquota" >&5
+$as_echo_n "checking for quota_open in -lquota... " >&6; }
+if test "${ac_cv_lib_quota_quota_open+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lquota -lprop -lrpcsvc $LIBS"
+LIBS="-lquota -lrpcsvc $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
@ -41783,31 +41783,31 @@ $NetBSD: patch-aa,v 1.23 2011/11/29 19:26:28 bouyer Exp $
+#ifdef __cplusplus
+extern "C"
+#endif
+char getfsquota ();
+char quota_open ();
+int
+main ()
+{
+return getfsquota ();
+return quota_open ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_quota_getfsquota=yes
+ ac_cv_lib_quota_quota_open=yes
else
- CFLAGS="-D_U_=\"\" $CFLAGS"
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+ ac_cv_lib_quota_getfsquota=no
+ ac_cv_lib_quota_quota_open=no
fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_quota_getfsquota" >&5
+$as_echo "$ac_cv_lib_quota_getfsquota" >&6; }
+if test "x$ac_cv_lib_quota_getfsquota" = x""yes; then :
+ QUOTA_LIBS="-lquota -lprop -lrpcsvc"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_quota_quota_open" >&5
+$as_echo "$ac_cv_lib_quota_quota_open" >&6; }
+if test "x$ac_cv_lib_quota_quota_open" = x""yes; then :
+ QUOTA_LIBS="-lquota -lrpcsvc"
+$as_echo "#define HAVE_LIBQUOTA 1" >>confdefs.h

View file

@ -1,61 +1,173 @@
$NetBSD: patch-etc_afpd_quota_c,v 1.1 2011/12/16 05:21:37 dholland Exp $
$NetBSD: patch-etc_afpd_quota_c,v 1.2 2012/05/12 21:53:20 dholland Exp $
Account for changes in prerelease NetBSD quota API.
Use the netbsd-6 quota API, not the prerelease stuff from 5.99.x.
--- etc/afpd/quota.c~ 2011-08-18 12:23:44.000000000 +0000
Fix some glaring bugs in the code for the 5.99.x quotas (seteuid'ing
to group ids, using uninitialized group quota values, etc.)
--- etc/afpd/quota.c.orig 2011-08-18 12:23:44.000000000 +0000
+++ etc/afpd/quota.c
@@ -49,13 +49,25 @@ char *strchr (), *strrchr ();
@@ -48,14 +48,18 @@ char *strchr (), *strrchr ();
#include "unix.h"
#ifdef HAVE_LIBQUOTA
#include <quota/quota.h>
+#include <quota/quotaprop.h>
-#include <quota/quota.h>
+#include <quota.h>
+
+/* Sleazy. */
+#if defined(__NetBSD__) && defined(_QUOTA_QUOTA_H)
+/* old names in -current only from ~March 2011 through ~Nov 2011 */
+#define quotaval ufs_quota_entry
+#define qv_hardlimit ufsqe_hardlimit
+#define qv_softlimit ufsqe_softlimit
+#define qv_usage ufsqe_cur
+#define qv_expiretime ufsqe_time
+#define qv_grace ufsqe_grace
+#endif
static int
getfreespace(struct vol *vol, VolSpace *bfree, VolSpace *btotal,
uid_t uid, const char *classq)
- uid_t uid, const char *classq)
+ id_t id, int idtype)
{
int retq;
- int retq;
- struct ufs_quota_entry ufsq[QUOTA_NLIMITS];
+ struct quotaval ufsq[QUOTA_NLIMITS];
+ uid_t prevuid;
+ const char *msg;
+ struct quotahandle *qh;
+ struct quotakey qk;
+ struct quotaval qv;
time_t now;
if (time(&now) == -1) {
@@ -77,19 +89,19 @@ getfreespace(struct vol *vol, VolSpace *
if (retq < 1)
return retq;
@@ -64,65 +68,107 @@ getfreespace(struct vol *vol, VolSpace *
return -1;
}
+ prevuid = geteuid();
+ if (prevuid == -1) {
+ LOG(log_info, logtype_afpd, "geteuid(): %s",
+ strerror(errno));
+ return -1;
+ }
+
if ( seteuid( getuid() ) != 0 ) {
LOG(log_info, logtype_afpd, "seteuid(): %s",
strerror(errno));
return -1;
}
- if ((retq = getfsquota(vol->v_path, ufsq, uid, classq)) < 0) {
- LOG(log_info, logtype_afpd, "getfsquota(%s, %s): %s",
- vol->v_path, classq, strerror(errno));
+
+ /*
+ * In a tidier world we might keep the quotahandle open for longer...
+ */
+ qh = quota_open(vol->v_path);
+ if (qh == NULL) {
+ if (errno == EOPNOTSUPP || errno == ENXIO) {
+ /* no quotas on this volume */
+ seteuid( prevuid );
+ return 0;
+ }
+
+ LOG(log_info, logtype_afpd, "quota_open(%s): %s", vol->v_path,
+ strerror(errno));
+ seteuid( prevuid );
+ return -1;
}
- seteuid( uid );
- if (retq < 1)
- return retq;
- switch(QL_STATUS(quota_check_limit(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_cur, 1,
- ufsq[QUOTA_LIMIT_BLOCK].ufsqe_softlimit,
- ufsq[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit,
- ufsq[QUOTA_LIMIT_BLOCK].ufsqe_time, now))) {
+ switch(QL_STATUS(quota_check_limit(ufsq[QUOTA_LIMIT_BLOCK].qv_usage, 1,
+ ufsq[QUOTA_LIMIT_BLOCK].qv_softlimit,
+ ufsq[QUOTA_LIMIT_BLOCK].qv_hardlimit,
+ ufsq[QUOTA_LIMIT_BLOCK].qv_expiretime, now))) {
case QL_S_DENY_HARD:
case QL_S_DENY_GRACE:
- case QL_S_DENY_HARD:
- case QL_S_DENY_GRACE:
+ qk.qk_idtype = idtype;
+ qk.qk_id = id;
+ qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
+ if (quota_get(qh, &qk, &qv) < 0) {
+ if (errno == ENOENT) {
+ /* no quotas for this id */
+ quota_close(qh);
+ seteuid( prevuid );
+ return 0;
+ }
+ msg = strerror(errno);
+ LOG(log_info, logtype_afpd, "quota_get(%s, %s): %s",
+ vol->v_path, quota_idtype_getname(qh, idtype), msg);
+ quota_close(qh);
+ seteuid( prevuid );
+ return -1;
+ }
+
+ quota_close(qh);
+
+ seteuid( prevuid );
+
+ if (qv.qv_usage >= qv.qv_hardlimit ||
+ (qv.qv_usage >= qv.qv_softlimit && now > qv.qv_expiretime)) {
*bfree = 0;
- *btotal = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_cur);
+ *btotal = dbtob(ufsq[QUOTA_LIMIT_BLOCK].qv_usage);
break;
default:
- break;
- default:
- *bfree = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit -
- ufsq[QUOTA_LIMIT_BLOCK].ufsqe_cur);
- *btotal = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit);
+ *bfree = dbtob(ufsq[QUOTA_LIMIT_BLOCK].qv_hardlimit -
+ ufsq[QUOTA_LIMIT_BLOCK].qv_usage);
+ *btotal = dbtob(ufsq[QUOTA_LIMIT_BLOCK].qv_hardlimit);
break;
- break;
+ *btotal = dbtob(qv.qv_usage);
+ }
+ else {
+ *bfree = dbtob(qv.qv_hardlimit - qv.qv_usage);
+ *btotal = dbtob(qv.qv_hardlimit);
}
+
return 1;
}
int uquota_getvolspace( struct vol *vol, VolSpace *bfree, VolSpace *btotal, const u_int32_t bsize)
{
- int uretq, gretq;
+ int uret, gret;
VolSpace ubfree, ubtotal;
VolSpace gbfree, gbtotal;
- uretq = getfreespace(vol, &ubfree, &ubtotal,
- uuid, QUOTADICT_CLASS_USER);
- LOG(log_info, logtype_afpd, "getfsquota(%s): %d %d",
- vol->v_path, (int)ubfree, (int)ubtotal);
+ uret = getfreespace(vol, &ubfree, &ubtotal,
+ uuid, QUOTA_IDTYPE_USER);
+ if (uret == 1) {
+ LOG(log_info, logtype_afpd, "quota_get(%s, user): %d %d",
+ vol->v_path, (int)ubfree, (int)ubtotal);
+ }
+
if (ngroups >= 1) {
- gretq = getfreespace(vol, &ubfree, &ubtotal,
- groups[0], QUOTADICT_CLASS_GROUP);
+ gret = getfreespace(vol, &gbfree, &gbtotal,
+ groups[0], QUOTA_IDTYPE_GROUP);
+ if (gret == 1) {
+ LOG(log_info, logtype_afpd, "quota_get(%s, group): %d %d",
+ vol->v_path, (int)gbfree, (int)gbtotal);
+ }
} else
- gretq = -1;
- if (uretq < 1 && gretq < 1) { /* no quota for this fs */
+ gret = 0;
+
+ if (uret < 1 && gret < 1) { /* no quota for this fs */
return AFPERR_PARAM;
}
- if (uretq < 1) {
- /* use group quotas */
+ if (uret < 1) {
+ /* no user quotas, but group quotas; use them */
*bfree = gbfree;
*btotal = gbtotal;
- } else if (gretq < 1) {
- /* use user quotas */
+ } else if (gret < 1) {
+ /* no group quotas, but user quotas; use them */
*bfree = ubfree;
*btotal = ubtotal;
} else {
- /* return smallest remaining space of user and group */
+ /* both; return smallest remaining space of user and group */
if (ubfree < gbfree) {
*bfree = ubfree;
*btotal = ubtotal;

View file

@ -1,8 +1,22 @@
$NetBSD: patch-macros_quota-check.m4,v 1.1 2011/11/29 19:26:28 bouyer Exp $
$NetBSD: patch-macros_quota-check.m4,v 1.2 2012/05/12 21:53:20 dholland Exp $
--- macros/quota-check.m4.orig 2011-11-29 18:51:25.000000000 +0100
+++ macros/quota-check.m4 2011-11-29 18:53:09.000000000 +0100
@@ -10,11 +10,7 @@
- do not disable quota support if some of rpc/rpc.h, rpc/pmap_prot.h,
rpcsvc/rquota.h are missing.
- fix libquota test to check for the netbsd-6 release quota API, not
the prerelease proplib-based API in 5.99 that got removed before
netbsd-6.
This logic should probably be simplified, and expanded some to
simplify the mess of quota-related ifdefs in the source; the rquotad
support connected to the rpc headers and -lrpcsvc should be
independent of the local quota support, and can be probed for
independently. However, this needs to be coordinated with upstream,
not done in pkgsrc.
--- macros/quota-check.m4.orig 2011-08-18 12:23:44.000000000 +0000
+++ macros/quota-check.m4
@@ -10,13 +10,9 @@ AC_DEFUN([AC_CHECK_QUOTA], [
QUOTA_LIBS=""
netatalk_cv_quotasupport="yes"
AC_CHECK_LIB(rpcsvc, main, [QUOTA_LIBS="-lrpcsvc"])
@ -11,7 +25,11 @@ $NetBSD: patch-macros_quota-check.m4,v 1.1 2011/11/29 19:26:28 bouyer Exp $
- netatalk_cv_quotasupport="no"
- AC_DEFINE(NO_QUOTA_SUPPORT, 1, [Define if quota support should not compiled])
- ])
- AC_CHECK_LIB(quota, getfsquota, [QUOTA_LIBS="-lquota -lprop -lrpcsvc"
- AC_DEFINE(HAVE_LIBQUOTA, 1, [define if you have libquota])], [], [-lprop -lrpcsvc])
+ AC_CHECK_HEADERS([rpc/rpc.h rpc/pmap_prot.h rpcsvc/rquota.h],[],[])
AC_CHECK_LIB(quota, getfsquota, [QUOTA_LIBS="-lquota -lprop -lrpcsvc"
AC_DEFINE(HAVE_LIBQUOTA, 1, [define if you have libquota])], [], [-lprop -lrpcsvc])
+ AC_CHECK_LIB(quota, quota_open, [QUOTA_LIBS="-lquota -lrpcsvc"
+ AC_DEFINE(HAVE_LIBQUOTA, 1, [define if you have libquota])], [], [-lrpcsvc])
else
netatalk_cv_quotasupport="no"
AC_DEFINE(NO_QUOTA_SUPPORT, 1, [Define if quota support should not compiled])