summaryrefslogtreecommitdiff
path: root/Linux-PAM/modules/pam_pwdb/pam_unix_acct.-c
diff options
context:
space:
mode:
Diffstat (limited to 'Linux-PAM/modules/pam_pwdb/pam_unix_acct.-c')
-rw-r--r--Linux-PAM/modules/pam_pwdb/pam_unix_acct.-c272
1 files changed, 272 insertions, 0 deletions
diff --git a/Linux-PAM/modules/pam_pwdb/pam_unix_acct.-c b/Linux-PAM/modules/pam_pwdb/pam_unix_acct.-c
new file mode 100644
index 00000000..3a6ff1ed
--- /dev/null
+++ b/Linux-PAM/modules/pam_pwdb/pam_unix_acct.-c
@@ -0,0 +1,272 @@
+/*
+ * $Id: pam_unix_acct.-c,v 1.1.1.1 2001/04/29 04:17:28 hartmans Exp $
+ *
+ * See end of file for copyright information
+ */
+
+static const char rcsid_acct[] =
+"$Id: pam_unix_acct.-c,v 1.1.1.1 2001/04/29 04:17:28 hartmans Exp $\n"
+" - PAM_PWDB account management <gafton@redhat.com>";
+
+/* the shadow suite has accout managment.. */
+
+static int _shadow_acct_mgmt_exp(pam_handle_t *pamh, unsigned int ctrl,
+ const struct pwdb *pw, const char *uname)
+{
+ const struct pwdb_entry *pwe = NULL;
+ time_t curdays;
+ int last_change, max_change;
+ int retval;
+
+ D(("called."));
+
+ /* Now start the checks */
+
+ curdays = time(NULL)/(60*60*24); /* today */
+
+ /* First: has account expired ? (CG)
+ * - expire < curdays
+ * - or (last_change + max_change + defer_change) < curdays
+ * - in both cases, deny access
+ */
+
+ D(("pwdb_get_entry"));
+ retval = pwdb_get_entry(pw, "expire", &pwe);
+ if (retval == PWDB_SUCCESS) {
+ int expire;
+
+ expire = *( (const int *) pwe->value );
+ (void) pwdb_entry_delete(&pwe); /* no longer needed */
+
+ if ((curdays > expire) && (expire > 0)) {
+
+ _log_err(LOG_NOTICE
+ , "acct: account %s has expired (account expired)"
+ , uname);
+ make_remark(pamh, ctrl, PAM_ERROR_MSG
+ , "Your account has expired; "
+ "please contact your system administrator");
+
+ D(("account expired"));
+ return PAM_ACCT_EXPIRED;
+ }
+ }
+
+ D(("pwdb_get_entry"));
+ retval = pwdb_get_entry(pw, "last_change", &pwe);
+ if ( retval == PWDB_SUCCESS ) {
+ last_change = *( (const int *) pwe->value );
+ } else {
+ last_change = curdays;
+ }
+ (void) pwdb_entry_delete(&pwe);
+
+ D(("pwdb_get_entry"));
+ retval = pwdb_get_entry(pw, "max_change", &pwe);
+ if ( retval == PWDB_SUCCESS ) {
+ max_change = *( (const int *) pwe->value );
+ } else {
+ max_change = -1;
+ }
+ (void) pwdb_entry_delete(&pwe);
+
+ D(("pwdb_get_entry"));
+ retval = pwdb_get_entry(pw, "defer_change", &pwe);
+ if (retval == PWDB_SUCCESS) {
+ int defer_change;
+
+ defer_change = *( (const int *) pwe->value );
+ (void) pwdb_entry_delete(&pwe);
+
+ if ((curdays > (last_change + max_change + defer_change))
+ && (max_change != -1) && (defer_change != -1)
+ && (last_change > 0)) {
+
+ if ( on(UNIX_DEBUG, ctrl) ) {
+ _log_err(LOG_NOTICE, "acct: account %s has expired "
+ "(failed to change password)", uname);
+ }
+ make_remark(pamh, ctrl, PAM_ERROR_MSG
+ , "Your password has expired; "
+ "please see your system administrator");
+
+ D(("account expired2"));
+ return PAM_ACCT_EXPIRED;
+ }
+ }
+
+ /* Now test if the password is expired, but the user still can
+ * change their password. (CG)
+ * - last_change = 0
+ * - last_change + max_change < curdays
+ */
+
+ D(("when was the last change"));
+ if (last_change == 0) {
+
+ if ( on(UNIX_DEBUG, ctrl) ) {
+ _log_err(LOG_NOTICE
+ , "acct: expired password for user %s (root enforced)"
+ , uname);
+ }
+ make_remark(pamh, ctrl, PAM_ERROR_MSG
+ , "You are required to change your password immediately"
+ );
+
+ D(("need a new password"));
+ return PAM_NEW_AUTHTOK_REQD;
+ }
+
+ if (((last_change + max_change) < curdays) &&
+ (max_change < 99999) && (max_change > 0)) {
+
+ if ( on(UNIX_DEBUG, ctrl) ) {
+ _log_err(LOG_DEBUG
+ , "acct: expired password for user %s (password aged)"
+ , uname);
+ }
+ make_remark(pamh, ctrl, PAM_ERROR_MSG
+ , "Your password has expired; please change it!");
+
+ D(("need a new password 2"));
+ return PAM_NEW_AUTHTOK_REQD;
+ }
+
+ /*
+ * Now test if the password is about to expire (CG)
+ * - last_change + max_change - curdays <= warn_change
+ */
+
+ retval = pwdb_get_entry(pw, "warn_change", &pwe);
+ if ( retval == PWDB_SUCCESS ) {
+ int warn_days, daysleft;
+
+ daysleft = last_change + max_change - curdays;
+ warn_days = *((const int *) pwe->value);
+ (void) pwdb_entry_delete(&pwe);
+
+ if ((daysleft <= warn_days) && (warn_days > 0)) {
+ char *s;
+
+ if ( on(UNIX_DEBUG, ctrl) ) {
+ _log_err(LOG_DEBUG
+ , "acct: password for user %s will expire in %d days"
+ , uname, daysleft);
+ }
+
+#define LocalComment "Warning: your password will expire in %d day%s"
+ if ((s = (char *) malloc(30+sizeof(LocalComment))) == NULL) {
+ _log_err(LOG_CRIT, "malloc failure in " __FILE__);
+ retval = PAM_BUF_ERR;
+ } else {
+
+ sprintf(s, LocalComment, daysleft, daysleft == 1 ? "":"s");
+
+ make_remark(pamh, ctrl, PAM_TEXT_INFO, s);
+ free(s);
+ }
+#undef LocalComment
+ }
+ } else {
+ retval = PAM_SUCCESS;
+ }
+
+ D(("all done"));
+ return retval;
+}
+
+
+/*
+ * this function checks for the account details. The user may not be
+ * permitted to log in at this time etc.. Within the context of
+ * vanilla Unix, this function simply does nothing. The shadow suite
+ * added password/account expiry, but PWDB takes care of this
+ * transparently.
+ */
+
+static int _unix_acct_mgmt(pam_handle_t *pamh, unsigned int ctrl)
+{
+ const struct pwdb *pw = NULL;
+
+ char *uname=NULL;
+ int retval;
+
+ D(("called."));
+
+ /* identify user */
+
+ retval = pam_get_item(pamh,PAM_USER,(const void **)&uname);
+ D(("user = `%s'", uname));
+ if (retval != PAM_SUCCESS || uname == NULL) {
+ _log_err(LOG_ALERT
+ , "acct; could not identify user (from uid=%d)"
+ , getuid());
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* get database information for user */
+
+ retval = pwdb_locate("user", PWDB_DEFAULT, uname, PWDB_ID_UNKNOWN, &pw);
+ if (retval != PWDB_SUCCESS || pw == NULL) {
+
+ _log_err(LOG_ALERT, "acct; %s (%s from uid=%d)"
+ , pwdb_strerror(retval), uname, getuid());
+ if ( pw ) {
+ (void) pwdb_delete(&pw);
+ }
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* now check the user's times etc.. */
+
+ retval = _shadow_acct_mgmt_exp(pamh, ctrl, pw, uname);
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_NOTICE, "expiry check failed for '%s'", uname);
+ }
+
+ /* Done with pw */
+
+ (void) pwdb_delete(&pw);
+
+ /* all done */
+
+ D(("done."));
+ return retval;
+}
+
+/*
+ * Copyright (c) Elliot Lee, 1996.
+ * Copyright (c) Andrew Morgan <morgan@parc.power.net> 1996.
+ * Copyright (c) Cristian Gafton <gafton@redhat.com> 1996.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */