lorikeet-heimdal: add wrap_ex_ntlm.diff from abartlet
[metze/heimdal/wip.git] / kadmin / mod.c
1 /*
2  * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include "kadmin_locl.h"
35 #include "kadmin-commands.h"
36
37 RCSID("$Id$");
38
39 static void
40 add_tl(kadm5_principal_ent_rec *princ, int type, krb5_data *data)
41 {
42     krb5_tl_data *tl, **ptl;
43
44     tl = ecalloc(1, sizeof(*tl));
45     tl->tl_data_next = NULL;
46     tl->tl_data_type = KRB5_TL_EXTENSION;
47     tl->tl_data_length = data->length;
48     tl->tl_data_contents = data->data;
49
50     princ->n_tl_data++;
51     ptl = &princ->tl_data;
52     while (*ptl != NULL)
53         ptl = &(*ptl)->tl_data_next;
54     *ptl = tl;
55
56     return;
57 }
58
59 static void
60 add_constrained_delegation(krb5_context context,
61                            kadm5_principal_ent_rec *princ,
62                            struct getarg_strings *strings)
63 {
64     krb5_error_code ret;
65     HDB_extension ext;
66     krb5_data buf;
67     size_t size;
68         
69     memset(&ext, 0, sizeof(ext));
70     ext.mandatory = FALSE;
71     ext.data.element = choice_HDB_extension_data_allowed_to_delegate_to;
72
73     if (strings->num_strings == 1 && strings->strings[0][0] == '\0') {
74         ext.data.u.allowed_to_delegate_to.val = NULL;
75         ext.data.u.allowed_to_delegate_to.len = 0;
76     } else {
77         krb5_principal p;
78         int i;
79
80         ext.data.u.allowed_to_delegate_to.val =
81             calloc(strings->num_strings,
82                    sizeof(ext.data.u.allowed_to_delegate_to.val[0]));
83         ext.data.u.allowed_to_delegate_to.len = strings->num_strings;
84         
85         for (i = 0; i < strings->num_strings; i++) {
86             ret = krb5_parse_name(context, strings->strings[i], &p);
87             if (ret)
88                 abort();
89             ret = copy_Principal(p, &ext.data.u.allowed_to_delegate_to.val[i]);
90             if (ret)
91                 abort();
92             krb5_free_principal(context, p);
93         }
94     }
95
96     ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length,
97                        &ext, &size, ret);
98     free_HDB_extension(&ext);
99     if (ret)
100         abort();
101     if (buf.length != size)
102         abort();
103
104     add_tl(princ, KRB5_TL_EXTENSION, &buf);
105 }
106
107 static void
108 add_aliases(krb5_context context, kadm5_principal_ent_rec *princ,
109             struct getarg_strings *strings)
110 {
111     krb5_error_code ret;
112     HDB_extension ext;
113     krb5_data buf;
114     krb5_principal p;
115     size_t size;
116     int i;
117
118     memset(&ext, 0, sizeof(ext));
119     ext.mandatory = FALSE;
120     ext.data.element = choice_HDB_extension_data_aliases;
121     ext.data.u.aliases.case_insensitive = 0;
122
123     if (strings->num_strings == 1 && strings->strings[0][0] == '\0') {
124         ext.data.u.aliases.aliases.val = NULL;
125         ext.data.u.aliases.aliases.len = 0;
126     } else {
127         ext.data.u.aliases.aliases.val =
128             calloc(strings->num_strings,
129                    sizeof(ext.data.u.aliases.aliases.val[0]));
130         ext.data.u.aliases.aliases.len = strings->num_strings;
131         
132         for (i = 0; i < strings->num_strings; i++) {
133             ret = krb5_parse_name(context, strings->strings[i], &p);
134             ret = copy_Principal(p, &ext.data.u.aliases.aliases.val[i]);
135             krb5_free_principal(context, p);
136         }
137     }
138
139     ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length,
140                        &ext, &size, ret);
141     free_HDB_extension(&ext);
142     if (ret)
143         abort();
144     if (buf.length != size)
145         abort();
146
147     add_tl(princ, KRB5_TL_EXTENSION, &buf);
148 }
149
150 static void
151 add_pkinit_acl(krb5_context context, kadm5_principal_ent_rec *princ,
152                struct getarg_strings *strings)
153 {
154     krb5_error_code ret;
155     HDB_extension ext;
156     krb5_data buf;
157     size_t size;
158     int i;
159
160     memset(&ext, 0, sizeof(ext));
161     ext.mandatory = FALSE;
162     ext.data.element = choice_HDB_extension_data_pkinit_acl;
163     ext.data.u.aliases.case_insensitive = 0;
164
165     if (strings->num_strings == 1 && strings->strings[0][0] == '\0') {
166         ext.data.u.pkinit_acl.val = NULL;
167         ext.data.u.pkinit_acl.len = 0;
168     } else {
169         ext.data.u.pkinit_acl.val =
170             calloc(strings->num_strings,
171                    sizeof(ext.data.u.pkinit_acl.val[0]));
172         ext.data.u.pkinit_acl.len = strings->num_strings;
173         
174         for (i = 0; i < strings->num_strings; i++) {
175             ext.data.u.pkinit_acl.val[i].subject = estrdup(strings->strings[i]);
176         }
177     }
178
179     ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length,
180                        &ext, &size, ret);
181     free_HDB_extension(&ext);
182     if (ret)
183         abort();
184     if (buf.length != size)
185         abort();
186
187     add_tl(princ, KRB5_TL_EXTENSION, &buf);
188 }
189
190 static int
191 do_mod_entry(krb5_principal principal, void *data)
192 {
193     krb5_error_code ret;
194     kadm5_principal_ent_rec princ;
195     int mask = 0;
196     struct modify_options *e = data;
197
198     memset (&princ, 0, sizeof(princ));
199     ret = kadm5_get_principal(kadm_handle, principal, &princ,
200                               KADM5_PRINCIPAL | KADM5_ATTRIBUTES |
201                               KADM5_MAX_LIFE | KADM5_MAX_RLIFE |
202                               KADM5_PRINC_EXPIRE_TIME |
203                               KADM5_PW_EXPIRATION);
204     if(ret)
205         return ret;
206
207     if(e->max_ticket_life_string ||
208        e->max_renewable_life_string ||
209        e->expiration_time_string ||
210        e->pw_expiration_time_string ||
211        e->attributes_string ||
212        e->kvno_integer != -1 ||
213        e->constrained_delegation_strings.num_strings ||
214        e->alias_strings.num_strings ||
215        e->pkinit_acl_strings.num_strings) {
216         ret = set_entry(context, &princ, &mask,
217                         e->max_ticket_life_string,
218                         e->max_renewable_life_string,
219                         e->expiration_time_string,
220                         e->pw_expiration_time_string,
221                         e->attributes_string);
222         if(e->kvno_integer != -1) {
223             princ.kvno = e->kvno_integer;
224             mask |= KADM5_KVNO;
225         }
226         if (e->constrained_delegation_strings.num_strings) {
227             add_constrained_delegation(context, &princ,
228                                        &e->constrained_delegation_strings);
229             mask |= KADM5_TL_DATA;
230         }
231         if (e->alias_strings.num_strings) {
232             add_aliases(context, &princ, &e->alias_strings);
233             mask |= KADM5_TL_DATA;
234         }
235         if (e->pkinit_acl_strings.num_strings) {
236             add_pkinit_acl(context, &princ, &e->pkinit_acl_strings);
237             mask |= KADM5_TL_DATA;
238         }
239
240     } else
241         ret = edit_entry(&princ, &mask, NULL, 0);
242     if(ret == 0) {
243         ret = kadm5_modify_principal(kadm_handle, &princ, mask);
244         if(ret)
245             krb5_warn(context, ret, "kadm5_modify_principal");
246     }
247
248     kadm5_free_principal_ent(kadm_handle, &princ);
249     return ret;
250 }
251
252 int
253 mod_entry(struct modify_options *opt, int argc, char **argv)
254 {
255     krb5_error_code ret = 0;
256     int i;
257
258     for(i = 0; i < argc; i++) {
259         ret = foreach_principal(argv[i], do_mod_entry, "mod", opt);
260         if (ret)
261             break;
262     }
263     return ret != 0;
264 }
265