17c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
27c478bd9Sstevel@tonic-gate /*
37c478bd9Sstevel@tonic-gate  * prof_set.c --- routines that expose the public interfaces for
47c478bd9Sstevel@tonic-gate  * 	inserting, updating and deleting items from the profile.
57c478bd9Sstevel@tonic-gate  *
67c478bd9Sstevel@tonic-gate  * WARNING: These routines only look at the first file opened in the
77c478bd9Sstevel@tonic-gate  * profile.  It's not clear how to handle multiple files, actually.
87c478bd9Sstevel@tonic-gate  * In the future it may be necessary to modify this public interface,
97c478bd9Sstevel@tonic-gate  * or possibly add higher level functions to support this correctly.
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  * WARNING: We're not yet doing locking yet, either.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  */
147c478bd9Sstevel@tonic-gate 
15*505d05c7Sgtb #include "prof_int.h"
16*505d05c7Sgtb 
177c478bd9Sstevel@tonic-gate #include <stdio.h>
187c478bd9Sstevel@tonic-gate #include <string.h>
197c478bd9Sstevel@tonic-gate #ifdef HAVE_STDLIB_H
207c478bd9Sstevel@tonic-gate #include <stdlib.h>
217c478bd9Sstevel@tonic-gate #endif
227c478bd9Sstevel@tonic-gate #include <errno.h>
237c478bd9Sstevel@tonic-gate 
rw_setup(profile_t profile)24*505d05c7Sgtb static errcode_t rw_setup(profile_t profile)
257c478bd9Sstevel@tonic-gate {
267c478bd9Sstevel@tonic-gate    	prf_file_t	file;
27*505d05c7Sgtb 	errcode_t	retval = 0;
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate 	if (!profile)
307c478bd9Sstevel@tonic-gate 		return PROF_NO_PROFILE;
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate 	if (profile->magic != PROF_MAGIC_PROFILE)
337c478bd9Sstevel@tonic-gate 		return PROF_MAGIC_PROFILE;
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate 	file = profile->first_file;
36*505d05c7Sgtb 
37*505d05c7Sgtb 	retval = profile_lock_global();
38*505d05c7Sgtb 	if (retval)
39*505d05c7Sgtb 	    return retval;
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate 	/* Don't update the file if we've already made modifications */
42*505d05c7Sgtb 	if (file->data->flags & PROFILE_FILE_DIRTY) {
43*505d05c7Sgtb 	    profile_unlock_global();
44*505d05c7Sgtb 	    return 0;
45*505d05c7Sgtb 	}
46*505d05c7Sgtb 
47*505d05c7Sgtb 	if ((file->data->flags & PROFILE_FILE_SHARED) != 0) {
48*505d05c7Sgtb 	    prf_data_t new_data;
49*505d05c7Sgtb 	    new_data = profile_make_prf_data(file->data->filespec);
50*505d05c7Sgtb 	    if (new_data == NULL) {
51*505d05c7Sgtb 		retval = ENOMEM;
52*505d05c7Sgtb 	    } else {
53*505d05c7Sgtb 		retval = k5_mutex_init(&new_data->lock);
54*505d05c7Sgtb 		if (retval == 0) {
55*505d05c7Sgtb 		    new_data->root = NULL;
56*505d05c7Sgtb 		    new_data->flags = file->data->flags & ~PROFILE_FILE_SHARED;
57*505d05c7Sgtb 		    new_data->timestamp = 0;
58*505d05c7Sgtb 		    new_data->upd_serial = file->data->upd_serial;
59*505d05c7Sgtb 		}
60*505d05c7Sgtb 	    }
61*505d05c7Sgtb 
62*505d05c7Sgtb 	    if (retval != 0) {
63*505d05c7Sgtb 		profile_unlock_global();
64*505d05c7Sgtb 		free(new_data);
65*505d05c7Sgtb 		return retval;
66*505d05c7Sgtb 	    }
67*505d05c7Sgtb 	    profile_dereference_data_locked(file->data);
68*505d05c7Sgtb 	    file->data = new_data;
69*505d05c7Sgtb 	}
70*505d05c7Sgtb 
71*505d05c7Sgtb 	profile_unlock_global();
727c478bd9Sstevel@tonic-gate 	retval = profile_update_file(file);
73*505d05c7Sgtb 
747c478bd9Sstevel@tonic-gate 	return retval;
757c478bd9Sstevel@tonic-gate }
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate /*
797c478bd9Sstevel@tonic-gate  * Delete or update a particular child node
807c478bd9Sstevel@tonic-gate  *
817c478bd9Sstevel@tonic-gate  * ADL - 2/23/99, rewritten TYT 2/25/99
827c478bd9Sstevel@tonic-gate  */
83*505d05c7Sgtb errcode_t KRB5_CALLCONV
profile_update_relation(profile_t profile,const char ** names,const char * old_value,const char * new_value)84*505d05c7Sgtb profile_update_relation(profile_t profile, const char **names,
85*505d05c7Sgtb 			const char *old_value, const char *new_value)
867c478bd9Sstevel@tonic-gate {
877c478bd9Sstevel@tonic-gate 	errcode_t	retval;
887c478bd9Sstevel@tonic-gate 	struct profile_node *section, *node;
897c478bd9Sstevel@tonic-gate 	void		*state;
907c478bd9Sstevel@tonic-gate 	const char	**cpp;
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	retval = rw_setup(profile);
937c478bd9Sstevel@tonic-gate 	if (retval)
947c478bd9Sstevel@tonic-gate 		return retval;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	if (names == 0 || names[0] == 0 || names[1] == 0)
977c478bd9Sstevel@tonic-gate 		return PROF_BAD_NAMESET;
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 	if (!old_value || !*old_value)
1007c478bd9Sstevel@tonic-gate 		return PROF_EINVAL;
1017c478bd9Sstevel@tonic-gate 
102*505d05c7Sgtb 	retval = k5_mutex_lock(&profile->first_file->data->lock);
103*505d05c7Sgtb 	if (retval)
104*505d05c7Sgtb 	    return retval;
105*505d05c7Sgtb 	section = profile->first_file->data->root;
1067c478bd9Sstevel@tonic-gate 	for (cpp = names; cpp[1]; cpp++) {
1077c478bd9Sstevel@tonic-gate 		state = 0;
1087c478bd9Sstevel@tonic-gate 		retval = profile_find_node(section, *cpp, 0, 1,
1097c478bd9Sstevel@tonic-gate 					   &state, &section);
110*505d05c7Sgtb 		if (retval) {
111*505d05c7Sgtb 		    k5_mutex_unlock(&profile->first_file->data->lock);
112*505d05c7Sgtb 		    return retval;
113*505d05c7Sgtb 		}
1147c478bd9Sstevel@tonic-gate 	}
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate 	state = 0;
1177c478bd9Sstevel@tonic-gate 	retval = profile_find_node(section, *cpp, old_value, 0, &state, &node);
118*505d05c7Sgtb 	if (retval == 0) {
119*505d05c7Sgtb 	    if (new_value)
1207c478bd9Sstevel@tonic-gate 		retval = profile_set_relation_value(node, new_value);
121*505d05c7Sgtb 	    else
1227c478bd9Sstevel@tonic-gate 		retval = profile_remove_node(node);
123*505d05c7Sgtb 	}
124*505d05c7Sgtb 	if (retval == 0)
125*505d05c7Sgtb 	    profile->first_file->data->flags |= PROFILE_FILE_DIRTY;
126*505d05c7Sgtb 	k5_mutex_unlock(&profile->first_file->data->lock);
1277c478bd9Sstevel@tonic-gate 
128*505d05c7Sgtb 	return retval;
1297c478bd9Sstevel@tonic-gate }
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate /*
1327c478bd9Sstevel@tonic-gate  * Clear a particular all of the relations with a specific name.
1337c478bd9Sstevel@tonic-gate  *
1347c478bd9Sstevel@tonic-gate  * TYT - 2/25/99
1357c478bd9Sstevel@tonic-gate  */
136*505d05c7Sgtb errcode_t KRB5_CALLCONV
profile_clear_relation(profile_t profile,const char ** names)137