1
2/*
3 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
4 *
5 *	Openvision retains the copyright to derivative works of
6 *	this source code.  Do *NOT* create a derivative of this
7 *	source code before consulting with your legal department.
8 *	Do *NOT* integrate *ANY* of this source code into another
9 *	product before consulting with your legal department.
10 *
11 *	For further information, read the top-level Openvision
12 *	copyright which is contained in the top-level MIT Kerberos
13 *	copyright.
14 *
15 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
16 *
17 */
18
19
20/*
21 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
22 *
23 * $Header$
24 */
25
26#if !defined(lint) && !defined(__CODECENTER__)
27static char *rcsid = "$Header$";
28#endif
29
30#include    <sys/types.h>
31#include    <sys/file.h>
32#include    <fcntl.h>
33#include    <sys/stat.h>
34#include    <unistd.h>
35#include <errno.h>
36#include    "server_internal.h"
37#include    <kadm5/admin.h>
38#include    <stdlib.h>
39#include    <stdio.h>
40#include    <string.h>
41#ifdef HAVE_MEMORY_H
42#include    <memory.h>
43#endif
44#include    "adm_proto.h"
45#include    <syslog.h>
46#include    <libintl.h>
47
48static char	    **word_list = NULL;	    /* list of word pointers */
49static char	    *word_block = NULL;	    /* actual word data */
50static unsigned int word_count = 0;	    /* number of words */
51
52
53/*
54 * Function: word_compare
55 *
56 * Purpose: compare two words in the dictionary.
57 *
58 * Arguments:
59 *	w1		(input)	pointer to first word
60 *	w2		(input) pointer to second word
61 *	<return value>	result of strcmp
62 *
63 * Requires:
64 *	w1 and w2 to point to valid memory
65 *
66 */
67
68static int
69word_compare(const void *s1, const void *s2)
70{
71    return (strcasecmp(*(const char **)s1, *(const char **)s2));
72}
73
74/*
75 * Function: init-dict
76 *
77 * Purpose: Initialize in memory word dictionary
78 *
79 * Arguments:
80 *	    none
81 *	    <return value> KADM5_OK on success errno on failure;
82 * 			   (but success on ENOENT)
83 *
84 * Requires:
85 *	If WORDFILE exists, it must contain a list of words,
86 *	one word per-line.
87 *
88 * Effects:
89 *	If WORDFILE exists, it is read into memory sorted for future
90 * use.  If it does not exist, it syslogs an error message and returns
91 * success.
92 *
93 * Modifies:
94 *	word_list to point to a chunck of allocated memory containing
95 *	pointers to words
96 *	word_block to contain the dictionary.
97 *
98 */
99
100int init_dict(kadm5_config_params *params)
101{
102    int		    fd,
103		    len,
104		    i;
105    char	    *p,
106		    *t;
107    struct  stat    sb;
108
109    if(word_list != NULL && word_block != NULL)
110	return KADM5_OK;
111    if (! (params->mask & KADM5_CONFIG_DICT_FILE)) {
112	/* Solaris Kerberos */
113	 krb5_klog_syslog(LOG_INFO,
114		dgettext(TEXT_DOMAIN,
115			"No dictionary file specified, continuing "
116			"without one."));
117	 return KADM5_OK;
118    }
119    if ((fd = open(params->dict_file, O_RDONLY)) == -1) {
120	 if (errno == ENOENT) {
121	/* Solaris Kerberos */
122	      krb5_klog_syslog(LOG_ERR,
123		     dgettext(TEXT_DOMAIN,
124			"WARNING!  Cannot find dictionary file %s, "
125			     "continuing without one."), params->dict_file);
126	      return KADM5_OK;
127	 } else
128	      return errno;
129    }
130    if (fstat(fd, &sb) == -1)
131	return errno;
132    if ((word_block = (char *) malloc(sb.st_size + 1)) == NULL)
133	return errno;
134    if (read(fd, word_block, sb.st_size) != sb.st_size)
135	return errno;
136    (void) close(fd);
137    word_block[sb.st_size] = '\0';
138
139    p = word_block;
140    len = sb.st_size;
141    while(len > 0 && (t = memchr(p, '\n', len)) != NULL) {
142	*t = '\0';
143	len -= t - p + 1;
144	p = t + 1;
145	word_count++;
146    }
147    if ((word_list = (char **) malloc(word_count * sizeof(char *))) == NULL)
148	return errno;
149    p = word_block;
150    for (i = 0; i < word_count; i++) {
151	word_list[i] = p;
152	p += strlen(p) + 1;
153    }
154    qsort(word_list, word_count, sizeof(char *), word_compare);
155    return KADM5_OK;
156}
157
158/*
159 * Function: find_word
160 *
161 * Purpose: See if the specified word exists in the in-core dictionary
162 *
163 * Arguments:
164 *	word		(input) word to search for.
165 * 	<return value>	WORD_NOT_FOUND if not in dictionary,
166 *			KADM5_OK if if found word
167 *			errno if init needs to be called and returns an
168 *			error
169 *
170 * Requires:
171 *	word to be a null terminated string.
172 *	That word_list and word_block besetup
173 *
174 * Effects:
175 *	finds word in dictionary.
176 * Modifies:
177 *	nothing.
178 *
179 */
180
181int
182find_word(const char *word)
183{
184    char    **value;
185
186    if(word_list == NULL || word_block == NULL)
187	    return WORD_NOT_FOUND;
188    if ((value = (char **) bsearch(&word, word_list, word_count, sizeof(char *),
189				   word_compare)) == NULL)
190	return WORD_NOT_FOUND;
191    else
192	return KADM5_OK;
193}
194
195/*
196 * Function: destroy_dict
197 *
198 * Purpose: destroy in-core copy of dictionary.
199 *
200 * Arguments:
201 *	    none
202 *	    <return value>  none
203 * Requires:
204 *	    nothing
205 * Effects:
206 *	frees up memory occupied by word_list and word_block
207 *	sets count back to 0, and resets the pointers to NULL
208 *
209 * Modifies:
210 *	word_list, word_block, and word_count.
211 *
212 */
213
214void
215destroy_dict(void)
216{
217    if(word_list) {
218	free(word_list);
219	word_list = NULL;
220    }
221    if(word_block) {
222	free(word_block);
223	word_block = NULL;
224    }
225    if(word_count)
226	word_count = 0;
227    return;
228}
229