187187# include <util.h>
188188#endif
189189
190+ #ifdef USE_LOGIND
191+ # include <systemd/sd-bus.h>
192+ #endif
193+
190194/**
191195 ** prototypes for helper functions in this file
192196 **/
@@ -200,6 +204,9 @@ void construct_utmp(struct logininfo *li, struct utmp *ut);
200204void set_utmpx_time (struct logininfo * li , struct utmpx * ut );
201205void construct_utmpx (struct logininfo * li , struct utmpx * ut );
202206#endif
207+ #ifdef USE_LOGIND
208+ int logind_set_tty (struct logininfo * li );
209+ #endif
203210
204211int utmp_write_entry (struct logininfo * li );
205212int utmpx_write_entry (struct logininfo * li );
@@ -467,6 +474,9 @@ login_write(struct logininfo *li)
467474#ifdef USE_WTMPX
468475 wtmpx_write_entry (li );
469476#endif
477+ #ifdef USE_LOGIND
478+ logind_set_tty (li );
479+ #endif
470480#ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN
471481 if (li -> type == LTYPE_LOGIN &&
472482 !sys_auth_record_login (li -> username ,li -> hostname ,li -> line ,
@@ -1409,6 +1419,88 @@ wtmpx_get_entry(struct logininfo *li)
14091419}
14101420#endif /* USE_WTMPX */
14111421
1422+ #ifdef USE_LOGIND
1423+ #define DBUS_DESTINATION "org.freedesktop.login1"
1424+ #define DBUS_PATH_ID "/org/freedesktop/login1/session/auto"
1425+ #define DBUS_INTERFACE "org.freedesktop.login1.Session"
1426+ #define DBUS_PATH "/org/freedesktop/login1/session/%s"
1427+
1428+ static int
1429+ logind_perform_login (struct logininfo * li )
1430+ {
1431+ sd_bus * bus = NULL ;
1432+ sd_bus_error error = SD_BUS_ERROR_NULL ;
1433+ char * session_id = NULL ;
1434+ char * dbus_path ;
1435+ const char * tty ;
1436+ char buf [PATH_MAX ];
1437+ int r ;
1438+ int fd ;
1439+
1440+ if (sd_bus_open_system (& bus ) < 0 )
1441+ {
1442+ logit ("logind: canot open dbus" );
1443+ return (0 );
1444+ }
1445+
1446+ if (sd_bus_get_property_string (bus , DBUS_DESTINATION ,
1447+ DBUS_PATH_ID , DBUS_INTERFACE ,
1448+ "Id" , & error , & session_id ) < 0 )
1449+ {
1450+ logit ("logind: cannot get session ID" );
1451+ return (0 );
1452+ }
1453+
1454+ if (strncmp (li -> line , "/dev/" , 5 ) != 0 )
1455+ snprintf (buf , sizeof (buf ), "/dev/%s" , li -> line );
1456+ else
1457+ tty = li -> line ;
1458+
1459+ fd = open (tty , O_RDWR |O_CLOEXEC |O_NOCTTY );
1460+
1461+ if (asprintf (& dbus_path , DBUS_PATH , session_id ) < 0 )
1462+ return (0 );
1463+
1464+ if (sd_bus_call_method (bus , DBUS_DESTINATION , dbus_path ,
1465+ DBUS_INTERFACE , "TakeControl" , & error , NULL ,
1466+ "b" , 1 ) < 0 ) {
1467+ logit ("logind: cannot take control" );
1468+ free (dbus_path );
1469+ return (0 );
1470+ }
1471+
1472+ if ((r = sd_bus_call_method (bus , DBUS_DESTINATION , dbus_path ,
1473+ DBUS_INTERFACE , "SetTTY" , & error , NULL ,
1474+ "h" , fd )) < 0 ) {
1475+ if (r != - EBADR ) /* logind does not support "SetTTY" */
1476+ logit ("logind: cannot set TTY(%s, %s): %s" , session_id , tty , strerror (- r ));
1477+ free (dbus_path );
1478+ return (0 );
1479+ }
1480+
1481+ free (dbus_path );
1482+
1483+ if (sd_bus_flush (bus ) < 0 )
1484+ return (0 );
1485+
1486+ return (1 );
1487+ }
1488+
1489+ int
1490+ logind_set_tty (struct logininfo * li )
1491+ {
1492+ switch (li -> type ) {
1493+ case LTYPE_LOGIN :
1494+ return (logind_perform_login (li ));
1495+ case LTYPE_LOGOUT :
1496+ return (1 );
1497+ default :
1498+ logit ("%s: invalid type field" , __func__ );
1499+ return (0 );
1500+ }
1501+ }
1502+ #endif
1503+
14121504/**
14131505 ** Low-level libutil login() functions
14141506 **/
0 commit comments