/src/sudo/plugins/sudoers/locale.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * SPDX-License-Identifier: ISC |
3 | | * |
4 | | * Copyright (c) 2012-2016, 2020, 2022 Todd C. Miller <Todd.Miller@sudo.ws> |
5 | | * |
6 | | * Permission to use, copy, modify, and distribute this software for any |
7 | | * purpose with or without fee is hereby granted, provided that the above |
8 | | * copyright notice and this permission notice appear in all copies. |
9 | | * |
10 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 | | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 | | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 | | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 | | */ |
18 | | |
19 | | /* |
20 | | * This is an open source non-commercial project. Dear PVS-Studio, please check it. |
21 | | * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com |
22 | | */ |
23 | | |
24 | | #include <config.h> |
25 | | |
26 | | #include <stdio.h> |
27 | | #include <stdlib.h> |
28 | | #include <string.h> |
29 | | #ifdef HAVE_STDBOOL_H |
30 | | # include <stdbool.h> |
31 | | #else |
32 | | # include "compat/stdbool.h" |
33 | | #endif /* HAVE_STDBOOL_H */ |
34 | | |
35 | | #define DEFAULT_TEXT_DOMAIN "sudoers" |
36 | | |
37 | | #include "sudo_compat.h" |
38 | | #include "sudo_eventlog.h" |
39 | | #include "sudo_fatal.h" |
40 | | #include "sudo_gettext.h" |
41 | | #include "sudoers_debug.h" |
42 | | |
43 | | #include "defaults.h" |
44 | | #include "logging.h" |
45 | | |
46 | | static int current_locale = SUDOERS_LOCALE_USER; |
47 | | static char *user_locale; |
48 | | static char *sudoers_locale; |
49 | | |
50 | | int |
51 | | sudoers_getlocale(void) |
52 | 0 | { |
53 | 0 | debug_decl(sudoers_getlocale, SUDOERS_DEBUG_UTIL); |
54 | 0 | debug_return_int(current_locale); |
55 | 0 | } |
56 | | |
57 | | bool |
58 | | sudoers_initlocale(const char *ulocale, const char *slocale) |
59 | 59.4k | { |
60 | 59.4k | debug_decl(sudoers_initlocale, SUDOERS_DEBUG_UTIL); |
61 | | |
62 | 59.4k | if (ulocale != NULL) { |
63 | 21.8k | free(user_locale); |
64 | 21.8k | if ((user_locale = strdup(ulocale)) == NULL) |
65 | 0 | debug_return_bool(false); |
66 | 21.8k | } |
67 | 59.4k | if (slocale != NULL) { |
68 | 59.4k | free(sudoers_locale); |
69 | 59.4k | if ((sudoers_locale = strdup(slocale)) == NULL) |
70 | 0 | debug_return_bool(false); |
71 | 59.4k | } |
72 | 59.4k | sudo_debug_printf(SUDO_DEBUG_INFO, "%s: user locale %s, sudoers locale %s", |
73 | 59.4k | __func__, user_locale, sudoers_locale); |
74 | 59.4k | debug_return_bool(true); |
75 | 59.4k | } |
76 | | |
77 | | /* |
78 | | * Set locale to user or sudoers value. |
79 | | * Returns true on success and false on failure, |
80 | | * If prev_locale is non-NULL it will be filled in with the |
81 | | * old SUDOERS_LOCALE_* value. |
82 | | */ |
83 | | bool |
84 | | sudoers_setlocale(int locale_type, int *prev_locale) |
85 | 137k | { |
86 | 137k | char *res = NULL; |
87 | 137k | debug_decl(sudoers_setlocale, SUDOERS_DEBUG_UTIL); |
88 | | |
89 | 137k | switch (locale_type) { |
90 | 86.0k | case SUDOERS_LOCALE_USER: |
91 | 86.0k | if (prev_locale) |
92 | 17.3k | *prev_locale = current_locale; |
93 | 86.0k | if (current_locale != SUDOERS_LOCALE_USER) { |
94 | 51.4k | current_locale = SUDOERS_LOCALE_USER; |
95 | 51.4k | sudo_debug_printf(SUDO_DEBUG_DEBUG, |
96 | 51.4k | "%s: setting locale to %s (user)", __func__, |
97 | 51.4k | user_locale ? user_locale : ""); |
98 | 51.4k | res = setlocale(LC_ALL, user_locale ? user_locale : ""); |
99 | 51.4k | if (res != NULL && user_locale == NULL) { |
100 | 0 | user_locale = setlocale(LC_ALL, NULL); |
101 | 0 | if (user_locale != NULL) |
102 | 0 | user_locale = strdup(user_locale); |
103 | 0 | if (user_locale == NULL) |
104 | 0 | res = NULL; |
105 | 0 | } |
106 | 51.4k | } |
107 | 86.0k | break; |
108 | 51.4k | case SUDOERS_LOCALE_SUDOERS: |
109 | 51.4k | if (prev_locale) |
110 | 51.4k | *prev_locale = current_locale; |
111 | 51.4k | if (current_locale != SUDOERS_LOCALE_SUDOERS) { |
112 | 51.4k | current_locale = SUDOERS_LOCALE_SUDOERS; |
113 | 51.4k | sudo_debug_printf(SUDO_DEBUG_DEBUG, |
114 | 51.4k | "%s: setting locale to %s (sudoers)", __func__, |
115 | 51.4k | sudoers_locale ? sudoers_locale : "C"); |
116 | 51.4k | res = setlocale(LC_ALL, sudoers_locale ? sudoers_locale : "C"); |
117 | 51.4k | if (res == NULL && sudoers_locale != NULL) { |
118 | 0 | if (strcmp(sudoers_locale, "C") != 0) { |
119 | 0 | free(sudoers_locale); |
120 | 0 | sudoers_locale = strdup("C"); |
121 | 0 | if (sudoers_locale != NULL) |
122 | 0 | res = setlocale(LC_ALL, "C"); |
123 | 0 | } |
124 | 0 | } |
125 | 51.4k | } |
126 | 51.4k | break; |
127 | 137k | } |
128 | 137k | debug_return_bool(res ? true : false); |
129 | 137k | } |
130 | | |
131 | | bool |
132 | | sudoers_warn_setlocale(bool restore, int *cookie) |
133 | 34.6k | { |
134 | 34.6k | debug_decl(sudoers_warn_setlocale, SUDOERS_DEBUG_UTIL); |
135 | | |
136 | 34.6k | if (restore) |
137 | 17.3k | debug_return_bool(sudoers_setlocale(*cookie, NULL)); |
138 | 17.3k | debug_return_bool(sudoers_setlocale(SUDOERS_LOCALE_USER, cookie)); |
139 | 17.3k | } |
140 | | |
141 | | /* |
142 | | * Callback for sudoers_locale sudoers setting. |
143 | | */ |
144 | | bool |
145 | | sudoers_locale_callback(const char *file, int line, int column, |
146 | | const union sudo_defs_val *sd_un, int op) |
147 | 0 | { |
148 | 0 | debug_decl(sudoers_locale_callback, SUDOERS_DEBUG_UTIL); |
149 | |
|
150 | 0 | if (sudoers_initlocale(NULL, sd_un->str)) { |
151 | 0 | if (setlocale(LC_ALL, sd_un->str) != NULL) |
152 | 0 | debug_return_bool(true); |
153 | 0 | } |
154 | 0 | debug_return_bool(false); |
155 | 0 | } |