1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15- // Integration with the systemd logind API. See http://www.freedesktop.org/wiki/Software/systemd/logind/
15+ // Package login1 provides integration with the systemd logind API. See http://www.freedesktop.org/wiki/Software/systemd/logind/
1616package login1
1717
1818import (
@@ -34,7 +34,7 @@ type Conn struct {
3434 object dbus.BusObject
3535}
3636
37- // New() establishes a connection to the system bus and authenticates.
37+ // New establishes a connection to the system bus and authenticates.
3838func New () (* Conn , error ) {
3939 c := new (Conn )
4040
@@ -74,6 +74,147 @@ func (c *Conn) initConnection() error {
7474 return nil
7575}
7676
77+ // Session object definition.
78+ type Session struct {
79+ ID string
80+ UID uint32
81+ User string
82+ Seat string
83+ Path dbus.ObjectPath
84+ }
85+
86+ // User object definition.
87+ type User struct {
88+ UID uint32
89+ Name string
90+ Path dbus.ObjectPath
91+ }
92+
93+ func (s Session ) toInterface () []interface {} {
94+ return []interface {}{s .ID , s .UID , s .User , s .Seat , s .Path }
95+ }
96+
97+ func sessionFromInterfaces (session []interface {}) (* Session , error ) {
98+ if len (session ) < 5 {
99+ return nil , fmt .Errorf ("invalid number of session fields: %d" , len (session ))
100+ }
101+ id , ok := session [0 ].(string )
102+ if ! ok {
103+ return nil , fmt .Errorf ("failed to typecast session field 0 to string" )
104+ }
105+ uid , ok := session [1 ].(uint32 )
106+ if ! ok {
107+ return nil , fmt .Errorf ("failed to typecast session field 1 to uint32" )
108+ }
109+ user , ok := session [2 ].(string )
110+ if ! ok {
111+ return nil , fmt .Errorf ("failed to typecast session field 2 to string" )
112+ }
113+ seat , ok := session [3 ].(string )
114+ if ! ok {
115+ return nil , fmt .Errorf ("failed to typecast session field 2 to string" )
116+ }
117+ path , ok := session [4 ].(dbus.ObjectPath )
118+ if ! ok {
119+ return nil , fmt .Errorf ("failed to typecast session field 4 to ObjectPath" )
120+ }
121+
122+ ret := Session {ID : id , UID : uid , User : user , Seat : seat , Path : path }
123+ return & ret , nil
124+ }
125+
126+ func userFromInterfaces (user []interface {}) (* User , error ) {
127+ if len (user ) < 3 {
128+ return nil , fmt .Errorf ("invalid number of user fields: %d" , len (user ))
129+ }
130+ uid , ok := user [0 ].(uint32 )
131+ if ! ok {
132+ return nil , fmt .Errorf ("failed to typecast user field 0 to uint32" )
133+ }
134+ name , ok := user [1 ].(string )
135+ if ! ok {
136+ return nil , fmt .Errorf ("failed to typecast session field 1 to string" )
137+ }
138+ path , ok := user [2 ].(dbus.ObjectPath )
139+ if ! ok {
140+ return nil , fmt .Errorf ("failed to typecast user field 2 to ObjectPath" )
141+ }
142+
143+ ret := User {UID : uid , Name : name , Path : path }
144+ return & ret , nil
145+ }
146+
147+ // GetSession may be used to get the session object path for the session with the specified ID.
148+ func (c * Conn ) GetSession (id string ) (dbus.ObjectPath , error ) {
149+ var out interface {}
150+ if err := c .object .Call (dbusInterface + ".GetSession" , 0 , id ).Store (& out ); err != nil {
151+ return "" , err
152+ }
153+
154+ ret , ok := out .(dbus.ObjectPath )
155+ if ! ok {
156+ return "" , fmt .Errorf ("failed to typecast session to ObjectPath" )
157+ }
158+
159+ return ret , nil
160+ }
161+
162+ // ListSessions returns an array with all current sessions.
163+ func (c * Conn ) ListSessions () ([]Session , error ) {
164+ out := [][]interface {}{}
165+ if err := c .object .Call (dbusInterface + ".ListSessions" , 0 ).Store (& out ); err != nil {
166+ return nil , err
167+ }
168+
169+ ret := []Session {}
170+ for _ , el := range out {
171+ session , err := sessionFromInterfaces (el )
172+ if err != nil {
173+ return nil , err
174+ }
175+ ret = append (ret , * session )
176+ }
177+ return ret , nil
178+ }
179+
180+ // ListUsers returns an array with all currently logged in users.
181+ func (c * Conn ) ListUsers () ([]User , error ) {
182+ out := [][]interface {}{}
183+ if err := c .object .Call (dbusInterface + ".ListUsers" , 0 ).Store (& out ); err != nil {
184+ return nil , err
185+ }
186+
187+ ret := []User {}
188+ for _ , el := range out {
189+ user , err := userFromInterfaces (el )
190+ if err != nil {
191+ return nil , err
192+ }
193+ ret = append (ret , * user )
194+ }
195+ return ret , nil
196+ }
197+
198+ // LockSession asks the session with the specified ID to activate the screen lock.
199+ func (c * Conn ) LockSession (id string ) {
200+ c .object .Call (dbusInterface + ".LockSession" , 0 , id )
201+ }
202+
203+ // LockSessions asks all sessions to activate the screen locks. This may be used to lock any access to the machine in one action.
204+ func (c * Conn ) LockSessions () {
205+ c .object .Call (dbusInterface + ".LockSessions" , 0 )
206+ }
207+
208+ // TerminateSession forcibly terminate one specific session.
209+ func (c * Conn ) TerminateSession (id string ) {
210+ c .object .Call (dbusInterface + ".TerminateSession" , 0 , id )
211+ }
212+
213+ // TerminateUser forcibly terminates all processes of a user.
214+ func (c * Conn ) TerminateUser (uid uint32 ) {
215+ c .object .Call (dbusInterface + ".TerminateUser" , 0 , uid )
216+ }
217+
77218// Reboot asks logind for a reboot optionally asking for auth.
78219func (c * Conn ) Reboot (askForAuth bool ) {
79220 c .object .Call (dbusInterface + ".Reboot" , 0 , askForAuth )
0 commit comments