1 /*
2 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
3 *
4 * Openvision retains the copyright to derivative works of
5 * this source code. Do *NOT* create a derivative of this
6 * source code before consulting with your legal department.
7 * Do *NOT* integrate *ANY* of this source code into another
8 * product before consulting with your legal department.
9 *
10 * For further information, read the top-level Openvision
11 * copyright which is contained in the top-level MIT Kerberos
12 * copyright.
13 *
14 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
15 *
16 */
17
18
19 /*
20 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
21 *
22 * $Header$
23 */
24
25 #if !defined(lint) && !defined(__CODECENTER__)
26 static char *rcsid = "$Header$";
27 #endif
28
29 #include "server_internal.h"
30 #include <sys/types.h>
31 #include <kadm5/admin.h>
32 #include <stdlib.h>
33 #include <errno.h>
34
35 #define MAX_PW_HISTORY 10
36 #define MIN_PW_HISTORY 1
37 #define MIN_PW_CLASSES 1
38 #define MAX_PW_CLASSES 5
39 #define MIN_PW_LENGTH 1
40
41 /*
42 * Function: kadm5_create_policy
43 *
44 * Purpose: Create Policies in the policy DB.
45 *
46 * Arguments:
47 * entry (input) The policy entry to be written out to the DB.
48 * mask (input) Specifies which fields in entry are to ge written out
49 * and which get default values.
50 * <return value> 0 if successful otherwise an error code is returned.
51 *
52 * Requires:
53 * Entry must be a valid principal entry, and mask have a valid value.
54 *
55 * Effects:
56 * Verifies that mask does not specify that the refcount should
57 * be set as part of the creation, and calls
58 * kadm5_create_policy_internal. If the refcount *is*
59 * specified, returns KADM5_BAD_MASK.
60 */
61
62 kadm5_ret_t
kadm5_create_policy(void * server_handle,kadm5_policy_ent_t entry,long mask)63 kadm5_create_policy(void *server_handle,
64 kadm5_policy_ent_t entry, long mask)
65 {
66 CHECK_HANDLE(server_handle);
67
68 krb5_clear_error_message(((kadm5_server_handle_t)server_handle)->context);
69
70 if (mask & KADM5_REF_COUNT)
71 return KADM5_BAD_MASK;
72 else
73 return kadm5_create_policy_internal(server_handle, entry, mask);
74 }
75
76 /*
77 * Function: kadm5_create_policy_internal
78 *
79 * Purpose: Create Policies in the policy DB.
80 *
81 * Arguments:
82 * entry (input) The policy entry to be written out to the DB.
83 * mask (input) Specifies which fields in entry are to ge written out
84 * and which get default values.
85 * <return value> 0 if successful otherwise an error code is returned.
86 *
87 * Requires:
88 * Entry must be a valid principal entry, and mask have a valid value.
89 *
90 * Effects:
91 * Writes the data to the database, and does a database sync if
92 * successful.
93 *
94 */
95
96 kadm5_ret_t
kadm5_create_policy_internal(void * server_handle,kadm5_policy_ent_t entry,long mask)97 kadm5_create_policy_internal(void *server_handle,
98 kadm5_policy_ent_t entry, long mask)
99 {
100 kadm5_server_handle_t handle = server_handle;
101 osa_policy_ent_rec pent;
102 int ret;
103 char *p;
104
105 CHECK_HANDLE(server_handle);
106
107 if ((entry == (kadm5_policy_ent_t) NULL) || (entry->policy == NULL))
108 return EINVAL;
109 if(strlen(entry->policy) == 0)
110 return KADM5_BAD_POLICY;
111 if (!(mask & KADM5_POLICY))
112 return KADM5_BAD_MASK;
113
114 pent.name = entry->policy;
115 p = entry->policy;
116 while(*p != '\0') {
117 if(*p < ' ' || *p > '~')
118 return KADM5_BAD_POLICY;
119 else
120 p++;
121 }
122 if (!(mask & KADM5_PW_MAX_LIFE))
123 pent.pw_max_life = 0;
124 else
125 pent.pw_max_life = entry->pw_max_life;
126 if (!(mask & KADM5_PW_MIN_LIFE))
127 pent.pw_min_life = 0;
128 else {
129 if((mask & KADM5_PW_MAX_LIFE)) {
130 if(entry->pw_min_life > entry->pw_max_life && entry->pw_max_life != 0)
131 return KADM5_BAD_MIN_PASS_LIFE;
132 }
133 pent.pw_min_life = entry->pw_min_life;
134 }
135 if (!(mask & KADM5_PW_MIN_LENGTH))
136 pent.pw_min_length = MIN_PW_LENGTH;
137 else {
138 if(entry->pw_min_length < MIN_PW_LENGTH)
139 return KADM5_BAD_LENGTH;
140 pent.pw_min_length = entry->pw_min_length;
141 }
142 if (!(mask & KADM5_PW_MIN_CLASSES))
143 pent.pw_min_classes = MIN_PW_CLASSES;
144 else {
145 if(entry->pw_min_classes > MAX_PW_CLASSES || entry->pw_min_classes < MIN_PW_CLASSES)
146 return KADM5_BAD_CLASS;
147 pent.pw_min_classes = entry->pw_min_classes;
148 }
149 if (!(mask & KADM5_PW_HISTORY_NUM))
150 pent.pw_history_num = MIN_PW_HISTORY;
151 else {
152 if(entry->pw_history_num < MIN_PW_HISTORY ||
153 entry->pw_history_num > MAX_PW_HISTORY)
154 return KADM5_BAD_HISTORY;
155 else
156 pent.pw_history_num = entry->pw_history_num;
157 }
158 if (!(mask & KADM5_REF_COUNT))
159 pent.policy_refcnt = 0;
160 else
161 pent.policy_refcnt = entry->policy_refcnt;
162 if ((ret = krb5_db_create_policy(handle->context, &pent)))
163 return ret;
164 else
165 return KADM5_OK;
166 }
167
168 kadm5_ret_t
kadm5_delete_policy(void * server_handle,kadm5_policy_t name)169 kadm5_delete_policy(void *server_handle, kadm5_policy_t name)
170 {
171 kadm5_server_handle_t handle = server_handle;
172 osa_policy_ent_t entry;
173 int ret;
174 int cnt=1;
175
176 CHECK_HANDLE(server_handle);
177
178 krb5_clear_error_message(handle->context);
179
180 if(name == (kadm5_policy_t) NULL)
181 return EINVAL;
182 if(strlen(name) == 0)
183 return KADM5_BAD_POLICY;
184 if((ret = krb5_db_get_policy(handle->context, name, &entry,&cnt)))
185 return ret;
186 if( cnt != 1 )
187 return KADM5_UNK_POLICY;
188
189 if(entry->policy_refcnt != 0) {
190 krb5_db_free_policy(handle->context, entry);
191 return KADM5_POLICY_REF;
192 }
193 krb5_db_free_policy(handle->context, entry);
194 if ((ret = krb5_db_delete_policy(handle->context, name)))
195 return ret;
196 else
197 return KADM5_OK;
198 }
199
200 kadm5_ret_t
kadm5_modify_policy(void * server_handle,kadm5_policy_ent_t entry,long mask)201 kadm5_modify_policy(void *server_handle,
202 kadm5_policy_ent_t entry, long mask)
203 {
204 CHECK_HANDLE(server_handle);
205
206 krb5_clear_error_message(((kadm5_server_handle_t)server_handle)->context);
207
208 if (mask & KADM5_REF_COUNT)
209 return KADM5_BAD_MASK;
210 else
211 return kadm5_modify_policy_internal(server_handle, entry, mask);
212 }
213
214 kadm5_ret_t
kadm5_modify_policy_internal(void * server_handle,kadm5_policy_ent_t entry,long mask)215 kadm5_modify_policy_internal(void *server_handle,
216 kadm5_policy_ent_t entry, long mask)
217 {
218 kadm5_server_handle_t handle = server_handle;
219 osa_policy_ent_t p;
220 int ret;
221 int cnt=1;
222
223 CHECK_HANDLE(server_handle);
224
225 if((entry == (kadm5_policy_ent_t) NULL) || (entry->policy == NULL))
226 return EINVAL;
227 if(strlen(entry->policy) == 0)
228 return KADM5_BAD_POLICY;
229 if((mask & KADM5_POLICY))
230 return KADM5_BAD_MASK;
231
232 if ((ret = krb5_db_get_policy(handle->context, entry->policy, &p, &cnt)))
233 return ret;
234 if (cnt != 1)
235 return KADM5_UNK_POLICY;
236
237 if ((mask & KADM5_PW_MAX_LIFE))
238 p->pw_max_life = entry->pw_max_life;
239 if ((mask & KADM5_PW_MIN_LIFE)) {
240 if(entry->pw_min_life > p->pw_max_life && p->pw_max_life != 0) {
241 krb5_db_free_policy(handle->context, p);
242 return KADM5_BAD_MIN_PASS_LIFE;
243 }
244 p->pw_min_life = entry->pw_min_life;
245 }
246 if ((mask & KADM5_PW_MIN_LENGTH)) {
247 if(entry->pw_min_length < MIN_PW_LENGTH) {
248 krb5_db_free_policy(handle->context, p);
249 return KADM5_BAD_LENGTH;
250 }
251 p->pw_min_length = entry->pw_min_length;
252 }
253 if ((mask & KADM5_PW_MIN_CLASSES)) {
254 if(entry->pw_min_classes > MAX_PW_CLASSES ||
255 entry->pw_min_classes < MIN_PW_CLASSES) {
256 krb5_db_free_policy(handle->context, p);
257 return KADM5_BAD_CLASS;
258 }
259 p->pw_min_classes = entry->pw_min_classes;
260 }
261 if ((mask & KADM5_PW_HISTORY_NUM)) {
262 if(entry->pw_history_num < MIN_PW_HISTORY ||
263 entry->pw_history_num > MAX_PW_HISTORY) {
264 krb5_db_free_policy(handle->context, p);
265 return KADM5_BAD_HISTORY;
266 }
267 p->pw_history_num = entry->pw_history_num;
268 }
269 if ((mask & KADM5_REF_COUNT))
270 p->policy_refcnt = entry->policy_refcnt;
271 ret = krb5_db_put_policy(handle->context, p);
272 krb5_db_free_policy(handle->context, p);
273 return ret;
274 }
275
276 kadm5_ret_t
kadm5_get_policy(void * server_handle,kadm5_policy_t name,kadm5_policy_ent_t entry)277 kadm5_get_policy(void *server_handle, kadm5_policy_t name,
278 kadm5_policy_ent_t entry)
279 {
280 osa_policy_ent_t t;
281 kadm5_policy_ent_rec entry_local, **entry_orig, *new;
282 int ret;
283 kadm5_server_handle_t handle = server_handle;
284 int cnt=1;
285
286 CHECK_HANDLE(server_handle);
287
288 krb5_clear_error_message(handle->context);
289
290 /*
291 * In version 1, entry is a pointer to a kadm5_policy_ent_t that
292 * should be filled with allocated memory.
293 */
294 if (handle->api_version == KADM5_API_VERSION_1) {
295 entry_orig = (kadm5_policy_ent_rec **) entry;
296 *entry_orig = NULL;
297 entry = &entry_local;
298 }
299
300 if (name == (kadm5_policy_t) NULL)
301 return EINVAL;
302 if(strlen(name) == 0)
303 return KADM5_BAD_POLICY;
304 if((ret = krb5_db_get_policy(handle->context, name, &t, &cnt)))
305 return ret;
306
307 if( cnt != 1 )
308 return KADM5_UNK_POLICY;
309
310 if ((entry->policy = (char *) malloc(strlen(t->name) + 1)) == NULL) {
311 krb5_db_free_policy(handle->context, t);
312 return ENOMEM;
313 }
314 strcpy(entry->policy, t->name);
315 entry->pw_min_life = t->pw_min_life;
316 entry->pw_max_life = t->pw_max_life;
317 entry->pw_min_length = t->pw_min_length;
318 entry->pw_min_classes = t->pw_min_classes;
319 entry->pw_history_num = t->pw_history_num;
320 entry->policy_refcnt = t->policy_refcnt;
321 krb5_db_free_policy(handle->context, t);
322
323 if (handle->api_version == KADM5_API_VERSION_1) {
324 new = (kadm5_policy_ent_t) malloc(sizeof(kadm5_policy_ent_rec));
325 if (new == NULL) {
326 free(entry->policy);
327 krb5_db_free_policy(handle->context, t);
328 return ENOMEM;
329 }
330 *new = *entry;
331 *entry_orig = new;
332 }
333
334 return KADM5_OK;
335 }
336