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