session and seat management daemon
0

Configure Feed

Select the types of activity you want to include in your feed.

XDG_RUNTIME_DIR creation

Oskar Rochowiak (Jun 9, 2026, 6:23 PM +0200) 3237bdb7 589525b4

+46 -27
+45 -27
daemon/src/main.rs
··· 95 95 return; 96 96 }; 97 97 98 + if !client.creds().uid.is_root() { 99 + log::warn!(uid = client.creds().uid.as_raw(); "rejected request from non-root client"); 100 + return; 101 + } 102 + 98 103 match event { 99 104 session_manager::Event::CreateSession { uid, username, tty } => { 100 - if !client.creds().uid.is_root() { 101 - log::warn!(uid = client.creds().uid.as_raw(); "rejected request from non-root client"); 102 - return; 103 - } 104 - 105 105 log::info!(session_id = self.next_session_id, uid, username = username.as_str(), tty = tty.as_str(); "session created"); 106 106 107 107 let leader_id = client.creds().pid.as_raw_pid(); ··· 132 132 session.set_state(session_core_v1::ActiveState::Active); 133 133 } 134 134 135 + let runtime_dir = format!("/run/user/{uid}"); 136 + if let Err(e) = fs::create_dir_all(&runtime_dir) { 137 + log::error!(uid, error = e.to_string().as_str(); "failed to create runtime dir"); 138 + } 139 + if let Err(e) = 140 + rustix::fs::chown(&runtime_dir, Some(rustix::fs::Uid::from_raw(uid)), None) 141 + { 142 + log::error!(uid, error = e.to_string().as_str(); "failed to chown runtime dir"); 143 + } 144 + if let Err(e) = 145 + rustix::fs::chmod(&runtime_dir, rustix::fs::Mode::from_bits_truncate(0o700)) 146 + { 147 + log::error!(uid, error = e.to_string().as_str(); "failed to chmod runtime dir"); 148 + } 149 + 135 150 object.send_session_created(self.next_session_id); 136 151 self.sessions.push(session); 137 152 ··· 142 157 self.next_session_id = self.next_session_id.wrapping_add(1); 143 158 } 144 159 session_manager::Event::DestroySession { session_id } => { 145 - if !client.creds().uid.is_root() { 146 - log::warn!(uid = client.creds().uid.as_raw(); "rejected request from non-root client"); 147 - return; 148 - } 149 - 150 - if let Some(mut session) = self 160 + let Some(mut session) = self 151 161 .sessions 152 162 .extract_if(.., |session| session.id == session_id) 153 163 .next() 154 - { 155 - log::info!(session_id, uid = session.uid, username = session.username.as_str(); "session destroyed"); 156 - 157 - session.set_state(session_core_v1::ActiveState::Closing); 158 - for object in session.objects.iter() { 159 - object.send_destroyed(); 160 - } 164 + else { 165 + log::warn!(session_id; "destroy requested for unknown session"); 166 + return; 167 + }; 168 + log::info!(session_id, uid = session.uid, username = session.username.as_str(); "session destroyed"); 161 169 162 - for manager in &self.info_managers { 163 - manager.send_session_removed(session_id); 164 - } 170 + session.set_state(session_core_v1::ActiveState::Closing); 171 + for object in session.objects.iter() { 172 + object.send_destroyed(); 173 + } 165 174 166 - if let Err(e) = self.cgroup_manager.poll_destroy(session_id) { 167 - log::error!(session_id, error = e.to_string().as_str(); "failed to poll destroy session cgroup"); 168 - } 175 + for manager in &self.info_managers { 176 + manager.send_session_removed(session_id); 177 + } 169 178 170 - return; 179 + if let Err(e) = self.cgroup_manager.poll_destroy(session_id) { 180 + log::error!(session_id, error = e.to_string().as_str(); "failed to poll destroy session cgroup"); 171 181 } 172 182 173 - log::warn!(session_id; "destroy requested for unknown session"); 183 + if !self.sessions.iter().any(|s| s.uid == session.uid) 184 + && let Err(e) = fs::remove_dir(format!("/run/user/{}", session.uid)) 185 + { 186 + log::error!(session_id, uid = session.uid, error = e.to_string().as_str(); "failed to remove runtime dir"); 187 + } 174 188 } 175 189 session_manager::Event::Destroy => {} 176 190 } ··· 205 219 pid, 206 220 } => { 207 221 let Ok(Some(session_id)) = self.cgroup_manager.find_session_by_pid(pid) else { 222 + log::warn!(pid; "get_session_by_pid: no session found for pid"); 223 + session_core_session.send_destroyed(); 208 224 return; 209 225 }; 210 226 ··· 217 233 return; 218 234 } 219 235 220 - log::warn!(session_id; "get_session requested for unknown session"); 236 + log::warn!(session_id; "get_session_by_pid requested for unknown session"); 221 237 session_core_session.send_destroyed(); 222 238 } 223 239 session_core_manager::Event::Destroy => { ··· 286 302 log::info!(session_id = self.sessions[idx].id; "lock requested"); 287 303 for object in self.sessions[idx].objects.iter() { 288 304 object.send_locked(); 305 + object.send_ok(); 289 306 } 290 307 } 291 308 session_core_session::Event::Unlock => { 292 309 log::info!(session_id = self.sessions[idx].id; "unlock requested"); 293 310 for object in self.sessions[idx].objects.iter() { 294 311 object.send_unlocked(); 312 + object.send_ok(); 295 313 } 296 314 } 297 315 _ => unreachable!(),
+1
pam/src/lib.rs
··· 76 76 .map_err(|_| pamsm::PamError::SESSION_ERR)?; 77 77 78 78 pamh.putenv(&format!("XDG_SESSION_ID={session_id}"))?; 79 + pamh.putenv(&format!("XDG_RUNTIME_DIR=/run/user/{uid}"))?; 79 80 80 81 Ok(()) 81 82 }