xref: /illumos-gate/usr/src/lib/krb5/kadm5/srv/svr_policy.c (revision 56a424cca6b3f91f31bdab72a4626c48c779fe8b)
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	"adb.h"
34 #include	"server_internal.h"
35 #include	<stdlib.h>
36 
37 #define MAX_PW_HISTORY	10
38 #define MIN_PW_HISTORY	1
39 #define	MIN_PW_CLASSES	1
40 #define MAX_PW_CLASSES	5
41 #define	MIN_PW_LENGTH	1
42 
43 /*
44  * Function: kadm5_create_policy
45  *
46  * Purpose: Create Policies in the policy DB.
47  *
48  * Arguments:
49  *	entry	(input) The policy entry to be written out to the DB.
50  *	mask	(input)	Specifies which fields in entry are to ge written out
51  *			and which get default values.
52  *	<return value> 0 if successful otherwise an error code is returned.
53  *
54  * Requires:
55  *	Entry must be a valid principal entry, and mask have a valid value.
56  *
57  * Effects:
58  *	Verifies that mask does not specify that the refcount should
59  *	be set as part of the creation, and calls
60  *	kadm5_create_policy_internal.  If the refcount *is*
61  *	specified, returns KADM5_BAD_MASK.
62  */
63 
64 kadm5_ret_t
65 kadm5_create_policy(void *server_handle,
66 			 kadm5_policy_ent_t entry, long mask)
67 {
68     CHECK_HANDLE(server_handle);
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 = osa_adb_create_policy(handle->policy_db, &pent)) == OSA_ADB_OK)
163 	return KADM5_OK;
164     else
165 	return ret;
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 
175     CHECK_HANDLE(server_handle);
176 
177     if(name == (kadm5_policy_t) NULL)
178 	return EINVAL;
179     if(strlen(name) == 0)
180 	return KADM5_BAD_POLICY;
181     if ((ret = osa_adb_get_policy(handle->policy_db, name, &entry)) != OSA_ADB_OK)
182 	return ret;
183     if(entry->policy_refcnt != 0) {
184 	osa_free_policy_ent(entry);
185 	return KADM5_POLICY_REF;
186     }
187     osa_free_policy_ent(entry);
188     if ((ret = osa_adb_destroy_policy(handle->policy_db, name)) == OSA_ADB_OK)
189 	return KADM5_OK;
190     else
191 	return ret;
192 }
193 
194 kadm5_ret_t
195 kadm5_modify_policy(void *server_handle,
196 			 kadm5_policy_ent_t entry, long mask)
197 {
198     CHECK_HANDLE(server_handle);
199 
200     if (mask & KADM5_REF_COUNT)
201 	return KADM5_BAD_MASK;
202     else
203 	return kadm5_modify_policy_internal(server_handle, entry, mask);
204 }
205 
206 kadm5_ret_t
207 kadm5_modify_policy_internal(void *server_handle,
208 				  kadm5_policy_ent_t entry, long mask)
209 {
210     kadm5_server_handle_t handle = server_handle;
211     osa_policy_ent_t	p;
212     int			ret;
213 
214     CHECK_HANDLE(server_handle);
215 
216     if((entry == (kadm5_policy_ent_t) NULL) || (entry->policy == NULL))
217 	return EINVAL;
218     if(strlen(entry->policy) == 0)
219 	return KADM5_BAD_POLICY;
220     if((mask & KADM5_POLICY))
221 	return KADM5_BAD_MASK;
222 
223     switch ((ret = osa_adb_get_policy(handle->policy_db, entry->policy, &p))) {
224     case OSA_ADB_OK:
225 	break;
226     case OSA_ADB_NOENT:
227 	return KADM5_UNK_POLICY;
228     default:
229 	break;
230     }
231     if ((mask & KADM5_PW_MAX_LIFE))
232 	p->pw_max_life = entry->pw_max_life;
233     if ((mask & KADM5_PW_MIN_LIFE)) {
234 	if(entry->pw_min_life > p->pw_max_life && p->pw_max_life != 0)	{
235 	     osa_free_policy_ent(p);
236 	     return KADM5_BAD_MIN_PASS_LIFE;
237 	}
238 	p->pw_min_life = entry->pw_min_life;
239     }
240     if ((mask & KADM5_PW_MIN_LENGTH)) {
241 	if(entry->pw_min_length < MIN_PW_LENGTH) {
242 	      osa_free_policy_ent(p);
243 	      return KADM5_BAD_LENGTH;
244 	 }
245 	p->pw_min_length = entry->pw_min_length;
246     }
247     if ((mask & KADM5_PW_MIN_CLASSES)) {
248 	if(entry->pw_min_classes > MAX_PW_CLASSES ||
249 	   entry->pw_min_classes < MIN_PW_CLASSES) {
250 	     osa_free_policy_ent(p);
251 	     return KADM5_BAD_CLASS;
252 	}
253 	p->pw_min_classes = entry->pw_min_classes;
254     }
255     if ((mask & KADM5_PW_HISTORY_NUM)) {
256 	if(entry->pw_history_num < MIN_PW_HISTORY ||
257 	   entry->pw_history_num > MAX_PW_HISTORY) {
258 	     osa_free_policy_ent(p);
259 	     return KADM5_BAD_HISTORY;
260 	}
261 	p->pw_history_num = entry->pw_history_num;
262     }
263     if ((mask & KADM5_REF_COUNT))
264 	p->policy_refcnt = entry->policy_refcnt;
265     switch ((ret = osa_adb_put_policy(handle->policy_db, p))) {
266     case OSA_ADB_OK:
267 	ret = KADM5_OK;
268 	break;
269     case OSA_ADB_NOENT:	/* this should not happen here ... */
270 	ret = KADM5_UNK_POLICY;
271 	break;
272     }
273     osa_free_policy_ent(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 
286     CHECK_HANDLE(server_handle);
287 
288     /*
289      * In version 1, entry is a pointer to a kadm5_policy_ent_t that
290      * should be filled with allocated memory.
291      */
292     if (handle->api_version == KADM5_API_VERSION_1) {
293 	 entry_orig = (kadm5_policy_ent_rec **) entry;
294 	 *entry_orig = NULL;
295 	 entry = &entry_local;
296     }
297 
298     if (name == (kadm5_policy_t) NULL)
299 	return EINVAL;
300     if(strlen(name) == 0)
301 	return KADM5_BAD_POLICY;
302     switch((ret = osa_adb_get_policy(handle->policy_db, name, &t))) {
303     case OSA_ADB_OK:
304 	break;
305     case OSA_ADB_NOENT:
306 	return KADM5_UNK_POLICY;
307     default:
308 	return ret;
309     }
310     if ((entry->policy = (char *) malloc(strlen(t->name) + 1)) == NULL) {
311 	 osa_free_policy_ent(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     osa_free_policy_ent(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 	      osa_free_policy_ent(t);
328 	      return ENOMEM;
329 	 }
330 	 *new = *entry;
331 	 *entry_orig = new;
332     }
333 
334     return KADM5_OK;
335 }
336