xref: /illumos-gate/usr/src/lib/krb5/kadm5/srv/svr_policy.c (revision e00bdde3c6d406f40f53f3025defadc22f7ec31a)
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
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
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
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
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
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
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