~ubuntu-branches/ubuntu/trusty/systemd/trusty

« back to all changes in this revision

Viewing changes to src/login/loginctl.c

  • Committer: Package Import Robot
  • Author(s): Michael Biebl, Michael Biebl, Michael Stapelberg, Daniel Schaal, Ondrej Balaz
  • Date: 2013-09-12 00:13:11 UTC
  • mfrom: (1.1.11) (9.1.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 53.
  • Revision ID: package-import@ubuntu.com-20130912001311-dz35it34wr2lbday
Tags: 204-3
[ Michael Biebl ]
* Upload to unstable.
* Use /bin/bash in debug-shell.service as Debian doesn't have /sbin/sushell.
* Only import net.ifaces cmdline property for network devices.
* Generate strict dependencies between the binary packages using a
  shlibs.local file and add an explicit versioned dependency on
  libsystemd-login0 to systemd to ensure packages are upgraded in sync.
  Closes: #719444
* Drop obsolete Replaces: libudev0 from udev package.
* Use correct paths for various binaries, like /sbin/quotaon, which are
  installed in / and not /usr in Debian.  Closes: #721347
* Don't install kernel-install(8) man page since we don't install the
  corresponding binary either.  Closes: #722180
* Cherry-pick upstream fixes to make switching runlevels and starting
  reboot via ctrl-alt-del more robust.
* Cherry-pick upstream fix to properly apply ACLs to Journal files.

[ Michael Stapelberg ]
* Make systemctl enable|disable call update-rc.d for SysV init scripts.
  Closes: #709780
* Don't mount /tmp as tmpfs by default and make it possible to enable this
  feature via "systemctl enable tmp.mount".

[ Daniel Schaal ]
* Add bug-script to systemd and udev.  Closes: #711245

[ Ondrej Balaz ]
* Recognize discard option in /etc/crypttab.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
  Copyright 2010 Lennart Poettering
7
7
 
8
8
  systemd is free software; you can redistribute it and/or modify it
9
 
  under the terms of the GNU General Public License as published by
10
 
  the Free Software Foundation; either version 2 of the License, or
 
9
  under the terms of the GNU Lesser General Public License as published by
 
10
  the Free Software Foundation; either version 2.1 of the License, or
11
11
  (at your option) any later version.
12
12
 
13
13
  systemd is distributed in the hope that it will be useful, but
14
14
  WITHOUT ANY WARRANTY; without even the implied warranty of
15
15
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
 
  General Public License for more details.
 
16
  Lesser General Public License for more details.
17
17
 
18
 
  You should have received a copy of the GNU General Public License
 
18
  You should have received a copy of the GNU Lesser General Public License
19
19
  along with systemd; If not, see <http://www.gnu.org/licenses/>.
20
20
***/
21
21
 
25
25
#include <string.h>
26
26
#include <getopt.h>
27
27
#include <pwd.h>
 
28
#include <locale.h>
28
29
 
29
30
#include "log.h"
30
31
#include "util.h"
35
36
#include "strv.h"
36
37
#include "cgroup-show.h"
37
38
#include "sysfs-show.h"
 
39
#include "spawn-polkit-agent.h"
38
40
 
39
41
static char **arg_property = NULL;
40
42
static bool arg_all = false;
 
43
static bool arg_full = false;
41
44
static bool arg_no_pager = false;
42
45
static const char *arg_kill_who = NULL;
43
46
static int arg_signal = SIGTERM;
46
49
        TRANSPORT_SSH,
47
50
        TRANSPORT_POLKIT
48
51
} arg_transport = TRANSPORT_NORMAL;
 
52
static bool arg_ask_password = true;
49
53
static const char *arg_host = NULL;
50
54
 
51
 
static bool on_tty(void) {
52
 
        static int t = -1;
53
 
 
54
 
        /* Note that this is invoked relatively early, before we start
55
 
         * the pager. That means the value we return reflects whether
56
 
         * we originally were started on a tty, not if we currently
57
 
         * are. But this is intended, since we want colour and so on
58
 
         * when run in our own pager. */
59
 
 
60
 
        if (_unlikely_(t < 0))
61
 
                t = isatty(STDOUT_FILENO) > 0;
62
 
 
63
 
        return t;
64
 
}
65
 
 
66
55
static void pager_open_if_enabled(void) {
67
56
 
68
57
        /* Cache result before we open the pager */
69
 
        on_tty();
70
 
 
71
 
        if (!arg_no_pager)
72
 
                pager_open();
 
58
        if (arg_no_pager)
 
59
                return;
 
60
 
 
61
        pager_open(false);
 
62
}
 
63
 
 
64
static void polkit_agent_open_if_enabled(void) {
 
65
 
 
66
        /* Open the polkit agent as a child process if necessary */
 
67
 
 
68
        if (!arg_ask_password)
 
69
                return;
 
70
 
 
71
        polkit_agent_open();
73
72
}
74
73
 
75
74
static int list_sessions(DBusConnection *bus, char **args, unsigned n) {
76
 
        DBusMessage *m = NULL, *reply = NULL;
77
 
        DBusError error;
 
75
        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
78
76
        int r;
79
77
        DBusMessageIter iter, sub, sub2;
80
78
        unsigned k = 0;
81
79
 
82
 
        dbus_error_init(&error);
83
 
 
84
 
        assert(bus);
85
 
 
86
80
        pager_open_if_enabled();
87
81
 
88
 
        m = dbus_message_new_method_call(
 
82
        r = bus_method_call_with_reply (
 
83
                        bus,
89
84
                        "org.freedesktop.login1",
90
85
                        "/org/freedesktop/login1",
91
86
                        "org.freedesktop.login1.Manager",
92
 
                        "ListSessions");
93
 
        if (!m) {
94
 
                log_error("Could not allocate message.");
95
 
                return -ENOMEM;
96
 
        }
97
 
 
98
 
        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
99
 
        if (!reply) {
100
 
                log_error("Failed to issue method call: %s", bus_error_message(&error));
101
 
                r = -EIO;
102
 
                goto finish;
103
 
        }
 
87
                        "ListSessions",
 
88
                        &reply,
 
89
                        NULL,
 
90
                        DBUS_TYPE_INVALID);
 
91
        if (r)
 
92
                return r;
104
93
 
105
94
        if (!dbus_message_iter_init(reply, &iter) ||
106
95
            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
107
96
            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
108
97
                log_error("Failed to parse reply.");
109
 
                r = -EIO;
110
 
                goto finish;
 
98
                return -EIO;
111
99
        }
112
100
 
113
101
        dbus_message_iter_recurse(&iter, &sub);
121
109
 
122
110
                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
123
111
                        log_error("Failed to parse reply.");
124
 
                        r = -EIO;
125
 
                        goto finish;
 
112
                        return -EIO;
126
113
                }
127
114
 
128
115
                dbus_message_iter_recurse(&sub, &sub2);
133
120
                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &seat, true) < 0 ||
134
121
                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) {
135
122
                        log_error("Failed to parse reply.");
136
 
                        r = -EIO;
137
 
                        goto finish;
 
123
                        return -EIO;
138
124
                }
139
125
 
140
126
                printf("%10s %10u %-16s %-16s\n", id, (unsigned) uid, user, seat);
147
133
        if (on_tty())
148
134
                printf("\n%u sessions listed.\n", k);
149
135
 
150
 
        r = 0;
151
 
 
152
 
finish:
153
 
        if (m)
154
 
                dbus_message_unref(m);
155
 
 
156
 
        if (reply)
157
 
                dbus_message_unref(reply);
158
 
 
159
 
        dbus_error_free(&error);
160
 
 
161
 
        return r;
 
136
        return 0;
162
137
}
163
138
 
164
139
static int list_users(DBusConnection *bus, char **args, unsigned n) {
165
 
        DBusMessage *m = NULL, *reply = NULL;
166
 
        DBusError error;
 
140
        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
167
141
        int r;
168
142
        DBusMessageIter iter, sub, sub2;
169
143
        unsigned k = 0;
170
144
 
171
 
        dbus_error_init(&error);
172
 
 
173
 
        assert(bus);
174
 
 
175
145
        pager_open_if_enabled();
176
146
 
177
 
        m = dbus_message_new_method_call(
 
147
        r = bus_method_call_with_reply (
 
148
                        bus,
178
149
                        "org.freedesktop.login1",
179
150
                        "/org/freedesktop/login1",
180
151
                        "org.freedesktop.login1.Manager",
181
 
                        "ListUsers");
182
 
        if (!m) {
183
 
                log_error("Could not allocate message.");
184
 
                return -ENOMEM;
185
 
        }
186
 
 
187
 
        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
188
 
        if (!reply) {
189
 
                log_error("Failed to issue method call: %s", bus_error_message(&error));
190
 
                r = -EIO;
191
 
                goto finish;
192
 
        }
 
152
                        "ListUsers",
 
153
                        &reply,
 
154
                        NULL,
 
155
                        DBUS_TYPE_INVALID);
 
156
        if (r)
 
157
                return r;
193
158
 
194
159
        if (!dbus_message_iter_init(reply, &iter) ||
195
160
            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
196
161
            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
197
162
                log_error("Failed to parse reply.");
198
 
                r = -EIO;
199
 
                goto finish;
 
163
                return -EIO;
200
164
        }
201
165
 
202
166
        dbus_message_iter_recurse(&iter, &sub);
210
174
 
211
175
                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
212
176
                        log_error("Failed to parse reply.");
213
 
                        r = -EIO;
214
 
                        goto finish;
 
177
                        return -EIO;
215
178
                }
216
179
 
217
180
                dbus_message_iter_recurse(&sub, &sub2);
220
183
                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &user, true) < 0 ||
221
184
                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) {
222
185
                        log_error("Failed to parse reply.");
223
 
                        r = -EIO;
224
 
                        goto finish;
 
186
                        return -EIO;
225
187
                }
226
188
 
227
189
                printf("%10u %-16s\n", (unsigned) uid, user);
234
196
        if (on_tty())
235
197
                printf("\n%u users listed.\n", k);
236
198
 
237
 
        r = 0;
238
 
 
239
 
finish:
240
 
        if (m)
241
 
                dbus_message_unref(m);
242
 
 
243
 
        if (reply)
244
 
                dbus_message_unref(reply);
245
 
 
246
 
        dbus_error_free(&error);
247
 
 
248
 
        return r;
 
199
        return 0;
249
200
}
250
201
 
251
202
static int list_seats(DBusConnection *bus, char **args, unsigned n) {
252
 
        DBusMessage *m = NULL, *reply = NULL;
253
 
        DBusError error;
 
203
        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
254
204
        int r;
255
205
        DBusMessageIter iter, sub, sub2;
256
206
        unsigned k = 0;
257
207
 
258
 
        dbus_error_init(&error);
259
 
 
260
 
        assert(bus);
261
 
 
262
208
        pager_open_if_enabled();
263
209
 
264
 
        m = dbus_message_new_method_call(
 
210
        r = bus_method_call_with_reply (
 
211
                        bus,
265
212
                        "org.freedesktop.login1",
266
213
                        "/org/freedesktop/login1",
267
214
                        "org.freedesktop.login1.Manager",
268
 
                        "ListSeats");
269
 
        if (!m) {
270
 
                log_error("Could not allocate message.");
271
 
                return -ENOMEM;
272
 
        }
273
 
 
274
 
        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
275
 
        if (!reply) {
276
 
                log_error("Failed to issue method call: %s", bus_error_message(&error));
277
 
                r = -EIO;
278
 
                goto finish;
279
 
        }
 
215
                        "ListSeats",
 
216
                        &reply,
 
217
                        NULL,
 
218
                        DBUS_TYPE_INVALID);
 
219
        if (r)
 
220
                return r;
280
221
 
281
222
        if (!dbus_message_iter_init(reply, &iter) ||
282
223
            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
283
224
            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
284
225
                log_error("Failed to parse reply.");
285
 
                r = -EIO;
286
 
                goto finish;
 
226
                return -EIO;
287
227
        }
288
228
 
289
229
        dbus_message_iter_recurse(&iter, &sub);
296
236
 
297
237
                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
298
238
                        log_error("Failed to parse reply.");
299
 
                        r = -EIO;
300
 
                        goto finish;
 
239
                        return -EIO;
301
240
                }
302
241
 
303
242
                dbus_message_iter_recurse(&sub, &sub2);
305
244
                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &seat, true) < 0 ||
306
245
                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) {
307
246
                        log_error("Failed to parse reply.");
308
 
                        r = -EIO;
309
 
                        goto finish;
 
247
                        return -EIO;
310
248
                }
311
249
 
312
250
                printf("%-16s\n", seat);
319
257
        if (on_tty())
320
258
                printf("\n%u seats listed.\n", k);
321
259
 
322
 
        r = 0;
323
 
 
324
 
finish:
325
 
        if (m)
326
 
                dbus_message_unref(m);
327
 
 
328
 
        if (reply)
329
 
                dbus_message_unref(reply);
330
 
 
331
 
        dbus_error_free(&error);
332
 
 
333
 
        return r;
 
260
        return 0;
334
261
}
335
262
 
336
263
typedef struct SessionStatusInfo {
338
265
        uid_t uid;
339
266
        const char *name;
340
267
        usec_t timestamp;
341
 
        const char *control_group;
 
268
        const char *default_control_group;
342
269
        int vtnr;
343
270
        const char *seat;
344
271
        const char *tty;
350
277
        pid_t leader;
351
278
        const char *type;
352
279
        const char *class;
353
 
        bool active;
 
280
        const char *state;
354
281
} SessionStatusInfo;
355
282
 
356
283
typedef struct UserStatusInfo {
357
284
        uid_t uid;
358
285
        const char *name;
359
286
        usec_t timestamp;
360
 
        const char *control_group;
 
287
        const char *default_control_group;
361
288
        const char *state;
362
289
        char **sessions;
363
290
        const char *display;
370
297
} SeatStatusInfo;
371
298
 
372
299
static void print_session_status_info(SessionStatusInfo *i) {
373
 
        char since1[FORMAT_TIMESTAMP_PRETTY_MAX], *s1;
 
300
        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
374
301
        char since2[FORMAT_TIMESTAMP_MAX], *s2;
375
302
        assert(i);
376
303
 
381
308
        else
382
309
                printf("%u\n", (unsigned) i->uid);
383
310
 
384
 
        s1 = format_timestamp_pretty(since1, sizeof(since1), i->timestamp);
 
311
        s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
385
312
        s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
386
313
 
387
314
        if (s1)
444
371
        } else if (i->class)
445
372
                printf("\t   Class: %s\n", i->class);
446
373
 
447
 
 
448
 
        printf("\t  Active: %s\n", yes_no(i->active));
449
 
 
450
 
        if (i->control_group) {
 
374
        if (i->state)
 
375
                printf("\t   State: %s\n", i->state);
 
376
 
 
377
        if (i->default_control_group) {
451
378
                unsigned c;
 
379
                int output_flags =
 
380
                        arg_all * OUTPUT_SHOW_ALL |
 
381
                        arg_full * OUTPUT_FULL_WIDTH;
452
382
 
453
 
                printf("\t  CGroup: %s\n", i->control_group);
 
383
                printf("\t  CGroup: %s\n", i->default_control_group);
454
384
 
455
385
                if (arg_transport != TRANSPORT_SSH) {
456
386
                        c = columns();
459
389
                        else
460
390
                                c = 0;
461
391
 
462
 
                        show_cgroup_by_path(i->control_group, "\t\t  ", c, false);
 
392
                        show_cgroup_and_extra_by_spec(i->default_control_group,
 
393
                                                      "\t\t  ", c, false, &i->leader,
 
394
                                                      i->leader > 0 ? 1 : 0,
 
395
                                                      output_flags);
463
396
                }
464
397
        }
465
398
}
466
399
 
467
400
static void print_user_status_info(UserStatusInfo *i) {
468
 
        char since1[FORMAT_TIMESTAMP_PRETTY_MAX], *s1;
 
401
        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
469
402
        char since2[FORMAT_TIMESTAMP_MAX], *s2;
470
403
        assert(i);
471
404
 
474
407
        else
475
408
                printf("%u\n", (unsigned) i->uid);
476
409
 
477
 
        s1 = format_timestamp_pretty(since1, sizeof(since1), i->timestamp);
 
410
        s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
478
411
        s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
479
412
 
480
413
        if (s1)
499
432
                printf("\n");
500
433
        }
501
434
 
502
 
        if (i->control_group) {
 
435
        if (i->default_control_group) {
503
436
                unsigned c;
 
437
                int output_flags =
 
438
                        arg_all * OUTPUT_SHOW_ALL |
 
439
                        arg_full * OUTPUT_FULL_WIDTH;
504
440
 
505
 
                printf("\t  CGroup: %s\n", i->control_group);
 
441
                printf("\t  CGroup: %s\n", i->default_control_group);
506
442
 
507
443
                if (arg_transport != TRANSPORT_SSH) {
508
444
                        c = columns();
511
447
                        else
512
448
                                c = 0;
513
449
 
514
 
                        show_cgroup_by_path(i->control_group, "\t\t  ", c, false);
 
450
                        show_cgroup_by_path(i->default_control_group, "\t\t  ",
 
451
                                            c, false, output_flags);
515
452
                }
516
453
        }
517
454
}
567
504
                                i->id = s;
568
505
                        else if (streq(name, "Name"))
569
506
                                i->name = s;
570
 
                        else if (streq(name, "ControlGroupPath"))
571
 
                                i->control_group = s;
 
507
                        else if (streq(name, "DefaultControlGroup"))
 
508
                                i->default_control_group = s;
572
509
                        else if (streq(name, "TTY"))
573
510
                                i->tty = s;
574
511
                        else if (streq(name, "Display"))
583
520
                                i->type = s;
584
521
                        else if (streq(name, "Class"))
585
522
                                i->class = s;
 
523
                        else if (streq(name, "State"))
 
524
                                i->state = s;
586
525
                }
587
526
                break;
588
527
        }
607
546
 
608
547
                if (streq(name, "Remote"))
609
548
                        i->remote = b;
610
 
                else if (streq(name, "Active"))
611
 
                        i->active = b;
612
549
 
613
550
                break;
614
551
        }
666
603
                if (!isempty(s)) {
667
604
                        if (streq(name, "Name"))
668
605
                                i->name = s;
669
 
                        else if (streq(name, "ControlGroupPath"))
670
 
                                i->control_group = s;
 
606
                        else if (streq(name, "DefaultControlGroup"))
 
607
                                i->default_control_group = s;
671
608
                        else if (streq(name, "State"))
672
609
                                i->state = s;
673
610
                }
893
830
}
894
831
 
895
832
static int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) {
896
 
        DBusMessage *m = NULL, *reply = NULL;
 
833
        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
897
834
        const char *interface = "";
898
835
        int r;
899
 
        DBusError error;
900
836
        DBusMessageIter iter, sub, sub2, sub3;
901
 
        SessionStatusInfo session_info;
902
 
        UserStatusInfo user_info;
903
 
        SeatStatusInfo seat_info;
 
837
        SessionStatusInfo session_info = {};
 
838
        UserStatusInfo user_info = {};
 
839
        SeatStatusInfo seat_info = {};
904
840
 
905
 
        assert(bus);
906
841
        assert(path);
907
842
        assert(new_line);
908
843
 
909
 
        zero(session_info);
910
 
        zero(user_info);
911
 
        zero(seat_info);
912
 
 
913
 
        dbus_error_init(&error);
914
 
 
915
 
        m = dbus_message_new_method_call(
 
844
        r = bus_method_call_with_reply(
 
845
                        bus,
916
846
                        "org.freedesktop.login1",
917
847
                        path,
918
848
                        "org.freedesktop.DBus.Properties",
919
 
                        "GetAll");
920
 
        if (!m) {
921
 
                log_error("Could not allocate message.");
922
 
                r = -ENOMEM;
923
 
                goto finish;
924
 
        }
925
 
 
926
 
        if (!dbus_message_append_args(m,
927
 
                                      DBUS_TYPE_STRING, &interface,
928
 
                                      DBUS_TYPE_INVALID)) {
929
 
                log_error("Could not append arguments to message.");
930
 
                r = -ENOMEM;
931
 
                goto finish;
932
 
        }
933
 
 
934
 
        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
935
 
        if (!reply) {
936
 
                log_error("Failed to issue method call: %s", bus_error_message(&error));
937
 
                r = -EIO;
938
 
                goto finish;
939
 
        }
 
849
                        "GetAll",
 
850
                        &reply,
 
851
                        NULL,
 
852
                        DBUS_TYPE_STRING, &interface,
 
853
                        DBUS_TYPE_INVALID);
 
854
        if (r < 0)
 
855
                goto finish;
940
856
 
941
857
        if (!dbus_message_iter_init(reply, &iter) ||
942
858
            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
989
905
 
990
906
                if (r < 0) {
991
907
                        log_error("Failed to parse reply.");
992
 
                        r = -EIO;
993
908
                        goto finish;
994
909
                }
995
910
 
1005
920
                        print_seat_status_info(&seat_info);
1006
921
        }
1007
922
 
 
923
        r = 0;
 
924
 
 
925
finish:
1008
926
        strv_free(seat_info.sessions);
1009
927
        strv_free(user_info.sessions);
1010
928
 
1011
 
        r = 0;
1012
 
 
1013
 
finish:
1014
 
        if (m)
1015
 
                dbus_message_unref(m);
1016
 
 
1017
 
        if (reply)
1018
 
                dbus_message_unref(reply);
1019
 
 
1020
 
        dbus_error_free(&error);
1021
 
 
1022
929
        return r;
1023
930
}
1024
931
 
1025
932
static int show(DBusConnection *bus, char **args, unsigned n) {
1026
 
        DBusMessage *m = NULL, *reply = NULL;
 
933
        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
1027
934
        int r, ret = 0;
1028
935
        DBusError error;
1029
936
        unsigned i;
1036
943
 
1037
944
        show_properties = !strstr(args[0], "status");
1038
945
 
1039
 
        if (show_properties)
1040
 
                pager_open_if_enabled();
 
946
        pager_open_if_enabled();
1041
947
 
1042
948
        if (show_properties && n <= 1) {
1043
949
                /* If not argument is specified inspect the manager
1052
958
 
1053
959
                if (strstr(args[0], "session")) {
1054
960
 
1055
 
                        m = dbus_message_new_method_call(
 
961
                        ret = bus_method_call_with_reply (
 
962
                                        bus,
1056
963
                                        "org.freedesktop.login1",
1057
964
                                        "/org/freedesktop/login1",
1058
965
                                        "org.freedesktop.login1.Manager",
1059
 
                                        "GetSession");
1060
 
                        if (!m) {
1061
 
                                log_error("Could not allocate message.");
1062
 
                                ret = -ENOMEM;
1063
 
                                goto finish;
1064
 
                        }
1065
 
 
1066
 
                        if (!dbus_message_append_args(m,
1067
 
                                                      DBUS_TYPE_STRING, &args[i],
1068
 
                                                      DBUS_TYPE_INVALID)) {
1069
 
                                log_error("Could not append arguments to message.");
1070
 
                                ret = -ENOMEM;
1071
 
                                goto finish;
1072
 
                        }
 
966
                                        "GetSession",
 
967
                                        &reply,
 
968
                                        NULL,
 
969
                                        DBUS_TYPE_STRING, &args[i],
 
970
                                        DBUS_TYPE_INVALID);
1073
971
 
1074
972
                } else if (strstr(args[0], "user")) {
1075
973
                        uid_t uid;
1076
974
                        uint32_t u;
1077
975
 
1078
 
                        ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL);
 
976
                        ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL);
1079
977
                        if (ret < 0) {
1080
978
                                log_error("User %s unknown.", args[i]);
1081
979
                                goto finish;
1082
980
                        }
1083
981
 
1084
 
                        m = dbus_message_new_method_call(
1085
 
                                        "org.freedesktop.login1",
1086
 
                                        "/org/freedesktop/login1",
1087
 
                                        "org.freedesktop.login1.Manager",
1088
 
                                        "GetUser");
1089
 
                        if (!m) {
1090
 
                                log_error("Could not allocate message.");
1091
 
                                ret = -ENOMEM;
1092
 
                                goto finish;
1093
 
                        }
1094
 
 
1095
982
                        u = (uint32_t) uid;
1096
 
                        if (!dbus_message_append_args(m,
1097
 
                                                      DBUS_TYPE_UINT32, &u,
1098
 
                                                      DBUS_TYPE_INVALID)) {
1099
 
                                log_error("Could not append arguments to message.");
1100
 
                                ret = -ENOMEM;
1101
 
                                goto finish;
1102
 
                        }
 
983
                        ret = bus_method_call_with_reply (
 
984
                                        bus,
 
985
                                        "org.freedesktop.login1",
 
986
                                        "/org/freedesktop/login1",
 
987
                                        "org.freedesktop.login1.Manager",
 
988
                                        "GetUser",
 
989
                                        &reply,
 
990
                                        NULL,
 
991
                                        DBUS_TYPE_UINT32, &u,
 
992
                                        DBUS_TYPE_INVALID);
1103
993
                } else {
1104
994
 
1105
 
                        m = dbus_message_new_method_call(
 
995
                        ret = bus_method_call_with_reply (
 
996
                                        bus,
1106
997
                                        "org.freedesktop.login1",
1107
998
                                        "/org/freedesktop/login1",
1108
999
                                        "org.freedesktop.login1.Manager",
1109
 
                                        "GetSeat");
1110
 
                        if (!m) {
1111
 
                                log_error("Could not allocate message.");
1112
 
                                ret = -ENOMEM;
1113
 
                                goto finish;
1114
 
                        }
1115
 
 
1116
 
                        if (!dbus_message_append_args(m,
1117
 
                                                      DBUS_TYPE_STRING, &args[i],
1118
 
                                                      DBUS_TYPE_INVALID)) {
1119
 
                                log_error("Could not append arguments to message.");
1120
 
                                ret = -ENOMEM;
1121
 
                                goto finish;
1122
 
                        }
 
1000
                                        "GetSeat",
 
1001
                                        &reply,
 
1002
                                        NULL,
 
1003
                                        DBUS_TYPE_STRING, &args[i],
 
1004
                                        DBUS_TYPE_INVALID);
1123
1005
                }
1124
 
 
1125
 
                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
1126
 
                if (!reply) {
1127
 
                        log_error("Failed to issue method call: %s", bus_error_message(&error));
1128
 
                        ret = -EIO;
 
1006
                if (ret)
1129
1007
                        goto finish;
1130
 
                }
1131
1008
 
1132
1009
                if (!dbus_message_get_args(reply, &error,
1133
1010
                                           DBUS_TYPE_OBJECT_PATH, &path,
1140
1017
                r = show_one(args[0], bus, path, show_properties, &new_line);
1141
1018
                if (r != 0)
1142
1019
                        ret = r;
1143
 
 
1144
 
                dbus_message_unref(m);
1145
 
                dbus_message_unref(reply);
1146
 
                m = reply = NULL;
1147
1020
        }
1148
1021
 
1149
1022
finish:
1150
 
        if (m)
1151
 
                dbus_message_unref(m);
1152
 
 
1153
 
        if (reply)
1154
 
                dbus_message_unref(reply);
1155
 
 
1156
1023
        dbus_error_free(&error);
1157
1024
 
1158
1025
        return ret;
1159
1026
}
1160
1027
 
1161
1028
static int activate(DBusConnection *bus, char **args, unsigned n) {
1162
 
        DBusMessage *m = NULL;
1163
1029
        int ret = 0;
1164
 
        DBusError error;
1165
1030
        unsigned i;
1166
1031
 
1167
 
        assert(bus);
1168
1032
        assert(args);
1169
1033
 
1170
 
        dbus_error_init(&error);
1171
 
 
1172
1034
        for (i = 1; i < n; i++) {
1173
 
                DBusMessage *reply;
1174
1035
 
1175
 
                m = dbus_message_new_method_call(
 
1036
                ret = bus_method_call_with_reply (
 
1037
                                bus,
1176
1038
                                "org.freedesktop.login1",
1177
1039
                                "/org/freedesktop/login1",
1178
1040
                                "org.freedesktop.login1.Manager",
1179
1041
                                streq(args[0], "lock-session")      ? "LockSession" :
1180
1042
                                streq(args[0], "unlock-session")    ? "UnlockSession" :
1181
1043
                                streq(args[0], "terminate-session") ? "TerminateSession" :
1182
 
                                                                      "ActivateSession");
1183
 
                if (!m) {
1184
 
                        log_error("Could not allocate message.");
1185
 
                        ret = -ENOMEM;
1186
 
                        goto finish;
1187
 
                }
1188
 
 
1189
 
                if (!dbus_message_append_args(m,
1190
 
                                              DBUS_TYPE_STRING, &args[i],
1191
 
                                              DBUS_TYPE_INVALID)) {
1192
 
                        log_error("Could not append arguments to message.");
1193
 
                        ret = -ENOMEM;
1194
 
                        goto finish;
1195
 
                }
1196
 
 
1197
 
                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
1198
 
                if (!reply) {
1199
 
                        log_error("Failed to issue method call: %s", bus_error_message(&error));
1200
 
                        ret = -EIO;
1201
 
                        goto finish;
1202
 
                }
1203
 
 
1204
 
                dbus_message_unref(m);
1205
 
                dbus_message_unref(reply);
1206
 
                m = reply = NULL;
 
1044
                                                                      "ActivateSession",
 
1045
                                NULL,
 
1046
                                NULL,
 
1047
                                DBUS_TYPE_STRING, &args[i],
 
1048
                                DBUS_TYPE_INVALID);
 
1049
                if (ret)
 
1050
                        goto finish;
1207
1051
        }
1208
1052
 
1209
1053
finish:
1210
 
        if (m)
1211
 
                dbus_message_unref(m);
1212
 
 
1213
 
        dbus_error_free(&error);
1214
 
 
1215
1054
        return ret;
1216
1055
}
1217
1056
 
1218
1057
static int kill_session(DBusConnection *bus, char **args, unsigned n) {
1219
 
        DBusMessage *m = NULL;
1220
 
        int ret = 0;
1221
 
        DBusError error;
1222
1058
        unsigned i;
1223
1059
 
1224
 
        assert(bus);
1225
1060
        assert(args);
1226
1061
 
1227
 
        dbus_error_init(&error);
1228
 
 
1229
1062
        if (!arg_kill_who)
1230
1063
                arg_kill_who = "all";
1231
1064
 
1232
1065
        for (i = 1; i < n; i++) {
1233
 
                DBusMessage *reply;
1234
 
 
1235
 
                m = dbus_message_new_method_call(
1236
 
                                "org.freedesktop.login1",
1237
 
                                "/org/freedesktop/login1",
1238
 
                                "org.freedesktop.login1.Manager",
1239
 
                                "KillSession");
1240
 
                if (!m) {
1241
 
                        log_error("Could not allocate message.");
1242
 
                        ret = -ENOMEM;
1243
 
                        goto finish;
1244
 
                }
1245
 
 
1246
 
                if (!dbus_message_append_args(m,
1247
 
                                              DBUS_TYPE_STRING, &args[i],
1248
 
                                              DBUS_TYPE_STRING, &arg_kill_who,
1249
 
                                              DBUS_TYPE_INT32, arg_signal,
1250
 
                                              DBUS_TYPE_INVALID)) {
1251
 
                        log_error("Could not append arguments to message.");
1252
 
                        ret = -ENOMEM;
1253
 
                        goto finish;
1254
 
                }
1255
 
 
1256
 
                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
1257
 
                if (!reply) {
1258
 
                        log_error("Failed to issue method call: %s", bus_error_message(&error));
1259
 
                        ret = -EIO;
1260
 
                        goto finish;
1261
 
                }
1262
 
 
1263
 
                dbus_message_unref(m);
1264
 
                dbus_message_unref(reply);
1265
 
                m = reply = NULL;
 
1066
                int r;
 
1067
 
 
1068
                r = bus_method_call_with_reply (
 
1069
                        bus,
 
1070
                        "org.freedesktop.login1",
 
1071
                        "/org/freedesktop/login1",
 
1072
                        "org.freedesktop.login1.Manager",
 
1073
                        "KillSession",
 
1074
                        NULL,
 
1075
                        NULL,
 
1076
                        DBUS_TYPE_STRING, &args[i],
 
1077
                        DBUS_TYPE_STRING, &arg_kill_who,
 
1078
                        DBUS_TYPE_INT32, &arg_signal,
 
1079
                        DBUS_TYPE_INVALID);
 
1080
                if (r)
 
1081
                        return r;
1266
1082
        }
1267
1083
 
1268
 
finish:
1269
 
        if (m)
1270
 
                dbus_message_unref(m);
1271
 
 
1272
 
        dbus_error_free(&error);
1273
 
 
1274
 
        return ret;
 
1084
        return 0;
1275
1085
}
1276
1086
 
1277
1087
static int enable_linger(DBusConnection *bus, char **args, unsigned n) {
1278
 
        DBusMessage *m = NULL;
1279
 
        int ret = 0;
1280
 
        DBusError error;
1281
1088
        unsigned i;
1282
1089
        dbus_bool_t b, interactive = true;
1283
1090
 
1284
 
        assert(bus);
1285
1091
        assert(args);
1286
1092
 
1287
 
        dbus_error_init(&error);
 
1093
        polkit_agent_open_if_enabled();
1288
1094
 
1289
1095
        b = streq(args[0], "enable-linger");
1290
1096
 
1291
1097
        for (i = 1; i < n; i++) {
1292
 
                DBusMessage *reply;
1293
1098
                uint32_t u;
1294
1099
                uid_t uid;
1295
 
 
1296
 
                m = dbus_message_new_method_call(
1297
 
                                "org.freedesktop.login1",
1298
 
                                "/org/freedesktop/login1",
1299
 
                                "org.freedesktop.login1.Manager",
1300
 
                                "SetUserLinger");
1301
 
                if (!m) {
1302
 
                        log_error("Could not allocate message.");
1303
 
                        ret = -ENOMEM;
1304
 
                        goto finish;
1305
 
                }
1306
 
 
1307
 
                ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL);
1308
 
                if (ret < 0) {
1309
 
                        log_error("Failed to resolve user %s: %s", args[i], strerror(-ret));
1310
 
                        goto finish;
 
1100
                int r;
 
1101
 
 
1102
                r = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL);
 
1103
                if (r < 0) {
 
1104
                        log_error("Failed to resolve user %s: %s", args[i], strerror(-r));
 
1105
                        return r;
1311
1106
                }
1312
1107
 
1313
1108
                u = (uint32_t) uid;
1314
 
                if (!dbus_message_append_args(m,
1315
 
                                              DBUS_TYPE_UINT32, &u,
1316
 
                                              DBUS_TYPE_BOOLEAN, &b,
1317
 
                                              DBUS_TYPE_BOOLEAN, &interactive,
1318
 
                                              DBUS_TYPE_INVALID)) {
1319
 
                        log_error("Could not append arguments to message.");
1320
 
                        ret = -ENOMEM;
1321
 
                        goto finish;
1322
 
                }
1323
 
 
1324
 
                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
1325
 
                if (!reply) {
1326
 
                        log_error("Failed to issue method call: %s", bus_error_message(&error));
1327
 
                        ret = -EIO;
1328
 
                        goto finish;
1329
 
                }
1330
 
 
1331
 
                dbus_message_unref(m);
1332
 
                dbus_message_unref(reply);
1333
 
                m = reply = NULL;
 
1109
                r = bus_method_call_with_reply (
 
1110
                        bus,
 
1111
                        "org.freedesktop.login1",
 
1112
                        "/org/freedesktop/login1",
 
1113
                        "org.freedesktop.login1.Manager",
 
1114
                        "SetUserLinger",
 
1115
                        NULL,
 
1116
                        NULL,
 
1117
                        DBUS_TYPE_UINT32, &u,
 
1118
                        DBUS_TYPE_BOOLEAN, &b,
 
1119
                        DBUS_TYPE_BOOLEAN, &interactive,
 
1120
                        DBUS_TYPE_INVALID);
 
1121
                if (r)
 
1122
                        return r;
1334
1123
        }
1335
1124
 
1336
 
        ret = 0;
1337
 
 
1338
 
finish:
1339
 
        if (m)
1340
 
                dbus_message_unref(m);
1341
 
 
1342
 
        dbus_error_free(&error);
1343
 
 
1344
 
        return ret;
 
1125
        return 0;
1345
1126
}
1346
1127
 
1347
1128
static int terminate_user(DBusConnection *bus, char **args, unsigned n) {
1348
 
        DBusMessage *m = NULL;
1349
 
        int ret = 0;
1350
 
        DBusError error;
1351
1129
        unsigned i;
1352
1130
 
1353
 
        assert(bus);
1354
1131
        assert(args);
1355
1132
 
1356
 
        dbus_error_init(&error);
1357
 
 
1358
1133
        for (i = 1; i < n; i++) {
1359
1134
                uint32_t u;
1360
1135
                uid_t uid;
1361
 
                DBusMessage *reply;
1362
 
 
1363
 
                m = dbus_message_new_method_call(
1364
 
                                "org.freedesktop.login1",
1365
 
                                "/org/freedesktop/login1",
1366
 
                                "org.freedesktop.login1.Manager",
1367
 
                                "TerminateUser");
1368
 
                if (!m) {
1369
 
                        log_error("Could not allocate message.");
1370
 
                        ret = -ENOMEM;
1371
 
                        goto finish;
1372
 
                }
1373
 
 
1374
 
                ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL);
1375
 
                if (ret < 0) {
1376
 
                        log_error("Failed to look up user %s: %s", args[i], strerror(-ret));
1377
 
                        goto finish;
 
1136
                int r;
 
1137
 
 
1138
                r = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL);
 
1139
                if (r < 0) {
 
1140
                        log_error("Failed to look up user %s: %s", args[i], strerror(-r));
 
1141
                        return r;
1378
1142
                }
1379
1143
 
1380
1144
                u = (uint32_t) uid;
1381
 
                if (!dbus_message_append_args(m,
1382
 
                                              DBUS_TYPE_UINT32, &u,
1383
 
                                              DBUS_TYPE_INVALID)) {
1384
 
                        log_error("Could not append arguments to message.");
1385
 
                        ret = -ENOMEM;
1386
 
                        goto finish;
1387
 
                }
1388
 
 
1389
 
                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
1390
 
                if (!reply) {
1391
 
                        log_error("Failed to issue method call: %s", bus_error_message(&error));
1392
 
                        ret = -EIO;
1393
 
                        goto finish;
1394
 
                }
1395
 
 
1396
 
                dbus_message_unref(m);
1397
 
                dbus_message_unref(reply);
1398
 
                m = reply = NULL;
 
1145
                r = bus_method_call_with_reply (
 
1146
                        bus,
 
1147
                        "org.freedesktop.login1",
 
1148
                        "/org/freedesktop/login1",
 
1149
                        "org.freedesktop.login1.Manager",
 
1150
                        "TerminateUser",
 
1151
                        NULL,
 
1152
                        NULL,
 
1153
                        DBUS_TYPE_UINT32, &u,
 
1154
                        DBUS_TYPE_INVALID);
 
1155
                if (r)
 
1156
                        return r;
1399
1157
        }
1400
1158
 
1401
 
        ret = 0;
1402
 
 
1403
 
finish:
1404
 
        if (m)
1405
 
                dbus_message_unref(m);
1406
 
 
1407
 
        dbus_error_free(&error);
1408
 
 
1409
 
        return ret;
 
1159
        return 0;
1410
1160
}
1411
1161
 
1412
1162
static int kill_user(DBusConnection *bus, char **args, unsigned n) {
1413
 
        DBusMessage *m = NULL;
1414
 
        int ret = 0;
1415
 
        DBusError error;
1416
1163
        unsigned i;
1417
1164
 
1418
 
        assert(bus);
1419
1165
        assert(args);
1420
1166
 
1421
 
        dbus_error_init(&error);
1422
 
 
1423
1167
        if (!arg_kill_who)
1424
1168
                arg_kill_who = "all";
1425
1169
 
1426
1170
        for (i = 1; i < n; i++) {
1427
 
                DBusMessage *reply;
1428
1171
                uid_t uid;
1429
1172
                uint32_t u;
1430
 
 
1431
 
                m = dbus_message_new_method_call(
1432
 
                                "org.freedesktop.login1",
1433
 
                                "/org/freedesktop/login1",
1434
 
                                "org.freedesktop.login1.Manager",
1435
 
                                "KillUser");
1436
 
                if (!m) {
1437
 
                        log_error("Could not allocate message.");
1438
 
                        ret = -ENOMEM;
1439
 
                        goto finish;
1440
 
                }
1441
 
 
1442
 
                ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL);
1443
 
                if (ret < 0) {
1444
 
                        log_error("Failed to look up user %s: %s", args[i], strerror(-ret));
1445
 
                        goto finish;
 
1173
                int r;
 
1174
 
 
1175
                r = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL);
 
1176
                if (r < 0) {
 
1177
                        log_error("Failed to look up user %s: %s", args[i], strerror(-r));
 
1178
                        return r;
1446
1179
                }
1447
1180
 
1448
1181
                u = (uint32_t) uid;
1449
 
                if (!dbus_message_append_args(m,
1450
 
                                              DBUS_TYPE_UINT32, &u,
1451
 
                                              DBUS_TYPE_INT32, arg_signal,
1452
 
                                              DBUS_TYPE_INVALID)) {
1453
 
                        log_error("Could not append arguments to message.");
1454
 
                        ret = -ENOMEM;
1455
 
                        goto finish;
1456
 
                }
1457
 
 
1458
 
                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
1459
 
                if (!reply) {
1460
 
                        log_error("Failed to issue method call: %s", bus_error_message(&error));
1461
 
                        ret = -EIO;
1462
 
                        goto finish;
1463
 
                }
1464
 
 
1465
 
                dbus_message_unref(m);
1466
 
                dbus_message_unref(reply);
1467
 
                m = reply = NULL;
 
1182
                r = bus_method_call_with_reply (
 
1183
                        bus,
 
1184
                        "org.freedesktop.login1",
 
1185
                        "/org/freedesktop/login1",
 
1186
                        "org.freedesktop.login1.Manager",
 
1187
                        "KillUser",
 
1188
                        NULL,
 
1189
                        NULL,
 
1190
                        DBUS_TYPE_UINT32, &u,
 
1191
                        DBUS_TYPE_INT32, &arg_signal,
 
1192
                        DBUS_TYPE_INVALID);
 
1193
                if (r)
 
1194
                        return r;
1468
1195
        }
1469
1196
 
1470
 
        ret = 0;
1471
 
 
1472
 
finish:
1473
 
        if (m)
1474
 
                dbus_message_unref(m);
1475
 
 
1476
 
        dbus_error_free(&error);
1477
 
 
1478
 
        return ret;
 
1197
        return 0;
1479
1198
}
1480
1199
 
1481
1200
static int attach(DBusConnection *bus, char **args, unsigned n) {
1482
 
        DBusMessage *m = NULL;
1483
 
        int ret = 0;
1484
 
        DBusError error;
1485
1201
        unsigned i;
1486
1202
        dbus_bool_t interactive = true;
1487
1203
 
1488
 
        assert(bus);
1489
1204
        assert(args);
1490
1205
 
1491
 
        dbus_error_init(&error);
 
1206
        polkit_agent_open_if_enabled();
1492
1207
 
1493
1208
        for (i = 2; i < n; i++) {
1494
 
                DBusMessage *reply;
1495
 
 
1496
 
                m = dbus_message_new_method_call(
1497
 
                                "org.freedesktop.login1",
1498
 
                                "/org/freedesktop/login1",
1499
 
                                "org.freedesktop.login1.Manager",
1500
 
                                "AttachDevice");
1501
 
                if (!m) {
1502
 
                        log_error("Could not allocate message.");
1503
 
                        ret = -ENOMEM;
1504
 
                        goto finish;
1505
 
                }
1506
 
 
1507
 
                if (!dbus_message_append_args(m,
1508
 
                                              DBUS_TYPE_STRING, &args[1],
1509
 
                                              DBUS_TYPE_STRING, &args[i],
1510
 
                                              DBUS_TYPE_BOOLEAN, &interactive,
1511
 
                                              DBUS_TYPE_INVALID)) {
1512
 
                        log_error("Could not append arguments to message.");
1513
 
                        ret = -ENOMEM;
1514
 
                        goto finish;
1515
 
                }
1516
 
 
1517
 
                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
1518
 
                if (!reply) {
1519
 
                        log_error("Failed to issue method call: %s", bus_error_message(&error));
1520
 
                        ret = -EIO;
1521
 
                        goto finish;
1522
 
                }
1523
 
 
1524
 
                dbus_message_unref(m);
1525
 
                dbus_message_unref(reply);
1526
 
                m = reply = NULL;
 
1209
                int r;
 
1210
 
 
1211
                r = bus_method_call_with_reply (
 
1212
                        bus,
 
1213
                        "org.freedesktop.login1",
 
1214
                        "/org/freedesktop/login1",
 
1215
                        "org.freedesktop.login1.Manager",
 
1216
                        "AttachDevice",
 
1217
                        NULL,
 
1218
                        NULL,
 
1219
                        DBUS_TYPE_STRING, &args[1],
 
1220
                        DBUS_TYPE_STRING, &args[i],
 
1221
                        DBUS_TYPE_BOOLEAN, &interactive,
 
1222
                        DBUS_TYPE_INVALID);
 
1223
                if (r)
 
1224
                        return r;
1527
1225
        }
1528
1226
 
1529
 
finish:
1530
 
        if (m)
1531
 
                dbus_message_unref(m);
1532
 
 
1533
 
        dbus_error_free(&error);
1534
 
 
1535
 
        return ret;
 
1227
        return 0;
1536
1228
}
1537
1229
 
1538
1230
static int flush_devices(DBusConnection *bus, char **args, unsigned n) {
1539
 
        DBusMessage *m = NULL, *reply = NULL;
1540
 
        int ret = 0;
1541
 
        DBusError error;
1542
1231
        dbus_bool_t interactive = true;
1543
1232
 
1544
 
        assert(bus);
1545
 
        assert(args);
1546
 
 
1547
 
        dbus_error_init(&error);
1548
 
 
1549
 
        m = dbus_message_new_method_call(
1550
 
                        "org.freedesktop.login1",
1551
 
                        "/org/freedesktop/login1",
1552
 
                        "org.freedesktop.login1.Manager",
1553
 
                        "FlushDevices");
1554
 
        if (!m) {
1555
 
                log_error("Could not allocate message.");
1556
 
                ret = -ENOMEM;
1557
 
                goto finish;
1558
 
        }
1559
 
 
1560
 
        if (!dbus_message_append_args(m,
1561
 
                                      DBUS_TYPE_BOOLEAN, &interactive,
1562
 
                                      DBUS_TYPE_INVALID)) {
1563
 
                log_error("Could not append arguments to message.");
1564
 
                ret = -ENOMEM;
1565
 
                goto finish;
1566
 
        }
1567
 
 
1568
 
        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
1569
 
        if (!reply) {
1570
 
                log_error("Failed to issue method call: %s", bus_error_message(&error));
1571
 
                ret = -EIO;
1572
 
                goto finish;
1573
 
        }
1574
 
 
1575
 
finish:
1576
 
        if (m)
1577
 
                dbus_message_unref(m);
1578
 
 
1579
 
        if (reply)
1580
 
                dbus_message_unref(reply);
1581
 
 
1582
 
        dbus_error_free(&error);
1583
 
 
1584
 
        return ret;
 
1233
        assert(args);
 
1234
 
 
1235
        polkit_agent_open_if_enabled();
 
1236
 
 
1237
        return bus_method_call_with_reply (
 
1238
                        bus,
 
1239
                        "org.freedesktop.login1",
 
1240
                        "/org/freedesktop/login1",
 
1241
                        "org.freedesktop.login1.Manager",
 
1242
                        "FlushDevices",
 
1243
                        NULL,
 
1244
                        NULL,
 
1245
                        DBUS_TYPE_BOOLEAN, &interactive,
 
1246
                        DBUS_TYPE_INVALID);
 
1247
}
 
1248
 
 
1249
static int lock_sessions(DBusConnection *bus, char **args, unsigned n) {
 
1250
        assert(args);
 
1251
 
 
1252
        polkit_agent_open_if_enabled();
 
1253
 
 
1254
        return bus_method_call_with_reply (
 
1255
                        bus,
 
1256
                        "org.freedesktop.login1",
 
1257
                        "/org/freedesktop/login1",
 
1258
                        "org.freedesktop.login1.Manager",
 
1259
                        streq(args[0], "lock-sessions") ? "LockSessions" : "UnlockSessions",
 
1260
                        NULL,
 
1261
                        NULL,
 
1262
                        DBUS_TYPE_INVALID);
1585
1263
}
1586
1264
 
1587
1265
static int terminate_seat(DBusConnection *bus, char **args, unsigned n) {
1588
 
        DBusMessage *m = NULL;
1589
 
        int ret = 0;
1590
 
        DBusError error;
1591
1266
        unsigned i;
1592
1267
 
1593
 
        assert(bus);
1594
1268
        assert(args);
1595
1269
 
1596
 
        dbus_error_init(&error);
1597
 
 
1598
1270
        for (i = 1; i < n; i++) {
1599
 
                DBusMessage *reply;
1600
 
 
1601
 
                m = dbus_message_new_method_call(
1602
 
                                "org.freedesktop.login1",
1603
 
                                "/org/freedesktop/login1",
1604
 
                                "org.freedesktop.login1.Manager",
1605
 
                                "TerminateSeat");
1606
 
                if (!m) {
1607
 
                        log_error("Could not allocate message.");
1608
 
                        ret = -ENOMEM;
1609
 
                        goto finish;
1610
 
                }
1611
 
 
1612
 
                if (!dbus_message_append_args(m,
1613
 
                                              DBUS_TYPE_STRING, &args[i],
1614
 
                                              DBUS_TYPE_INVALID)) {
1615
 
                        log_error("Could not append arguments to message.");
1616
 
                        ret = -ENOMEM;
1617
 
                        goto finish;
1618
 
                }
1619
 
 
1620
 
                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
1621
 
                if (!reply) {
1622
 
                        log_error("Failed to issue method call: %s", bus_error_message(&error));
1623
 
                        ret = -EIO;
1624
 
                        goto finish;
1625
 
                }
1626
 
 
1627
 
                dbus_message_unref(m);
1628
 
                dbus_message_unref(reply);
1629
 
                m = reply = NULL;
 
1271
                int r;
 
1272
 
 
1273
                r = bus_method_call_with_reply (
 
1274
                        bus,
 
1275
                        "org.freedesktop.login1",
 
1276
                        "/org/freedesktop/login1",
 
1277
                        "org.freedesktop.login1.Manager",
 
1278
                        "TerminateSeat",
 
1279
                        NULL,
 
1280
                        NULL,
 
1281
                        DBUS_TYPE_STRING, &args[i],
 
1282
                        DBUS_TYPE_INVALID);
 
1283
                if (r)
 
1284
                        return r;
1630
1285
        }
1631
1286
 
1632
 
finish:
1633
 
        if (m)
1634
 
                dbus_message_unref(m);
1635
 
 
1636
 
        dbus_error_free(&error);
1637
 
 
1638
 
        return ret;
 
1287
        return 0;
1639
1288
}
1640
1289
 
1641
1290
static int help(void) {
1642
1291
 
1643
1292
        printf("%s [OPTIONS...] {COMMAND} ...\n\n"
1644
1293
               "Send control commands to or query the login manager.\n\n"
1645
 
               "  -h --help           Show this help\n"
1646
 
               "     --version        Show package version\n"
1647
 
               "  -p --property=NAME  Show only properties by this name\n"
1648
 
               "  -a --all            Show all properties, including empty ones\n"
1649
 
               "     --kill-who=WHO   Who to send signal to\n"
1650
 
               "  -s --signal=SIGNAL  Which signal to send\n"
1651
 
               "  -H --host=[USER@]HOST\n"
1652
 
               "                      Show information for remote host\n"
1653
 
               "  -P --privileged     Acquire privileges before execution\n"
1654
 
               "     --no-pager       Do not pipe output into a pager\n\n"
 
1294
               "  -h --help              Show this help\n"
 
1295
               "     --version           Show package version\n"
 
1296
               "  -p --property=NAME     Show only properties by this name\n"
 
1297
               "  -a --all               Show all properties, including empty ones\n"
 
1298
               "     --kill-who=WHO      Who to send signal to\n"
 
1299
               "     --full              Do not ellipsize output\n"
 
1300
               "  -s --signal=SIGNAL     Which signal to send\n"
 
1301
               "     --no-ask-password   Don't prompt for password\n"
 
1302
               "  -H --host=[USER@]HOST  Show information for remote host\n"
 
1303
               "  -P --privileged        Acquire privileges before execution\n"
 
1304
               "     --no-pager          Do not pipe output into a pager\n\n"
1655
1305
               "Commands:\n"
1656
1306
               "  list-sessions                   List sessions\n"
1657
1307
               "  session-status [ID...]          Show session status\n"
1659
1309
               "  activate [ID]                   Activate a session\n"
1660
1310
               "  lock-session [ID...]            Screen lock one or more sessions\n"
1661
1311
               "  unlock-session [ID...]          Screen unlock one or more sessions\n"
 
1312
               "  lock-sessions                   Screen lock all current sessions\n"
 
1313
               "  unlock-sessions                 Screen unlock all current sessions\n"
1662
1314
               "  terminate-session [ID...]       Terminate one or more sessions\n"
1663
1315
               "  kill-session [ID...]            Send signal to processes of a session\n"
1664
1316
               "  list-users                      List users\n"
1684
1336
        enum {
1685
1337
                ARG_VERSION = 0x100,
1686
1338
                ARG_NO_PAGER,
1687
 
                ARG_KILL_WHO
 
1339
                ARG_KILL_WHO,
 
1340
                ARG_NO_ASK_PASSWORD,
 
1341
                ARG_FULL,
1688
1342
        };
1689
1343
 
1690
1344
        static const struct option options[] = {
1691
 
                { "help",      no_argument,       NULL, 'h'           },
1692
 
                { "version",   no_argument,       NULL, ARG_VERSION   },
1693
 
                { "property",  required_argument, NULL, 'p'           },
1694
 
                { "all",       no_argument,       NULL, 'a'           },
1695
 
                { "no-pager",  no_argument,       NULL, ARG_NO_PAGER  },
1696
 
                { "kill-who",  required_argument, NULL, ARG_KILL_WHO  },
1697
 
                { "signal",    required_argument, NULL, 's'           },
1698
 
                { "host",      required_argument, NULL, 'H'           },
1699
 
                { "privileged",no_argument,       NULL, 'P'           },
1700
 
                { NULL,        0,                 NULL, 0             }
 
1345
                { "help",            no_argument,       NULL, 'h'                 },
 
1346
                { "version",         no_argument,       NULL, ARG_VERSION         },
 
1347
                { "property",        required_argument, NULL, 'p'                 },
 
1348
                { "all",             no_argument,       NULL, 'a'                 },
 
1349
                { "no-pager",        no_argument,       NULL, ARG_NO_PAGER        },
 
1350
                { "kill-who",        required_argument, NULL, ARG_KILL_WHO        },
 
1351
                { "signal",          required_argument, NULL, 's'                 },
 
1352
                { "host",            required_argument, NULL, 'H'                 },
 
1353
                { "privileged",      no_argument,       NULL, 'P'                 },
 
1354
                { "no-ask-password", no_argument,       NULL, ARG_NO_ASK_PASSWORD },
 
1355
                { "full",            no_argument,       NULL, ARG_FULL            },
 
1356
                { NULL,              0,                 NULL, 0                   }
1701
1357
        };
1702
1358
 
1703
1359
        int c;
1715
1371
 
1716
1372
                case ARG_VERSION:
1717
1373
                        puts(PACKAGE_STRING);
1718
 
                        puts(DISTRIBUTION);
1719
1374
                        puts(SYSTEMD_FEATURES);
1720
1375
                        return 0;
1721
1376
 
1744
1399
                        arg_no_pager = true;
1745
1400
                        break;
1746
1401
 
 
1402
                case ARG_NO_ASK_PASSWORD:
 
1403
                        arg_ask_password = false;
 
1404
                        break;
 
1405
 
1747
1406
                case ARG_KILL_WHO:
1748
1407
                        arg_kill_who = optarg;
1749
1408
                        break;
1765
1424
                        arg_host = optarg;
1766
1425
                        break;
1767
1426
 
 
1427
                case ARG_FULL:
 
1428
                        arg_full = true;
 
1429
                        break;
 
1430
 
1768
1431
                case '?':
1769
1432
                        return -EINVAL;
1770
1433
 
1795
1458
                { "activate",              EQUAL,  2, activate         },
1796
1459
                { "lock-session",          MORE,   2, activate         },
1797
1460
                { "unlock-session",        MORE,   2, activate         },
 
1461
                { "lock-sessions",         EQUAL,  1, lock_sessions    },
 
1462
                { "unlock-sessions",       EQUAL,  1, lock_sessions    },
1798
1463
                { "terminate-session",     MORE,   2, activate         },
1799
1464
                { "kill-session",          MORE,   2, kill_session     },
1800
1465
                { "list-users",            EQUAL,  1, list_users       },
1885
1550
 
1886
1551
        dbus_error_init(&error);
1887
1552
 
 
1553
        setlocale(LC_ALL, "");
1888
1554
        log_parse_environment();
1889
1555
        log_open();
1890
1556