~ubuntu-branches/ubuntu/breezy/pam/breezy

« back to all changes in this revision

Viewing changes to Linux-PAM/modules/pam_pwdb/pam_unix_acct.-c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman
  • Date: 2004-06-28 14:28:08 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20040628142808-adikk7vtfg3pzcjw
Tags: 0.76-22
* Add uploaders
* Document location of repository
* Fix options containing arguments in pam_unix, Closes: #254904

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * $Id: pam_unix_acct.-c,v 1.1 2001/04/29 04:17:28 hartmans Exp $
 
3
 *
 
4
 * See end of file for copyright information
 
5
 */
 
6
 
 
7
static const char rcsid_acct[] =
 
8
"$Id: pam_unix_acct.-c,v 1.1 2001/04/29 04:17:28 hartmans Exp $\n"
 
9
" - PAM_PWDB account management <gafton@redhat.com>";
 
10
 
 
11
/* the shadow suite has accout managment.. */
 
12
 
 
13
static int _shadow_acct_mgmt_exp(pam_handle_t *pamh, unsigned int ctrl,
 
14
                                 const struct pwdb *pw, const char *uname)
 
15
{
 
16
    const struct pwdb_entry *pwe = NULL;
 
17
    time_t curdays;
 
18
    int last_change, max_change;
 
19
    int retval;
 
20
 
 
21
    D(("called."));
 
22
 
 
23
    /* Now start the checks */
 
24
 
 
25
    curdays = time(NULL)/(60*60*24);                        /* today */
 
26
 
 
27
    /* First: has account expired ? (CG)
 
28
     *     - expire < curdays
 
29
     *     - or (last_change + max_change + defer_change) < curdays
 
30
     *     - in both cases, deny access
 
31
     */
 
32
 
 
33
    D(("pwdb_get_entry"));
 
34
    retval = pwdb_get_entry(pw, "expire", &pwe);
 
35
    if (retval == PWDB_SUCCESS) {
 
36
        int expire;
 
37
 
 
38
        expire = *( (const int *) pwe->value );
 
39
        (void) pwdb_entry_delete(&pwe);              /* no longer needed */
 
40
 
 
41
        if ((curdays > expire) && (expire > 0)) {
 
42
 
 
43
            _log_err(LOG_NOTICE
 
44
                     , "acct: account %s has expired (account expired)"
 
45
                     , uname);
 
46
            make_remark(pamh, ctrl, PAM_ERROR_MSG
 
47
                        , "Your account has expired; "
 
48
                        "please contact your system administrator");
 
49
 
 
50
            D(("account expired"));
 
51
            return PAM_ACCT_EXPIRED;
 
52
        }
 
53
    }
 
54
 
 
55
    D(("pwdb_get_entry"));
 
56
    retval = pwdb_get_entry(pw, "last_change", &pwe);
 
57
    if ( retval == PWDB_SUCCESS ) {
 
58
        last_change = *( (const int *) pwe->value );
 
59
    } else {
 
60
        last_change = curdays;
 
61
    }
 
62
    (void) pwdb_entry_delete(&pwe);
 
63
 
 
64
    D(("pwdb_get_entry"));
 
65
    retval = pwdb_get_entry(pw, "max_change", &pwe);
 
66
    if ( retval == PWDB_SUCCESS ) {
 
67
        max_change = *( (const int *) pwe->value );
 
68
    } else {
 
69
        max_change = -1;
 
70
    }
 
71
    (void) pwdb_entry_delete(&pwe);
 
72
 
 
73
    D(("pwdb_get_entry"));
 
74
    retval = pwdb_get_entry(pw, "defer_change", &pwe);
 
75
    if (retval == PWDB_SUCCESS) {
 
76
        int defer_change;
 
77
 
 
78
        defer_change = *( (const int *) pwe->value );
 
79
        (void) pwdb_entry_delete(&pwe);
 
80
 
 
81
        if ((curdays > (last_change + max_change + defer_change))
 
82
            && (max_change != -1) && (defer_change != -1)
 
83
            && (last_change > 0)) {
 
84
 
 
85
            if ( on(UNIX_DEBUG, ctrl) ) {
 
86
                _log_err(LOG_NOTICE, "acct: account %s has expired "
 
87
                         "(failed to change password)", uname);
 
88
            }
 
89
            make_remark(pamh, ctrl, PAM_ERROR_MSG
 
90
                        , "Your password has expired; "
 
91
                        "please see your system administrator");
 
92
 
 
93
            D(("account expired2"));
 
94
            return PAM_ACCT_EXPIRED;
 
95
        }
 
96
    }
 
97
 
 
98
    /* Now test if the password is expired, but the user still can
 
99
     * change their password. (CG)
 
100
     *     - last_change = 0
 
101
     *     - last_change + max_change < curdays
 
102
     */
 
103
 
 
104
    D(("when was the last change"));
 
105
    if (last_change == 0) {
 
106
 
 
107
        if ( on(UNIX_DEBUG, ctrl) ) {
 
108
            _log_err(LOG_NOTICE
 
109
                     , "acct: expired password for user %s (root enforced)"
 
110
                     , uname);
 
111
        }
 
112
        make_remark(pamh, ctrl, PAM_ERROR_MSG
 
113
                    , "You are required to change your password immediately"
 
114
            );
 
115
 
 
116
        D(("need a new password"));
 
117
        return PAM_NEW_AUTHTOK_REQD;
 
118
    }
 
119
 
 
120
    if (((last_change + max_change) < curdays) &&
 
121
        (max_change < 99999) && (max_change > 0)) {
 
122
 
 
123
        if ( on(UNIX_DEBUG, ctrl) ) {
 
124
            _log_err(LOG_DEBUG
 
125
                     , "acct: expired password for user %s (password aged)"
 
126
                     , uname);
 
127
        }
 
128
        make_remark(pamh, ctrl, PAM_ERROR_MSG
 
129
                    , "Your password has expired; please change it!");
 
130
 
 
131
        D(("need a new password 2"));
 
132
        return PAM_NEW_AUTHTOK_REQD;
 
133
    }
 
134
 
 
135
    /*
 
136
     * Now test if the password is about to expire (CG)
 
137
     *     - last_change + max_change - curdays <= warn_change
 
138
     */
 
139
 
 
140
    retval = pwdb_get_entry(pw, "warn_change", &pwe);
 
141
    if ( retval == PWDB_SUCCESS ) {
 
142
        int warn_days, daysleft;
 
143
 
 
144
        daysleft = last_change + max_change - curdays;
 
145
        warn_days = *((const int *) pwe->value);
 
146
        (void) pwdb_entry_delete(&pwe);
 
147
 
 
148
        if ((daysleft <= warn_days) && (warn_days > 0)) {
 
149
            char *s;
 
150
 
 
151
            if ( on(UNIX_DEBUG, ctrl) ) {
 
152
                _log_err(LOG_DEBUG
 
153
                         , "acct: password for user %s will expire in %d days"
 
154
                         , uname, daysleft);
 
155
            }
 
156
 
 
157
#define LocalComment "Warning: your password will expire in %d day%s"
 
158
            if ((s = (char *) malloc(30+sizeof(LocalComment))) == NULL) {
 
159
                _log_err(LOG_CRIT, "malloc failure in " __FILE__);
 
160
                retval = PAM_BUF_ERR;
 
161
            } else {
 
162
 
 
163
                sprintf(s, LocalComment, daysleft, daysleft == 1 ? "":"s");
 
164
 
 
165
                make_remark(pamh, ctrl, PAM_TEXT_INFO, s);
 
166
                free(s);
 
167
            }
 
168
#undef LocalComment
 
169
        }
 
170
    } else {
 
171
        retval = PAM_SUCCESS;
 
172
    }
 
173
 
 
174
    D(("all done"));
 
175
    return retval;
 
176
}
 
177
 
 
178
 
 
179
/*
 
180
 * this function checks for the account details. The user may not be
 
181
 * permitted to log in at this time etc.. Within the context of
 
182
 * vanilla Unix, this function simply does nothing. The shadow suite
 
183
 * added password/account expiry, but PWDB takes care of this
 
184
 * transparently.
 
185
 */
 
186
 
 
187
static int _unix_acct_mgmt(pam_handle_t *pamh, unsigned int ctrl)
 
188
{
 
189
    const struct pwdb *pw = NULL;
 
190
 
 
191
    char *uname=NULL;
 
192
    int retval;
 
193
 
 
194
    D(("called."));
 
195
 
 
196
    /* identify user */
 
197
 
 
198
    retval = pam_get_item(pamh,PAM_USER,(const void **)&uname);
 
199
    D(("user = `%s'", uname));
 
200
    if (retval != PAM_SUCCESS || uname == NULL) {
 
201
        _log_err(LOG_ALERT
 
202
                 , "acct; could not identify user (from uid=%d)"
 
203
                 , getuid());
 
204
        return PAM_USER_UNKNOWN;
 
205
    }
 
206
 
 
207
    /* get database information for user */
 
208
 
 
209
    retval = pwdb_locate("user", PWDB_DEFAULT, uname, PWDB_ID_UNKNOWN, &pw);
 
210
    if (retval != PWDB_SUCCESS || pw == NULL) {
 
211
 
 
212
        _log_err(LOG_ALERT, "acct; %s (%s from uid=%d)"
 
213
                 , pwdb_strerror(retval), uname, getuid());
 
214
        if ( pw ) {
 
215
            (void) pwdb_delete(&pw);
 
216
        }
 
217
        return PAM_USER_UNKNOWN;
 
218
    }
 
219
 
 
220
    /* now check the user's times etc.. */
 
221
 
 
222
    retval = _shadow_acct_mgmt_exp(pamh, ctrl, pw, uname);
 
223
    if (retval != PAM_SUCCESS) {
 
224
        _log_err(LOG_NOTICE, "expiry check failed for '%s'", uname);
 
225
    }
 
226
 
 
227
    /* Done with pw */
 
228
 
 
229
    (void) pwdb_delete(&pw);
 
230
 
 
231
    /* all done */
 
232
 
 
233
    D(("done."));
 
234
    return retval;
 
235
}
 
236
 
 
237
/*
 
238
 * Copyright (c) Elliot Lee, 1996.
 
239
 * Copyright (c) Andrew Morgan <morgan@parc.power.net> 1996.
 
240
 * Copyright (c) Cristian Gafton <gafton@redhat.com> 1996.
 
241
 *
 
242
 * Redistribution and use in source and binary forms, with or without
 
243
 * modification, are permitted provided that the following conditions
 
244
 * are met:
 
245
 * 1. Redistributions of source code must retain the above copyright
 
246
 *    notice, and the entire permission notice in its entirety,
 
247
 *    including the disclaimer of warranties.
 
248
 * 2. Redistributions in binary form must reproduce the above copyright
 
249
 *    notice, this list of conditions and the following disclaimer in the
 
250
 *    documentation and/or other materials provided with the distribution.
 
251
 * 3. The name of the author may not be used to endorse or promote
 
252
 *    products derived from this software without specific prior
 
253
 *    written permission.
 
254
 * 
 
255
 * ALTERNATIVELY, this product may be distributed under the terms of
 
256
 * the GNU Public License, in which case the provisions of the GPL are
 
257
 * required INSTEAD OF the above restrictions.  (This clause is
 
258
 * necessary due to a potential bad interaction between the GPL and
 
259
 * the restrictions contained in a BSD-style copyright.)
 
260
 * 
 
261
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 
262
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
263
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
264
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 
265
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
266
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
267
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
268
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
269
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
270
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 
271
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 
272
 */