2 Copyright (C) 2006-2021 Ben Kibbey <bjk@luxsci.net>
4 This file is part of pwmd.
6 Pwmd is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
10 Pwmd is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
24 #include <sys/types.h>
32 #include "pwmd-error.h"
35 #include "util-misc.h"
37 #include "util-slist.h"
38 #include "util-string.h"
47 int max_recursion_depth
;
48 int disable_list_and_dump
;
49 struct slist_s
*global_config
;
51 pthread_mutex_t rcfile_mutex
;
52 pthread_cond_t rcfile_cond
;
54 struct invoking_user_s
*invoking_users
;
58 #define DEFAULT_CACHE_TIMEOUT "600"
59 #define DEFAULT_KEEPALIVE_INTERVAL "60"
60 #define DEFAULT_LOCK_TIMEOUT "50" // MUTEX_TRYLOCK in tenths of a second
61 #define DEFAULT_BACKLOG "128"
62 #define DEFAULT_CIPHER_PRIORITY "SECURE256:SECURE192:SECURE128:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1:-AES-128-CBC:-AES-256-CBC"
64 #define INVALID_VALUE(file, line) do { \
66 log_write(_("%s(%i): invalid value for parameter."), file, line); \
71 PARAM_INT
, PARAM_CHARP
, PARAM_LONG
, PARAM_LONGLONG
, PARAM_CHARPP
,
72 PARAM_BOOL
, PARAM_INVALID
75 static struct config_params_s
81 { "backup", PARAM_BOOL
, "true"},
82 { "socket_path", PARAM_CHARP
, NULL
},
83 { "socket_perms", PARAM_CHARP
, NULL
},
84 { "backlog", PARAM_INT
, DEFAULT_BACKLOG
},
85 { "passphrase_file", PARAM_CHARP
, NULL
},
86 { "log_path", PARAM_CHARP
, "~/.pwmd/log"},
87 { "enable_logging", PARAM_BOOL
, "0"},
88 { "log_keepopen", PARAM_BOOL
, "true"},
89 { "log_level", PARAM_INT
, "0"},
90 { "disable_mlockall", PARAM_BOOL
, "true"},
91 { "cache_timeout", PARAM_LONG
, DEFAULT_CACHE_TIMEOUT
},
92 { "cache_push", PARAM_CHARPP
, NULL
},
93 { "disable_list_and_dump", PARAM_BOOL
, "false"},
94 { "recursion_depth", PARAM_INT
, "100"},
95 { "syslog", PARAM_BOOL
, "false"},
96 { "allowed", PARAM_CHARPP
, NULL
},
97 { "allowed_file", PARAM_CHARP
, NULL
},
98 { "priority", PARAM_INT
, INVALID_PRIORITY
},
99 { "keepalive_interval", PARAM_INT
, DEFAULT_KEEPALIVE_INTERVAL
},
100 { "tcp_port", PARAM_INT
, "6466"},
101 { "enable_tcp", PARAM_BOOL
, "false"},
102 { "tcp_require_key", PARAM_BOOL
, "false"},
103 { "tcp_bind", PARAM_CHARP
, "any"},
104 { "tcp_interface", PARAM_CHARP
, NULL
},
105 { "tls_timeout", PARAM_INT
, "300"},
106 { "tls_cipher_suite", PARAM_CHARP
, DEFAULT_CIPHER_PRIORITY
},
107 { "tls_dh_params_file", PARAM_CHARP
, NULL
},
108 { "tls_use_crl", PARAM_BOOL
, "false"},
109 { "tls_crl_file", PARAM_CHARP
, NULL
},
110 { "tls_ca_file", PARAM_CHARP
, NULL
},
111 { "tls_server_cert_file", PARAM_CHARP
, NULL
},
112 { "tls_server_key_file", PARAM_CHARP
, NULL
},
113 { "require_save_key", PARAM_BOOL
, "true"},
114 { "invoking_user", PARAM_CHARPP
, NULL
},
115 { "invoking_file", PARAM_CHARP
, NULL
},
116 { "encrypt_to", PARAM_BOOL
, "false"},
117 { "always_trust", PARAM_BOOL
, "false"},
118 { "gpg_homedir", PARAM_CHARP
, NULL
},
119 { "strict_kill", PARAM_BOOL
, "false"},
120 { "lock_timeout", PARAM_LONG
, DEFAULT_LOCK_TIMEOUT
},
121 { "kill_scd", PARAM_BOOL
, "false"},
122 { "strict_open", PARAM_BOOL
, "false"},
123 { NULL
, PARAM_INVALID
, NULL
},
126 struct config_param_s
147 static struct config_section_s
*config_find_section (struct slist_s
*config
,
149 static int new_param (struct config_section_s
*section
, const char *filename
,
150 int lineno
, const char *name
, const char *value
,
152 static void free_section (struct config_section_s
*s
);
153 static int set_defaults (struct slist_s
**config
, int reload
);
156 section_remove_param (struct config_section_s
*section
, const char *name
)
158 unsigned i
, t
= slist_length (section
->params
);
160 for (i
= 0; i
< t
; i
++)
162 struct config_param_s
*p
= slist_nth_data (section
->params
, i
);
167 if (!strcmp (p
->name
, name
))
172 xfree (p
->value
.cptype
);
175 strv_free (p
->value
.cpptype
);
179 section
->params
= slist_remove (section
->params
, p
);
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_long_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
.ltype
: -1;
361 config_set_longlong_param (struct slist_s
**config
, const char *section
,
362 const char *name
, const char *value
)
364 struct config_section_s
*s
= config_find_section (*config
, section
);
368 s
= new_section (config
, section
);
373 return new_param (s
, NULL
, 0, name
, value
, PARAM_LONGLONG
);
377 config_get_longlong_param (struct slist_s
*config
,
378 const char *section
, const char *what
, int *exists
)
380 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
381 return *exists
? p
->value
.lltype
: -1;
385 config_set_list_param (struct slist_s
**config
, const char *section
,
386 const char *name
, const char *value
)
388 struct config_section_s
*s
= config_find_section (*config
, section
);
392 s
= new_section (config
, section
);
397 return new_param (s
, NULL
, 0, name
, value
, PARAM_CHARPP
);
401 config_get_list_param (struct slist_s
*config
, const char *section
,
402 const char *what
, int *exists
)
404 struct config_param_s
*p
= config_get_param (config
, section
, what
, exists
);
405 return *exists
&& p
->value
.cpptype
? strv_dup (p
->value
.cpptype
) : NULL
;
409 config_get_string (const char *section
, const char *what
)
412 const char *where
= section
? section
: "global";
415 MUTEX_LOCK (&rcfile_mutex
);
416 val
= config_get_string_param (global_config
, where
, what
, &exists
);
417 if (!exists
&& strcmp (section
? section
: "", "global"))
418 val
= config_get_string_param (global_config
, "global", what
, &exists
);
420 MUTEX_UNLOCK (&rcfile_mutex
);
425 config_get_list (const char *section
, const char *what
)
428 const char *where
= section
? section
: "global";
431 MUTEX_LOCK (&rcfile_mutex
);
432 val
= config_get_list_param (global_config
, where
, what
, &exists
);
433 if (!exists
&& strcmp (section
? section
: "", "global"))
434 val
= config_get_list_param (global_config
, "global", what
, &exists
);
436 MUTEX_UNLOCK (&rcfile_mutex
);
441 config_get_integer (const char *section
, const char *what
)
444 const char *where
= section
? section
: "global";
447 MUTEX_LOCK (&rcfile_mutex
);
448 val
= config_get_int_param (global_config
, where
, what
, &exists
);
449 if (!exists
&& strcmp (section
? section
: "", "global"))
450 val
= config_get_int_param (global_config
, "global", what
, &exists
);
452 MUTEX_UNLOCK (&rcfile_mutex
);
457 config_get_longlong (const char *section
, const char *what
)
460 const char *where
= section
? section
: "global";
463 MUTEX_LOCK (&rcfile_mutex
);
464 val
= config_get_longlong_param (global_config
, where
, what
, &exists
);
465 if (!exists
&& strcmp (section
? section
: "", "global"))
466 val
= config_get_longlong_param (global_config
, "global", what
, &exists
);
468 MUTEX_UNLOCK (&rcfile_mutex
);
473 config_get_long (const char *section
, const char *what
)
476 const char *where
= section
? section
: "global";
479 MUTEX_LOCK (&rcfile_mutex
);
480 val
= config_get_long_param (global_config
, where
, what
, &exists
);
481 if (!exists
&& strcmp (section
? section
: "", "global"))
482 val
= config_get_long_param (global_config
, "global", what
, &exists
);
484 MUTEX_UNLOCK (&rcfile_mutex
);
489 config_get_boolean (const char *section
, const char *what
)
491 return config_get_integer (section
, what
);
495 config_get_value (const char *section
, const char *what
)
497 const char *where
= section
? section
: "global";
507 MUTEX_LOCK (&rcfile_mutex
);
509 for (i
= 0; config_params
[i
].name
; i
++)
511 if (!strcmp (config_params
[i
].name
, what
))
513 switch (config_params
[i
].type
)
517 ival
= config_get_int_param (global_config
, where
, what
,
519 if (!exists
&& strcmp (section
? section
: "", "global"))
520 ival
= config_get_int_param (global_config
, "global", what
,
522 result
= str_asprintf ("%i", ival
);
525 cpval
= config_get_string_param (global_config
, where
, what
,
527 if (!exists
&& strcmp (section
? section
: "", "global"))
529 config_get_string_param (global_config
, "global", what
,
534 lval
= config_get_long_param (global_config
, where
, what
,
536 if (!exists
&& strcmp (section
? section
: "", "global"))
537 lval
= config_get_long_param (global_config
, "global", what
,
539 result
= str_asprintf ("%li", lval
);
542 llval
= config_get_longlong_param (global_config
, where
, what
,
544 if (!exists
&& strcmp (section
? section
: "", "global"))
545 llval
= config_get_longlong_param (global_config
, "global",
547 result
= str_asprintf ("%lli", llval
);
550 cppval
= config_get_list_param (global_config
, where
, what
,
552 if (!exists
&& strcmp (section
? section
: "", "global"))
553 cppval
= config_get_list_param (global_config
, "global", what
,
557 result
= strv_join (",", cppval
);
565 MUTEX_UNLOCK (&rcfile_mutex
);
569 /* 'file' is the list parameter file to load into the list parameter 'what'.
570 * The parsing of the parameter is not done here. */
572 parse_list_file (struct slist_s
*config
, const char *section
,
573 const char *file
, const char *what
)
576 char buf
[LINE_MAX
] = {0};
580 char *p
= config_get_string_param (config
, section
, file
, &exists
);
589 tmp
= expand_homedir (p
);
595 rc
= gpg_error_from_errno (errno
);
596 log_write ("%s: %s", p
, pwmd_strerror (rc
));
602 list
= config_get_list_param (config
, section
, what
, &exists
);
606 log_write ("%s", pwmd_strerror (ENOMEM
));
607 return gpg_error (ENOMEM
);
610 while ((p
= fgets (buf
, sizeof (buf
)-1, fp
)))
614 if (p
[strlen(p
)-1] == '\n')
617 while (*p
&& isspace (*p
))
620 if (!*p
|| *p
== ';')
625 pp
= strv_cat (list
, str_dup (p
));
632 log_write ("%s", strerror (ENOMEM
));
633 return gpg_error (ENOMEM
);
644 p
= strv_join (",", list
);
649 log_write ("%s", pwmd_strerror (ENOMEM
));
650 return gpg_error (ENOMEM
);
653 config_set_list_param (&config
, section
, what
, p
);
659 fixup_allowed_once (struct slist_s
**config
, const char *section
)
661 char **list
, **pp
, *p
;
665 rc
= parse_list_file (*config
, section
, "allowed_file", "allowed");
669 list
= config_get_list_param (*config
, section
, "allowed", &exists
);
670 for (pp
= list
; pp
&& *pp
; pp
++)
674 for (p
= *pp
; p
&& *p
; p
++)
682 if (!strcmp (section
, "global"))
684 p
= get_username (getuid());
686 if (config_set_list_param (config
, section
, "allowed", p
))
696 list
= config_get_list_param (*config
, "global", "allowed", &exists
);
699 p
= strv_join (",", list
);
701 if (config_set_list_param (config
, section
, "allowed", p
))
716 fixup_allowed (struct slist_s
**config
)
718 int n
, t
= slist_length (*config
);
720 for (n
= 0; n
< t
; n
++)
722 struct config_section_s
*section
;
724 section
= slist_nth_data (*config
, n
);
725 if (fixup_allowed_once (config
, section
->name
))
733 add_invoking_user (struct invoking_user_s
**users
, char *id
,
734 struct slist_s
**config
)
736 struct passwd
*pwd
= NULL
;
737 struct group
*grp
= NULL
;
738 struct invoking_user_s
*user
, *p
;
741 if (id
&& (*id
== '!' || *id
== '-'))
750 pwd
= getpwuid (getuid ());
753 log_write (_("could not set any invoking user: %s"),
754 pwmd_strerror (errno
? errno
: GPG_ERR_INV_VALUE
));
760 grp
= getgrnam (id
+1);
763 log_write (_("could not parse group '%s': %s"), id
+1,
764 pwmd_strerror (errno
? errno
: GPG_ERR_INV_VALUE
));
771 if (!grp
&& !pwd
&& id
&& *id
!= '#')
774 log_write (_("could not set invoking user '%s': %s"), id
,
775 pwmd_strerror (errno
? errno
: GPG_ERR_INV_VALUE
));
777 log_write (_("could not set any invoking user!"));
782 user
= xcalloc (1, sizeof (struct invoking_user_s
));
785 log_write ("%s", pwmd_strerror (ENOMEM
));
790 user
->type
= pwd
? INVOKING_UID
: grp
? INVOKING_GID
: INVOKING_TLS
;
792 user
->uid
= pwd
->pw_uid
;
794 user
->id
= str_dup (id
+1);
799 for (s
= id
; s
&& *s
; s
++)
802 user
->id
= str_dup (id
+1);
805 /* Set the default invoking_user since it doesn't exist. */
806 if (pwd
&& (!id
|| !*id
))
807 config_set_list_param (config
, "global", "invoking_user", pwd
->pw_name
);
815 for (p
= *users
; p
; p
= p
->next
)
828 parse_invoking_users (struct slist_s
**config
)
830 struct invoking_user_s
*users
= NULL
;
834 if (parse_list_file (*config
, "global", "invoking_file", "invoking_user"))
837 list
= config_get_list_param (*config
, "global", "invoking_user", &exists
);
838 for (l
= list
; l
&& *l
; l
++)
840 if (add_invoking_user (&users
, *l
, config
))
843 free_invoking_users (users
);
850 config_set_list_param (config
, "global", "invoking_user", DEFAULT_INVOKER
);
851 if (add_invoking_user (&users
, (char *)DEFAULT_INVOKER
, config
))
858 free_invoking_users (invoking_users
);
859 invoking_users
= users
;
865 set_defaults (struct slist_s
**config
, int reload
)
872 for (i
= 0; config_params
[i
].name
; i
++)
874 switch (config_params
[i
].type
)
877 config_get_bool_param (*config
, "global", config_params
[i
].name
,
881 if (config_set_bool_param
882 (config
, "global", config_params
[i
].name
,
883 config_params
[i
].value
))
888 config_get_int_param (*config
, "global", config_params
[i
].name
,
892 if (config_set_int_param
893 (config
, "global", config_params
[i
].name
,
894 config_params
[i
].value
))
899 s
= config_get_string_param (*config
, "global",
900 config_params
[i
].name
, &exists
);
902 if (!exists
&& config_params
[i
].value
)
904 if (config_set_string_param (config
, "global",
905 config_params
[i
].name
,
906 config_params
[i
].value
))
911 list
= config_get_list_param (*config
, "global",
912 config_params
[i
].name
, &exists
);
914 if (!exists
&& config_params
[i
].value
)
916 if (config_set_list_param (config
, "global",
917 config_params
[i
].name
,
918 config_params
[i
].value
))
923 config_get_long_param (*config
, "global", config_params
[i
].name
,
927 if (config_set_long_param
928 (config
, "global", config_params
[i
].name
,
929 config_params
[i
].value
))
934 config_get_longlong_param (*config
, "global", config_params
[i
].name
,
938 if (config_set_longlong_param (config
, "global",
939 config_params
[i
].name
,
940 config_params
[i
].value
))
948 if (!reload
&& fixup_allowed (config
))
951 if (!reload
&& parse_invoking_users (config
))
954 log_level
= config_get_int_param (*config
, "global",
955 "log_level", &exists
);
956 log_keepopen
= config_get_int_param (*config
, "global",
957 "log_keepopen", &exists
);
958 max_recursion_depth
= config_get_int_param (*config
, "global",
959 "recursion_depth", &exists
);
960 disable_list_and_dump
= config_get_bool_param (*config
, "global",
961 "disable_list_and_dump",
965 config_get_bool_param (*config
, "global", "disable_mlockall", &exists
);
976 static struct config_section_s
*
977 config_find_section (struct slist_s
*config
, const char *name
)
979 unsigned i
, t
= slist_length (config
);
981 for (i
= 0; i
< t
; i
++)
983 struct config_section_s
*s
= slist_nth_data (config
, i
);
985 if (!strcmp (s
->name
, name
))
992 /* Append a new parameter to the list of parameters for a file
993 * section. When an existing parameter of the same name exists, its
997 new_param (struct config_section_s
*section
, const char *filename
, int lineno
,
998 const char *name
, const char *value
, int type
)
1000 struct config_param_s
*param
= NULL
;
1001 struct slist_s
*tmp
;
1003 unsigned i
, t
= slist_length (section
->params
);
1006 for (i
= 0; i
< t
; i
++)
1008 struct config_param_s
*p
= slist_nth_data (section
->params
, i
);
1012 if (!strcmp (name
, p
->name
))
1022 param
= xcalloc (1, sizeof (struct config_param_s
));
1025 log_write ("%s", pwmd_strerror (ENOMEM
));
1029 param
->name
= str_dup (name
);
1033 log_write ("%s", pwmd_strerror (ENOMEM
));
1043 if (!strcasecmp (value
, "no") || !strcasecmp (value
, "0")
1044 || !strcasecmp (value
, "false"))
1045 param
->value
.itype
= 0;
1046 else if (!strcasecmp (value
, "yes") || !strcasecmp (value
, "1")
1047 || !strcasecmp (value
, "true"))
1048 param
->value
.itype
= 1;
1051 INVALID_VALUE (filename
, lineno
);
1054 param
->type
= PARAM_INT
;
1057 xfree (param
->value
.cptype
);
1058 param
->value
.cptype
= NULL
;
1059 param
->value
.cptype
= value
&& *value
? str_dup (value
) : NULL
;
1060 if (value
&& *value
&& !param
->value
.cptype
)
1062 log_write ("%s", pwmd_strerror (ENOMEM
));
1067 strv_free (param
->value
.cpptype
);
1068 param
->value
.cpptype
= NULL
;
1069 param
->value
.cpptype
= value
&& *value
?
1070 str_split_ws (value
, ",", 0) : NULL
;
1071 if (value
&& *value
&& !param
->value
.cpptype
)
1073 log_write ("%s", pwmd_strerror (ENOMEM
));
1078 param
->value
.itype
= strtol (value
, &e
, 10);
1081 INVALID_VALUE (filename
, lineno
);
1086 param
->value
.ltype
= strtol (value
, &e
, 10);
1089 INVALID_VALUE (filename
, lineno
);
1093 case PARAM_LONGLONG
:
1094 param
->value
.lltype
= strtoll (value
, &e
, 10);
1097 INVALID_VALUE (filename
, lineno
);
1106 tmp
= slist_append (section
->params
, param
);
1109 log_write ("%s", pwmd_strerror (ENOMEM
));
1113 section
->params
= tmp
;
1117 xfree (param
->name
);
1123 config_parse (const char *filename
, int reload
)
1125 struct slist_s
*tmpconfig
= NULL
, *tmp
;
1126 struct config_section_s
*cur_section
= NULL
;
1127 char buf
[LINE_MAX
] = {0};
1130 int have_global
= 0;
1131 FILE *fp
= fopen (filename
, "r");
1135 log_write ("%s: %s", filename
,
1136 pwmd_strerror (gpg_error_from_errno (errno
)));
1138 if (errno
!= ENOENT
)
1141 log_write (_("Using defaults!"));
1145 for (; (s
= fgets (buf
, sizeof (buf
), fp
)); lineno
++)
1147 char line
[LINE_MAX
] = { 0 };
1158 /* New file section. */
1161 struct config_section_s
*section
;
1162 char *p
= strchr (++s
, ']');
1166 log_write (_("%s(%i): unbalanced braces"), filename
, lineno
);
1172 log_write (_("%s(%i): trailing characters"), filename
, lineno
);
1176 len
= strlen (s
) - strlen (p
);
1177 memcpy (line
, s
, len
);
1180 section
= config_find_section (tmpconfig
, line
);
1183 log_write (_("%s(%i): section '%s' already exists!"),
1184 filename
, lineno
, line
);
1188 if (!strcmp (line
, "global"))
1191 section
= xcalloc (1, sizeof (struct config_section_s
));
1192 section
->name
= str_dup (line
);
1196 tmp
= slist_append (tmpconfig
, cur_section
);
1199 log_write ("%s", pwmd_strerror (ENOMEM
));
1206 cur_section
= section
;
1212 log_write (_("%s(%i): parameter outside of section!"), filename
,
1217 /* Parameters for each section. */
1218 for (int m
= 0; config_params
[m
].name
; m
++)
1220 len
= strlen (config_params
[m
].name
);
1221 if (!strncmp (s
, config_params
[m
].name
, len
))
1225 while (*p
&& *p
== ' ')
1228 if (!*p
|| *p
!= '=')
1232 while (*p
&& isspace (*p
))
1236 if (new_param (cur_section
, filename
, lineno
, s
, p
,
1237 config_params
[m
].type
))
1247 log_write (_("%s(%i): unknown parameter"), filename
, lineno
);
1254 tmp
= slist_append (tmpconfig
, cur_section
);
1257 log_write ("%s", pwmd_strerror (ENOMEM
));
1267 ("WARNING: %s: could not find a [global] configuration section!"),
1271 if (set_defaults (&tmpconfig
, reload
))
1283 config_free (tmpconfig
);
1284 free_section (cur_section
);
1289 free_section (struct config_section_s
*s
)
1296 struct config_param_s
*p
= slist_nth_data (s
->params
, 0);
1301 section_remove_param (s
, p
->name
);
1310 config_free (struct slist_s
*config
)
1314 struct config_section_s
*s
= slist_nth_data (config
, 0);
1319 config
= slist_remove (config
, s
);
1325 free_invoking_users (struct invoking_user_s
*users
)
1327 struct invoking_user_s
*p
;
1331 struct invoking_user_s
*next
= p
->next
;
1333 if (p
->type
== INVOKING_TLS
|| p
->type
== INVOKING_GID
)
1342 param_type (const char *name
)
1346 for (i
= 0; config_params
[i
].name
; i
++)
1348 if (!strcmp (config_params
[i
].name
, name
))
1349 return config_params
[i
].type
;
1352 return PARAM_INVALID
;
1356 keep_parse (struct config_keep_s
*k
, const char *section
, const char *key
)
1364 int type
= param_type (key
);
1371 ival
= config_get_int_param (global_config
, section
, key
, &exists
);
1373 value
= str_asprintf ("%i", ival
);
1376 lval
= config_get_long_param (global_config
, section
, key
, &exists
);
1378 value
= str_asprintf ("%li", lval
);
1380 case PARAM_LONGLONG
:
1381 llval
= config_get_longlong_param (global_config
, section
, key
, &exists
);
1383 value
= str_asprintf ("%lli", llval
);
1386 cpval
= config_get_string_param (global_config
, section
, key
, &exists
);
1391 cppval
= config_get_list_param (global_config
, section
, key
, &exists
);
1394 char *s
= strv_join (",", cppval
);
1407 k
->section
= str_dup(section
);
1408 k
->name
= str_dup(key
);
1413 static struct slist_s
*
1414 keep_add (struct slist_s
*k
, const char *s
, const char *key
)
1416 int n
, t
= slist_length (global_config
);
1418 for (n
= 0; n
< t
; n
++)
1420 struct config_section_s
*section
;
1421 struct config_keep_s
*tmp
;
1424 section
= slist_nth_data (global_config
, n
);
1425 tmp
= xcalloc (1, sizeof(struct config_keep_s
));
1427 // Process all sections.
1429 ret
= keep_parse (tmp
, section
->name
, key
);
1431 ret
= keep_parse (tmp
, s
, key
);
1434 k
= slist_append (k
, tmp
);
1442 /* Keep security sensitive settings across SIGHUP. */
1446 struct slist_s
*keep
= NULL
;
1449 keep
= keep_add (keep
, NULL
, "tcp_require_key");
1451 keep
= keep_add (keep
, NULL
, "require_save_key");
1452 keep
= keep_add (keep
, NULL
, "allowed");
1453 keep
= keep_add (keep
, NULL
, "allowed_file");
1454 keep
= keep_add (keep
, "global", "encrypt_to");
1455 keep
= keep_add (keep
, "global", "always_trust");
1456 keep
= keep_add (keep
, "global", "invoking_user");
1457 keep
= keep_add (keep
, "global", "invoking_file");
1458 keep
= keep_add (keep
, "global", "gpg_homedir");
1462 /* Restore parameters previously saved with config_keep_save(). This will also
1466 config_keep_restore (struct slist_s
*keep
)
1468 int n
, t
= slist_length (keep
);
1470 for (n
= 0; n
< t
; n
++)
1472 struct config_keep_s
*k
= slist_nth_data (keep
, n
);
1473 int type
= param_type (k
->name
);
1478 config_set_bool_param (&global_config
, k
->section
, k
->name
, k
->value
);
1481 config_set_int_param (&global_config
, k
->section
, k
->name
, k
->value
);
1484 config_set_long_param (&global_config
, k
->section
, k
->name
, k
->value
);
1486 case PARAM_LONGLONG
:
1487 config_set_longlong_param (&global_config
, k
->section
, k
->name
,
1491 config_set_string_param (&global_config
, k
->section
, k
->name
,
1495 config_set_list_param (&global_config
, k
->section
, k
->name
, k
->value
);