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_ULONGLONG
, PARAM_CHARPP
,
57 PARAM_BOOL
, PARAM_INVALID
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 { "s2k_count", PARAM_ULONGLONG
, "0"},
91 { "priority", PARAM_INT
, INVALID_PRIORITY
},
92 { "keepalive_interval", PARAM_INT
, DEFAULT_KEEPALIVE_INTERVAL
},
93 { "tcp_port", PARAM_INT
, "6466"},
94 { "enable_tcp", PARAM_BOOL
, "false"},
95 { "tcp_require_key", PARAM_BOOL
, "false"},
96 { "tcp_wait", PARAM_INT
, "0"},
97 { "tcp_bind", PARAM_CHARP
, "any"},
98 { "tcp_interface", PARAM_CHARP
, NULL
},
99 { "tls_timeout", PARAM_INT
, "300"},
100 { "tls_cipher_suite", PARAM_CHARP
, "SECURE256:SECURE192:SECURE128:-VERS-SSL3.0:-VERS-TLS1.0"},
101 { "tls_dh_level", PARAM_CHARP
, "medium"},
102 { "pinentry_path", PARAM_CHARP
, PINENTRY_PATH
},
103 { "pinentry_timeout", PARAM_INT
, DEFAULT_PINENTRY_TIMEOUT
},
104 { "use_agent", PARAM_BOOL
, "false"},
105 { "require_save_key", PARAM_BOOL
, "true"},
106 { "invoking_user", PARAM_CHARPP
, NULL
},
107 { "invoking_file", PARAM_CHARP
, NULL
},
108 { "strict_kill", PARAM_BOOL
, "false"},
109 { "lock_timeout", PARAM_INT
, DEFAULT_LOCK_TIMEOUT
},
110 { "send_state", PARAM_INT
, "2"},
111 { NULL
, PARAM_INVALID
, NULL
},
114 struct config_param_s
125 unsigned long ultype
;
126 unsigned long long ulltype
;
137 static struct config_section_s
*config_find_section (struct slist_s
*config
,
139 static int new_param (struct config_section_s
*section
, const char *filename
,
140 int lineno
, const char *name
, const char *value
,
142 static void free_section (struct config_section_s
*s
);
143 static int set_defaults (struct slist_s
**config
, int reload
);
146 section_remove_param (struct config_section_s
*section
, const char *name
)
148 unsigned i
, t
= slist_length (section
->params
);
150 for (i
= 0; i
< t
; i
++)
152 struct config_param_s
*p
= slist_nth_data (section
->params
, i
);
157 if (!strcmp (p
->name
, name
))
162 xfree (p
->value
.cptype
);
165 strv_free (p
->value
.cpptype
);
169 section
->params
= slist_remove (section
->params
, p
);
180 MUTEX_LOCK (&rcfile_mutex
);
181 unsigned i
, t
= slist_length (global_config
);
183 for (i
= 0; i
< t
; i
++)
185 struct config_section_s
*s
= slist_nth_data (global_config
, i
);
189 section_remove_param (s
, "passphrase");
192 MUTEX_UNLOCK (&rcfile_mutex
);
195 static struct config_param_s
*
196 config_has_param (struct config_section_s
*s
, const char *what
)
198 unsigned i
, t
= slist_length (s
->params
);
200 for (i
= 0; i
< t
; i
++)
202 struct config_param_s
*p
= slist_nth_data (s
->params
, i
);
206 if (!strcmp (p
->name
, what
))
213 static struct config_param_s
*
214 config_get_param (struct slist_s
*config
,
215 const char *section
, const char *what
, int *exists
)
217 unsigned i
, t
= slist_length (config
);
221 for (i
= 0; i
< t
; i
++)
223 struct config_param_s
*p
;
224 struct config_section_s
*s
= slist_nth_data (config
, i
);
229 if (strcmp (s
->name
, section
))
232 p
= config_has_param (s
, what
);
243 static struct config_section_s
*
244 new_section (struct slist_s
**config
, const char *name
)
247 struct config_section_s
*s
= xcalloc (1, sizeof (struct config_section_s
));
252 s
->name
= str_dup (name
);
255 log_write ("%s", pwmd_strerror (ENOMEM
));
260 tmp
= slist_append (*config
, s
);
263 log_write ("%s", pwmd_strerror (ENOMEM
));
274 config_set_string_param (struct slist_s
**config
, const char *section
,
275 const char *name
, const char *value
)
277 struct config_section_s
*s
= config_find_section (*config
, section
);
281 s
= new_section (config
, section
);
286 return new_param (s
, NULL
, 0, name
, value
, PARAM_CHARP
);
290 config_get_string_param (struct slist_s
*config
, const char *section
,
291 const char *what
, int *exists
)
293 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
294 return *exists
&& p
->value
.cptype
? str_dup (p
->value
.cptype
) : NULL
;
298 config_set_int_param (struct slist_s
**config
, const char *section
,
299 const char *name
, const char *value
)
301 struct config_section_s
*s
= config_find_section (*config
, section
);
305 s
= new_section (config
, section
);
310 return new_param (s
, NULL
, 0, name
, value
, PARAM_INT
);
314 config_get_int_param (struct slist_s
*config
, const char *section
,
315 const char *what
, int *exists
)
317 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
318 return *exists
? p
->value
.itype
: -1;
322 config_set_bool_param (struct slist_s
**config
, const char *section
,
323 const char *name
, const char *value
)
325 struct config_section_s
*s
= config_find_section (*config
, section
);
329 s
= new_section (config
, section
);
334 return new_param (s
, NULL
, 0, name
, value
, PARAM_BOOL
);
338 config_get_bool_param (struct slist_s
*config
, const char *section
,
339 const char *what
, int *exists
)
341 return config_get_int_param (config
, section
, what
, exists
);
345 config_set_long_param (struct slist_s
**config
, const char *section
,
346 const char *name
, const char *value
)
348 struct config_section_s
*s
= config_find_section (*config
, section
);
352 s
= new_section (config
, section
);
357 return new_param (s
, NULL
, 0, name
, value
, PARAM_LONG
);
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_ulonglong_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_ULONGLONG
);
385 config_get_ulonglong_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
.ulltype
: -1;
393 config_set_list_param (struct slist_s
**config
, const char *section
,
394 const char *name
, const char *value
)
396 struct config_section_s
*s
= config_find_section (*config
, section
);
400 s
= new_section (config
, section
);
405 return new_param (s
, NULL
, 0, name
, value
, PARAM_CHARPP
);
409 config_get_list_param (struct slist_s
*config
, const char *section
,
410 const char *what
, int *exists
)
412 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
413 return *exists
&& p
->value
.cpptype
? strv_dup (p
->value
.cpptype
) : NULL
;
417 config_get_string (const char *section
, const char *what
)
420 const char *where
= section
? section
: "global";
423 MUTEX_LOCK (&rcfile_mutex
);
424 val
= config_get_string_param (global_config
, where
, what
, &exists
);
425 if (!exists
&& strcmp (section
? section
: "", "global"))
426 val
= config_get_string_param (global_config
, "global", what
, &exists
);
428 MUTEX_UNLOCK (&rcfile_mutex
);
433 config_get_list (const char *section
, const char *what
)
436 const char *where
= section
? section
: "global";
439 MUTEX_LOCK (&rcfile_mutex
);
440 val
= config_get_list_param (global_config
, where
, what
, &exists
);
441 if (!exists
&& strcmp (section
? section
: "", "global"))
442 val
= config_get_list_param (global_config
, "global", what
, &exists
);
444 MUTEX_UNLOCK (&rcfile_mutex
);
449 config_get_integer (const char *section
, const char *what
)
452 const char *where
= section
? section
: "global";
455 MUTEX_LOCK (&rcfile_mutex
);
456 val
= config_get_int_param (global_config
, where
, what
, &exists
);
457 if (!exists
&& strcmp (section
? section
: "", "global"))
458 val
= config_get_int_param (global_config
, "global", what
, &exists
);
460 MUTEX_UNLOCK (&rcfile_mutex
);
465 config_get_ulonglong (const char *section
, const char *what
)
467 unsigned long long val
= 0;
468 const char *where
= section
? section
: "global";
471 MUTEX_LOCK (&rcfile_mutex
);
472 val
= config_get_ulonglong_param (global_config
, where
, what
, &exists
);
473 if (!exists
&& strcmp (section
? section
: "", "global"))
474 val
= config_get_ulonglong_param (global_config
, "global", what
, &exists
);
476 MUTEX_UNLOCK (&rcfile_mutex
);
481 config_get_long (const char *section
, const char *what
)
484 const char *where
= section
? section
: "global";
487 MUTEX_LOCK (&rcfile_mutex
);
488 val
= config_get_long_param (global_config
, where
, what
, &exists
);
489 if (!exists
&& strcmp (section
? section
: "", "global"))
490 val
= config_get_long_param (global_config
, "global", what
, &exists
);
492 MUTEX_UNLOCK (&rcfile_mutex
);
497 config_get_boolean (const char *section
, const char *what
)
499 return config_get_integer (section
, what
);
503 config_get_value (const char *section
, const char *what
)
505 const char *where
= section
? section
: "global";
510 unsigned long long ullval
;
515 MUTEX_LOCK (&rcfile_mutex
);
517 for (i
= 0; config_params
[i
].name
; i
++)
519 if (!strcmp (config_params
[i
].name
, what
))
521 switch (config_params
[i
].type
)
525 ival
= config_get_int_param (global_config
, where
, what
,
527 if (!exists
&& strcmp (section
? section
: "", "global"))
528 ival
= config_get_int_param (global_config
, "global", what
,
530 result
= str_asprintf ("%i", ival
);
533 cpval
= config_get_string_param (global_config
, where
, what
,
535 if (!exists
&& strcmp (section
? section
: "", "global"))
537 config_get_string_param (global_config
, "global", what
,
542 lval
= config_get_long_param (global_config
, where
, what
,
544 if (!exists
&& strcmp (section
? section
: "", "global"))
545 lval
= config_get_long_param (global_config
, "global", what
,
547 result
= str_asprintf ("%li", lval
);
549 case PARAM_ULONGLONG
:
550 ullval
= config_get_ulonglong_param (global_config
, where
, what
,
552 if (!exists
&& strcmp (section
? section
: "", "global"))
553 ullval
= config_get_ulonglong_param (global_config
, "global",
555 result
= str_asprintf ("%llu", ullval
);
558 cppval
= config_get_list_param (global_config
, where
, what
,
560 if (!exists
&& strcmp (section
? section
: "", "global"))
561 cppval
= config_get_list_param (global_config
, "global", what
,
565 result
= strv_join (",", cppval
);
573 MUTEX_UNLOCK (&rcfile_mutex
);
577 /* 'file' is the list parameter file to load into the list parameter 'what'.
578 * The parsing of the parameter is not done here. */
580 parse_list_file (struct slist_s
*config
, const char *section
,
581 const char *file
, const char *what
)
588 char *p
= config_get_string_param (config
, section
, file
, &exists
);
597 tmp
= expand_homedir (p
);
603 rc
= gpg_error_from_errno (errno
);
604 log_write ("%s: %s", p
, pwmd_strerror (rc
));
610 list
= config_get_list_param (config
, section
, what
, &exists
);
614 log_write ("%s", pwmd_strerror (ENOMEM
));
615 return gpg_error (ENOMEM
);
618 while ((p
= fgets (buf
, sizeof (buf
), fp
)))
622 if (!*p
|| *p
== ';')
625 if (p
[strlen(p
)-1] == '\n')
628 while (*p
&& isspace (*p
))
636 pp
= strv_cat (list
, str_dup (p
));
643 log_write ("%s", strerror (ENOMEM
));
644 return gpg_error (ENOMEM
);
655 p
= strv_join (",", list
);
660 log_write ("%s", pwmd_strerror (ENOMEM
));
661 return gpg_error (ENOMEM
);
664 config_set_list_param (&config
, section
, what
, p
);
670 fixup_allowed_once (struct slist_s
**config
, const char *section
)
672 char **list
, **pp
, *p
;
676 rc
= parse_list_file (*config
, section
, "allowed_file", "allowed");
680 list
= config_get_list_param (*config
, section
, "allowed", &exists
);
681 for (pp
= list
; pp
&& *pp
; pp
++)
685 for (p
= *pp
; p
&& *p
; p
++)
693 if (!strcmp (section
, "global"))
695 p
= get_username (getuid());
697 if (config_set_list_param (config
, section
, "allowed", p
))
707 list
= config_get_list_param (*config
, "global", "allowed", &exists
);
710 p
= strv_join (",", list
);
712 if (config_set_list_param (config
, section
, "allowed", p
))
727 fixup_allowed (struct slist_s
**config
)
729 int n
, t
= slist_length (*config
);
731 for (n
= 0; n
< t
; n
++)
733 struct config_section_s
*section
;
735 section
= slist_nth_data (*config
, n
);
736 if (fixup_allowed_once (config
, section
->name
))
744 add_invoking_user (struct invoking_user_s
**users
, char *id
,
745 struct slist_s
**config
)
747 struct passwd
*pwd
= NULL
;
748 struct group
*grp
= NULL
;
749 struct invoking_user_s
*user
, *p
;
752 if (id
&& (*id
== '!' || *id
== '-'))
761 pwd
= getpwuid (getuid ());
764 log_write (_("could not set any invoking user: %s"),
765 pwmd_strerror (errno
));
771 grp
= getgrnam (id
+1);
774 log_write (_("could not parse group '%s': %s"), id
+1,
775 pwmd_strerror (errno
));
782 if (!grp
&& !pwd
&& id
&& *id
!= '#')
785 log_write (_("could not set invoking user '%s': %s"), id
,
786 pwmd_strerror (errno
));
788 log_write (_("could not set any invoking user!"));
793 user
= xcalloc (1, sizeof (struct invoking_user_s
));
796 log_write ("%s", pwmd_strerror (ENOMEM
));
801 user
->type
= pwd
? INVOKING_UID
: grp
? INVOKING_GID
: INVOKING_TLS
;
803 user
->uid
= pwd
->pw_uid
;
805 user
->id
= str_dup (id
+1);
810 for (s
= id
; s
&& *s
; s
++)
813 user
->id
= str_dup (id
+1);
816 /* Set the default invoking_user since it doesn't exist. */
818 config_set_list_param (config
, "global", "invoking_user", pwd
->pw_name
);
826 for (p
= *users
; p
; p
= p
->next
)
839 parse_invoking_users (struct slist_s
**config
)
841 struct invoking_user_s
*users
= NULL
;
845 if (parse_list_file (*config
, "global", "invoking_file", "invoking_user"))
848 list
= config_get_list_param(*config
, "global", "invoking_user", &exists
);
849 for (l
= list
; l
&& *l
; l
++)
851 if (add_invoking_user (&users
, *l
, config
))
854 free_invoking_users (users
);
861 if (add_invoking_user (&users
, NULL
, config
))
870 free_invoking_users (invoking_users
);
871 invoking_users
= users
;
876 set_defaults (struct slist_s
**config
, int reload
)
878 char *s
= NULL
, *tmp
;
883 for (i
= 0; config_params
[i
].name
; i
++)
885 switch (config_params
[i
].type
)
888 config_get_bool_param (*config
, "global", config_params
[i
].name
,
892 if (config_set_bool_param
893 (config
, "global", config_params
[i
].name
,
894 config_params
[i
].value
))
899 config_get_int_param (*config
, "global", config_params
[i
].name
,
903 if (config_set_int_param
904 (config
, "global", config_params
[i
].name
,
905 config_params
[i
].value
))
910 s
= config_get_string_param (*config
, "global",
911 config_params
[i
].name
, &exists
);
913 if (!exists
&& config_params
[i
].value
)
915 if (config_set_string_param (config
, "global",
916 config_params
[i
].name
,
917 config_params
[i
].value
))
922 list
= config_get_list_param (*config
, "global",
923 config_params
[i
].name
, &exists
);
925 if (!exists
&& config_params
[i
].value
)
927 if (config_set_list_param (config
, "global",
928 config_params
[i
].name
,
929 config_params
[i
].value
))
934 config_get_long_param (*config
, "global", config_params
[i
].name
,
938 if (config_set_long_param
939 (config
, "global", config_params
[i
].name
,
940 config_params
[i
].value
))
944 case PARAM_ULONGLONG
:
945 config_get_ulonglong_param (*config
, "global", config_params
[i
].name
,
949 if (config_set_ulonglong_param (config
, "global",
950 config_params
[i
].name
,
951 config_params
[i
].value
))
959 if (!reload
&& fixup_allowed (config
))
962 if (!reload
&& parse_invoking_users (config
))
965 s
= config_get_string_param(*config
, "global", "gpg_agent_socket", &exists
);
969 s
= str_asprintf ("%s/.gnupg/S.gpg-agent", get_home_dir());
970 config_set_string_param(config
, "global", "gpg_agent_socket", s
);
974 tmp
= expand_homedir (s
);
975 config_set_string_param(config
, "global", "gpg_agent_socket", tmp
);
979 log_level
= config_get_int_param (*config
, "global",
980 "log_level", &exists
);
981 log_keepopen
= config_get_int_param (*config
, "global",
982 "log_keepopen", &exists
);
983 max_recursion_depth
= config_get_int_param (*config
, "global",
984 "recursion_depth", &exists
);
985 disable_list_and_dump
= config_get_bool_param (*config
, "global",
986 "disable_list_and_dump",
990 config_get_bool_param (*config
, "global", "disable_mlockall", &exists
);
1001 static struct config_section_s
*
1002 config_find_section (struct slist_s
*config
, const char *name
)
1004 unsigned i
, t
= slist_length (config
);
1006 for (i
= 0; i
< t
; i
++)
1008 struct config_section_s
*s
= slist_nth_data (config
, i
);
1010 if (!strcmp (s
->name
, name
))
1017 /* Append a new parameter to the list of parameters for a file
1018 * section. When an existing parameter of the same name exists, its
1022 new_param (struct config_section_s
*section
, const char *filename
, int lineno
,
1023 const char *name
, const char *value
, int type
)
1025 struct config_param_s
*param
= NULL
;
1026 struct slist_s
*tmp
;
1028 unsigned i
, t
= slist_length (section
->params
);
1031 for (i
= 0; i
< t
; i
++)
1033 struct config_param_s
*p
= slist_nth_data (section
->params
, i
);
1037 if (!strcmp (name
, p
->name
))
1047 param
= xcalloc (1, sizeof (struct config_param_s
));
1050 log_write ("%s", pwmd_strerror (ENOMEM
));
1054 param
->name
= str_dup (name
);
1058 log_write ("%s", pwmd_strerror (ENOMEM
));
1068 if (!strcasecmp (value
, "no") || !strcasecmp (value
, "0")
1069 || !strcasecmp (value
, "false"))
1070 param
->value
.itype
= 0;
1071 else if (!strcasecmp (value
, "yes") || !strcasecmp (value
, "1")
1072 || !strcasecmp (value
, "true"))
1073 param
->value
.itype
= 1;
1076 INVALID_VALUE (filename
, lineno
);
1079 param
->type
= PARAM_INT
;
1082 xfree (param
->value
.cptype
);
1083 param
->value
.cptype
= NULL
;
1084 param
->value
.cptype
= value
&& *value
? str_dup (value
) : NULL
;
1085 if (value
&& *value
&& !param
->value
.cptype
)
1087 log_write ("%s", pwmd_strerror (ENOMEM
));
1092 strv_free (param
->value
.cpptype
);
1093 param
->value
.cpptype
= NULL
;
1094 param
->value
.cpptype
= value
&& *value
?
1095 str_split_ws (value
, ",", 0) : NULL
;
1096 if (value
&& *value
&& !param
->value
.cpptype
)
1098 log_write ("%s", pwmd_strerror (ENOMEM
));
1103 param
->value
.itype
= strtol (value
, &e
, 10);
1106 INVALID_VALUE (filename
, lineno
);
1111 param
->value
.ltype
= strtol (value
, &e
, 10);
1114 INVALID_VALUE (filename
, lineno
);
1118 case PARAM_ULONGLONG
:
1119 param
->value
.ulltype
= strtoll (value
, &e
, 10);
1122 INVALID_VALUE (filename
, lineno
);
1131 tmp
= slist_append (section
->params
, param
);
1134 log_write ("%s", pwmd_strerror (ENOMEM
));
1138 section
->params
= tmp
;
1142 xfree (param
->name
);
1148 config_parse (const char *filename
, int reload
)
1150 struct slist_s
*tmpconfig
= NULL
, *tmp
;
1151 struct config_section_s
*cur_section
= NULL
;
1155 int have_global
= 0;
1156 FILE *fp
= fopen (filename
, "r");
1160 log_write ("%s: %s", filename
,
1161 pwmd_strerror (gpg_error_from_errno (errno
)));
1163 if (errno
!= ENOENT
)
1166 log_write (_("Using defaults!"));
1170 for (; (s
= fgets (buf
, sizeof (buf
), fp
)); lineno
++)
1172 char line
[LINE_MAX
] = { 0 };
1179 for (; s
&& *s
; s
++)
1183 /* New file section. */
1186 struct config_section_s
*section
;
1187 char *p
= strchr (++s
, ']');
1191 log_write (_("%s(%i): unbalanced braces"), filename
,
1196 len
= strlen (s
) - strlen (p
);
1197 memcpy (line
, s
, len
);
1200 section
= config_find_section (tmpconfig
, line
);
1203 log_write (_("%s(%i): section '%s' already exists!"),
1204 filename
, lineno
, line
);
1208 if (!strcmp (line
, "global"))
1211 section
= xcalloc (1, sizeof (struct config_section_s
));
1212 section
->name
= str_dup (line
);
1216 tmp
= slist_append (tmpconfig
, cur_section
);
1219 log_write ("%s", pwmd_strerror (ENOMEM
));
1226 cur_section
= section
;
1232 log_write (_("%s(%i): parameter outside of section!"), filename
,
1237 /* Parameters for each section. */
1238 for (int m
= 0; config_params
[m
].name
; m
++)
1240 size_t len
= strlen (config_params
[m
].name
);
1242 if (!strncmp (s
, config_params
[m
].name
, len
))
1246 while (*p
&& *p
== ' ')
1249 if (!*p
|| *p
!= '=')
1253 while (*p
&& isspace (*p
))
1257 if (new_param (cur_section
, filename
, lineno
, s
, p
,
1258 config_params
[m
].type
))
1268 log_write (_("%s(%i): unknown parameter"), filename
, lineno
);
1278 tmp
= slist_append (tmpconfig
, cur_section
);
1281 log_write ("%s", pwmd_strerror (ENOMEM
));
1291 ("WARNING: %s: could not find a [global] configuration section!"),
1296 char *tmp
= config_get_string_param (tmpconfig
, "global", "tls_dh_level",
1300 if (strcasecmp (tmp
, "low") && strcasecmp (tmp
, "medium")
1301 && strcasecmp (tmp
, "high"))
1304 log_write (_("invalid tls_dh_level value"));
1313 if (set_defaults (&tmpconfig
, reload
))
1325 config_free (tmpconfig
);
1326 free_section (cur_section
);
1331 free_section (struct config_section_s
*s
)
1338 struct config_param_s
*p
= slist_nth_data (s
->params
, 0);
1343 section_remove_param (s
, p
->name
);
1352 config_free (struct slist_s
*config
)
1356 struct config_section_s
*s
= slist_nth_data (config
, 0);
1361 config
= slist_remove (config
, s
);
1367 free_invoking_users (struct invoking_user_s
*users
)
1369 struct invoking_user_s
*p
;
1373 struct invoking_user_s
*next
= p
->next
;
1375 if (p
->type
== INVOKING_TLS
|| p
->type
== INVOKING_GID
)
1384 param_type (const char *name
)
1388 for (i
= 0; config_params
[i
].name
; i
++)
1390 if (!strcmp (config_params
[i
].name
, name
))
1391 return config_params
[i
].type
;
1394 return PARAM_INVALID
;
1398 keep_parse (struct config_keep_s
*k
, const char *section
, const char *key
)
1403 unsigned long long ullval
;
1406 int type
= param_type (key
);
1413 ival
= config_get_int_param (global_config
, section
, key
, &exists
);
1415 value
= str_asprintf ("%i", ival
);
1418 lval
= config_get_long_param (global_config
, section
, key
, &exists
);
1420 value
= str_asprintf ("%li", lval
);
1422 case PARAM_ULONGLONG
:
1423 ullval
= config_get_ulonglong_param (global_config
, section
, key
,
1426 value
= str_asprintf ("%llu", ullval
);
1429 cpval
= config_get_string_param (global_config
, section
, key
, &exists
);
1434 cppval
= config_get_list_param (global_config
, section
, key
, &exists
);
1437 char *s
= strv_join (",", cppval
);
1450 k
->section
= str_dup(section
);
1451 k
->name
= str_dup(key
);
1456 static struct slist_s
*
1457 keep_add (struct slist_s
*k
, const char *s
, const char *key
)
1459 int n
, t
= slist_length (global_config
);
1461 for (n
= 0; n
< t
; n
++)
1463 struct config_section_s
*section
;
1464 struct config_keep_s
*tmp
;
1467 section
= slist_nth_data (global_config
, n
);
1468 tmp
= xcalloc (1, sizeof(struct config_keep_s
));
1470 // Process all sections.
1472 ret
= keep_parse (tmp
, section
->name
, key
);
1474 ret
= keep_parse (tmp
, s
, key
);
1477 k
= slist_append (k
, tmp
);
1485 /* Keep security sensitive settings across SIGHUP. */
1489 struct slist_s
*keep
= NULL
;
1492 keep
= keep_add (keep
, NULL
, "tcp_require_key");
1494 keep
= keep_add (keep
, NULL
, "require_save_key");
1495 keep
= keep_add (keep
, NULL
, "allowed");
1496 keep
= keep_add (keep
, "global", "invoking_user");
1500 /* Restore parameters previously saved with config_keep_save(). This will also
1504 config_keep_restore (struct slist_s
*keep
)
1506 int n
, t
= slist_length (keep
);
1508 for (n
= 0; n
< t
; n
++)
1510 struct config_keep_s
*k
= slist_nth_data (keep
, n
);
1511 int type
= param_type (k
->name
);
1516 config_set_bool_param (&global_config
, k
->section
, k
->name
, k
->value
);
1519 config_set_int_param (&global_config
, k
->section
, k
->name
, k
->value
);
1522 config_set_long_param (&global_config
, k
->section
, k
->name
, k
->value
);
1524 case PARAM_ULONGLONG
:
1525 config_set_ulonglong_param (&global_config
, k
->section
, k
->name
,
1529 config_set_string_param (&global_config
, k
->section
, k
->name
,
1533 config_set_list_param (&global_config
, k
->section
, k
->name
, k
->value
);