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