summaryrefslogtreecommitdiffstats
path: root/src/lib/kadm5/srv/server_misc.c
blob: 1faeb86b16f7d6ba42f235ae66fb7617bbc537dc (plain)
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
 *
 * $Header$
 */

#if !defined(lint) && !defined(__CODECENTER__)
static char *rcsid = "$Header$";
#endif

#include    "k5-int.h"
#include    <kdb.h>
#include    <ctype.h>
#include    <pwd.h>

/* for strcasecmp */
#include    <string.h>

#include    "server_internal.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;
}

#ifdef HESIOD
/* stolen from v4sever/kadm_funcs.c */
static char *
reverse(str)
    char    *str;
{
    static char newstr[80];
    char    *p, *q;
    int     i;

    i = strlen(str);
    if (i >= sizeof(newstr))
        i = sizeof(newstr)-1;
    p = str+i-1;
    q = newstr;
    q[i]='\0';
    for(; i > 0; i--)
        *q++ = *p--;

    return(newstr);
}
#endif /* HESIOD */

#if 0
static int
lower(str)
    char    *str;
{
    register char   *cp;
    int     effect=0;

    for (cp = str; *cp; cp++) {
        if (isupper(*cp)) {
            *cp = tolower(*cp);
            effect++;
        }
    }
    return(effect);
}
#endif

#ifdef HESIOD
static int
str_check_gecos(gecos, pwstr)
    char    *gecos;
    char    *pwstr;
{
    char            *cp, *ncp, *tcp;

    for (cp = gecos; *cp; ) {
        /* Skip past punctuation */
        for (; *cp; cp++)
            if (isalnum(*cp))
                break;
        /* Skip to the end of the word */
        for (ncp = cp; *ncp; ncp++)
            if (!isalnum(*ncp) && *ncp != '\'')
                break;
        /* Delimit end of word */
        if (*ncp)
            *ncp++ = '\0';
        /* Check word to see if it's the password */
        if (*cp) {
            if (!strcasecmp(pwstr, cp))
                return 1;
            tcp = reverse(cp);
            if (!strcasecmp(pwstr, tcp))
                return 1;
            cp = ncp;
        } else
            break;
    }
    return 0;
}
#endif /* HESIOD */

/* some of this is stolen from gatekeeper ... */
kadm5_ret_t
passwd_check(kadm5_server_handle_t handle,
             char *password, int use_policy, kadm5_policy_ent_t pol,
             krb5_principal principal)
{
    int     nupper = 0,
        nlower = 0,
        ndigit = 0,
        npunct = 0,
        nspec = 0;
    char    c, *s, *cp;
#ifdef HESIOD
    extern  struct passwd *hes_getpwnam();
    struct  passwd *ent;
#endif

    if(use_policy) {
        if(strlen(password) < pol->pw_min_length)
            return KADM5_PASS_Q_TOOSHORT;
        s = password;
        while ((c = *s++)) {
            if (islower((unsigned char) c)) {
                nlower = 1;
                continue;
            }
            else if (isupper((unsigned char) c)) {
                nupper = 1;
                continue;
            } else if (isdigit((unsigned char) c)) {
                ndigit = 1;
                continue;
            } else if (ispunct((unsigned char) c)) {
                npunct = 1;
                continue;
            } else {
                nspec = 1;
                continue;
            }
        }
        if ((nupper + nlower + ndigit + npunct + nspec) < pol->pw_min_classes)
            return KADM5_PASS_Q_CLASS;
        if((find_word(password) == KADM5_OK))
            return KADM5_PASS_Q_DICT;
        else {
            int i, n = krb5_princ_size(handle->context, principal);
            cp = krb5_princ_realm(handle->context, principal)->data;
            if (strcasecmp(cp, password) == 0)
                return KADM5_PASS_Q_DICT;
            for (i = 0; i < n ; i++) {
                cp = krb5_princ_component(handle->context, principal, i)->data;
                if (strcasecmp(cp, password) == 0)
                    return KADM5_PASS_Q_DICT;
#ifdef HESIOD
                ent = hes_getpwnam(cp);
                if (ent && ent->pw_gecos)
                    if (str_check_gecos(ent->pw_gecos, password))
                        return KADM5_PASS_Q_DICT; /* XXX new error code? */
#endif
            }
            return KADM5_OK;
        }
    } else {
        if (strlen(password) < 1)
            return KADM5_PASS_Q_TOOSHORT;
    }
    return KADM5_OK;
}