1 /*
2  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3  */
4 
5 /*
6  * prof-int.h
7  */
8 
9 /* Solaris Kerberos */
10 #ifndef __PROF_INT_H
11 #define	__PROF_INT_H
12 
13 #include <time.h>
14 #include <stdio.h>
15 
16 #if defined(__MACH__) && defined(__APPLE__)
17 #include <TargetConditionals.h>
18 #define PROFILE_SUPPORTS_FOREIGN_NEWLINES
19 #endif
20 
21 #include "k5-thread.h"
22 #include "k5-platform.h"
23 #include "com_err.h"
24 #include "profile.h"
25 
26 typedef long prf_magic_t;
27 
28 /*
29  * This is the structure which stores the profile information for a
30  * particular configuration file.
31  *
32  * Locking strategy:
33  * - filespec, fslen are fixed after creation
34  * - refcount and next should only be tweaked with the global lock held
35  * - other fields can be tweaked after grabbing the in-struct lock
36  */
37 struct _prf_data_t {
38 	prf_magic_t	magic;
39 	k5_mutex_t	lock;
40 	struct profile_node *root;
41 	time_t		last_stat;
42 	time_t		timestamp; /* time tree was last updated from file */
43 	unsigned long	frac_ts;   /* fractional part of timestamp, if any */
44 	int		flags;	/* r/w, dirty */
45 	int		upd_serial; /* incremented when data changes */
46 	char		*comment;
47 
48 	size_t		fslen;
49 
50 	/* Some separation between fields controlled by different
51 	   mutexes.  Theoretically, both could be accessed at the same
52 	   time from different threads on different CPUs with separate
53 	   caches.  Don't let the threads clobber each other's
54 	   changes.  One mutex controlling the whole thing would be
55 	   better, but sufficient separation might suffice.
56 
57 	   This is icky.  I just hope it's adequate.
58 
59 	   For next major release, fix this.  */
60 	union { double d; void *p; UINT64_TYPE ll; k5_mutex_t m; } pad;
61 
62 	int		refcount; /* prf_file_t references */
63 	struct _prf_data_t *next;
64 	/* Was: "profile_filespec_t filespec".  Now: flexible char
65 	   array ... except, we need to work in C89, so an array
66 	   length must be specified.  */
67 	const char	filespec[sizeof("/etc/krb5.conf")];
68 };
69 
70 typedef struct _prf_data_t *prf_data_t;
71 prf_data_t profile_make_prf_data(const char *);
72 
73 struct _prf_file_t {
74 	prf_magic_t	magic;
75 	struct _prf_data_t	*data;
76 	struct _prf_file_t *next;
77 };
78 
79 typedef struct _prf_file_t *prf_file_t;
80 
81 /*
82  * The profile flags
83  */
84 #define PROFILE_FILE_RW		0x0001
85 #define PROFILE_FILE_DIRTY	0x0002
86 #define PROFILE_FILE_SHARED	0x0004
87 
88 /*
89  * This structure defines the high-level, user visible profile_t
90  * object, which is used as a handle by users who need to query some
91  * configuration file(s)
92  */
93 struct _profile_t {
94 	prf_magic_t	magic;
95 	prf_file_t	first_file;
96 };
97 
98 typedef struct _profile_options {
99 	char *name;
100 	int  *value;
101 	int  found;
102 } profile_options_boolean;
103 
104 typedef struct _profile_times {
105 	char *name;
106 	char **value;
107 	int  found;
108 } profile_option_strings;
109 
110 /*
111  * Solaris Kerberos: Added here to provide to other non-prof_get functions.
112  * The profile_string_list structure is used for internal booking
113  * purposes to build up the list, which is returned in *ret_list by
114  * the end_list() function.
115  */
116 struct profile_string_list {
117 	char	**list;
118 	int	num;
119 	int	max;
120 };
121 
122 /*
123  * Used by the profile iterator in prof_get.c
124  */
125 #define PROFILE_ITER_LIST_SECTION	0x0001
126 #define PROFILE_ITER_SECTIONS_ONLY	0x0002
127 #define PROFILE_ITER_RELATIONS_ONLY	0x0004
128 
129 #define PROFILE_ITER_FINAL_SEEN		0x0100
130 
131 /*
132  * Check if a filespec is last in a list (NULL on UNIX, invalid FSSpec on MacOS
133  */
134 
135 #define	PROFILE_LAST_FILESPEC(x) (((x) == NULL) || ((x)[0] == '\0'))
136 
137 /* profile_parse.c */
138 
139 errcode_t profile_parse_file
140 	(FILE *f, struct profile_node **root);
141 
142 errcode_t profile_write_tree_file
143 	(struct profile_node *root, FILE *dstfile);
144 
145 errcode_t profile_write_tree_to_buffer
146 	(struct profile_node *root, char **buf);
147 
148 
149 /* prof_tree.c */
150 
151 void profile_free_node
152 	(struct profile_node *relation);
153 
154 errcode_t profile_create_node
155 	(const char *name, const char *value,
156 		   struct profile_node **ret_node);
157 
158 errcode_t profile_verify_node
159 	(struct profile_node *node);
160 
161 errcode_t profile_add_node
162 	(struct profile_node *section,
163 		    const char *name, const char *value,
164 		    struct profile_node **ret_node);
165 
166 errcode_t profile_make_node_final
167 	(struct profile_node *node);
168 
169 int profile_is_node_final
170 	(struct profile_node *node);
171 
172 const char *profile_get_node_name
173 	(struct profile_node *node);
174 
175 const char *profile_get_node_value
176 	(struct profile_node *node);
177 
178 errcode_t profile_find_node
179 	(struct profile_node *section,
180 		    const char *name, const char *value,
181 		    int section_flag, void **state,
182 		    struct profile_node **node);
183 
184 errcode_t profile_find_node_relation
185 	(struct profile_node *section,
186 		    const char *name, void **state,
187 		    char **ret_name, char **value);
188 
189 errcode_t profile_find_node_subsection
190 	(struct profile_node *section,
191 		    const char *name, void **state,
192 		    char **ret_name, struct profile_node **subsection);
193 
194 errcode_t profile_get_node_parent
195 	(struct profile_node *section,
196 		   struct profile_node **parent);
197 
198 errcode_t profile_delete_node_relation
199 	(struct profile_node *section, const char *name);
200 
201 errcode_t profile_find_node_name
202 	(struct profile_node *section, void **state,
203 		    char **ret_name);
204 
205 errcode_t profile_node_iterator_create
206 	(profile_t profile, const char *const *names,
207 		   int flags, void **ret_iter);
208 
209 void profile_node_iterator_free
210 	(void	**iter_p);
211 
212 errcode_t profile_node_iterator
213 	(void	**iter_p, struct profile_node **ret_node,
214 		   char **ret_name, char **ret_value);
215 
216 errcode_t profile_remove_node
217 	(struct profile_node *node);
218 
219 errcode_t profile_set_relation_value
220 	(struct profile_node *node, const char *new_value);
221 
222 errcode_t profile_rename_node
223 	(struct profile_node *node, const char *new_name);
224 
225 /* prof_file.c */
226 
227 errcode_t KRB5_CALLCONV profile_copy (profile_t, profile_t *);
228 
229 errcode_t profile_open_file
230 	(const_profile_filespec_t file, prf_file_t *ret_prof);
231 
232 #define profile_update_file(P) profile_update_file_data((P)->data)
233 errcode_t profile_update_file_data
234 	(prf_data_t profile);
235 
236 #define profile_flush_file(P) (((P) && (P)->magic == PROF_MAGIC_FILE) ? profile_flush_file_data((P)->data) : PROF_MAGIC_FILE)
237 errcode_t profile_flush_file_data
238 	(prf_data_t data);
239 
240 #define profile_flush_file_to_file(P,F) (((P) && (P)->magic == PROF_MAGIC_FILE) ? profile_flush_file_data_to_file((P)->data, (F)) : PROF_MAGIC_FILE)
241 errcode_t profile_flush_file_data_to_file
242 	(prf_data_t data, const char *outfile);
243 
244 errcode_t profile_flush_file_data_to_buffer
245 	(prf_data_t data, char **bufp);
246 
247 void profile_free_file
248 	(prf_file_t profile);
249 
250 errcode_t profile_close_file
251 	(prf_file_t profile);
252 
253 void profile_dereference_data (prf_data_t);
254 void profile_dereference_data_locked (prf_data_t);
255 
256 int profile_lock_global (void);
257 int profile_unlock_global (void);
258 
259 /* prof_init.c -- included from profile.h */
260 errcode_t profile_ser_size
261         (const char *, profile_t, size_t *);
262 
263 errcode_t profile_ser_externalize
264         (const char *, profile_t, unsigned char **, size_t *);
265 
266 errcode_t profile_ser_internalize
267         (const char *, profile_t *, unsigned char **, size_t *);
268 
269 /* prof_get.c */
270 
271 errcode_t profile_get_value
272 	(profile_t profile, const char **names,
273 		    const char	**ret_value);
274 
275 /*
276  * Solaris Kerberos: Need basic routines for other functions besides prof_get.
277  */
278 errcode_t init_list(struct profile_string_list *list);
279 void end_list(struct profile_string_list *list, char ***ret_list);
280 errcode_t add_to_list(struct profile_string_list *list, const char *str);
281 
282 /* Others included from profile.h */
283 
284 /* prof_set.c -- included from profile.h */
285 
286 /* Solaris Kerberos */
287 #endif /* __PROF_INT_H */
288