2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of pwmd.
7 Pwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Pwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
26 #include <sys/types.h>
34 #include "pwmd-error.h"
38 #include "util-misc.h"
40 #include "util-slist.h"
41 #include "util-string.h"
44 #define DEFAULT_PINENTRY_TIMEOUT "30"
45 #define DEFAULT_CACHE_TIMEOUT "600"
46 #define DEFAULT_KEEPALIVE_INTERVAL "60"
47 #define DEFAULT_LOCK_TIMEOUT "50" // MUTEX_TRYLOCK in tenths of a second
49 #define INVALID_VALUE(file, line) do { \
51 log_write(_("%s(%i): invalid value for parameter."), file, line); \
56 PARAM_INT
, PARAM_CHARP
, PARAM_LONG
, PARAM_LONGLONG
, PARAM_CHARPP
,
57 PARAM_BOOL
, PARAM_ULONG
, PARAM_ULONGLONG
60 static struct config_params_s
66 { "backup", PARAM_BOOL
, "true"},
67 { "socket_path", PARAM_CHARP
, NULL
},
68 { "socket_perms", PARAM_CHARP
, NULL
},
69 { "passphrase", PARAM_CHARP
, NULL
},
70 { "passphrase_file", PARAM_CHARP
, NULL
},
71 { "gpg_agent_socket", PARAM_CHARP
, NULL
},
72 { "log_path", PARAM_CHARP
, "~/.pwmd/log"},
73 { "enable_logging", PARAM_BOOL
, "0"},
74 { "log_keepopen", PARAM_BOOL
, "true"},
75 { "log_level", PARAM_INT
, "0"},
76 { "disable_mlockall", PARAM_BOOL
, "true"},
77 { "cache_timeout", PARAM_INT
, DEFAULT_CACHE_TIMEOUT
},
78 { "cache_push", PARAM_CHARPP
, NULL
},
79 { "disable_list_and_dump", PARAM_BOOL
, "false"},
80 { "recursion_depth", PARAM_INT
, "100"},
81 { "syslog", PARAM_BOOL
, "false"},
82 { "xfer_progress", PARAM_INT
, "8196"},
83 { "allowed", PARAM_CHARPP
, NULL
},
84 { "allowed_file", PARAM_CHARP
, NULL
},
85 { "keyparam", PARAM_CHARP
, "(genkey (rsa (nbits 4:2048)))"},
86 { "cipher", PARAM_CHARP
, "aes256"},
87 { "kill_scd", PARAM_BOOL
, "false"},
88 { "cipher_iterations", PARAM_ULONGLONG
, "0"},
89 { "cipher_progress", PARAM_LONG
, DEFAULT_ITERATION_PROGRESS
},
90 { "priority", PARAM_INT
, INVALID_PRIORITY
},
91 { "keepalive_interval", PARAM_INT
, DEFAULT_KEEPALIVE_INTERVAL
},
92 { "tcp_port", PARAM_INT
, "6466"},
93 { "enable_tcp", PARAM_BOOL
, "false"},
94 { "tcp_require_key", PARAM_BOOL
, "false"},
95 { "tcp_wait", PARAM_INT
, "0"},
96 { "tcp_bind", PARAM_CHARP
, "any"},
97 { "tcp_interface", PARAM_CHARP
, NULL
},
98 { "tls_timeout", PARAM_INT
, "300"},
99 { "tls_cipher_suite", PARAM_CHARP
, "SECURE256:SECURE192:SECURE128:-VERS-SSL3.0"},
100 { "tls_dh_level", PARAM_CHARP
, "medium"},
101 { "pinentry_path", PARAM_CHARP
, PINENTRY_PATH
},
102 { "pinentry_timeout", PARAM_INT
, DEFAULT_PINENTRY_TIMEOUT
},
103 { "use_agent", PARAM_BOOL
, "false"},
104 { "require_save_key", PARAM_BOOL
, "true"},
105 { "invoking_user", PARAM_CHARPP
, NULL
},
106 { "invoking_file", PARAM_CHARP
, NULL
},
107 { "invoking_tls", PARAM_CHARP
, NULL
},
108 { "lock_timeout", PARAM_INT
, DEFAULT_LOCK_TIMEOUT
},
109 { "send_state", PARAM_INT
, "2"},
113 struct config_param_s
124 unsigned long ultype
;
125 unsigned long long ulltype
;
129 static struct config_section_s
*config_find_section (struct slist_s
*config
,
131 static int new_param (struct config_section_s
*section
, const char *filename
,
132 int lineno
, const char *name
, const char *value
,
134 static void free_section (struct config_section_s
*s
);
135 static int set_defaults (struct slist_s
**config
, int reload
);
138 section_remove_param (struct config_section_s
*section
, const char *name
)
140 unsigned i
, t
= slist_length (section
->params
);
142 for (i
= 0; i
< t
; i
++)
144 struct config_param_s
*p
= slist_nth_data (section
->params
, i
);
149 if (!strcmp (p
->name
, name
))
154 xfree (p
->value
.cptype
);
157 strv_free (p
->value
.cpptype
);
161 section
->params
= slist_remove (section
->params
, p
);
172 MUTEX_LOCK (&rcfile_mutex
);
173 unsigned i
, t
= slist_length (global_config
);
175 for (i
= 0; i
< t
; i
++)
177 struct config_section_s
*s
= slist_nth_data (global_config
, i
);
181 section_remove_param (s
, "passphrase");
184 MUTEX_UNLOCK (&rcfile_mutex
);
187 static struct config_param_s
*
188 config_has_param (struct config_section_s
*s
, const char *what
)
190 unsigned i
, t
= slist_length (s
->params
);
192 for (i
= 0; i
< t
; i
++)
194 struct config_param_s
*p
= slist_nth_data (s
->params
, i
);
198 if (!strcmp (p
->name
, what
))
205 static struct config_param_s
*
206 config_get_param (struct slist_s
*config
,
207 const char *section
, const char *what
, int *exists
)
209 unsigned i
, t
= slist_length (config
);
213 for (i
= 0; i
< t
; i
++)
215 struct config_param_s
*p
;
216 struct config_section_s
*s
= slist_nth_data (config
, i
);
221 if (strcmp (s
->name
, section
))
224 p
= config_has_param (s
, what
);
235 static struct config_section_s
*
236 new_section (struct slist_s
**config
, const char *name
)
239 struct config_section_s
*s
= xcalloc (1, sizeof (struct config_section_s
));
244 s
->name
= str_dup (name
);
247 log_write ("%s", pwmd_strerror (ENOMEM
));
252 tmp
= slist_append (*config
, s
);
255 log_write ("%s", pwmd_strerror (ENOMEM
));
266 config_set_string_param (struct slist_s
**config
, const char *section
,
267 const char *name
, const char *value
)
269 struct config_section_s
*s
= config_find_section (*config
, section
);
273 s
= new_section (config
, section
);
278 return new_param (s
, NULL
, 0, name
, value
, PARAM_CHARP
);
282 config_get_string_param (struct slist_s
*config
, const char *section
,
283 const char *what
, int *exists
)
285 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
286 return *exists
&& p
->value
.cptype
? str_dup (p
->value
.cptype
) : NULL
;
290 config_set_int_param (struct slist_s
**config
, const char *section
,
291 const char *name
, const char *value
)
293 struct config_section_s
*s
= config_find_section (*config
, section
);
297 s
= new_section (config
, section
);
302 return new_param (s
, NULL
, 0, name
, value
, PARAM_INT
);
306 config_get_int_param (struct slist_s
*config
, const char *section
,
307 const char *what
, int *exists
)
309 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
310 return *exists
? p
->value
.itype
: -1;
314 config_set_bool_param (struct slist_s
**config
, const char *section
,
315 const char *name
, const char *value
)
317 struct config_section_s
*s
= config_find_section (*config
, section
);
321 s
= new_section (config
, section
);
326 return new_param (s
, NULL
, 0, name
, value
, PARAM_BOOL
);
330 config_get_bool_param (struct slist_s
*config
, const char *section
,
331 const char *what
, int *exists
)
333 return config_get_int_param (config
, section
, what
, exists
);
337 config_set_long_param (struct slist_s
**config
, const char *section
,
338 const char *name
, const char *value
)
340 struct config_section_s
*s
= config_find_section (*config
, section
);
344 s
= new_section (config
, section
);
349 return new_param (s
, NULL
, 0, name
, value
, PARAM_LONG
);
353 config_get_ulong_param (struct slist_s
*config
, const char *section
,
354 const char *what
, int *exists
)
356 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
357 return *exists
? p
->value
.ultype
: 0;
361 config_get_long_param (struct slist_s
*config
, const char *section
,
362 const char *what
, int *exists
)
364 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
365 return *exists
? p
->value
.ltype
: -1;
369 config_set_longlong_param (struct slist_s
**config
, const char *section
,
370 const char *name
, const char *value
)
372 struct config_section_s
*s
= config_find_section (*config
, section
);
376 s
= new_section (config
, section
);
381 return new_param (s
, NULL
, 0, name
, value
, PARAM_LONGLONG
);
385 config_get_longlong_param (struct slist_s
*config
,
386 const char *section
, const char *what
, int *exists
)
388 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
389 return *exists
? p
->value
.lltype
: -1;
393 config_get_ulonglong_param (struct slist_s
*config
,
395 const char *what
, int *exists
)
397 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
398 return *exists
? p
->value
.ulltype
: 0;
402 config_set_list_param (struct slist_s
**config
, const char *section
,
403 const char *name
, const char *value
)
405 struct config_section_s
*s
= config_find_section (*config
, section
);
409 s
= new_section (config
, section
);
414 return new_param (s
, NULL
, 0, name
, value
, PARAM_CHARPP
);
418 config_get_list_param (struct slist_s
*config
, const char *section
,
419 const char *what
, int *exists
)
421 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
422 return *exists
&& p
->value
.cpptype
? strv_dup (p
->value
.cpptype
) : NULL
;
426 config_get_string (const char *section
, const char *what
)
429 const char *where
= section
? section
: "global";
432 MUTEX_LOCK (&rcfile_mutex
);
433 val
= config_get_string_param (global_config
, where
, what
, &exists
);
434 if (!exists
&& strcmp (section
? section
: "", "global"))
435 val
= config_get_string_param (global_config
, "global", what
, &exists
);
437 MUTEX_UNLOCK (&rcfile_mutex
);
442 config_get_list (const char *section
, const char *what
)
445 const char *where
= section
? section
: "global";
448 MUTEX_LOCK (&rcfile_mutex
);
449 val
= config_get_list_param (global_config
, where
, what
, &exists
);
450 if (!exists
&& strcmp (section
? section
: "", "global"))
451 val
= config_get_list_param (global_config
, "global", what
, &exists
);
453 MUTEX_UNLOCK (&rcfile_mutex
);
458 config_get_integer (const char *section
, const char *what
)
461 const char *where
= section
? section
: "global";
464 MUTEX_LOCK (&rcfile_mutex
);
465 val
= config_get_int_param (global_config
, where
, what
, &exists
);
466 if (!exists
&& strcmp (section
? section
: "", "global"))
467 val
= config_get_int_param (global_config
, "global", what
, &exists
);
469 MUTEX_UNLOCK (&rcfile_mutex
);
474 config_get_longlong (const char *section
, const char *what
)
477 const char *where
= section
? section
: "global";
480 MUTEX_LOCK (&rcfile_mutex
);
481 val
= config_get_longlong_param (global_config
, where
, what
, &exists
);
482 if (!exists
&& strcmp (section
? section
: "", "global"))
483 val
= config_get_longlong_param (global_config
, "global", what
, &exists
);
485 MUTEX_UNLOCK (&rcfile_mutex
);
490 config_get_ulonglong (const char *section
, const char *what
)
492 unsigned long long val
= 0;
493 const char *where
= section
? section
: "global";
496 MUTEX_LOCK (&rcfile_mutex
);
497 val
= config_get_ulonglong_param (global_config
, where
, what
, &exists
);
498 if (!exists
&& strcmp (section
? section
: "", "global"))
499 val
= config_get_ulonglong_param (global_config
, "global", what
, &exists
);
501 MUTEX_UNLOCK (&rcfile_mutex
);
506 config_get_long (const char *section
, const char *what
)
509 const char *where
= section
? section
: "global";
512 MUTEX_LOCK (&rcfile_mutex
);
513 val
= config_get_long_param (global_config
, where
, what
, &exists
);
514 if (!exists
&& strcmp (section
? section
: "", "global"))
515 val
= config_get_long_param (global_config
, "global", what
, &exists
);
517 MUTEX_UNLOCK (&rcfile_mutex
);
522 config_get_ulong (const char *section
, const char *what
)
524 unsigned long val
= 0;
525 const char *where
= section
? section
: "global";
528 MUTEX_LOCK (&rcfile_mutex
);
529 val
= config_get_ulong_param (global_config
, where
, what
, &exists
);
530 if (!exists
&& strcmp (section
? section
: "", "global"))
531 val
= config_get_ulong_param (global_config
, "global", what
, &exists
);
533 MUTEX_UNLOCK (&rcfile_mutex
);
538 config_get_boolean (const char *section
, const char *what
)
540 return config_get_integer (section
, what
);
544 config_get_value (const char *section
, const char *what
)
546 const char *where
= section
? section
: "global";
553 unsigned long long ullval
;
558 MUTEX_LOCK (&rcfile_mutex
);
560 for (i
= 0; config_params
[i
].name
; i
++)
562 if (!strcmp (config_params
[i
].name
, what
))
564 switch (config_params
[i
].type
)
568 ival
= config_get_int_param (global_config
, where
, what
,
570 if (!exists
&& strcmp (section
? section
: "", "global"))
571 ival
= config_get_int_param (global_config
, "global", what
,
573 result
= str_asprintf ("%i", ival
);
576 cpval
= config_get_string_param (global_config
, where
, what
,
578 if (!exists
&& strcmp (section
? section
: "", "global"))
580 config_get_string_param (global_config
, "global", what
,
585 lval
= config_get_long_param (global_config
, where
, what
,
587 if (!exists
&& strcmp (section
? section
: "", "global"))
588 lval
= config_get_long_param (global_config
, "global", what
,
590 result
= str_asprintf ("%li", lval
);
593 ulval
= config_get_ulong_param (global_config
, where
, what
,
595 if (!exists
&& strcmp (section
? section
: "", "global"))
596 ulval
= config_get_ulong_param (global_config
, "global", what
,
598 result
= str_asprintf ("%lu", ulval
);
601 llval
= config_get_longlong_param (global_config
, where
, what
,
603 if (!exists
&& strcmp (section
? section
: "", "global"))
604 llval
= config_get_longlong_param (global_config
, "global",
606 result
= str_asprintf ("%lli", llval
);
608 case PARAM_ULONGLONG
:
609 ullval
= config_get_ulonglong_param (global_config
, where
, what
,
611 if (!exists
&& strcmp (section
? section
: "", "global"))
612 ullval
= config_get_ulonglong_param (global_config
, "global",
614 result
= str_asprintf ("%llu", ullval
);
617 cppval
= config_get_list_param (global_config
, where
, what
,
619 if (!exists
&& strcmp (section
? section
: "", "global"))
620 cppval
= config_get_list_param (global_config
, "global", what
,
624 result
= strv_join (",", cppval
);
632 MUTEX_UNLOCK (&rcfile_mutex
);
636 /* 'file' is the list parameter file to load into the list parameter 'what'.
637 * The parsing of the parameter is not done here. */
639 parse_list_file (struct slist_s
*config
, const char *section
,
640 const char *file
, const char *what
)
647 char *p
= config_get_string_param (config
, section
, file
, &exists
);
656 tmp
= expand_homedir (p
);
662 rc
= gpg_error_from_errno (errno
);
663 log_write ("%s: %s", p
, pwmd_strerror (rc
));
669 list
= config_get_list_param (config
, section
, what
, &exists
);
673 log_write ("%s", pwmd_strerror (ENOMEM
));
674 return gpg_error (ENOMEM
);
677 while ((p
= fgets (buf
, sizeof (buf
), fp
)))
681 if (p
[strlen(p
)-1] == '\n')
684 while (*p
&& isspace (*p
))
692 pp
= strv_cat (list
, str_dup (p
));
699 log_write ("%s", strerror (ENOMEM
));
700 return gpg_error (ENOMEM
);
711 p
= strv_join (",", list
);
716 log_write ("%s", pwmd_strerror (ENOMEM
));
717 return gpg_error (ENOMEM
);
720 config_set_list_param (&config
, section
, what
, p
);
726 fixup_allowed_once (struct slist_s
**config
, const char *section
)
728 char **list
, **pp
, *p
;
732 rc
= parse_list_file (*config
, section
, "allowed_file", "allowed");
736 list
= config_get_list_param (*config
, section
, "allowed", &exists
);
737 for (pp
= list
; pp
&& *pp
; pp
++)
741 for (p
= *pp
; p
&& *p
; p
++)
749 if (!strcmp (section
, "global"))
751 p
= get_username (getuid());
753 if (config_set_list_param (config
, section
, "allowed", p
))
763 list
= config_get_list_param (*config
, "global", "allowed", &exists
);
766 p
= strv_join (",", list
);
768 if (config_set_list_param (config
, section
, "allowed", p
))
783 fixup_allowed (struct slist_s
**config
)
785 int n
, t
= slist_length (*config
);
787 for (n
= 0; n
< t
; n
++)
789 struct config_section_s
*section
;
791 section
= slist_nth_data (*config
, n
);
792 if (fixup_allowed_once (config
, section
->name
))
800 add_invoking_user (struct invoking_user_s
**users
, char *id
,
801 struct slist_s
**config
)
803 struct passwd
*pwd
= NULL
;
804 struct group
*grp
= NULL
;
805 struct invoking_user_s
*user
, *p
;
808 if (id
&& (*id
== '!' || *id
== '-'))
817 pwd
= getpwuid (getuid ());
820 log_write (_("could not set any invoking user: %s"),
821 pwmd_strerror (errno
));
827 grp
= getgrnam (id
+1);
830 log_write (_("could not parse group '%s': %s"), id
+1,
831 pwmd_strerror (errno
));
838 if (!grp
&& !pwd
&& id
&& *id
!= '#')
841 log_write (_("could not set invoking user '%s': %s"), id
,
842 pwmd_strerror (errno
));
844 log_write (_("could not set any invoking user!"));
849 user
= xcalloc (1, sizeof (struct invoking_user_s
));
852 log_write ("%s", pwmd_strerror (ENOMEM
));
857 user
->type
= pwd
? INVOKING_UID
: grp
? INVOKING_GID
: INVOKING_TLS
;
859 user
->uid
= pwd
->pw_uid
;
861 user
->id
= str_dup (id
+1);
866 for (s
= id
; s
&& *s
; s
++)
869 user
->id
= str_dup (id
+1);
872 /* Set the default invoking_user since it doesn't exist. */
874 config_set_list_param (config
, "global", "invoking_user", pwd
->pw_name
);
882 for (p
= *users
; p
; p
= p
->next
)
895 parse_invoking_users (struct slist_s
**config
)
897 struct invoking_user_s
*users
= NULL
;
901 if (parse_list_file (*config
, "global", "invoking_file", "invoking_user"))
904 list
= config_get_list_param(*config
, "global", "invoking_user", &exists
);
905 for (l
= list
; l
&& *l
; l
++)
907 if (add_invoking_user (&users
, *l
, config
))
910 free_invoking_users (users
);
917 if (add_invoking_user (&users
, NULL
, config
))
924 list
= config_get_list_param(*config
, "global", "invoking_user", &exists
);
928 /* This option is deprecated. Parse it into invoking_user. */
929 char *tls
= config_get_string_param(*config
, "global", "invoking_tls",
936 if (add_invoking_user (&users
, tls
, config
))
938 free_invoking_users (users
);
942 pp
= strv_cat (list
, tls
);
946 free_invoking_users (users
);
947 log_write ("%s", pwmd_strerror (ENOMEM
));
952 p
= strv_join (",", list
);
954 config_set_list_param (config
, "global", "invoking_user", p
);
959 free_invoking_users (invoking_users
);
960 invoking_users
= users
;
965 set_defaults (struct slist_s
**config
, int reload
)
967 char *s
= NULL
, *tmp
;
972 for (i
= 0; config_params
[i
].name
; i
++)
974 switch (config_params
[i
].type
)
977 config_get_bool_param (*config
, "global", config_params
[i
].name
,
981 if (config_set_bool_param
982 (config
, "global", config_params
[i
].name
,
983 config_params
[i
].value
))
988 config_get_int_param (*config
, "global", config_params
[i
].name
,
992 if (config_set_int_param
993 (config
, "global", config_params
[i
].name
,
994 config_params
[i
].value
))
999 s
= config_get_string_param (*config
, "global",
1000 config_params
[i
].name
, &exists
);
1002 if (!exists
&& config_params
[i
].value
)
1004 if (config_set_string_param (config
, "global",
1005 config_params
[i
].name
,
1006 config_params
[i
].value
))
1011 list
= config_get_list_param (*config
, "global",
1012 config_params
[i
].name
, &exists
);
1014 if (!exists
&& config_params
[i
].value
)
1016 if (config_set_list_param (config
, "global",
1017 config_params
[i
].name
,
1018 config_params
[i
].value
))
1023 config_get_long_param (*config
, "global", config_params
[i
].name
,
1027 if (config_set_long_param
1028 (config
, "global", config_params
[i
].name
,
1029 config_params
[i
].value
))
1033 case PARAM_LONGLONG
:
1034 config_get_longlong_param (*config
, "global", config_params
[i
].name
,
1038 if (config_set_longlong_param (config
, "global",
1039 config_params
[i
].name
,
1040 config_params
[i
].value
))
1048 if (!reload
&& fixup_allowed (config
))
1051 max_recursion_depth
= config_get_int_param (*config
, "global",
1052 "recursion_depth", &exists
);
1053 disable_list_and_dump
= config_get_bool_param (*config
, "global",
1054 "disable_list_and_dump",
1056 #ifdef HAVE_MLOCKALL
1058 config_get_bool_param (*config
, "global", "disable_mlockall", &exists
);
1061 if (!reload
&& parse_invoking_users (config
))
1064 s
= config_get_string_param(*config
, "global", "gpg_agent_socket", &exists
);
1068 s
= str_asprintf ("%s/.gnupg/S.gpg-agent", get_home_dir());
1069 config_set_string_param(config
, "global", "gpg_agent_socket", s
);
1073 tmp
= expand_homedir (s
);
1074 config_set_string_param(config
, "global", "gpg_agent_socket", tmp
);
1086 static struct config_section_s
*
1087 config_find_section (struct slist_s
*config
, const char *name
)
1089 unsigned i
, t
= slist_length (config
);
1091 for (i
= 0; i
< t
; i
++)
1093 struct config_section_s
*s
= slist_nth_data (config
, i
);
1095 if (!strcmp (s
->name
, name
))
1102 /* Append a new parameter to the list of parameters for a file
1103 * section. When an existing parameter of the same name exists, its
1107 new_param (struct config_section_s
*section
, const char *filename
, int lineno
,
1108 const char *name
, const char *value
, int type
)
1110 struct config_param_s
*param
= NULL
;
1111 struct slist_s
*tmp
;
1113 unsigned i
, t
= slist_length (section
->params
);
1116 for (i
= 0; i
< t
; i
++)
1118 struct config_param_s
*p
= slist_nth_data (section
->params
, i
);
1122 if (!strcmp (name
, p
->name
))
1132 param
= xcalloc (1, sizeof (struct config_param_s
));
1135 log_write ("%s", pwmd_strerror (ENOMEM
));
1139 param
->name
= str_dup (name
);
1143 log_write ("%s", pwmd_strerror (ENOMEM
));
1153 if (!strcasecmp (value
, "no") || !strcasecmp (value
, "0")
1154 || !strcasecmp (value
, "false"))
1155 param
->value
.itype
= 0;
1156 else if (!strcasecmp (value
, "yes") || !strcasecmp (value
, "1")
1157 || !strcasecmp (value
, "true"))
1158 param
->value
.itype
= 1;
1161 INVALID_VALUE (filename
, lineno
);
1164 param
->type
= PARAM_INT
;
1167 xfree (param
->value
.cptype
);
1168 param
->value
.cptype
= NULL
;
1169 param
->value
.cptype
= value
&& *value
? str_dup (value
) : NULL
;
1170 if (value
&& *value
&& !param
->value
.cptype
)
1172 log_write ("%s", pwmd_strerror (ENOMEM
));
1177 strv_free (param
->value
.cpptype
);
1178 param
->value
.cpptype
= NULL
;
1179 param
->value
.cpptype
= value
&& *value
? str_split (value
, ",", 0) : NULL
;
1180 if (value
&& *value
&& !param
->value
.cpptype
)
1182 log_write ("%s", pwmd_strerror (ENOMEM
));
1187 param
->value
.itype
= strtol (value
, &e
, 10);
1190 INVALID_VALUE (filename
, lineno
);
1195 param
->value
.ltype
= strtol (value
, &e
, 10);
1198 INVALID_VALUE (filename
, lineno
);
1202 case PARAM_LONGLONG
:
1203 param
->value
.lltype
= strtoll (value
, &e
, 10);
1206 INVALID_VALUE (filename
, lineno
);
1210 case PARAM_ULONGLONG
:
1211 param
->value
.ulltype
= strtoull (value
, &e
, 10);
1214 INVALID_VALUE (filename
, lineno
);
1219 param
->value
.ultype
= strtoul (value
, &e
, 10);
1222 INVALID_VALUE (filename
, lineno
);
1231 tmp
= slist_append (section
->params
, param
);
1234 log_write ("%s", pwmd_strerror (ENOMEM
));
1238 section
->params
= tmp
;
1242 xfree (param
->name
);
1248 config_parse (const char *filename
, int reload
)
1250 struct slist_s
*tmpconfig
= NULL
, *tmp
;
1251 struct config_section_s
*cur_section
= NULL
;
1255 int have_global
= 0;
1256 FILE *fp
= fopen (filename
, "r");
1260 log_write ("%s: %s", filename
,
1261 pwmd_strerror (gpg_error_from_errno (errno
)));
1263 if (errno
!= ENOENT
)
1266 log_write (_("Using defaults!"));
1270 for (; (s
= fgets (buf
, sizeof (buf
), fp
)); lineno
++)
1272 char line
[LINE_MAX
] = { 0 };
1279 for (; s
&& *s
; s
++)
1283 /* New file section. */
1286 struct config_section_s
*section
;
1287 char *p
= strchr (++s
, ']');
1291 log_write (_("%s(%i): unbalanced braces"), filename
,
1296 len
= strlen (s
) - strlen (p
);
1297 memcpy (line
, s
, len
);
1300 section
= config_find_section (tmpconfig
, line
);
1303 log_write (_("%s(%i): section '%s' already exists!"),
1304 filename
, lineno
, line
);
1308 if (!strcmp (line
, "global"))
1311 section
= xcalloc (1, sizeof (struct config_section_s
));
1312 section
->name
= str_dup (line
);
1316 tmp
= slist_append (tmpconfig
, cur_section
);
1319 log_write ("%s", pwmd_strerror (ENOMEM
));
1326 cur_section
= section
;
1332 log_write (_("%s(%i): parameter outside of section!"), filename
,
1337 /* Parameters for each section. */
1338 for (int m
= 0; config_params
[m
].name
; m
++)
1340 size_t len
= strlen (config_params
[m
].name
);
1342 if (!strncmp (s
, config_params
[m
].name
, len
))
1346 while (*p
&& *p
== ' ')
1349 if (!*p
|| *p
!= '=')
1353 while (*p
&& isspace (*p
))
1357 if (new_param (cur_section
, filename
, lineno
, s
, p
,
1358 config_params
[m
].type
))
1368 log_write (_("%s(%i): unknown parameter"), filename
, lineno
);
1378 tmp
= slist_append (tmpconfig
, cur_section
);
1381 log_write ("%s", pwmd_strerror (ENOMEM
));
1391 ("WARNING: %s: could not find a [global] configuration section!"),
1396 char *tmp
= config_get_string_param (tmpconfig
, "global", "tls_dh_level",
1400 if (strcasecmp (tmp
, "low") && strcasecmp (tmp
, "medium")
1401 && strcasecmp (tmp
, "high"))
1404 log_write (_("invalid tls_dh_level value"));
1413 if (set_defaults (&tmpconfig
, reload
))
1425 config_free (tmpconfig
);
1426 free_section (cur_section
);
1431 free_section (struct config_section_s
*s
)
1438 struct config_param_s
*p
= slist_nth_data (s
->params
, 0);
1443 section_remove_param (s
, p
->name
);
1452 config_free (struct slist_s
*config
)
1456 struct config_section_s
*s
= slist_nth_data (config
, 0);
1461 config
= slist_remove (config
, s
);
1467 free_invoking_users (struct invoking_user_s
*users
)
1469 struct invoking_user_s
*p
;
1473 struct invoking_user_s
*next
= p
->next
;
1475 if (p
->type
== INVOKING_TLS
|| p
->type
== INVOKING_GID
)