xref: /freebsd/crypto/krb5/src/lib/kadm5/srv/svr_policy.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1*7f2fe78bSCy Schubert /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
4*7f2fe78bSCy Schubert  *
5*7f2fe78bSCy Schubert  * $Header$
6*7f2fe78bSCy Schubert  */
7*7f2fe78bSCy Schubert 
8*7f2fe78bSCy Schubert #include        <sys/types.h>
9*7f2fe78bSCy Schubert #include        <kadm5/admin.h>
10*7f2fe78bSCy Schubert #include        "server_internal.h"
11*7f2fe78bSCy Schubert #include        <stdlib.h>
12*7f2fe78bSCy Schubert #include        <string.h>
13*7f2fe78bSCy Schubert #include        <errno.h>
14*7f2fe78bSCy Schubert 
15*7f2fe78bSCy Schubert #define MIN_PW_HISTORY  1
16*7f2fe78bSCy Schubert #define MIN_PW_CLASSES  1
17*7f2fe78bSCy Schubert #define MAX_PW_CLASSES  5
18*7f2fe78bSCy Schubert #define MIN_PW_LENGTH   1
19*7f2fe78bSCy Schubert 
20*7f2fe78bSCy Schubert /* Validate allowed_keysalts. */
21*7f2fe78bSCy Schubert static kadm5_ret_t
validate_allowed_keysalts(const char * allowed_keysalts)22*7f2fe78bSCy Schubert validate_allowed_keysalts(const char *allowed_keysalts)
23*7f2fe78bSCy Schubert {
24*7f2fe78bSCy Schubert     kadm5_ret_t ret;
25*7f2fe78bSCy Schubert     krb5_key_salt_tuple *ks_tuple = NULL;
26*7f2fe78bSCy Schubert     krb5_int32 n_ks_tuple = 0;
27*7f2fe78bSCy Schubert 
28*7f2fe78bSCy Schubert     if (strchr(allowed_keysalts, '\t') != NULL)
29*7f2fe78bSCy Schubert         return KADM5_BAD_KEYSALTS;
30*7f2fe78bSCy Schubert     ret = krb5_string_to_keysalts(allowed_keysalts, ",", NULL, 0,
31*7f2fe78bSCy Schubert                                   &ks_tuple, &n_ks_tuple);
32*7f2fe78bSCy Schubert     free(ks_tuple);
33*7f2fe78bSCy Schubert     if (ret == EINVAL)
34*7f2fe78bSCy Schubert         return KADM5_BAD_KEYSALTS;
35*7f2fe78bSCy Schubert     return ret;
36*7f2fe78bSCy Schubert }
37*7f2fe78bSCy Schubert 
38*7f2fe78bSCy Schubert /*
39*7f2fe78bSCy Schubert  * Function: kadm5_create_policy
40*7f2fe78bSCy Schubert  *
41*7f2fe78bSCy Schubert  * Purpose: Create Policies in the policy DB.
42*7f2fe78bSCy Schubert  *
43*7f2fe78bSCy Schubert  * Arguments:
44*7f2fe78bSCy Schubert  *      entry   (input) The policy entry to be written out to the DB.
45*7f2fe78bSCy Schubert  *      mask    (input) Specifies which fields in entry are to ge written out
46*7f2fe78bSCy Schubert  *                      and which get default values.
47*7f2fe78bSCy Schubert  *      <return value> 0 if successful otherwise an error code is returned.
48*7f2fe78bSCy Schubert  *
49*7f2fe78bSCy Schubert  * Requires:
50*7f2fe78bSCy Schubert  *      Entry must be a valid principal entry, and mask have a valid value.
51*7f2fe78bSCy Schubert  *
52*7f2fe78bSCy Schubert  * Effects:
53*7f2fe78bSCy Schubert  *      Writes the data to the database, and does a database sync if
54*7f2fe78bSCy Schubert  *      successful.
55*7f2fe78bSCy Schubert  *
56*7f2fe78bSCy Schubert  */
57*7f2fe78bSCy Schubert 
58*7f2fe78bSCy Schubert kadm5_ret_t
kadm5_create_policy(void * server_handle,kadm5_policy_ent_t entry,long mask)59*7f2fe78bSCy Schubert kadm5_create_policy(void *server_handle, kadm5_policy_ent_t entry, long mask)
60*7f2fe78bSCy Schubert {
61*7f2fe78bSCy Schubert     kadm5_server_handle_t handle = server_handle;
62*7f2fe78bSCy Schubert     osa_policy_ent_rec  pent, *check_pol;
63*7f2fe78bSCy Schubert     int                 ret;
64*7f2fe78bSCy Schubert     char                *p;
65*7f2fe78bSCy Schubert 
66*7f2fe78bSCy Schubert     CHECK_HANDLE(server_handle);
67*7f2fe78bSCy Schubert 
68*7f2fe78bSCy Schubert     krb5_clear_error_message(handle->context);
69*7f2fe78bSCy Schubert 
70*7f2fe78bSCy Schubert     if ((entry == (kadm5_policy_ent_t) NULL) || (entry->policy == NULL))
71*7f2fe78bSCy Schubert         return EINVAL;
72*7f2fe78bSCy Schubert     if(strlen(entry->policy) == 0)
73*7f2fe78bSCy Schubert         return KADM5_BAD_POLICY;
74*7f2fe78bSCy Schubert     if (!(mask & KADM5_POLICY) || (mask & ~ALL_POLICY_MASK))
75*7f2fe78bSCy Schubert         return KADM5_BAD_MASK;
76*7f2fe78bSCy Schubert     if ((mask & KADM5_POLICY_ALLOWED_KEYSALTS) &&
77*7f2fe78bSCy Schubert         entry->allowed_keysalts != NULL) {
78*7f2fe78bSCy Schubert         ret = validate_allowed_keysalts(entry->allowed_keysalts);
79*7f2fe78bSCy Schubert         if (ret)
80*7f2fe78bSCy Schubert             return ret;
81*7f2fe78bSCy Schubert     }
82*7f2fe78bSCy Schubert 
83*7f2fe78bSCy Schubert     ret = krb5_db_get_policy(handle->context, entry->policy, &check_pol);
84*7f2fe78bSCy Schubert     if (!ret) {
85*7f2fe78bSCy Schubert         krb5_db_free_policy(handle->context, check_pol);
86*7f2fe78bSCy Schubert         return KADM5_DUP;
87*7f2fe78bSCy Schubert     } else if (ret != KRB5_KDB_NOENTRY) {
88*7f2fe78bSCy Schubert         return ret;
89*7f2fe78bSCy Schubert     }
90*7f2fe78bSCy Schubert 
91*7f2fe78bSCy Schubert     memset(&pent, 0, sizeof(pent));
92*7f2fe78bSCy Schubert     pent.name = entry->policy;
93*7f2fe78bSCy Schubert     p = entry->policy;
94*7f2fe78bSCy Schubert     while(*p != '\0') {
95*7f2fe78bSCy Schubert         if(*p < ' ' || *p > '~')
96*7f2fe78bSCy Schubert             return KADM5_BAD_POLICY;
97*7f2fe78bSCy Schubert         else
98*7f2fe78bSCy Schubert             p++;
99*7f2fe78bSCy Schubert     }
100*7f2fe78bSCy Schubert     if (!(mask & KADM5_PW_MAX_LIFE))
101*7f2fe78bSCy Schubert         pent.pw_max_life = 0;
102*7f2fe78bSCy Schubert     else
103*7f2fe78bSCy Schubert         pent.pw_max_life = entry->pw_max_life;
104*7f2fe78bSCy Schubert     if (!(mask & KADM5_PW_MIN_LIFE))
105*7f2fe78bSCy Schubert         pent.pw_min_life = 0;
106*7f2fe78bSCy Schubert     else {
107*7f2fe78bSCy Schubert         if((mask & KADM5_PW_MAX_LIFE)) {
108*7f2fe78bSCy Schubert             if(entry->pw_min_life > entry->pw_max_life && entry->pw_max_life != 0)
109*7f2fe78bSCy Schubert                 return KADM5_BAD_MIN_PASS_LIFE;
110*7f2fe78bSCy Schubert         }
111*7f2fe78bSCy Schubert         pent.pw_min_life = entry->pw_min_life;
112*7f2fe78bSCy Schubert     }
113*7f2fe78bSCy Schubert     if (!(mask & KADM5_PW_MIN_LENGTH))
114*7f2fe78bSCy Schubert         pent.pw_min_length = MIN_PW_LENGTH;
115*7f2fe78bSCy Schubert     else {
116*7f2fe78bSCy Schubert         if(entry->pw_min_length < MIN_PW_LENGTH)
117*7f2fe78bSCy Schubert             return KADM5_BAD_LENGTH;
118*7f2fe78bSCy Schubert         pent.pw_min_length = entry->pw_min_length;
119*7f2fe78bSCy Schubert     }
120*7f2fe78bSCy Schubert     if (!(mask & KADM5_PW_MIN_CLASSES))
121*7f2fe78bSCy Schubert         pent.pw_min_classes = MIN_PW_CLASSES;
122*7f2fe78bSCy Schubert     else {
123*7f2fe78bSCy Schubert         if(entry->pw_min_classes > MAX_PW_CLASSES || entry->pw_min_classes < MIN_PW_CLASSES)
124*7f2fe78bSCy Schubert             return KADM5_BAD_CLASS;
125*7f2fe78bSCy Schubert         pent.pw_min_classes = entry->pw_min_classes;
126*7f2fe78bSCy Schubert     }
127*7f2fe78bSCy Schubert     if (!(mask & KADM5_PW_HISTORY_NUM))
128*7f2fe78bSCy Schubert         pent.pw_history_num = MIN_PW_HISTORY;
129*7f2fe78bSCy Schubert     else {
130*7f2fe78bSCy Schubert         if(entry->pw_history_num < MIN_PW_HISTORY)
131*7f2fe78bSCy Schubert             return KADM5_BAD_HISTORY;
132*7f2fe78bSCy Schubert         else
133*7f2fe78bSCy Schubert             pent.pw_history_num = entry->pw_history_num;
134*7f2fe78bSCy Schubert     }
135*7f2fe78bSCy Schubert 
136*7f2fe78bSCy Schubert     if (handle->api_version >= KADM5_API_VERSION_4) {
137*7f2fe78bSCy Schubert         if (!(mask & KADM5_POLICY_ATTRIBUTES))
138*7f2fe78bSCy Schubert             pent.attributes = 0;
139*7f2fe78bSCy Schubert         else
140*7f2fe78bSCy Schubert             pent.attributes = entry->attributes;
141*7f2fe78bSCy Schubert         if (!(mask & KADM5_POLICY_MAX_LIFE))
142*7f2fe78bSCy Schubert             pent.max_life = 0;
143*7f2fe78bSCy Schubert         else
144*7f2fe78bSCy Schubert             pent.max_life = entry->max_life;
145*7f2fe78bSCy Schubert         if (!(mask & KADM5_POLICY_MAX_RLIFE))
146*7f2fe78bSCy Schubert             pent.max_renewable_life = 0;
147*7f2fe78bSCy Schubert         else
148*7f2fe78bSCy Schubert             pent.max_renewable_life = entry->max_renewable_life;
149*7f2fe78bSCy Schubert         if (!(mask & KADM5_POLICY_ALLOWED_KEYSALTS))
150*7f2fe78bSCy Schubert             pent.allowed_keysalts = 0;
151*7f2fe78bSCy Schubert         else
152*7f2fe78bSCy Schubert             pent.allowed_keysalts = entry->allowed_keysalts;
153*7f2fe78bSCy Schubert         if (!(mask & KADM5_POLICY_TL_DATA)) {
154*7f2fe78bSCy Schubert             pent.n_tl_data = 0;
155*7f2fe78bSCy Schubert             pent.tl_data = NULL;
156*7f2fe78bSCy Schubert         } else {
157*7f2fe78bSCy Schubert             pent.n_tl_data = entry->n_tl_data;
158*7f2fe78bSCy Schubert             pent.tl_data = entry->tl_data;
159*7f2fe78bSCy Schubert         }
160*7f2fe78bSCy Schubert     }
161*7f2fe78bSCy Schubert     if (handle->api_version >= KADM5_API_VERSION_3) {
162*7f2fe78bSCy Schubert         if (!(mask & KADM5_PW_MAX_FAILURE))
163*7f2fe78bSCy Schubert             pent.pw_max_fail = 0;
164*7f2fe78bSCy Schubert         else
165*7f2fe78bSCy Schubert             pent.pw_max_fail = entry->pw_max_fail;
166*7f2fe78bSCy Schubert         if (!(mask & KADM5_PW_FAILURE_COUNT_INTERVAL))
167*7f2fe78bSCy Schubert             pent.pw_failcnt_interval = 0;
168*7f2fe78bSCy Schubert         else
169*7f2fe78bSCy Schubert             pent.pw_failcnt_interval = entry->pw_failcnt_interval;
170*7f2fe78bSCy Schubert         if (!(mask & KADM5_PW_LOCKOUT_DURATION))
171*7f2fe78bSCy Schubert             pent.pw_lockout_duration = 0;
172*7f2fe78bSCy Schubert         else
173*7f2fe78bSCy Schubert             pent.pw_lockout_duration = entry->pw_lockout_duration;
174*7f2fe78bSCy Schubert     }
175*7f2fe78bSCy Schubert 
176*7f2fe78bSCy Schubert     if ((ret = krb5_db_create_policy(handle->context, &pent)))
177*7f2fe78bSCy Schubert         return ret;
178*7f2fe78bSCy Schubert     else
179*7f2fe78bSCy Schubert         return KADM5_OK;
180*7f2fe78bSCy Schubert }
181*7f2fe78bSCy Schubert 
182*7f2fe78bSCy Schubert kadm5_ret_t
kadm5_delete_policy(void * server_handle,kadm5_policy_t name)183*7f2fe78bSCy Schubert kadm5_delete_policy(void *server_handle, kadm5_policy_t name)
184*7f2fe78bSCy Schubert {
185*7f2fe78bSCy Schubert     kadm5_server_handle_t handle = server_handle;
186*7f2fe78bSCy Schubert     osa_policy_ent_t            entry;
187*7f2fe78bSCy Schubert     int                         ret;
188*7f2fe78bSCy Schubert 
189*7f2fe78bSCy Schubert     CHECK_HANDLE(server_handle);
190*7f2fe78bSCy Schubert 
191*7f2fe78bSCy Schubert     krb5_clear_error_message(handle->context);
192*7f2fe78bSCy Schubert 
193*7f2fe78bSCy Schubert     if(name == (kadm5_policy_t) NULL)
194*7f2fe78bSCy Schubert         return EINVAL;
195*7f2fe78bSCy Schubert     if(strlen(name) == 0)
196*7f2fe78bSCy Schubert         return KADM5_BAD_POLICY;
197*7f2fe78bSCy Schubert     ret = krb5_db_get_policy(handle->context, name, &entry);
198*7f2fe78bSCy Schubert     if (ret == KRB5_KDB_NOENTRY)
199*7f2fe78bSCy Schubert         return KADM5_UNK_POLICY;
200*7f2fe78bSCy Schubert     else if (ret)
201*7f2fe78bSCy Schubert         return ret;
202*7f2fe78bSCy Schubert 
203*7f2fe78bSCy Schubert     krb5_db_free_policy(handle->context, entry);
204*7f2fe78bSCy Schubert     ret = krb5_db_delete_policy(handle->context, name);
205*7f2fe78bSCy Schubert     if (ret == KRB5_KDB_POLICY_REF)
206*7f2fe78bSCy Schubert         ret = KADM5_POLICY_REF;
207*7f2fe78bSCy Schubert     return (ret == 0) ? KADM5_OK : ret;
208*7f2fe78bSCy Schubert }
209*7f2fe78bSCy Schubert 
210*7f2fe78bSCy Schubert /* Allocate and form a TL data list of a desired size. */
211*7f2fe78bSCy Schubert static int
alloc_tl_data(krb5_int16 n_tl_data,krb5_tl_data ** tldp)212*7f2fe78bSCy Schubert alloc_tl_data(krb5_int16 n_tl_data, krb5_tl_data **tldp)
213*7f2fe78bSCy Schubert {
214*7f2fe78bSCy Schubert     krb5_tl_data **tlp = tldp;
215*7f2fe78bSCy Schubert     int i;
216*7f2fe78bSCy Schubert 
217*7f2fe78bSCy Schubert     for (i = 0; i < n_tl_data; i++) {
218*7f2fe78bSCy Schubert         *tlp = calloc(1, sizeof(krb5_tl_data));
219*7f2fe78bSCy Schubert         if (*tlp == NULL)
220*7f2fe78bSCy Schubert             return ENOMEM; /* caller cleans up */
221*7f2fe78bSCy Schubert         memset(*tlp, 0, sizeof(krb5_tl_data));
222*7f2fe78bSCy Schubert         tlp = &((*tlp)->tl_data_next);
223*7f2fe78bSCy Schubert     }
224*7f2fe78bSCy Schubert 
225*7f2fe78bSCy Schubert     return 0;
226*7f2fe78bSCy Schubert }
227*7f2fe78bSCy Schubert 
228*7f2fe78bSCy Schubert static kadm5_ret_t
copy_tl_data(krb5_int16 n_tl_data,krb5_tl_data * tl_data,krb5_tl_data ** out)229*7f2fe78bSCy Schubert copy_tl_data(krb5_int16 n_tl_data, krb5_tl_data *tl_data,
230*7f2fe78bSCy Schubert              krb5_tl_data **out)
231*7f2fe78bSCy Schubert {
232*7f2fe78bSCy Schubert     kadm5_ret_t ret;
233*7f2fe78bSCy Schubert     krb5_tl_data *tl, *tl_new;
234*7f2fe78bSCy Schubert 
235*7f2fe78bSCy Schubert     if ((ret = alloc_tl_data(n_tl_data, out)))
236*7f2fe78bSCy Schubert         return ret; /* caller cleans up */
237*7f2fe78bSCy Schubert 
238*7f2fe78bSCy Schubert     tl = tl_data;
239*7f2fe78bSCy Schubert     tl_new = *out;
240*7f2fe78bSCy Schubert     for (; tl; tl = tl->tl_data_next, tl_new = tl_new->tl_data_next) {
241*7f2fe78bSCy Schubert         tl_new->tl_data_contents = malloc(tl->tl_data_length);
242*7f2fe78bSCy Schubert         if (tl_new->tl_data_contents == NULL)
243*7f2fe78bSCy Schubert             return ENOMEM;
244*7f2fe78bSCy Schubert         memcpy(tl_new->tl_data_contents, tl->tl_data_contents,
245*7f2fe78bSCy Schubert                tl->tl_data_length);
246*7f2fe78bSCy Schubert         tl_new->tl_data_type = tl->tl_data_type;
247*7f2fe78bSCy Schubert         tl_new->tl_data_length = tl->tl_data_length;
248*7f2fe78bSCy Schubert     }
249*7f2fe78bSCy Schubert 
250*7f2fe78bSCy Schubert     return 0;
251*7f2fe78bSCy Schubert }
252*7f2fe78bSCy Schubert 
253*7f2fe78bSCy Schubert kadm5_ret_t
kadm5_modify_policy(void * server_handle,kadm5_policy_ent_t entry,long mask)254*7f2fe78bSCy Schubert kadm5_modify_policy(void *server_handle, kadm5_policy_ent_t entry, long mask)
255*7f2fe78bSCy Schubert {
256*7f2fe78bSCy Schubert     kadm5_server_handle_t    handle = server_handle;
257*7f2fe78bSCy Schubert     krb5_tl_data            *tl;
258*7f2fe78bSCy Schubert     osa_policy_ent_t         p;
259*7f2fe78bSCy Schubert     int                      ret;
260*7f2fe78bSCy Schubert 
261*7f2fe78bSCy Schubert     CHECK_HANDLE(server_handle);
262*7f2fe78bSCy Schubert 
263*7f2fe78bSCy Schubert     krb5_clear_error_message(handle->context);
264*7f2fe78bSCy Schubert 
265*7f2fe78bSCy Schubert     if((entry == (kadm5_policy_ent_t) NULL) || (entry->policy == NULL))
266*7f2fe78bSCy Schubert         return EINVAL;
267*7f2fe78bSCy Schubert     if(strlen(entry->policy) == 0)
268*7f2fe78bSCy Schubert         return KADM5_BAD_POLICY;
269*7f2fe78bSCy Schubert     if ((mask & KADM5_POLICY) || (mask & ~ALL_POLICY_MASK))
270*7f2fe78bSCy Schubert         return KADM5_BAD_MASK;
271*7f2fe78bSCy Schubert     if ((mask & KADM5_POLICY_ALLOWED_KEYSALTS) &&
272*7f2fe78bSCy Schubert         entry->allowed_keysalts != NULL) {
273*7f2fe78bSCy Schubert         ret = validate_allowed_keysalts(entry->allowed_keysalts);
274*7f2fe78bSCy Schubert         if (ret)
275*7f2fe78bSCy Schubert             return ret;
276*7f2fe78bSCy Schubert     }
277*7f2fe78bSCy Schubert     if ((mask & KADM5_POLICY_TL_DATA)) {
278*7f2fe78bSCy Schubert         tl = entry->tl_data;
279*7f2fe78bSCy Schubert         while (tl != NULL) {
280*7f2fe78bSCy Schubert             if (tl->tl_data_type < 256)
281*7f2fe78bSCy Schubert                 return KADM5_BAD_TL_TYPE;
282*7f2fe78bSCy Schubert             tl = tl->tl_data_next;
283*7f2fe78bSCy Schubert         }
284*7f2fe78bSCy Schubert     }
285*7f2fe78bSCy Schubert 
286*7f2fe78bSCy Schubert     ret = krb5_db_get_policy(handle->context, entry->policy, &p);
287*7f2fe78bSCy Schubert     if (ret == KRB5_KDB_NOENTRY)
288*7f2fe78bSCy Schubert         return KADM5_UNK_POLICY;
289*7f2fe78bSCy Schubert     else if (ret)
290*7f2fe78bSCy Schubert         return ret;
291*7f2fe78bSCy Schubert 
292*7f2fe78bSCy Schubert     if ((mask & KADM5_PW_MAX_LIFE))
293*7f2fe78bSCy Schubert         p->pw_max_life = entry->pw_max_life;
294*7f2fe78bSCy Schubert     if ((mask & KADM5_PW_MIN_LIFE)) {
295*7f2fe78bSCy Schubert         if(entry->pw_min_life > p->pw_max_life && p->pw_max_life != 0)  {
296*7f2fe78bSCy Schubert             krb5_db_free_policy(handle->context, p);
297*7f2fe78bSCy Schubert             return KADM5_BAD_MIN_PASS_LIFE;
298*7f2fe78bSCy Schubert         }
299*7f2fe78bSCy Schubert         p->pw_min_life = entry->pw_min_life;
300*7f2fe78bSCy Schubert     }
301*7f2fe78bSCy Schubert     if ((mask & KADM5_PW_MIN_LENGTH)) {
302*7f2fe78bSCy Schubert         if(entry->pw_min_length < MIN_PW_LENGTH) {
303*7f2fe78bSCy Schubert             krb5_db_free_policy(handle->context, p);
304*7f2fe78bSCy Schubert             return KADM5_BAD_LENGTH;
305*7f2fe78bSCy Schubert         }
306*7f2fe78bSCy Schubert         p->pw_min_length = entry->pw_min_length;
307*7f2fe78bSCy Schubert     }
308*7f2fe78bSCy Schubert     if ((mask & KADM5_PW_MIN_CLASSES)) {
309*7f2fe78bSCy Schubert         if(entry->pw_min_classes > MAX_PW_CLASSES ||
310*7f2fe78bSCy Schubert            entry->pw_min_classes < MIN_PW_CLASSES) {
311*7f2fe78bSCy Schubert             krb5_db_free_policy(handle->context, p);
312*7f2fe78bSCy Schubert             return KADM5_BAD_CLASS;
313*7f2fe78bSCy Schubert         }
314*7f2fe78bSCy Schubert         p->pw_min_classes = entry->pw_min_classes;
315*7f2fe78bSCy Schubert     }
316*7f2fe78bSCy Schubert     if ((mask & KADM5_PW_HISTORY_NUM)) {
317*7f2fe78bSCy Schubert         if(entry->pw_history_num < MIN_PW_HISTORY) {
318*7f2fe78bSCy Schubert             krb5_db_free_policy(handle->context, p);
319*7f2fe78bSCy Schubert             return KADM5_BAD_HISTORY;
320*7f2fe78bSCy Schubert         }
321*7f2fe78bSCy Schubert         p->pw_history_num = entry->pw_history_num;
322*7f2fe78bSCy Schubert     }
323*7f2fe78bSCy Schubert     if (handle->api_version >= KADM5_API_VERSION_3) {
324*7f2fe78bSCy Schubert         if ((mask & KADM5_PW_MAX_FAILURE))
325*7f2fe78bSCy Schubert             p->pw_max_fail = entry->pw_max_fail;
326*7f2fe78bSCy Schubert         if ((mask & KADM5_PW_FAILURE_COUNT_INTERVAL))
327*7f2fe78bSCy Schubert             p->pw_failcnt_interval = entry->pw_failcnt_interval;
328*7f2fe78bSCy Schubert         if ((mask & KADM5_PW_LOCKOUT_DURATION))
329*7f2fe78bSCy Schubert             p->pw_lockout_duration = entry->pw_lockout_duration;
330*7f2fe78bSCy Schubert     }
331*7f2fe78bSCy Schubert     if (handle->api_version >= KADM5_API_VERSION_4) {
332*7f2fe78bSCy Schubert         if ((mask & KADM5_POLICY_ATTRIBUTES))
333*7f2fe78bSCy Schubert             p->attributes = entry->attributes;
334*7f2fe78bSCy Schubert         if ((mask & KADM5_POLICY_MAX_LIFE))
335*7f2fe78bSCy Schubert             p->max_life = entry->max_life;
336*7f2fe78bSCy Schubert         if ((mask & KADM5_POLICY_MAX_RLIFE))
337*7f2fe78bSCy Schubert             p->max_renewable_life = entry->max_renewable_life;
338*7f2fe78bSCy Schubert         if ((mask & KADM5_POLICY_ALLOWED_KEYSALTS)) {
339*7f2fe78bSCy Schubert             free(p->allowed_keysalts);
340*7f2fe78bSCy Schubert             p->allowed_keysalts = NULL;
341*7f2fe78bSCy Schubert             if (entry->allowed_keysalts != NULL) {
342*7f2fe78bSCy Schubert                 p->allowed_keysalts = strdup(entry->allowed_keysalts);
343*7f2fe78bSCy Schubert                 if (p->allowed_keysalts == NULL) {
344*7f2fe78bSCy Schubert                     ret = ENOMEM;
345*7f2fe78bSCy Schubert                     goto cleanup;
346*7f2fe78bSCy Schubert                 }
347*7f2fe78bSCy Schubert             }
348*7f2fe78bSCy Schubert         }
349*7f2fe78bSCy Schubert         if ((mask & KADM5_POLICY_TL_DATA)) {
350*7f2fe78bSCy Schubert             for (tl = entry->tl_data; tl != NULL; tl = tl->tl_data_next) {
351*7f2fe78bSCy Schubert                 ret = krb5_db_update_tl_data(handle->context, &p->n_tl_data,
352*7f2fe78bSCy Schubert                                              &p->tl_data, tl);
353*7f2fe78bSCy Schubert                 if (ret)
354*7f2fe78bSCy Schubert                     goto cleanup;
355*7f2fe78bSCy Schubert             }
356*7f2fe78bSCy Schubert         }
357*7f2fe78bSCy Schubert     }
358*7f2fe78bSCy Schubert     ret = krb5_db_put_policy(handle->context, p);
359*7f2fe78bSCy Schubert 
360*7f2fe78bSCy Schubert cleanup:
361*7f2fe78bSCy Schubert     krb5_db_free_policy(handle->context, p);
362*7f2fe78bSCy Schubert     return ret;
363*7f2fe78bSCy Schubert }
364*7f2fe78bSCy Schubert 
365*7f2fe78bSCy Schubert kadm5_ret_t
kadm5_get_policy(void * server_handle,kadm5_policy_t name,kadm5_policy_ent_t entry)366*7f2fe78bSCy Schubert kadm5_get_policy(void *server_handle, kadm5_policy_t name,
367*7f2fe78bSCy Schubert                  kadm5_policy_ent_t entry)
368*7f2fe78bSCy Schubert {
369*7f2fe78bSCy Schubert     osa_policy_ent_t            t;
370*7f2fe78bSCy Schubert     kadm5_ret_t                 ret;
371*7f2fe78bSCy Schubert     kadm5_server_handle_t handle = server_handle;
372*7f2fe78bSCy Schubert 
373*7f2fe78bSCy Schubert     memset(entry, 0, sizeof(*entry));
374*7f2fe78bSCy Schubert 
375*7f2fe78bSCy Schubert     CHECK_HANDLE(server_handle);
376*7f2fe78bSCy Schubert 
377*7f2fe78bSCy Schubert     krb5_clear_error_message(handle->context);
378*7f2fe78bSCy Schubert 
379*7f2fe78bSCy Schubert     if (name == (kadm5_policy_t) NULL)
380*7f2fe78bSCy Schubert         return EINVAL;
381*7f2fe78bSCy Schubert     if(strlen(name) == 0)
382*7f2fe78bSCy Schubert         return KADM5_BAD_POLICY;
383*7f2fe78bSCy Schubert     ret = krb5_db_get_policy(handle->context, name, &t);
384*7f2fe78bSCy Schubert     if (ret == KRB5_KDB_NOENTRY)
385*7f2fe78bSCy Schubert         return KADM5_UNK_POLICY;
386*7f2fe78bSCy Schubert     else if (ret)
387*7f2fe78bSCy Schubert         return ret;
388*7f2fe78bSCy Schubert 
389*7f2fe78bSCy Schubert     if ((entry->policy = strdup(t->name)) == NULL) {
390*7f2fe78bSCy Schubert         ret = ENOMEM;
391*7f2fe78bSCy Schubert         goto cleanup;
392*7f2fe78bSCy Schubert     }
393*7f2fe78bSCy Schubert     entry->pw_min_life = t->pw_min_life;
394*7f2fe78bSCy Schubert     entry->pw_max_life = t->pw_max_life;
395*7f2fe78bSCy Schubert     entry->pw_min_length = t->pw_min_length;
396*7f2fe78bSCy Schubert     entry->pw_min_classes = t->pw_min_classes;
397*7f2fe78bSCy Schubert     entry->pw_history_num = t->pw_history_num;
398*7f2fe78bSCy Schubert     if (handle->api_version >= KADM5_API_VERSION_3) {
399*7f2fe78bSCy Schubert         entry->pw_max_fail = t->pw_max_fail;
400*7f2fe78bSCy Schubert         entry->pw_failcnt_interval = t->pw_failcnt_interval;
401*7f2fe78bSCy Schubert         entry->pw_lockout_duration = t->pw_lockout_duration;
402*7f2fe78bSCy Schubert     }
403*7f2fe78bSCy Schubert     if (handle->api_version >= KADM5_API_VERSION_4) {
404*7f2fe78bSCy Schubert         entry->attributes = t->attributes;
405*7f2fe78bSCy Schubert         entry->max_life = t->max_life;
406*7f2fe78bSCy Schubert         entry->max_renewable_life = t->max_renewable_life;
407*7f2fe78bSCy Schubert         if (t->allowed_keysalts) {
408*7f2fe78bSCy Schubert             entry->allowed_keysalts = strdup(t->allowed_keysalts);
409*7f2fe78bSCy Schubert             if (!entry->allowed_keysalts) {
410*7f2fe78bSCy Schubert                 ret = ENOMEM;
411*7f2fe78bSCy Schubert                 goto cleanup;
412*7f2fe78bSCy Schubert             }
413*7f2fe78bSCy Schubert         }
414*7f2fe78bSCy Schubert         ret = copy_tl_data(t->n_tl_data, t->tl_data, &entry->tl_data);
415*7f2fe78bSCy Schubert         if (ret)
416*7f2fe78bSCy Schubert             goto cleanup;
417*7f2fe78bSCy Schubert         entry->n_tl_data = t->n_tl_data;
418*7f2fe78bSCy Schubert     }
419*7f2fe78bSCy Schubert 
420*7f2fe78bSCy Schubert     ret = 0;
421*7f2fe78bSCy Schubert 
422*7f2fe78bSCy Schubert cleanup:
423*7f2fe78bSCy Schubert     if (ret)
424*7f2fe78bSCy Schubert         kadm5_free_policy_ent(handle, entry);
425*7f2fe78bSCy Schubert     krb5_db_free_policy(handle->context, t);
426*7f2fe78bSCy Schubert     return ret;
427*7f2fe78bSCy Schubert }
428