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