1 |
commit: 52f4dc6163ecbc334f9ba949d6436f650ecf138d |
2 |
Author: Alexandre Rostovtsev <tetromino <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Feb 6 10:19:08 2012 +0000 |
4 |
Commit: Alexandre Restovtsev <tetromino <AT> gmail <DOT> com> |
5 |
CommitDate: Mon Feb 6 10:19:08 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/openrc-settingsd.git;a=commit;h=52f4dc61 |
7 |
|
8 |
Check polkit authorization asynchronously |
9 |
|
10 |
The other alternative (spawning a thread for each authorization |
11 |
request) seems less elegant, since such requests can take arbitrarily |
12 |
long to complete. |
13 |
|
14 |
--- |
15 |
src/bus-utils.c | 137 +++++++++++++++++++++------- |
16 |
src/bus-utils.h | 13 ++- |
17 |
src/hostnamed.c | 275 ++++++++++++++++++++++++++++++++++++++----------------- |
18 |
3 files changed, 302 insertions(+), 123 deletions(-) |
19 |
|
20 |
diff --git a/src/bus-utils.c b/src/bus-utils.c |
21 |
index d3bc7b2..aef8037 100644 |
22 |
--- a/src/bus-utils.c |
23 |
+++ b/src/bus-utils.c |
24 |
@@ -20,44 +20,115 @@ |
25 |
#include <gio/gio.h> |
26 |
#include <polkit/polkit.h> |
27 |
|
28 |
+#include "bus-utils.h" |
29 |
+ |
30 |
+struct check_polkit_data { |
31 |
+ const gchar *unique_name; |
32 |
+ const gchar *action_id; |
33 |
+ gboolean user_interaction; |
34 |
+ GAsyncReadyCallback callback; |
35 |
+ gpointer user_data; |
36 |
+ |
37 |
+ PolkitAuthority *authority; |
38 |
+ PolkitSubject *subject; |
39 |
+}; |
40 |
+ |
41 |
+void |
42 |
+check_polkit_data_free (struct check_polkit_data *data) |
43 |
+{ |
44 |
+ if (data == NULL) |
45 |
+ return; |
46 |
+ |
47 |
+ if (data->subject != NULL) |
48 |
+ g_object_unref (data->subject); |
49 |
+ if (data->authority != NULL) |
50 |
+ g_object_unref (data->authority); |
51 |
+ |
52 |
+ g_free (data); |
53 |
+} |
54 |
+ |
55 |
gboolean |
56 |
-check_polkit (const gchar *unique_name, |
57 |
- const gchar *action_id, |
58 |
- const gboolean user_interaction, |
59 |
- GError **error) |
60 |
+check_polkit_finish (GAsyncResult *res, |
61 |
+ GError **error) |
62 |
{ |
63 |
- gboolean ret = FALSE; |
64 |
- GDBusConnection *connection = NULL; |
65 |
- PolkitAuthority *authority = NULL; |
66 |
- PolkitSubject *subject = NULL; |
67 |
- PolkitAuthorizationResult *result = NULL; |
68 |
- |
69 |
- if ((authority = polkit_authority_get_sync (NULL, error)) == NULL) |
70 |
- goto end; |
71 |
- |
72 |
- if (unique_name == NULL || action_id == NULL || |
73 |
- (subject = polkit_system_bus_name_new (unique_name)) == NULL) { |
74 |
- g_propagate_error (error, |
75 |
- g_error_new (POLKIT_ERROR, POLKIT_ERROR_FAILED, |
76 |
- "Authorizing for '%s': failed sanity check", action_id)); |
77 |
- goto end; |
78 |
- } |
79 |
+ GSimpleAsyncResult *simple; |
80 |
+ |
81 |
+ simple = G_SIMPLE_ASYNC_RESULT (res); |
82 |
+ if (g_simple_async_result_propagate_error (simple, error)) |
83 |
+ return FALSE; |
84 |
+ |
85 |
+ return g_simple_async_result_get_op_res_gboolean (simple); |
86 |
+} |
87 |
+ |
88 |
+static void |
89 |
+check_polkit_authorization_cb (GObject *source_object, |
90 |
+ GAsyncResult *res, |
91 |
+ gpointer _data) |
92 |
+{ |
93 |
+ struct check_polkit_data *data; |
94 |
+ PolkitAuthorizationResult *result; |
95 |
+ GSimpleAsyncResult *simple; |
96 |
+ GError *err = NULL; |
97 |
|
98 |
- if ((result = polkit_authority_check_authorization_sync (authority, subject, action_id, NULL, (PolkitCheckAuthorizationFlags) user_interaction, NULL, error)) == NULL) |
99 |
- goto end; |
100 |
+ data = (struct check_polkit_data *) _data; |
101 |
+ if ((result = polkit_authority_check_authorization_finish (data->authority, res, &err)) == NULL) { |
102 |
+ g_simple_async_report_take_gerror_in_idle (NULL, data->callback, data->user_data, err); |
103 |
+ goto out; |
104 |
+ } |
105 |
|
106 |
- if ((ret = polkit_authorization_result_get_is_authorized (result)) == FALSE) { |
107 |
- g_propagate_error (error, |
108 |
- g_error_new (POLKIT_ERROR, POLKIT_ERROR_NOT_AUTHORIZED, |
109 |
- "Authorizing for '%s': not authorized", action_id)); |
110 |
+ if (!polkit_authorization_result_get_is_authorized (result)) { |
111 |
+ g_simple_async_report_error_in_idle (NULL, data->callback, data->user_data, POLKIT_ERROR, POLKIT_ERROR_NOT_AUTHORIZED, "Authorizing for '%s': not authorized", data->action_id); |
112 |
+ goto out; |
113 |
} |
114 |
- |
115 |
- end: |
116 |
+ simple = g_simple_async_result_new (NULL, data->callback, data->user_data, check_polkit_async); |
117 |
+ g_simple_async_result_set_op_res_gboolean (simple, TRUE); |
118 |
+ g_simple_async_result_complete_in_idle (simple); |
119 |
+ g_object_unref (simple); |
120 |
+ |
121 |
+ out: |
122 |
+ check_polkit_data_free (data); |
123 |
if (result != NULL) |
124 |
g_object_unref (result); |
125 |
- if (subject != NULL) |
126 |
- g_object_unref (subject); |
127 |
- if (authority != NULL) |
128 |
- g_object_unref (authority); |
129 |
- return ret; |
130 |
+} |
131 |
+ |
132 |
+static void |
133 |
+check_polkit_authority_cb (GObject *source_object, |
134 |
+ GAsyncResult *res, |
135 |
+ gpointer _data) |
136 |
+{ |
137 |
+ struct check_polkit_data *data; |
138 |
+ GError *err = NULL; |
139 |
+ |
140 |
+ data = (struct check_polkit_data *) _data; |
141 |
+ if ((data->authority = polkit_authority_get_finish (res, &err)) == NULL) { |
142 |
+ g_simple_async_report_take_gerror_in_idle (NULL, data->callback, data->user_data, err); |
143 |
+ check_polkit_data_free (data); |
144 |
+ return; |
145 |
+ } |
146 |
+ if (data->unique_name == NULL || data->action_id == NULL || |
147 |
+ (data->subject = polkit_system_bus_name_new (data->unique_name)) == NULL) { |
148 |
+ g_simple_async_report_error_in_idle (NULL, data->callback, data->user_data, POLKIT_ERROR, POLKIT_ERROR_FAILED, "Authorizing for '%s': failed sanity check", data->action_id); |
149 |
+ check_polkit_data_free (data); |
150 |
+ return; |
151 |
+ } |
152 |
+ polkit_authority_check_authorization (data->authority, data->subject, data->action_id, NULL, (PolkitCheckAuthorizationFlags) data->user_interaction, NULL, check_polkit_authorization_cb, data); |
153 |
+} |
154 |
+ |
155 |
+void |
156 |
+check_polkit_async (const gchar *unique_name, |
157 |
+ const gchar *action_id, |
158 |
+ const gboolean user_interaction, |
159 |
+ GAsyncReadyCallback callback, |
160 |
+ gpointer user_data) |
161 |
+{ |
162 |
+ struct check_polkit_data *data; |
163 |
+ |
164 |
+ data = g_new0 (struct check_polkit_data, 1); |
165 |
+ data->unique_name = unique_name; |
166 |
+ data->action_id = action_id; |
167 |
+ data->user_interaction = user_interaction; |
168 |
+ data->callback = callback; |
169 |
+ data->user_data = user_data; |
170 |
+ |
171 |
+ polkit_authority_get_async (NULL, check_polkit_authority_cb, data); |
172 |
} |
173 |
\ No newline at end of file |
174 |
|
175 |
diff --git a/src/bus-utils.h b/src/bus-utils.h |
176 |
index 31a2ef1..f2e80ea 100644 |
177 |
--- a/src/bus-utils.h |
178 |
+++ b/src/bus-utils.h |
179 |
@@ -21,10 +21,15 @@ |
180 |
|
181 |
#include <glib.h> |
182 |
|
183 |
+void |
184 |
+check_polkit_async (const gchar *unique_name, |
185 |
+ const gchar *action_id, |
186 |
+ const gboolean user_interaction, |
187 |
+ GAsyncReadyCallback callback, |
188 |
+ gpointer user_data); |
189 |
+ |
190 |
gboolean |
191 |
-check_polkit (const gchar *unique_name, |
192 |
- const gchar *action_id, |
193 |
- const gboolean user_interaction, |
194 |
- GError **error); |
195 |
+check_polkit_finish (GAsyncResult *res, |
196 |
+ GError **error); |
197 |
|
198 |
#endif |
199 |
\ No newline at end of file |
200 |
|
201 |
diff --git a/src/hostnamed.c b/src/hostnamed.c |
202 |
index 4f95d04..c5914bd 100644 |
203 |
--- a/src/hostnamed.c |
204 |
+++ b/src/hostnamed.c |
205 |
@@ -36,6 +36,11 @@ |
206 |
#define QUOTE(macro) #macro |
207 |
#define STR(macro) QUOTE(macro) |
208 |
|
209 |
+struct invoked_name { |
210 |
+ GDBusMethodInvocation *invocation; |
211 |
+ gchar *name; /* newly allocated */ |
212 |
+}; |
213 |
+ |
214 |
guint bus_id = 0; |
215 |
gboolean read_only = FALSE; |
216 |
|
217 |
@@ -103,152 +108,250 @@ guess_icon_name () |
218 |
icon_name = g_strdup ("computer"); |
219 |
} |
220 |
|
221 |
-static gboolean |
222 |
-on_handle_set_hostname (OpenrcSettingsdHostnamedHostname1 *hostname1, |
223 |
- GDBusMethodInvocation *invocation, |
224 |
- const gchar *name, |
225 |
- const gboolean user_interaction, |
226 |
- gpointer user_data) |
227 |
+static void |
228 |
+on_handle_set_hostname_authorized_cb (GObject *source_object, |
229 |
+ GAsyncResult *res, |
230 |
+ gpointer user_data) |
231 |
{ |
232 |
GError *err = NULL; |
233 |
- |
234 |
- if (read_only) { |
235 |
- g_dbus_method_invocation_return_dbus_error (invocation, |
236 |
- DBUS_ERROR_NOT_SUPPORTED, |
237 |
- "openrc-settingsd hostnamed is in read-only mode"); |
238 |
- goto end; |
239 |
- } |
240 |
- |
241 |
- if (!check_polkit (g_dbus_method_invocation_get_sender (invocation), "org.freedesktop.hostname1.set-hostname", user_interaction, &err)) { |
242 |
- g_dbus_method_invocation_return_gerror (invocation, err); |
243 |
- goto end; |
244 |
+ struct invoked_name *data; |
245 |
+ |
246 |
+ data = (struct invoked_name *) user_data; |
247 |
+ if (!check_polkit_finish (res, &err)) { |
248 |
+ g_dbus_method_invocation_return_gerror (data->invocation, err); |
249 |
+ goto out; |
250 |
} |
251 |
|
252 |
G_LOCK (hostname); |
253 |
/* Don't allow an empty or invalid hostname */ |
254 |
- if (!hostname_is_valid (name)) { |
255 |
- name = hostname; |
256 |
- if (!hostname_is_valid (name)) |
257 |
- name = "localhost"; |
258 |
+ if (!hostname_is_valid (data->name)) { |
259 |
+ if (data->name != NULL) |
260 |
+ g_free (data->name); |
261 |
+ |
262 |
+ if (hostname_is_valid (hostname)) |
263 |
+ data->name = g_strdup (hostname); |
264 |
+ else |
265 |
+ data->name = g_strdup ("localhost"); |
266 |
} |
267 |
- if (sethostname (name, strlen(name))) { |
268 |
+ if (sethostname (data->name, strlen(data->name))) { |
269 |
int errsv = errno; |
270 |
- g_dbus_method_invocation_return_dbus_error (invocation, |
271 |
+ g_dbus_method_invocation_return_dbus_error (data->invocation, |
272 |
DBUS_ERROR_FAILED, |
273 |
strerror (errsv)); |
274 |
G_UNLOCK (hostname); |
275 |
- goto end; |
276 |
+ goto out; |
277 |
} |
278 |
- g_strlcpy (hostname, name, HOST_NAME_MAX + 1); |
279 |
- openrc_settingsd_hostnamed_hostname1_complete_set_hostname (hostname1, invocation); |
280 |
+ g_strlcpy (hostname, data->name, HOST_NAME_MAX + 1); |
281 |
+ openrc_settingsd_hostnamed_hostname1_complete_set_hostname (hostname1, data->invocation); |
282 |
openrc_settingsd_hostnamed_hostname1_set_hostname (hostname1, hostname); |
283 |
G_UNLOCK (hostname); |
284 |
|
285 |
- end: |
286 |
- return TRUE; |
287 |
+ out: |
288 |
+ g_free (data->name); |
289 |
+ g_free (data); |
290 |
+ if (err != NULL) |
291 |
+ g_error_free (err); |
292 |
} |
293 |
|
294 |
static gboolean |
295 |
-on_handle_set_static_hostname (OpenrcSettingsdHostnamedHostname1 *hostname1, |
296 |
- GDBusMethodInvocation *invocation, |
297 |
- const gchar *name, |
298 |
- const gboolean user_interaction, |
299 |
- gpointer user_data) |
300 |
+on_handle_set_hostname (OpenrcSettingsdHostnamedHostname1 *hostname1, |
301 |
+ GDBusMethodInvocation *invocation, |
302 |
+ const gchar *name, |
303 |
+ const gboolean user_interaction, |
304 |
+ gpointer user_data) |
305 |
{ |
306 |
- ShellUtilsTrivial *confd_file = NULL; |
307 |
- GError *err = NULL; |
308 |
- |
309 |
- if (read_only) { |
310 |
+ if (read_only) |
311 |
g_dbus_method_invocation_return_dbus_error (invocation, |
312 |
DBUS_ERROR_NOT_SUPPORTED, |
313 |
"openrc-settingsd hostnamed is in read-only mode"); |
314 |
- goto end; |
315 |
+ else { |
316 |
+ struct invoked_name *data; |
317 |
+ data = g_new0 (struct invoked_name, 1); |
318 |
+ data->invocation = invocation; |
319 |
+ data->name = g_strdup (name); |
320 |
+ check_polkit_async (g_dbus_method_invocation_get_sender (invocation), "org.freedesktop.hostname1.set-hostname", user_interaction, on_handle_set_hostname_authorized_cb, data); |
321 |
} |
322 |
|
323 |
- if (!check_polkit (g_dbus_method_invocation_get_sender (invocation), "org.freedesktop.hostname1.set-static-hostname", user_interaction, &err)) { |
324 |
- g_dbus_method_invocation_return_gerror (invocation, err); |
325 |
- goto end; |
326 |
+ return TRUE; |
327 |
+} |
328 |
+ |
329 |
+static void |
330 |
+on_handle_set_static_hostname_authorized_cb (GObject *source_object, |
331 |
+ GAsyncResult *res, |
332 |
+ gpointer user_data) |
333 |
+{ |
334 |
+ GError *err = NULL; |
335 |
+ struct invoked_name *data; |
336 |
+ |
337 |
+ data = (struct invoked_name *) user_data; |
338 |
+ if (!check_polkit_finish (res, &err)) { |
339 |
+ g_dbus_method_invocation_return_gerror (data->invocation, err); |
340 |
+ goto out; |
341 |
} |
342 |
|
343 |
G_LOCK (static_hostname); |
344 |
/* Don't allow an empty or invalid hostname */ |
345 |
- if (!hostname_is_valid (name)) |
346 |
- name = "localhost"; |
347 |
+ if (!hostname_is_valid (data->name)) { |
348 |
+ if (data->name != NULL) |
349 |
+ g_free (data->name); |
350 |
+ |
351 |
+ data->name = g_strdup ("localhost"); |
352 |
+ } |
353 |
|
354 |
- if (!shell_utils_trivial_set_and_save (static_hostname_file, &err, "hostname", "HOSTNAME", name, NULL)) { |
355 |
- g_dbus_method_invocation_return_gerror (invocation, err); |
356 |
+ if (!shell_utils_trivial_set_and_save (static_hostname_file, &err, "hostname", "HOSTNAME", data->name, NULL)) { |
357 |
+ g_dbus_method_invocation_return_gerror (data->invocation, err); |
358 |
G_UNLOCK (static_hostname); |
359 |
- goto end; |
360 |
+ goto out; |
361 |
} |
362 |
|
363 |
g_free (static_hostname); |
364 |
- static_hostname = g_strdup (name); |
365 |
- openrc_settingsd_hostnamed_hostname1_complete_set_static_hostname (hostname1, invocation); |
366 |
+ static_hostname = data->name; /* data->name is g_strdup-ed already */; |
367 |
+ openrc_settingsd_hostnamed_hostname1_complete_set_static_hostname (hostname1, data->invocation); |
368 |
openrc_settingsd_hostnamed_hostname1_set_static_hostname (hostname1, static_hostname); |
369 |
G_UNLOCK (static_hostname); |
370 |
|
371 |
- end: |
372 |
- shell_utils_trivial_free (confd_file); |
373 |
+ out: |
374 |
+ g_free (data); |
375 |
if (err != NULL) |
376 |
g_error_free (err); |
377 |
+} |
378 |
+ |
379 |
+static gboolean |
380 |
+on_handle_set_static_hostname (OpenrcSettingsdHostnamedHostname1 *hostname1, |
381 |
+ GDBusMethodInvocation *invocation, |
382 |
+ const gchar *name, |
383 |
+ const gboolean user_interaction, |
384 |
+ gpointer user_data) |
385 |
+{ |
386 |
+ if (read_only) |
387 |
+ g_dbus_method_invocation_return_dbus_error (invocation, |
388 |
+ DBUS_ERROR_NOT_SUPPORTED, |
389 |
+ "openrc-settingsd hostnamed is in read-only mode"); |
390 |
+ else { |
391 |
+ struct invoked_name *data; |
392 |
+ data = g_new0 (struct invoked_name, 1); |
393 |
+ data->invocation = invocation; |
394 |
+ data->name = g_strdup (name); |
395 |
+ check_polkit_async (g_dbus_method_invocation_get_sender (invocation), "org.freedesktop.hostname1.set-static-hostname", user_interaction, on_handle_set_static_hostname_authorized_cb, data); |
396 |
+ } |
397 |
|
398 |
return TRUE; /* Always return TRUE to indicate signal has been handled */ |
399 |
} |
400 |
|
401 |
-static gboolean |
402 |
-on_handle_set_machine_info (OpenrcSettingsdHostnamedHostname1 *hostname1, |
403 |
- GDBusMethodInvocation *invocation, |
404 |
- const gchar *name, |
405 |
- const gboolean user_interaction, |
406 |
- gpointer user_data) |
407 |
+static void |
408 |
+on_handle_set_pretty_hostname_authorized_cb (GObject *source_object, |
409 |
+ GAsyncResult *res, |
410 |
+ gpointer user_data) |
411 |
{ |
412 |
- ShellUtilsTrivial *confd_file = NULL; |
413 |
GError *err = NULL; |
414 |
- gboolean is_pretty_hostname = GPOINTER_TO_INT(user_data); |
415 |
+ struct invoked_name *data; |
416 |
+ |
417 |
+ data = (struct invoked_name *) user_data; |
418 |
+ if (!check_polkit_finish (res, &err)) { |
419 |
+ g_dbus_method_invocation_return_gerror (data->invocation, err); |
420 |
+ goto out; |
421 |
+ } |
422 |
+ |
423 |
+ G_LOCK (machine_info); |
424 |
+ /* Don't allow a null pretty hostname */ |
425 |
+ if (data->name == NULL) |
426 |
+ data->name = g_strdup (""); |
427 |
|
428 |
- if (read_only) { |
429 |
+ if (!shell_utils_trivial_set_and_save (machine_info_file, &err, "PRETTY_HOSTNAME", NULL, data->name, NULL)) { |
430 |
+ g_dbus_method_invocation_return_gerror (data->invocation, err); |
431 |
+ G_UNLOCK (machine_info); |
432 |
+ goto out; |
433 |
+ } |
434 |
+ |
435 |
+ g_free (pretty_hostname); |
436 |
+ pretty_hostname = data->name; /* data->name is g_strdup-ed already */ |
437 |
+ openrc_settingsd_hostnamed_hostname1_complete_set_pretty_hostname (hostname1, data->invocation); |
438 |
+ openrc_settingsd_hostnamed_hostname1_set_pretty_hostname (hostname1, pretty_hostname); |
439 |
+ G_UNLOCK (machine_info); |
440 |
+ |
441 |
+ out: |
442 |
+ g_free (data); |
443 |
+ if (err != NULL) |
444 |
+ g_error_free (err); |
445 |
+} |
446 |
+ |
447 |
+static gboolean |
448 |
+on_handle_set_pretty_hostname (OpenrcSettingsdHostnamedHostname1 *hostname1, |
449 |
+ GDBusMethodInvocation *invocation, |
450 |
+ const gchar *name, |
451 |
+ const gboolean user_interaction, |
452 |
+ gpointer user_data) |
453 |
+{ |
454 |
+ if (read_only) |
455 |
g_dbus_method_invocation_return_dbus_error (invocation, |
456 |
DBUS_ERROR_NOT_SUPPORTED, |
457 |
"openrc-settingsd hostnamed is in read-only mode"); |
458 |
- goto end; |
459 |
+ else { |
460 |
+ struct invoked_name *data; |
461 |
+ data = g_new0 (struct invoked_name, 1); |
462 |
+ data->invocation = invocation; |
463 |
+ data->name = g_strdup (name); |
464 |
+ check_polkit_async (g_dbus_method_invocation_get_sender (invocation), "org.freedesktop.hostname1.set-machine-info", user_interaction, on_handle_set_pretty_hostname_authorized_cb, data); |
465 |
} |
466 |
|
467 |
- if (!check_polkit (g_dbus_method_invocation_get_sender (invocation), "org.freedesktop.hostname1.set-machine-info", user_interaction, &err)) { |
468 |
- g_dbus_method_invocation_return_gerror (invocation, err); |
469 |
- goto end; |
470 |
+ return TRUE; /* Always return TRUE to indicate signal has been handled */ |
471 |
+} |
472 |
+ |
473 |
+static void |
474 |
+on_handle_set_icon_name_authorized_cb (GObject *source_object, |
475 |
+ GAsyncResult *res, |
476 |
+ gpointer user_data) |
477 |
+{ |
478 |
+ GError *err = NULL; |
479 |
+ struct invoked_name *data; |
480 |
+ |
481 |
+ data = (struct invoked_name *) user_data; |
482 |
+ if (!check_polkit_finish (res, &err)) { |
483 |
+ g_dbus_method_invocation_return_gerror (data->invocation, err); |
484 |
+ goto out; |
485 |
} |
486 |
|
487 |
G_LOCK (machine_info); |
488 |
/* Don't allow a null pretty hostname */ |
489 |
- if (name == NULL) |
490 |
- name = ""; |
491 |
+ if (data->name == NULL) |
492 |
+ data->name = g_strdup (""); |
493 |
|
494 |
- if ((is_pretty_hostname && |
495 |
- !shell_utils_trivial_set_and_save (machine_info_file, &err, "PRETTY_HOSTNAME", NULL, name, NULL)) || |
496 |
- (!is_pretty_hostname && |
497 |
- !shell_utils_trivial_set_and_save (machine_info_file, &err, "ICON_NAME", NULL, name, NULL))) { |
498 |
- g_dbus_method_invocation_return_gerror (invocation, err); |
499 |
+ if (!shell_utils_trivial_set_and_save (machine_info_file, &err, "ICON_NAME", NULL, data->name, NULL)) { |
500 |
+ g_dbus_method_invocation_return_gerror (data->invocation, err); |
501 |
G_UNLOCK (machine_info); |
502 |
- goto end; |
503 |
+ goto out; |
504 |
} |
505 |
|
506 |
- if (is_pretty_hostname) { |
507 |
- g_free (pretty_hostname); |
508 |
- pretty_hostname = g_strdup (name); |
509 |
- openrc_settingsd_hostnamed_hostname1_complete_set_pretty_hostname (hostname1, invocation); |
510 |
- openrc_settingsd_hostnamed_hostname1_set_pretty_hostname (hostname1, pretty_hostname); |
511 |
- } else { |
512 |
- g_free (icon_name); |
513 |
- icon_name = g_strdup (name); |
514 |
- openrc_settingsd_hostnamed_hostname1_complete_set_icon_name (hostname1, invocation); |
515 |
- openrc_settingsd_hostnamed_hostname1_set_icon_name (hostname1, icon_name); |
516 |
- } |
517 |
+ g_free (icon_name); |
518 |
+ icon_name = data->name; /* data->name is g_strdup-ed already */ |
519 |
+ openrc_settingsd_hostnamed_hostname1_complete_set_icon_name (hostname1, data->invocation); |
520 |
+ openrc_settingsd_hostnamed_hostname1_set_icon_name (hostname1, icon_name); |
521 |
G_UNLOCK (machine_info); |
522 |
|
523 |
- end: |
524 |
- shell_utils_trivial_free (confd_file); |
525 |
+ out: |
526 |
+ g_free (data); |
527 |
if (err != NULL) |
528 |
g_error_free (err); |
529 |
+} |
530 |
+ |
531 |
+static gboolean |
532 |
+on_handle_set_icon_name (OpenrcSettingsdHostnamedHostname1 *hostname1, |
533 |
+ GDBusMethodInvocation *invocation, |
534 |
+ const gchar *name, |
535 |
+ const gboolean user_interaction, |
536 |
+ gpointer user_data) |
537 |
+{ |
538 |
+ if (read_only) |
539 |
+ g_dbus_method_invocation_return_dbus_error (invocation, |
540 |
+ DBUS_ERROR_NOT_SUPPORTED, |
541 |
+ "openrc-settingsd hostnamed is in read-only mode"); |
542 |
+ else { |
543 |
+ struct invoked_name *data; |
544 |
+ data = g_new0 (struct invoked_name, 1); |
545 |
+ data->invocation = invocation; |
546 |
+ data->name = g_strdup (name); |
547 |
+ check_polkit_async (g_dbus_method_invocation_get_sender (invocation), "org.freedesktop.hostname1.set-machine-info", user_interaction, on_handle_set_icon_name_authorized_cb, data); |
548 |
+ } |
549 |
|
550 |
return TRUE; /* Always return TRUE to indicate signal has been handled */ |
551 |
} |
552 |
@@ -272,8 +375,8 @@ on_bus_acquired (GDBusConnection *connection, |
553 |
|
554 |
g_signal_connect (hostname1, "handle-set-hostname", G_CALLBACK (on_handle_set_hostname), NULL); |
555 |
g_signal_connect (hostname1, "handle-set-static-hostname", G_CALLBACK (on_handle_set_static_hostname), NULL); |
556 |
- g_signal_connect (hostname1, "handle-set-pretty-hostname", G_CALLBACK (on_handle_set_machine_info), GINT_TO_POINTER(TRUE)); |
557 |
- g_signal_connect (hostname1, "handle-set-icon-name", G_CALLBACK (on_handle_set_machine_info), GINT_TO_POINTER(FALSE)); |
558 |
+ g_signal_connect (hostname1, "handle-set-pretty-hostname", G_CALLBACK (on_handle_set_pretty_hostname), NULL); |
559 |
+ g_signal_connect (hostname1, "handle-set-icon-name", G_CALLBACK (on_handle_set_icon_name), NULL); |
560 |
|
561 |
if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (hostname1), |
562 |
connection, |