Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/util/profile/prof_set.c
34878 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/*
3
* prof_set.c --- routines that expose the public interfaces for
4
* inserting, updating and deleting items from the profile.
5
*
6
* WARNING: These routines only look at the first file opened in the
7
* profile. It's not clear how to handle multiple files, actually.
8
* In the future it may be necessary to modify this public interface,
9
* or possibly add higher level functions to support this correctly.
10
*
11
* WARNING: We're not yet doing locking yet, either.
12
*
13
*/
14
15
#include "prof_int.h"
16
17
#include <stdio.h>
18
#include <string.h>
19
#ifdef HAVE_STDLIB_H
20
#include <stdlib.h>
21
#endif
22
#include <errno.h>
23
24
static errcode_t rw_setup(profile_t profile)
25
{
26
prf_file_t file;
27
prf_data_t new_data;
28
29
if (!profile)
30
return PROF_NO_PROFILE;
31
32
if (profile->magic != PROF_MAGIC_PROFILE)
33
return PROF_MAGIC_PROFILE;
34
35
/* If the profile has no files, create a memory-only data object. */
36
if (profile->first_file == NULL) {
37
profile->first_file = profile_open_memory();
38
return (profile->first_file == NULL) ? ENOMEM : 0;
39
}
40
41
file = profile->first_file;
42
43
profile_lock_global();
44
45
/* Don't update the file if we've already made modifications */
46
if (file->data->flags & PROFILE_FILE_DIRTY) {
47
profile_unlock_global();
48
return 0;
49
}
50
51
if ((file->data->flags & PROFILE_FILE_SHARED) != 0) {
52
new_data = profile_make_prf_data(file->data->filespec);
53
if (new_data == NULL) {
54
profile_unlock_global();
55
return ENOMEM;
56
}
57
new_data->root = NULL;
58
new_data->flags = file->data->flags & ~PROFILE_FILE_SHARED;
59
new_data->timestamp = 0;
60
new_data->upd_serial = file->data->upd_serial;
61
62
profile_dereference_data_locked(file->data);
63
file->data = new_data;
64
}
65
66
profile_unlock_global();
67
return profile_update_file(file, NULL);
68
}
69
70
71
/*
72
* Delete or update a particular child node
73
*
74
* ADL - 2/23/99, rewritten TYT 2/25/99
75
*/
76
errcode_t KRB5_CALLCONV
77
profile_update_relation(profile_t profile, const char **names,
78
const char *old_value, const char *new_value)
79
{
80
errcode_t retval;
81
struct profile_node *section, *node;
82
void *state;
83
const char **cpp;
84
85
if (profile->vt) {
86
if (!profile->vt->update_relation)
87
return PROF_UNSUPPORTED;
88
return profile->vt->update_relation(profile->cbdata, names, old_value,
89
new_value);
90
}
91
92
retval = rw_setup(profile);
93
if (retval)
94
return retval;
95
96
if (names == 0 || names[0] == 0 || names[1] == 0)
97
return PROF_BAD_NAMESET;
98
99
if (!old_value || !*old_value)
100
return PROF_EINVAL;
101
102
k5_mutex_lock(&profile->first_file->data->lock);
103
section = profile->first_file->data->root;
104
for (cpp = names; cpp[1]; cpp++) {
105
state = 0;
106
retval = profile_find_node(section, *cpp, 0, 1,
107
&state, &section);
108
if (retval) {
109
k5_mutex_unlock(&profile->first_file->data->lock);
110
return retval;
111
}
112
}
113
114
state = 0;
115
retval = profile_find_node(section, *cpp, old_value, 0, &state, &node);
116
if (retval == 0) {
117
if (new_value)
118
retval = profile_set_relation_value(node, new_value);
119
else
120
retval = profile_remove_node(node);
121
}
122
if (retval == 0)
123
profile->first_file->data->flags |= PROFILE_FILE_DIRTY;
124
k5_mutex_unlock(&profile->first_file->data->lock);
125
126
return retval;
127
}
128
129
/*
130
* Clear a particular all of the relations with a specific name.
131
*
132
* TYT - 2/25/99
133
*/
134
errcode_t KRB5_CALLCONV
135
profile_clear_relation(profile_t profile, const char **names)
136
{
137
errcode_t retval;
138
struct profile_node *section, *node;
139
void *state;
140
const char **cpp;
141
142
if (profile->vt) {
143
if (!profile->vt->update_relation)
144
return PROF_UNSUPPORTED;
145
return profile->vt->update_relation(profile->cbdata, names, NULL,
146
NULL);
147
}
148
149
retval = rw_setup(profile);
150
if (retval)
151
return retval;
152
153
if (names == 0 || names[0] == 0 || names[1] == 0)
154
return PROF_BAD_NAMESET;
155
156
section = profile->first_file->data->root;
157
for (cpp = names; cpp[1]; cpp++) {
158
state = 0;
159
retval = profile_find_node(section, *cpp, 0, 1,
160
&state, &section);
161
if (retval)
162
return retval;
163
}
164
165
state = 0;
166
do {
167
retval = profile_find_node(section, *cpp, 0, 0, &state, &node);
168
if (retval)
169
return retval;
170
retval = profile_remove_node(node);
171
if (retval)
172
return retval;
173
} while (state);
174
175
profile->first_file->data->flags |= PROFILE_FILE_DIRTY;
176
177
return 0;
178
}
179
180
/*
181
* Rename a particular section; if the new_section name is NULL,
182
* delete it.
183
*
184
* ADL - 2/23/99, rewritten TYT 2/25/99
185
*/
186
errcode_t KRB5_CALLCONV
187
profile_rename_section(profile_t profile, const char **names,
188
const char *new_name)
189
{
190
errcode_t retval;
191
struct profile_node *section, *node;
192
void *state;
193
const char **cpp;
194
195
if (profile->vt) {
196
if (!profile->vt->rename_section)
197
return PROF_UNSUPPORTED;
198
return profile->vt->rename_section(profile->cbdata, names, new_name);
199
}
200
201
retval = rw_setup(profile);
202
if (retval)
203
return retval;
204
205
if (names == 0 || names[0] == 0)
206
return PROF_BAD_NAMESET;
207
208
k5_mutex_lock(&profile->first_file->data->lock);
209
section = profile->first_file->data->root;
210
for (cpp = names; cpp[1]; cpp++) {
211
state = 0;
212
retval = profile_find_node(section, *cpp, 0, 1,
213
&state, &section);
214
if (retval) {
215
k5_mutex_unlock(&profile->first_file->data->lock);
216
return retval;
217
}
218
}
219
220
state = 0;
221
retval = profile_find_node(section, *cpp, 0, 1, &state, &node);
222
if (retval == 0) {
223
if (new_name)
224
retval = profile_rename_node(node, new_name);
225
else
226
retval = profile_remove_node(node);
227
}
228
if (retval == 0)
229
profile->first_file->data->flags |= PROFILE_FILE_DIRTY;
230
k5_mutex_unlock(&profile->first_file->data->lock);
231
return retval;
232
}
233
234
/*
235
* Insert a new relation. If the new_value argument is NULL, then
236
* create a new section instead.
237
*
238
* Note: if the intermediate sections do not exist, this function will
239
* automatically create them.
240
*
241
* ADL - 2/23/99, rewritten TYT 2/25/99
242
*/
243
errcode_t KRB5_CALLCONV
244
profile_add_relation(profile_t profile, const char **names,
245
const char *new_value)
246
{
247
errcode_t retval;
248
struct profile_node *section;
249
const char **cpp;
250
void *state;
251
252
if (profile->vt) {
253
if (!profile->vt->add_relation)
254
return PROF_UNSUPPORTED;
255
return profile->vt->add_relation(profile->cbdata, names, new_value);
256
}
257
258
retval = rw_setup(profile);
259
if (retval)
260
return retval;
261
262
/* Require at least two names for a new relation, one for a new section. */
263
if (names == 0 || names[0] == 0 || (names[1] == 0 && new_value))
264
return PROF_BAD_NAMESET;
265
266
k5_mutex_lock(&profile->first_file->data->lock);
267
section = profile->first_file->data->root;
268
for (cpp = names; cpp[1]; cpp++) {
269
state = 0;
270
retval = profile_find_node(section, *cpp, 0, 1,
271
&state, &section);
272
if (retval == PROF_NO_SECTION)
273
retval = profile_add_node(section, *cpp, NULL, 0, &section);
274
if (retval) {
275
k5_mutex_unlock(&profile->first_file->data->lock);
276
return retval;
277
}
278
}
279
280
if (new_value == 0) {
281
state = 0;
282
retval = profile_find_node(section, *cpp, 0, 1, &state, 0);
283
if (retval == 0) {
284
k5_mutex_unlock(&profile->first_file->data->lock);
285
return PROF_EXISTS;
286
} else if (retval != PROF_NO_SECTION) {
287
k5_mutex_unlock(&profile->first_file->data->lock);
288
return retval;
289
}
290
}
291
292
retval = profile_add_node(section, *cpp, new_value, 0, NULL);
293
if (retval) {
294
k5_mutex_unlock(&profile->first_file->data->lock);
295
return retval;
296
}
297
298
profile->first_file->data->flags |= PROFILE_FILE_DIRTY;
299
k5_mutex_unlock(&profile->first_file->data->lock);
300
return 0;
301
}
302
303