aboutsummaryrefslogtreecommitdiff
path: root/src/lib/kadm5/srv/server_dict.c
blob: ece7831c9000146c32df6f43e892bb8c98aa21ab (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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
 *
 * $Header$
 */

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

#include    <sys/types.h>
#include    <sys/file.h>
#include    <fcntl.h>
#include    <sys/stat.h>
#include    <unistd.h>
#include <errno.h>
#include    <kadm5/admin.h>
#include    <stdlib.h>
#include    <stdio.h>
#include    <string.h>
#ifdef HAVE_MEMORY_H
#include    <memory.h>
#endif
#include    "adm_proto.h"
#include    <syslog.h>
#include    "server_internal.h"

static char	    **word_list = NULL;	    /* list of word pointers */
static char	    *word_block = NULL;	    /* actual word data */
static unsigned int word_count = 0;	    /* number of words */


/*
 * Function: word_compare
 * 
 * Purpose: compare two words in the dictionary.
 *
 * Arguments:
 *	w1		(input)	pointer to first word
 *	w2		(input) pointer to second word
 *	<return value>	result of strcmp
 *
 * Requires:
 *	w1 and w2 to point to valid memory
 * 
 */

static int
word_compare(const void *s1, const void *s2)
{
    return (strcasecmp(*(const char **)s1, *(const char **)s2));
}

/*
 * Function: init-dict
 * 
 * Purpose: Initialize in memory word dictionary
 *
 * Arguments:
 *	    none
 *	    <return value> KADM5_OK on success errno on failure;
 * 			   (but success on ENOENT)
 *
 * Requires:
 *	If WORDFILE exists, it must contain a list of words,
 *	one word per-line.
 * 
 * Effects:
 *	If WORDFILE exists, it is read into memory sorted for future
 * use.  If it does not exist, it syslogs an error message and returns
 * success.
 *
 * Modifies:
 *	word_list to point to a chunck of allocated memory containing
 *	pointers to words
 *	word_block to contain the dictionary.
 * 
 */

int init_dict(kadm5_config_params *params)
{
    int		    fd,
		    len,
		    i;
    char	    *p,
		    *t;
    struct  stat    sb;
    
    if(word_list != NULL && word_block != NULL)
	return KADM5_OK;
    if (! (params->mask & KADM5_CONFIG_DICT_FILE)) {
	 krb5_klog_syslog(LOG_INFO, "No dictionary file specified, continuing "
		"without one.");
	 return KADM5_OK;
    }
    if ((fd = open(params->dict_file, O_RDONLY)) == -1) {
	 if (errno == ENOENT) {
	      krb5_klog_syslog(LOG_ERR, 
			       "WARNING!  Cannot find dictionary file %s, "
			       "continuing without one.", params->dict_file);
	      return KADM5_OK;
	 } else
	      return errno;
    }
    set_cloexec_fd(fd);
    if (fstat(fd, &sb) == -1) {
	close(fd);
	return errno;
    }
    if ((word_block = (char *) malloc(sb.st_size + 1)) == NULL)
	return ENOMEM;
    if (read(fd, word_block, sb.st_size) != sb.st_size)
	return errno;
    (void) close(fd);
    word_block[sb.st_size] = '\0';

    p = word_block;
    len = sb.st_size;
    while(len > 0 && (t = memchr(p, '\n', len)) != NULL) {
	*t = '\0';
	len -= t - p + 1;	
	p = t + 1;
	word_count++;
    }
    if ((word_list = (char **) malloc(word_count * sizeof(char *))) == NULL)
	return ENOMEM;
    p = word_block;
    for (i = 0; i < word_count; i++) {
	word_list[i] = p;
	p += strlen(p) + 1;
    }
    qsort(word_list, word_count, sizeof(char *), word_compare);
    return KADM5_OK;
}

/*
 * Function: find_word
 * 
 * Purpose: See if the specified word exists in the in-core dictionary
 *
 * Arguments:
 *	word		(input) word to search for.
 * 	<return value>	WORD_NOT_FOUND if not in dictionary,
 *			KADM5_OK if if found word
 *			errno if init needs to be called and returns an
 *			error
 *
 * Requires:
 *	word to be a null terminated string.
 *	That word_list and word_block besetup
 * 
 * Effects:
 *	finds word in dictionary.
 * Modifies:
 *	nothing.
 * 
 */

int
find_word(const char *word)
{
    char    **value;

    if(word_list == NULL || word_block == NULL) 
	    return WORD_NOT_FOUND;
    if ((value = (char **) bsearch(&word, word_list, word_count, sizeof(char *),
				   word_compare)) == NULL)
	return WORD_NOT_FOUND;
    else
	return KADM5_OK;
}

/*
 * Function: destroy_dict
 * 
 * Purpose: destroy in-core copy of dictionary.
 *
 * Arguments:
 *	    none
 *	    <return value>  none
 * Requires:
 *	    nothing
 * Effects:
 *	frees up memory occupied by word_list and word_block
 *	sets count back to 0, and resets the pointers to NULL
 *
 * Modifies:
 *	word_list, word_block, and word_count.
 * 
 */

void
destroy_dict(void)
{
    if(word_list) {
	free(word_list);
	word_list = NULL;
    }
    if(word_block) {
	free(word_block);
	word_block = NULL;
    }
    if(word_count)
	word_count = 0;
    return;
}