1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2010 by the Massachusetts Institute of Technology.
* All rights reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*/
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*/
#include "k5-int.h"
#include <kdb.h>
#include <ctype.h>
#include <pwd.h>
#include <syslog.h>
#include "server_internal.h"
#include <adm_proto.h>
kadm5_ret_t
adb_policy_init(kadm5_server_handle_t handle)
{
/* now policy is initialized as part of database. No seperate call needed */
if( krb5_db_inited( handle->context ) )
return KADM5_OK;
return krb5_db_open( handle->context, NULL,
KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN );
}
kadm5_ret_t
adb_policy_close(kadm5_server_handle_t handle)
{
/* will be taken care by database close */
return KADM5_OK;
}
kadm5_ret_t
init_pwqual(kadm5_server_handle_t handle)
{
krb5_error_code ret;
pwqual_handle *list;
const char *dict_file = NULL;
/* Register the built-in password quality modules. */
ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,
"dict", pwqual_dict_initvt);
if (ret != 0)
return ret;
ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,
"empty", pwqual_empty_initvt);
if (ret != 0)
return ret;
ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,
"hesiod", pwqual_hesiod_initvt);
if (ret != 0)
return ret;
ret = k5_plugin_register(handle->context, PLUGIN_INTERFACE_PWQUAL,
"princ", pwqual_princ_initvt);
if (ret != 0)
return ret;
/* Load all available password quality modules. */
if (handle->params.mask & KADM5_CONFIG_DICT_FILE)
dict_file = handle->params.dict_file;
ret = k5_pwqual_load(handle->context, dict_file, &list);
if (ret != 0)
return ret;
handle->qual_handles = list;
return 0;
}
/* Check that a password meets the quality constraints given in pol. */
static kadm5_ret_t
check_against_policy(kadm5_server_handle_t handle, const char *password,
kadm5_policy_ent_t pol)
{
int hasupper = 0, haslower = 0, hasdigit = 0, haspunct = 0, hasspec = 0;
int c, nclasses;
/* Check against the policy's minimum length. */
if (strlen(password) < (size_t)pol->pw_min_length)
return KADM5_PASS_Q_TOOSHORT;
/* Check against the policy's minimum number of character classes. */
while ((c = (unsigned char)*password++) != '\0') {
if (islower(c))
haslower = 1;
else if (isupper(c))
hasupper = 1;
else if (isdigit(c))
hasdigit = 1;
else if (ispunct(c))
haspunct = 1;
else
hasspec = 1;
}
nclasses = hasupper + haslower + hasdigit + haspunct + hasspec;
if (nclasses < pol->pw_min_classes)
return KADM5_PASS_Q_CLASS;
return KADM5_OK;
}
/* Check a password against all available password quality plugin modules
* and against policy. */
kadm5_ret_t
passwd_check(kadm5_server_handle_t handle, const char *password,
kadm5_policy_ent_t policy, krb5_principal princ)
{
krb5_error_code ret;
pwqual_handle *h;
const char *polname = (policy == NULL) ? NULL : policy->policy;
if (policy != NULL) {
ret = check_against_policy(handle, password, policy);
if (ret != 0)
return ret;
}
for (h = handle->qual_handles; *h != NULL; h++) {
ret = k5_pwqual_check(handle->context, *h, password, polname, princ);
if (ret != 0) {
const char *e = krb5_get_error_message(handle->context, ret);
const char *modname = k5_pwqual_name(handle->context, *h);
char *princname;
if (krb5_unparse_name(handle->context, princ, &princname) != 0)
princname = NULL;
krb5_klog_syslog(LOG_ERR,
_("password quality module %s rejected password "
"for %s: %s"), modname,
princname ? princname : "(can't unparse)", e);
krb5_free_error_message(handle->context, e);
free(princname);
return ret;
}
}
return 0;
}
void
destroy_pwqual(kadm5_server_handle_t handle)
{
k5_pwqual_free_handles(handle->context, handle->qual_handles);
handle->qual_handles = NULL;
}
|