pam: modules/pam_quota/Makefile (NEW), modules/pam_quota/README (N...

baggins baggins at pld-linux.org
Thu May 10 18:28:14 CEST 2007


Author: baggins                      Date: Thu May 10 16:28:14 2007 GMT
Module: pam                           Tag: HEAD
---- Log message:
- initial import from http://nixbit.com/cat/system/system-administration/pam-quota/

---- Files affected:
pam/modules/pam_quota:
   Makefile (NONE -> 1.1)  (NEW), README (NONE -> 1.1)  (NEW), pam_quota.c (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: pam/modules/pam_quota/Makefile
diff -u /dev/null pam/modules/pam_quota/Makefile:1.1
--- /dev/null	Thu May 10 18:28:14 2007
+++ pam/modules/pam_quota/Makefile	Thu May 10 18:28:09 2007
@@ -0,0 +1,23 @@
+#
+# pam_quota Makefile
+#
+# Mon Feb  2 16:33:18 CET 2004, Andrea Leofreddi, <andrea.leofreddi at libero.it>
+#
+#
+CFLAGS=					-fPIC -O2
+LDFLAGS=					-x --shared
+TARGET=					pam_quota.so
+DESTDIR=					/usr/lib
+ 
+.SUFFIXES:				.o .so
+  
+all:						$(TARGET)
+
+.o.so:
+	ld $(LDFLAGS) -o $@ $<
+
+clean:
+	rm -f $(TARGET) *.o
+
+install:					$(TARGET)
+	install -s -o0 -g0 -m755 $(TARGET) $(DESTDIR);

================================================================
Index: pam/modules/pam_quota/README
diff -u /dev/null pam/modules/pam_quota/README:1.1
--- /dev/null	Thu May 10 18:28:14 2007
+++ pam/modules/pam_quota/README	Thu May 10 18:28:09 2007
@@ -0,0 +1,21 @@
+This is a simple pam session module to automatically setup user quota (root 
+excluded). To build it simply type 'make' from its directory. To install simply
+issue a 'make install', and note that by default it will install into /usr/lib 
+(a good place for FreeBSD system): you can override that giving a different 
+DESTDIR to make. For example on Linux you may want to install pam_quota to 
+/lib/security issuing 'make install DESTDIR=/lib/security'.
+
+To enable pam_quota, just add a similar line into /etc/pam.d/<service>:
+
+	session         required pam_quota.so           bhardlimit=30000 bsoftlimit=25000 ihardlimit=15000 isoftlimit=20000 itime=86400 btime=86400
+
+Arguments are used to setup quota values (by default everything is zero) and
+follows the dqblk structure:
+
+   bhardlimit        absolute limit on disk blks alloc
+   bsoftlimit        preferred limit on disk blks
+   ihardlimit        maximum # allocated inodes + 1
+   isoftlimit        preferred inode limit
+   btime             time limit for excessive disk use
+   itime             time limit for excessive files
+

================================================================
Index: pam/modules/pam_quota/pam_quota.c
diff -u /dev/null pam/modules/pam_quota/pam_quota.c:1.1
--- /dev/null	Thu May 10 18:28:14 2007
+++ pam/modules/pam_quota/pam_quota.c	Thu May 10 18:28:09 2007
@@ -0,0 +1,228 @@
+/*
+ * pam_quota
+ *
+ * A simple pam module to automagically set a quota to non-root users.
+ *
+ * Mon Feb  2 01:31:36 CET 2004, Andrea Leofreddi, <andrea.leofreddi at libero.it>
+ *    first version. Runs on FreeBSD 5.2-RELEASE and Debian GNU/Linux 2.6.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
+#include <fstab.h>
+#include <errno.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <pwd.h>
+
+#if defined(__FreeBSD__)
+#include <ufs/ufs/quota.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <security/pam_appl.h>
+#elif defined(__linux__)
+#include <mntent.h>
+#include <sys/quota.h>
+#include <sys/vfs.h>
+#include <sys/stat.h>
+#endif
+
+#define  PAM_SM_SESSION
+#include <security/pam_modules.h>
+
+#define PAM_QUOTE_DEBUG		1
+
+struct pam_quota_conf {
+	unsigned flags; /* module flags */
+	struct dqblk q;	/* quota data */
+};
+
+/* logs pam_quota activities */
+static void _pam_log(int prio, const char *fmt, ...) {
+		va_list ap;
+
+		va_start(ap, fmt);
+
+		vfprintf(stderr, fmt, ap);
+		openlog("pam_quota", LOG_PID, LOG_AUTHPRIV);
+		vsyslog(prio, fmt, ap);
+
+		va_end(ap);
+
+		closelog();
+}
+
+static char *fs_from_home(const char *home) {
+#if defined(__linux__)
+	struct stat homestat, devstat;
+	struct mntent *mnt;
+	char *fs = 0;
+	FILE *f;
+
+	/* open mtab */
+	if(!(f = setmntent("/etc/mtab", "r"))) {
+		_pam_log(LOG_ERR, "unable to open mtab\n");
+		return 0;
+	}
+
+	/* do a stat on user home directory */
+	if(stat(home, &homestat) < 0) {
+		_pam_log(LOG_ERR, "unable to stat user home directory\n");
+		return 0;
+	}
+
+	/* iterates through mounted filesystem and check if home belongs to it */
+	while(mnt = getmntent(f)) {
+		if(!(!stat(mnt->mnt_fsname, &devstat) && S_ISBLK(devstat.st_mode)))
+			continue;
+
+		if(homestat.st_dev == devstat.st_rdev) {
+			fs = strdup(mnt->mnt_fsname);
+			break;
+		}
+	}
+
+	endmntent(f);
+
+	return fs;
+#elif defined(__FreeBSD__)
+	struct statfs homestat;
+
+	/* do a statfs on home */
+	if(statfs(home, &homestat) < 0) {
+		_pam_log(LOG_ERR, "unable to stat user home directory\n");
+		return 0;
+	}
+
+	return strdup(homestat.f_mntonname);
+#endif
+}
+
+PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) {
+	struct pam_quota_conf conf;
+	char *argument, *value;
+	char *username = 0, *fs = 0;
+	struct passwd *pwd;
+	unsigned err = 0, i, m;
+
+	/* initialize configuration */
+	memset(&conf, '\0', sizeof(struct pam_quota_conf));
+
+	/* parse line arguments */
+	for(i = 0; i < argc; ++i) {
+		if(!(argument = strdup(argv[i]))) {
+			_pam_log(LOG_ERR, "insufficient memory");
+			return PAM_SESSION_ERR;
+		}
+
+		value = strchr(argument, '=');
+
+		if(value) {
+			/* value arguments (argument=value) */
+
+			*value = '\0';
+			++value;
+
+			m = 0;
+
+#define CHECK_AND_SET(x)		!strcmp(argument, #x) && (m = 1) && (conf.q.dqb_##x = atoi(value)) < 0
+			if(CHECK_AND_SET(bhardlimit)) {
+				_pam_log(LOG_ERR, "bhardlimit argument must be greater or equal 0");
+				err = 1;
+			} else if(CHECK_AND_SET(bsoftlimit)) {
+				_pam_log(LOG_ERR, "bsoftlimit argument must be greater or equal 0");
+				err = 1;
+			} else if(CHECK_AND_SET(ihardlimit)) {
+				_pam_log(LOG_ERR, "ihardlimit argument must be greater or equal 0");
+				err = 1;
+			} else if(CHECK_AND_SET(isoftlimit)) {
+				_pam_log(LOG_ERR, "isoftlimit argument must be greater or equal 0");
+				err = 1;
+			} else if(CHECK_AND_SET(itime)) {
+				_pam_log(LOG_ERR, "itime argument must be greater or equal 0");
+				err = 1;
+			} else if(CHECK_AND_SET(btime)) {
+				_pam_log(LOG_ERR, "btime argument must be greater or equal 0");
+				err = 1;
+			} else if(!m) {
+				_pam_log(LOG_ERR, "invalid argument: %s\n", argument);
+				err = 1;
+			}
+		} else {
+			/* no value arguments */
+			if(!strcmp(argument, "debug"))
+				conf.flags ^= PAM_QUOTE_DEBUG;
+			else {
+				_pam_log(LOG_ERR, "invalid argument: %s\n", argument);
+				err = 1;
+			}
+		}
+
+		free(argument);
+	}
+
+	if(err)
+		return PAM_SESSION_ERR;
+	
+	/* get username */
+	if(pam_get_item(pamh, PAM_USER, (const void **)&username) != PAM_SUCCESS) {
+		_pam_log(LOG_ERR, "unknown user\n");
+		return PAM_USER_UNKNOWN;
+	}
+
+	/* get user's home directory */
+	if(!(pwd = getpwnam(username))) {
+		_pam_log(LOG_ERR, "unable to get user home directory\n");
+		return PAM_USER_UNKNOWN;
+	}
+
+	/* get home filesystem name */
+	if(!(fs = fs_from_home(pwd->pw_dir)))
+		return PAM_SESSION_ERR;
+
+	/* apply quota */
+#if defined(__FreeBSD__)
+	if(pwd->pw_uid && quotactl(fs, QCMD(Q_SETQUOTA, USRQUOTA), pwd->pw_uid, &conf.q) < 0) {
+#elif defined(__linux__)
+	if(pwd->pw_uid && quotactl(QCMD(Q_SETQUOTA, USRQUOTA), fs, pwd->pw_uid, (caddr_t)&conf.q) < 0) {
+#endif
+		_pam_log(LOG_ERR, "unable to set quota\n");
+		return PAM_SESSION_ERR;
+	}
+
+	free(fs);
+
+	return PAM_SUCCESS;
+}
+
+PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) {
+	return PAM_SUCCESS;
+}
+
+/* other not supported groups */
+
+PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) {
+	_pam_log(LOG_ERR, "authentication management group is not supported by this module");
+	return PAM_SERVICE_ERR;
+}
+
+PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) {
+	_pam_log(LOG_ERR, "authentication management group is not supported by this module");
+	return PAM_SERVICE_ERR;
+}
+
+PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) {
+	_pam_log(LOG_ERR, "account management group is not supported by this module");
+	return PAM_SERVICE_ERR;
+}
+
+PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) {
+	_pam_log(LOG_ERR, "password management group is not unsupported by this module");
+	return PAM_SERVICE_ERR;
+}
+
================================================================


More information about the pld-cvs-commit mailing list