From 8fbfbd6ee56c6f6649819f6126db827c3dd65276 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 18 Aug 2011 14:29:48 +0200 Subject: [PATCH] Add support for new NetBSD quota subsystem, Bug ID 3249879. --- NEWS | 1 + etc/afpd/nfsquota.c | 4 +- etc/afpd/quota.c | 91 +++++++++++++++++++++++++++++++++++++++++++ etc/afpd/unix.h | 2 + macros/quota-check.m4 | 2 + 5 files changed, 98 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 0e3c427b..ae1f6b6e 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ Changes in 2.2.1 to disable ACLs for a volume. * UPD: afpd: add a configurable hold time option to FCE file modification event generation, default is 60 s, new option "fceholdfmod" to change it +* UPD: afpd: add support for new NetBSD quota subsystem, Bug ID 3249879 * FIX: afpd: increase BerkeleyDB locks and lockobjs * FIX: afpd: create special folder as root * FIX: afpd: fix compilation error if --enable-ddp is used diff --git a/etc/afpd/nfsquota.c b/etc/afpd/nfsquota.c index e3ad5ddc..28e61695 100644 --- a/etc/afpd/nfsquota.c +++ b/etc/afpd/nfsquota.c @@ -18,7 +18,7 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ -#ifndef NO_QUOTA_SUPPORT +#if !defined(NO_QUOTA_SUPPORT) && !defined(HAVE_LIBQUOTA) #include /* STDC check */ #if STDC_HEADERS @@ -185,4 +185,4 @@ int getnfsquota(struct vol *vol, const int uid, const u_int32_t bsize, *hostpath = ':'; return AFPERR_PARAM; } -#endif /* ! NO_QUOTA_SUPPORT */ +#endif /* ! NO_QUOTA_SUPPORT && !HAVE_LIBQUOTA */ diff --git a/etc/afpd/quota.c b/etc/afpd/quota.c index 9992948c..577ddab7 100644 --- a/etc/afpd/quota.c +++ b/etc/afpd/quota.c @@ -47,6 +47,96 @@ char *strchr (), *strrchr (); #include "volume.h" #include "unix.h" +#ifdef HAVE_LIBQUOTA +#include + +static int +getfreespace(struct vol *vol, VolSpace *bfree, VolSpace *btotal, + uid_t uid, const char *classq) +{ + int retq; + struct ufs_quota_entry ufsq[QUOTA_NLIMITS]; + time_t now; + + if (time(&now) == -1) { + LOG(log_info, logtype_afpd, "time(): %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)); + } + 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))) { + case QL_S_DENY_HARD: + case QL_S_DENY_GRACE: + *bfree = 0; + *btotal = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_cur); + break; + default: + *bfree = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit - + ufsq[QUOTA_LIMIT_BLOCK].ufsqe_cur); + *btotal = dbtob(ufsq[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit); + break; + } + return 1; +} + +int uquota_getvolspace( struct vol *vol, VolSpace *bfree, VolSpace *btotal, const u_int32_t bsize) +{ + int uretq, gretq; + 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); + if (ngroups >= 1) { + gretq = getfreespace(vol, &ubfree, &ubtotal, + groups[0], QUOTADICT_CLASS_GROUP); + } else + gretq = -1; + if (uretq < 1 && gretq < 1) { /* no quota for this fs */ + return AFPERR_PARAM; + } + if (uretq < 1) { + /* use group quotas */ + *bfree = gbfree; + *btotal = gbtotal; + } else if (gretq < 1) { + /* use user quotas */ + *bfree = ubfree; + *btotal = ubtotal; + } else { + /* return smallest remaining space of user and group */ + if (ubfree < gbfree) { + *bfree = ubfree; + *btotal = ubtotal; + } else { + *bfree = gbfree; + *btotal = gbtotal; + } + } + return AFP_OK; + +} + +#else /* HAVE_LIBQUOTA */ + /* #define DEBUG_QUOTA 0 */ @@ -739,4 +829,5 @@ int uquota_getvolspace( struct vol *vol, VolSpace *bfree, VolSpace *btotal, cons return( AFP_OK ); } +#endif /* HAVE_LIBQUOTA */ #endif diff --git a/etc/afpd/unix.h b/etc/afpd/unix.h index c663ecac..be7b7bfb 100644 --- a/etc/afpd/unix.h +++ b/etc/afpd/unix.h @@ -59,6 +59,7 @@ typedef int mode_t; #ifndef NO_QUOTA_SUPPORT +#if !defined(HAVE_LIBQUOTA) #if !(defined(__svr4__) || defined(HAVE_DQB_BTIMELIMIT)) #define dqb_btimelimit dqb_btime @@ -211,6 +212,7 @@ extern long quotactl (unsigned int, const char *, int, caddr_t); extern int getnfsquota (struct vol *, const int, const u_int32_t, struct dqblk *); +#endif /* ! HAVE_LIBQUOTA */ extern int uquota_getvolspace (struct vol *, VolSpace *, VolSpace *, const u_int32_t); #endif /* NO_QUOTA_SUPPORT */ diff --git a/macros/quota-check.m4 b/macros/quota-check.m4 index 11ddd6ff..44e89bc9 100644 --- a/macros/quota-check.m4 +++ b/macros/quota-check.m4 @@ -15,6 +15,8 @@ AC_DEFUN([AC_CHECK_QUOTA], [ 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]) else netatalk_cv_quotasupport="no" AC_DEFINE(NO_QUOTA_SUPPORT, 1, [Define if quota support should not compiled]) -- 2.39.2