guardian_daemon
Modules:
-
config–Configuration management for the Guardian Daemon.
-
enforcer–Enforcement module for guardian-daemon.
-
ipc–IPC server for admin commands of the Guardian Daemon.
-
logging–Guardian logging setup module.
-
models–SQLAlchemy models for guardian_daemon.
-
net_client–API/WebSocket hub client for guardian-daemon.
-
policy–Policy loader for guardian-daemon.
-
sessions–Session tracking for guardian-daemon.
-
storage–Central SQLAlchemy interface for guardian-daemon.
-
systemd_manager–Systemd manager for guardian-daemon.
-
user_manager–User manager for guardian-daemon.
config
Configuration management for the Guardian Daemon.
Classes:
-
Config–Handles loading, merging, and validating the daemon's configuration.
-
ConfigError–Custom exception for configuration errors.
Config
Config(config_path=None)
Handles loading, merging, and validating the daemon's configuration.
Configuration Loading Priority (highest to lowest): 1. Explicitly provided path via config_path parameter 2. Environment variable GUARDIAN_DAEMON_CONFIG 3. System-wide config at /etc/guardian/daemon/config.yaml 4. Local config (development) in project directory
The configuration system uses a two-layer approach: - Default configuration (always loaded from default-config.yaml) - User configuration (merged on top of defaults)
This ensures that all required keys exist even if the user config is minimal or missing.
Example
config = Config("/etc/guardian/daemon/config.yaml") db_path = config.get("db_path") users = config["users"]
Parameters:
-
–config_pathOptional explicit path to configuration file. If not provided, searches in priority order: 1. GUARDIAN_DAEMON_CONFIG env var 2. /etc/guardian/daemon/config.yaml 3. Local config.yaml (development)
Raises:
-
ConfigError–If configuration validation fails
Methods:
-
get–Gets a configuration value.
ConfigError
Bases: Exception
Custom exception for configuration errors.
enforcer
Enforcement module for guardian-daemon. Checks quota and curfew, enforces limits by terminating sessions and blocking logins.
Classes:
-
Enforcer–Enforcement logic for quota and curfew. Handles session termination and user notifications.
Enforcer
Enforcer(policy: Policy, tracker: SessionTracker)
Enforcement logic for quota and curfew. Handles session termination and user notifications.
Methods:
-
enforce_user–Checks quota and curfew for a user and enforces actions if necessary.
-
handle_grace_period–Handles the grace period by notifying the user every minute until time is up.
-
notify_user–Sends a desktop notification to all matching agents of the given user (via D-Bus).
-
terminate_session–Terminates all running desktop sessions of the user (via systemd loginctl).
enforce_user
async
Checks quota and curfew for a user and enforces actions if necessary.
Uses intelligent throttling to avoid redundant enforcement checks: - Skips check if user is already in grace period - Skips check if last check was recent and time hasn't changed much
handle_grace_period
async
Handles the grace period by notifying the user every minute until time is up.
notify_user
async
Sends a desktop notification to all matching agents of the given user (via D-Bus). Implements a debounce mechanism to avoid sending too many similar notifications.
ipc
IPC server for admin commands of the Guardian Daemon.
Classes:
-
GuardianIPCServer–IPC server for admin commands of the Guardian Daemon.
GuardianIPCServer
GuardianIPCServer(
config, tracker: SessionTracker, policy: Policy
)
IPC server for admin commands of the Guardian Daemon. Provides a socket interface for status and control commands.
Security: Enforces request size limits and proper authentication.
Parameters:
-
(configdict) –Configuration data
-
(trackerSessionTracker) –The main session tracker instance.
-
(policyPolicy) –The main policy instance.
Methods:
-
close–Closes the IPC socket and removes the socket file.
-
handle_add_user–Add a new user to the database with default settings.
-
handle_connection–Handles an incoming client connection.
-
handle_describe_commands–Returns a description of all available IPC commands and their parameters as JSON.
-
handle_get_curfew–Returns the current curfew times of a kid.
-
handle_get_quota–Returns the current quota status of a kid.
-
handle_list_kids–Returns the list of all kids (users).
-
handle_list_timers–Lists all active Guardian timers.
-
handle_reload_timers–Reloads the timer configuration.
-
handle_reset_quota–Resets the daily quota for all users (deletes sessions since last reset).
-
handle_setup_user–Sets up a user with Guardian (adds to groups, creates systemd services, etc).
-
handle_sync_users_from_config–Reset user settings in the database to match the configuration file.
-
handle_unlock_all–Emergency unlock all managed user accounts.
-
handle_unlock_user–Unlock a specific user's account to allow login.
-
handle_update_user–Update a specific setting for a user.
-
start–Starts the IPC server.
handle_add_user
handle_add_user(username)
Add a new user to the database with default settings.
Parameters:
-
(usernamestr) –Username to add
handle_connection
async
Handles an incoming client connection. Enforces authentication, request size limits, and rate limiting.
handle_describe_commands
Returns a description of all available IPC commands and their parameters as JSON. This is used by the CLI for automatic command discovery.
handle_get_curfew
handle_get_curfew(kid)
Returns the current curfew times of a kid.
Parameters:
-
(kidstr) –Username
handle_get_quota
async
handle_get_quota(kid)
Returns the current quota status of a kid. All time values are in minutes in the returned JSON.
Parameters:
-
(kidstr) –Username
Returns:
-
str–JSON string with quota information (used, limit, remaining in minutes)
handle_reset_quota
async
Resets the daily quota for all users (deletes sessions since last reset).
handle_setup_user
handle_setup_user(username)
Sets up a user with Guardian (adds to groups, creates systemd services, etc).
Parameters:
-
(usernamestr) –Username of the user to set up
handle_sync_users_from_config
Reset user settings in the database to match the configuration file. This also imports new users from the config to the database.
handle_unlock_all
async
Emergency unlock all managed user accounts.
Returns:
-
–
JSON response with count of unlocked users and details
handle_unlock_user
async
handle_unlock_user(username)
Unlock a specific user's account to allow login.
Parameters:
-
–usernameUsername to unlock
Returns:
-
–
JSON response with success status or error message
handle_update_user
handle_update_user(args)
Update a specific setting for a user.
Parameters:
-
(argsstr) –Format should be "username setting_key setting_value"
logging
Guardian logging setup module. Configures log level, format, and target based on the application config.
Functions:
-
get_logger–Returns a configured structlog logger instance.
-
setup_logging–Sets up structlog and stdlib logging according to the provided config.
models
SQLAlchemy models for guardian_daemon.
Key design decisions: - Session.id is an autoincrement primary key (not using logind session_id as PK) - logind_session_id is stored but is transient and can be reused by the system - Unique constraint on (username, date, start_time) to prevent duplicate sessions
Classes:
-
Base–Base class for all models.
-
History–Historical session summaries by user and date.
-
Meta–Metadata key-value storage.
-
Session–Represents a user session.
-
UserSettings–User settings and configuration.
Base
Bases: DeclarativeBase
Base class for all models.
History
Meta
Session
Bases: Base
Represents a user session.
Note: The id is an autoincrement value, NOT the logind session ID. The logind_session_id is stored separately as it's transient and can be reused by the system for different users on different days.
UserSettings
net_client
API/WebSocket hub client for guardian-daemon.
NOTE: This module is not yet implemented. Only stub placeholder exists. The network client is planned for Phase 1 of the project roadmap.
Planned functionality: - HTTP client for guardian-hub API - WebSocket connection for real-time updates - Policy synchronization from hub - Usage data upload to hub - Heartbeat mechanism - Offline queue for when hub is unavailable
policy
Policy loader for guardian-daemon. Loads and validates settings from a YAML configuration file.
Classes:
-
Policy–
Policy
Policy(
config_path: Optional[str] = None,
db_path: Optional[str] = None,
)
Parameters:
-
(config_pathstr, default:None) –Path to the YAML configuration file.
-
(db_pathstr, default:None) –Path to the SQLite database.
Methods:
-
add_user–Adds a user to the policy with default settings.
-
get_all_usernames–Returns a list of all usernames in the policy.
-
get_default–Return a default value from the policy.
-
get_grace_time–Returns the grace time in minutes for a user.
-
get_monitored_users–Get list of all monitored users (excluding those with monitored: False).
-
get_timezone–Returns the configured timezone or the default timezone.
-
get_user_curfew–Get curfew settings for a user.
-
get_user_policy–Return the policy settings for a specific user.
-
get_user_quota–Get daily and weekly quota for a user.
-
has_curfew–Check if a user has curfew settings.
-
has_quota–Check if a user has quota settings and is not quota_exempt.
-
reload–Reload the policy configuration and synchronize with the database.
add_user
add_user(username: str) -> bool
Adds a user to the policy with default settings.
Parameters:
-
(usernamestr) –Username to add
Returns:
-
bool(bool) –True if the user was added, False otherwise
get_all_usernames
Returns a list of all usernames in the policy.
Returns:
-
list(list) –List of usernames
get_default
get_default(key: str) -> Any
Return a default value from the policy.
Parameters:
-
(keystr) –Name of the default key
Returns:
-
Any(Any) –The default value or None
get_grace_time
get_grace_time(username: str) -> int
Returns the grace time in minutes for a user. This is the time allowed after quota is exhausted before terminating the session.
Parameters:
-
(usernamestr) –Username to get grace time for
Returns:
-
int(int) –Grace time in minutes (defaults to 5)
get_monitored_users
Get list of all monitored users (excluding those with monitored: False).
get_timezone
Returns the configured timezone or the default timezone.
Returns:
-
str(str) –Timezone string
get_user_curfew
Get curfew settings for a user.
get_user_policy
get_user_policy(username: str) -> Optional[Dict[str, Any]]
Return the policy settings for a specific user.
Parameters:
-
(usernamestr) –Username
Returns:
-
Optional[Dict[str, Any]]–dict | None: The user's settings or None if not present.
get_user_quota
Get daily and weekly quota for a user.
has_quota
Check if a user has quota settings and is not quota_exempt.
sessions
Session tracking for guardian-daemon. Monitors logins/logouts via systemd-logind (DBus), measures usage time and checks quota/curfew. Stores data in SQLite.
Classes:
-
GuardianDaemonInterface– -
SessionTracker–Monitors and stores user sessions, checks quota and curfew.
Functions:
-
get_boot_id–Get the system boot ID to make session IDs unique across reboots.
-
make_unique_session_id–Create a unique session ID that persists across daemon restarts but changes across reboots.
GuardianDaemonInterface
Bases: ServiceInterface
Methods:
-
LockEvent–Receives lock/unlock events from agents and forwards to SessionTracker.
SessionTracker
SessionTracker(
policy: Policy, config: dict, user_manager: UserManager
)
Monitors and stores user sessions, checks quota and curfew. Connects to systemd-logind via DBus.
Parameters:
-
(policyPolicy) –Policy instance
-
(configdict) –Parsed configuration
-
(user_managerUserManager) –User manager instance for setting up user sessions
Methods:
-
check_curfew–Check if a user is allowed to log in at the current time based on curfew settings.
-
check_daily_reset_on_startup–Check if we need to perform a daily reset on daemon startup or system wake.
-
check_quota–Check if a user is within their quota limits.
-
check_usage_summarize–Check if we need to summarize usage and add to history.
-
discover_agent_names_for_user–Scans the D-Bus for all available agent service names for a given user
-
get_active_users–Return a list of currently active usernames.
-
get_agent_names_for_user–Return the cached list of D-Bus agent names for a user, or empty list if not found.
-
get_agent_paths_for_user–Returns a list of D-Bus object paths for agents belonging to the given user.
-
get_remaining_time–Returns the remaining allowed time for the given user today.
-
get_total_time–Returns the total allowed time (in minutes) for the given user today.
-
get_user_sessions–Returns a list of active session details for the given user.
-
handle_login–Register a new session on login for child accounts.
-
handle_logout–End a session on logout and save it in the database for child accounts.
-
pause_user_time–Pause time tracking for a user when a lock event is received for an unknown session.
-
perform_daily_reset–Perform daily reset: summarize sessions, create history entries,
-
periodic_session_update–Periodically update all active sessions in the database with current duration.
-
receive_lock_event–Called via D-Bus/IPC from agent to record lock/unlock events for a session.
-
refresh_agent_name_mapping–Refresh the mapping of usernames to their current D-Bus agent names using discover_agent_names_for_user().
-
run–Start session tracking, connect to systemd-logind via DBus, and listen for KDE lock events.
check_curfew
async
check_curfew(
username: str, current_time, is_weekend: bool
) -> bool
Check if a user is allowed to log in at the current time based on curfew settings.
Parameters:
-
(usernamestr) –Username
-
–current_timeCurrent time to check (datetime.time)
-
(is_weekendbool) –Whether it's a weekend day
Returns:
-
bool(bool) –True if allowed, False if curfew is in effect
check_daily_reset_on_startup
async
Check if we need to perform a daily reset on daemon startup or system wake. This is based on the date comparison between today and the last reset date.
check_quota
async
check_quota(username: str) -> bool
Check if a user is within their quota limits.
Parameters:
-
(usernamestr) –Username
Returns:
-
bool(bool) –True if within quota, False if exceeded
check_usage_summarize
async
check_usage_summarize(
username, used_time, quota_reached=False
)
Check if we need to summarize usage and add to history. This should be called when: 1. The user reaches their daily quota 2. The user logs out and it's their last session of the day
Parameters:
-
(usernamestr) –Username to check
-
(used_timefloat) –Used time in seconds
-
(quota_reachedbool, default:False) –Whether the quota was reached
discover_agent_names_for_user
async
Scans the D-Bus for all available agent service names for a given user and updates the internal map.
get_agent_names_for_user
Return the cached list of D-Bus agent names for a user, or empty list if not found. Converts from set to list if necessary.
get_agent_paths_for_user
Returns a list of D-Bus object paths for agents belonging to the given user. This should be tracked in active_sessions as 'agent_path' if available, otherwise default to /org/guardian/Agent or numbered agents.
get_remaining_time
async
Returns the remaining allowed time for the given user today. All calculations use minutes as the base unit to match the API contract.
Returns:
-
float(float) –Remaining screen time in minutes
get_total_time
async
Returns the total allowed time (in minutes) for the given user today.
Returns:
-
float(float) –Total allowed screen time in minutes
get_user_sessions
Returns a list of active session details for the given user. Each item is a dict with session_id, service, desktop, start_time, etc.
handle_login
async
handle_login(session_id, uid, username, props)
Register a new session on login for child accounts. Skips systemd-user sessions. Also ensure user account is set up: PAM time rules, systemd user service, and agent.
Parameters:
-
(session_idstr) –Session ID
-
(uidint) –User ID
-
(usernamestr) –Username
handle_logout
async
handle_logout(session_id)
End a session on logout and save it in the database for child accounts.
Parameters:
-
(session_idstr) –Logind session ID (will be mapped to unique session ID)
pause_user_time
Pause time tracking for a user when a lock event is received for an unknown session.
perform_daily_reset
async
Perform daily reset: summarize sessions, create history entries, clean up sessions table, and reset quotas.
This should be called when: 1. The system is first booted/unlocked for the day (normal reset) 2. The daily quota is reached 3. The configured reset_time is reached 4. Manually via reset-quota command (force=True)
When force=True, resets today's quota to zero by archiving current sessions.
periodic_session_update
async
Periodically update all active sessions in the database with current duration. This is critical for preserving session time across daemon restarts. Includes robust D-Bus connection handling with automatic reconnection.
receive_lock_event
async
receive_lock_event(
session_id: str,
username: str,
locked: bool,
timestamp: float,
)
Called via D-Bus/IPC from agent to record lock/unlock events for a session. Also updates session progress in the database.
Parameters:
-
(session_idstr) –Logind session ID from the agent (will be mapped to unique ID)
refresh_agent_name_mapping
async
Refresh the mapping of usernames to their current D-Bus agent names using discover_agent_names_for_user(). Stores the mapping in self.agent_name_map: {username: {dbus_name, ...}}
get_boot_id
Get the system boot ID to make session IDs unique across reboots.
Returns:
-
str(str) –Boot ID or empty string if not available
make_unique_session_id
make_unique_session_id(
logind_session_id: str, boot_id: str = None
) -> str
Create a unique session ID that persists across daemon restarts but changes across reboots.
Parameters:
-
(logind_session_idstr) –The session ID from logind (e.g., "4", "5")
-
(boot_idstr, default:None) –Optional boot ID (will fetch if not provided)
Returns:
-
str(str) –Unique session ID in format "bootid_sessionid" or just sessionid if no boot_id
storage
Central SQLAlchemy interface for guardian-daemon. Provides functions for session handling using SQLAlchemy ORM.
Classes:
-
Storage–Central SQLAlchemy interface for session and settings storage in Guardian Daemon.
Storage
Storage(db_path: str)
Central SQLAlchemy interface for session and settings storage in Guardian Daemon.
Key design changes: - Uses SQLAlchemy ORM instead of raw SQL - Session.id is autoincrement (not using logind session_id as primary key) - logind_session_id is stored separately as it's transient - Date field tracks which day the session belongs to
Parameters:
-
(db_pathstr) –Path to SQLite database.
Methods:
-
add_session–Adds a new session to the database.
-
add_session_time–Add a usage time entry for a user.
-
clean_old_sessions–Remove old session records for a user after they've been summarized to history.
-
cleanup_stale_sessions–Remove sessions older than the specified age.
-
close–Close the database connection.
-
delete_sessions_since–Delete all sessions from the database since the given timestamp.
-
end_session–End a session for a user.
-
get_active_session–Get an active session for a user.
-
get_all_active_sessions–Get all currently active sessions.
-
get_all_usernames–Return all usernames (except 'default') from the database.
-
get_daily_usage–Get total usage time for a user on a given date.
-
get_history–Retrieve history entries for a user within a date range.
-
get_last_reset_date–Retrieve the last daily reset date from the database.
-
get_last_reset_timestamp–Retrieve the last daily reset timestamp from the database.
-
get_open_sessions–Get all currently open sessions from the database.
-
get_sessions_count_since–Get count of sessions since a given timestamp.
-
get_sessions_for_user–Retrieve all sessions for a user, optionally since a specific time.
-
get_usage_in_date_range–Get total usage time for a user between two dates.
-
get_user_settings–Retrieve user settings from the database for the given username.
-
get_weekly_usage–Get total usage time for a user in the week containing the given date.
-
logind_to_epoch–Convert logind timestamp (microseconds since boot) to EPOCH timestamp.
-
save_history_entry–Save a history entry from a session summary.
-
set_last_reset_date–Store the last daily reset date in the database.
-
set_last_reset_timestamp–Store the last daily reset timestamp in the database.
-
set_user_settings–Store user settings in the database for the given username.
-
summarize_user_sessions–Summarize all sessions for a user on a given date and create a history entry.
-
sync_config_to_db–Synchronize configuration data to the database.
-
update_session_logout–Update session entry with logout time and duration.
-
update_session_progress–Periodically update session entry with current duration (while session is active).
add_session
async
add_session(
session_id: str,
username: str,
uid: int,
start_time: float,
end_time: float,
duration_seconds: float,
desktop: Optional[str] = None,
service: Optional[str] = None,
)
Adds a new session to the database.
Parameters:
-
(session_idstr) –Logind session ID (transient identifier)
-
(usernamestr) –Username
-
(uidint) –User ID
-
(start_timefloat) –Start time (EPOCH)
-
(end_timefloat) –End time (EPOCH, 0 if still active)
-
(duration_secondsfloat) –Session duration in seconds
-
(desktopstr, default:None) –Desktop environment
-
(servicestr, default:None) –Service (e.g. sddm)
add_session_time
async
add_session_time(
username: str, start_time: datetime, end_time: datetime
)
Add a usage time entry for a user.
Parameters:
-
(usernamestr) –Username
-
(start_timedatetime) –Start time
-
(end_timedatetime) –End time
clean_old_sessions
clean_old_sessions(username: str, before_date: str = None)
Remove old session records for a user after they've been summarized to history.
Parameters:
-
(usernamestr) –Username to clean sessions for
-
(before_datestr, default:None) –Remove sessions before this date (YYYY-MM-DD) If not provided, removes all sessions
cleanup_stale_sessions
async
cleanup_stale_sessions(max_age_hours: int)
Remove sessions older than the specified age.
Parameters:
-
(max_age_hoursint) –Maximum age in hours to keep sessions
delete_sessions_since
delete_sessions_since(since: float)
Delete all sessions from the database since the given timestamp.
Parameters:
-
(sincefloat) –Start timestamp (Unix timestamp)
end_session
async
end_session(
username: str, session_id: str, end_time: datetime
)
End a session for a user.
Parameters:
-
(usernamestr) –Username
-
(session_idstr) –Logind session ID
-
(end_timedatetime) –End time
get_active_session
async
get_active_session(username: str, session_id: str)
Get an active session for a user.
Parameters:
-
(usernamestr) –Username
-
(session_idstr) –Logind session ID
Returns:
-
tuple–Session data or None if not found
get_all_active_sessions
async
Get all currently active sessions.
Returns:
-
list–List of active sessions
get_all_usernames
Return all usernames (except 'default') from the database.
Returns:
-
list(list) –List of usernames
get_daily_usage
async
Get total usage time for a user on a given date.
Parameters:
-
(usernamestr) –Username
-
(datedate) –Date to check
Returns:
-
int–Total usage time in seconds
get_history
get_history(
username: str,
start_date: str = None,
end_date: str = None,
)
Retrieve history entries for a user within a date range.
Parameters:
-
(usernamestr) –Username to get history for
-
(start_datestr, default:None) –Start date in YYYY-MM-DD format
-
(end_datestr, default:None) –End date in YYYY-MM-DD format
Returns:
-
list–List of history entries as dictionaries
get_last_reset_date
Retrieve the last daily reset date from the database.
Returns:
-
str(str) –Date in YYYY-MM-DD format
get_last_reset_timestamp
Retrieve the last daily reset timestamp from the database.
Returns:
-
Optional[float]–float | None: EPOCH timestamp of last reset or None
get_open_sessions
Get all currently open sessions from the database.
Returns:
-
list(list) –List of tuples (logind_session_id, username, uid, start_time, duration, desktop, service)
get_sessions_count_since
get_sessions_count_since(timestamp: float) -> int
Get count of sessions since a given timestamp.
Parameters:
-
(timestampfloat) –Unix timestamp
Returns:
-
int(int) –Count of sessions
get_sessions_for_user
Retrieve all sessions for a user, optionally since a specific time.
Parameters:
-
(usernamestr) –Username
-
(sincefloat, default:None) –Start time (Unix timestamp)
Returns:
-
list(list) –List of sessions as tuples
get_usage_in_date_range
async
get_usage_in_date_range(
username: str, start_date: datetime, end_date: datetime
)
Get total usage time for a user between two dates.
Parameters:
-
(usernamestr) –Username
-
(start_datedatetime) –Start date
-
(end_datedatetime) –End date
Returns:
-
int–Total usage time in seconds
get_user_settings
get_user_settings(username: str) -> Optional[dict]
Retrieve user settings from the database for the given username.
Parameters:
-
(usernamestr) –Username
Returns:
-
Optional[dict]–dict | None: User settings or None
get_weekly_usage
async
Get total usage time for a user in the week containing the given date.
Parameters:
-
(usernamestr) –Username
-
(datedate) –Date within the week to check
Returns:
-
int–Total usage time in seconds
logind_to_epoch
staticmethod
logind_to_epoch(logind_timestamp: int) -> float
Convert logind timestamp (microseconds since boot) to EPOCH timestamp.
Parameters:
-
(logind_timestampint) –Microseconds since boot
Returns:
-
float(float) –EPOCH timestamp
save_history_entry
save_history_entry(summary: dict)
Save a history entry from a session summary.
Parameters:
-
(summarydict) –Session summary data
set_last_reset_date
set_last_reset_date(date_str: str)
Store the last daily reset date in the database.
Parameters:
-
(date_strstr) –Date in YYYY-MM-DD format
set_last_reset_timestamp
set_last_reset_timestamp(ts: float)
Store the last daily reset timestamp in the database.
Parameters:
-
(tsfloat) –EPOCH timestamp
set_user_settings
Store user settings in the database for the given username.
Parameters:
-
(usernamestr) –Username
-
(settingsdict) –Settings dictionary
summarize_user_sessions
Summarize all sessions for a user on a given date and create a history entry. If date is not provided, summarize sessions from the most recent day.
Parameters:
-
(usernamestr) –Username to summarize sessions for
-
(datestr, default:None) –Date in YYYY-MM-DD format, defaults to today
Returns:
-
dict–Summary of session data
sync_config_to_db
sync_config_to_db(config: dict)
Synchronize configuration data to the database. Merges user settings with defaults to ensure complete configuration.
Parameters:
-
(configdict) –Configuration data
update_session_logout
update_session_logout(
session_id: str,
end_time: float,
duration_seconds: float,
)
Update session entry with logout time and duration.
Parameters:
-
(session_idstr) –Logind session ID to update
-
(end_timefloat) –End time in EPOCH seconds
-
(duration_secondsfloat) –Session duration in seconds
update_session_progress
update_session_progress(
session_id: str, duration_seconds: float
)
Periodically update session entry with current duration (while session is active). This is critical for preserving session time across daemon restarts.
Parameters:
-
(session_idstr) –The logind session ID to update
-
(duration_secondsfloat) –Duration in seconds
systemd_manager
Systemd manager for guardian-daemon. Creates and manages systemd timers/units for daily reset and curfew.
Classes:
-
SystemdManager–Manages systemd timers and units for daily reset and curfew enforcement.
SystemdManager
Manages systemd timers and units for daily reset and curfew enforcement.
Methods:
-
create_curfew_timer–Create a systemd timer and service unit for curfew enforcement.
-
create_daily_reset_timer–Create a systemd timer and corresponding service unit for the daily quota reset.
-
reload_systemd–Reload systemd units to apply changes.
-
remove_timer_and_service–Remove a systemd timer and service unit by name.
create_curfew_timer
Create a systemd timer and service unit for curfew enforcement.
create_daily_reset_timer
Create a systemd timer and corresponding service unit for the daily quota reset.
user_manager
User manager for guardian-daemon. Manages login time windows for children via /etc/security/time.conf and handles user-specific systemd services.
Classes:
-
SetupError–Exception raised when critical setup operations fail.
-
UserManager–Manages user-specific configurations, PAM time rules, and systemd services.
SetupError
Bases: Exception
Exception raised when critical setup operations fail.
UserManager
UserManager(
policy: Policy = None, tracker: SessionTracker = None
)
Manages user-specific configurations, PAM time rules, and systemd services.
This class is responsible for: - Managing the 'kids' group and user memberships - Writing and maintaining PAM time.conf rules for curfews - Setting up user-specific systemd services (guardian-agent) - Configuring D-Bus policies for agent communication - Ensuring PAM modules are properly configured
The UserManager works closely with the Policy class to enforce time-based access controls and user quotas.
Security: All methods that accept usernames validate them against path traversal and use canonical system paths via pwd.getpwnam().
Parameters:
-
(policyPolicy, default:None) –The Policy instance containing user rules and configurations
-
(trackerSessionTracker, default:None) –The SessionTracker instance (optional, can be set later)
Note
The tracker can be set later using set_tracker() to avoid circular dependencies during initialization.
Methods:
-
check_if_locked–Check if a user account is currently locked by examining password status.
-
ensure_kids_group–Ensure the 'kids' group exists and all managed users are members of it.
-
ensure_pam_time_module–Ensures pam_time.so is active using two complementary approaches:
-
ensure_systemd_user_service–Ensure that systemd user services are set up for the given user without enabling lingering.
-
lock_user_account–Temporarily lock a user account to prevent login.
-
remove_time_rules–Remove time rules set by guardian-daemon from /etc/security/time.conf.
-
set_tracker–Set the session tracker after initialization to resolve circular dependencies.
-
setup_dbus_policy–Creates /etc/dbus-1/system.d/guardian.conf to allow managed users access to org.guardian.Daemon.
-
setup_user_login–Comprehensive setup for a user upon login.
-
setup_user_service–Sets up the guardian_agent.service for the given user's systemd.
-
sync_account_locks–Synchronize user account locks with their current quota status.
-
unlock_all_managed_users–Emergency function to unlock all managed user accounts.
-
unlock_user_account–Unlock a previously locked user account.
-
update_policy–Update the policy instance and re-evaluate rules.
-
user_exists–Check if a user exists on the system.
-
validate_username–Validate username format to prevent path traversal and injection attacks.
-
write_time_rules–Updates the time rules for all children according to the policy in /etc/security/time.conf,
check_if_locked
check_if_locked(username: str) -> bool
Check if a user account is currently locked by examining password status.
Parameters:
-
(usernamestr) –The username to check
Returns:
-
bool(bool) –True if account is locked, False otherwise
ensure_kids_group
Ensure the 'kids' group exists and all managed users are members of it. Also ensures all managed users are in the 'users' group to access agent files.
ensure_pam_time_module
Ensures pam_time.so is active using two complementary approaches:
-
Creates a custom authselect profile with pam_time.so in the system-auth stack (applies to all PAM services that include system-auth)
-
Directly modifies /etc/pam.d/sddm to explicitly include pam_time.so before the system-account include (ensuring SDDM enforces time restrictions even if authselect updates the system files)
This dual approach ensures maximum compatibility and resilience against system updates or configuration changes.
ensure_systemd_user_service
Ensure that systemd user services are set up for the given user without enabling lingering. Only starts the service if the user is actively logged in with a session.
Security: Validates username and uses pwd.getpwnam() to prevent path traversal.
lock_user_account
lock_user_account(username: str) -> bool
Temporarily lock a user account to prevent login. Uses usermod -L to disable password authentication.
Parameters:
-
(usernamestr) –The username to lock
Returns:
-
bool(bool) –True if successful, False otherwise
remove_time_rules
Remove time rules set by guardian-daemon from /etc/security/time.conf.
set_tracker
set_tracker(tracker: SessionTracker)
Set the session tracker after initialization to resolve circular dependencies.
setup_dbus_policy
Creates /etc/dbus-1/system.d/guardian.conf to allow managed users access to org.guardian.Daemon. Both 'kids' and 'users' groups are given permissions to support transition periods.
setup_user_login
Comprehensive setup for a user upon login. Ensures group membership, PAM rules, and systemd service are correctly configured.
setup_user_service
Sets up the guardian_agent.service for the given user's systemd. Updates the service file if its checksum has changed. Ensures correct directory structure and permissions.
Security: Validates username and uses pwd.getpwnam() to prevent path traversal.
sync_account_locks
async
Synchronize user account locks with their current quota status. Lock users who are out of time and within monitoring hours, unlock those who have time or are outside monitoring hours.
This should be called: - On daemon startup (to restore consistent state) - During quota reset - When curfew windows change
unlock_all_managed_users
Emergency function to unlock all managed user accounts. Used for manual recovery by administrators.
Returns:
-
int(int) –Number of users successfully unlocked
unlock_user_account
unlock_user_account(username: str) -> bool
Unlock a previously locked user account. Uses usermod -U to re-enable password authentication.
Parameters:
-
(usernamestr) –The username to unlock
Returns:
-
bool(bool) –True if successful, False otherwise
user_exists
user_exists(username)
Check if a user exists on the system.
Parameters:
-
–usernameThe username to check
Returns:
-
bool–True if user exists, False otherwise
validate_username
staticmethod
validate_username(username: str) -> bool
Validate username format to prevent path traversal and injection attacks.
Parameters:
-
(usernamestr) –The username to validate
Returns:
-
bool(bool) –True if username is valid, False otherwise
write_time_rules
Updates the time rules for all children according to the policy in /etc/security/time.conf, without overwriting foreign rules.
This method: 1. First checks if the file is excessively large and needs cleanup 2. Compares existing content with what we need to write 3. Only writes if content needs updating