29#include <systemd/sd-login.h>
39static void user_update_current_user(
void);
40static void user_set_current_user (uid_t uid);
47static gboolean user_watch_monitor_event_cb(GIOChannel *iochannel, GIOCondition cond, gpointer data);
48static bool user_watch_connect (
void);
49static void user_watch_disconnect (
void);
50bool user_watch_init (
void);
51void user_watch_stop (
void);
57static sd_login_monitor *user_watch_monitor = NULL;
58static guint user_change_watch_id = 0;
59static uid_t user_current_uid = UID_UNKNOWN;
71static void user_update_current_user(
void)
73#ifdef SAILFISH_ACCESS_CONTROL
74 uid_t active_uid = UID_UNKNOWN;
75 char **sessions = NULL;
79 if( (rc = sd_get_sessions(&sessions)) < 0 ) {
80 log_warning(
"sd_get_sessions: %s", strerror(-rc));
84 if( rc < 1 || !sessions )
87 for(
size_t i = 0; active_uid == UID_UNKNOWN && sessions[i]; ++i ) {
88 uid_t uid = UID_UNKNOWN;
92 if( (rc = sd_session_get_uid(sessions[i], &uid)) < 0 ) {
93 log_warning(
"sd_session_get_uid(%s): %s",
94 sessions[i], strerror(-rc));
96 else if( (rc = sd_session_get_state(sessions[i], &state)) < 0 ) {
97 log_warning(
"sd_session_get_state(%s): %s",
98 sessions[i], strerror(-rc));
100 else if( (rc = sd_session_get_seat(sessions[i], &seat)) < 0 ) {
106 else if( state && seat && !strcmp(seat,
"seat0") ) {
107 log_debug(
"session: seat=%s uid=%d state=%s", seat, (
int)uid, state);
108 if( !strcmp(state,
"active") || !strcmp(state,
"online") )
118 for(
size_t i = 0; sessions[i]; ++i )
123 user_set_current_user(active_uid);
125 user_set_current_user(0);
129static void user_set_current_user(uid_t uid)
132 if ( user_current_uid != uid ) {
133 log_debug(
"user_current_uid: %d -> %d",
134 (
int)user_current_uid, (
int)uid);
135 user_current_uid = uid;
153 return user_current_uid;
158static gboolean user_watch_monitor_event_cb(GIOChannel *iochannel G_GNUC_UNUSED, GIOCondition cond,
159 gpointer data G_GNUC_UNUSED)
161 LOG_REGISTER_CONTEXT;
164 if( cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL) ) {
165 log_crit(
"user watch hangup/error");
169 user_update_current_user();
171 sd_login_monitor_flush(user_watch_monitor);
175 user_change_watch_id = 0;
176 user_watch_disconnect();
177 return G_SOURCE_REMOVE;
179 return G_SOURCE_CONTINUE;
182static bool user_watch_connect(
void)
184 LOG_REGISTER_CONTEXT;
186 bool success =
false;
187 GIOChannel *iochan = NULL;
189 if ( sd_login_monitor_new(
"session", &user_watch_monitor) < 0 ) {
190 log_err(
"Failed to create login monitor\n");
194 user_update_current_user();
196 iochan = g_io_channel_unix_new(sd_login_monitor_get_fd(user_watch_monitor));
198 log_err(
"Failed to setup I/O channel for sd_login_monitor\n");
202 user_change_watch_id = g_io_add_watch(iochan,
203 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
204 user_watch_monitor_event_cb,
206 if ( user_change_watch_id )
211 g_io_channel_unref(iochan);
213 user_watch_disconnect();
217static void user_watch_disconnect(
void)
219 LOG_REGISTER_CONTEXT;
221 if ( user_change_watch_id ) {
222 g_source_remove(user_change_watch_id);
223 user_change_watch_id = 0;
225 if ( user_watch_monitor ) {
226 sd_login_monitor_unref(user_watch_monitor);
227 user_watch_monitor = NULL;
231bool user_watch_init(
void)
233 LOG_REGISTER_CONTEXT;
235 return user_watch_connect();
238void user_watch_stop(
void)
240 LOG_REGISTER_CONTEXT;
242 user_watch_disconnect();
void control_user_changed(void)
uid_t user_get_current_user(void)