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
@@ -85,6 +85,147 @@ func (c *Conn) initConnection() error {
8585 return nil
8686}
8787
88+ // Session object definition.
89+ type Session struct {
90+ ID string
91+ UID uint32
92+ User string
93+ Seat string
94+ Path dbus.ObjectPath
95+ }
96+
97+ // User object definition.
98+ type User struct {
99+ UID uint32
100+ Name string
101+ Path dbus.ObjectPath
102+ }
103+
104+ func (s Session ) toInterface () []interface {} {
105+ return []interface {}{s .ID , s .UID , s .User , s .Seat , s .Path }
106+ }
107+
108+ func sessionFromInterfaces (session []interface {}) (* Session , error ) {
109+ if len (session ) < 5 {
110+ return nil , fmt .Errorf ("invalid number of session fields: %d" , len (session ))
111+ }
112+ id , ok := session [0 ].(string )
113+ if ! ok {
114+ return nil , fmt .Errorf ("failed to typecast session field 0 to string" )
115+ }
116+ uid , ok := session [1 ].(uint32 )
117+ if ! ok {
118+ return nil , fmt .Errorf ("failed to typecast session field 1 to uint32" )
119+ }
120+ user , ok := session [2 ].(string )
121+ if ! ok {
122+ return nil , fmt .Errorf ("failed to typecast session field 2 to string" )
123+ }
124+ seat , ok := session [3 ].(string )
125+ if ! ok {
126+ return nil , fmt .Errorf ("failed to typecast session field 2 to string" )
127+ }
128+ path , ok := session [4 ].(dbus.ObjectPath )
129+ if ! ok {
130+ return nil , fmt .Errorf ("failed to typecast session field 4 to ObjectPath" )
131+ }
132+
133+ ret := Session {ID : id , UID : uid , User : user , Seat : seat , Path : path }
134+ return & ret , nil
135+ }
136+
137+ func userFromInterfaces (user []interface {}) (* User , error ) {
138+ if len (user ) < 3 {
139+ return nil , fmt .Errorf ("invalid number of user fields: %d" , len (user ))
140+ }
141+ uid , ok := user [0 ].(uint32 )
142+ if ! ok {
143+ return nil , fmt .Errorf ("failed to typecast user field 0 to uint32" )
144+ }
145+ name , ok := user [1 ].(string )
146+ if ! ok {
147+ return nil , fmt .Errorf ("failed to typecast session field 1 to string" )
148+ }
149+ path , ok := user [2 ].(dbus.ObjectPath )
150+ if ! ok {
151+ return nil , fmt .Errorf ("failed to typecast user field 2 to ObjectPath" )
152+ }
153+
154+ ret := User {UID : uid , Name : name , Path : path }
155+ return & ret , nil
156+ }
157+
158+ // GetSession may be used to get the session object path for the session with the specified ID.
159+ func (c * Conn ) GetSession (id string ) (dbus.ObjectPath , error ) {
160+ var out interface {}
161+ if err := c .object .Call (dbusInterface + ".GetSession" , 0 , id ).Store (& out ); err != nil {
162+ return "" , err
163+ }
164+
165+ ret , ok := out .(dbus.ObjectPath )
166+ if ! ok {
167+ return "" , fmt .Errorf ("failed to typecast session to ObjectPath" )
168+ }
169+
170+ return ret , nil
171+ }
172+
173+ // ListSessions returns an array with all current sessions.
174+ func (c * Conn ) ListSessions () ([]Session , error ) {
175+ out := [][]interface {}{}
176+ if err := c .object .Call (dbusInterface + ".ListSessions" , 0 ).Store (& out ); err != nil {
177+ return nil , err
178+ }
179+
180+ ret := []Session {}
181+ for _ , el := range out {
182+ session , err := sessionFromInterfaces (el )
183+ if err != nil {
184+ return nil , err
185+ }
186+ ret = append (ret , * session )
187+ }
188+ return ret , nil
189+ }
190+
191+ // ListUsers returns an array with all currently logged in users.
192+ func (c * Conn ) ListUsers () ([]User , error ) {
193+ out := [][]interface {}{}
194+ if err := c .object .Call (dbusInterface + ".ListUsers" , 0 ).Store (& out ); err != nil {
195+ return nil , err
196+ }
197+
198+ ret := []User {}
199+ for _ , el := range out {
200+ user , err := userFromInterfaces (el )
201+ if err != nil {
202+ return nil , err
203+ }
204+ ret = append (ret , * user )
205+ }
206+ return ret , nil
207+ }
208+
209+ // LockSession asks the session with the specified ID to activate the screen lock.
210+ func (c * Conn ) LockSession (id string ) {
211+ c .object .Call (dbusInterface + ".LockSession" , 0 , id )
212+ }
213+
214+ // LockSessions asks all sessions to activate the screen locks. This may be used to lock any access to the machine in one action.
215+ func (c * Conn ) LockSessions () {
216+ c .object .Call (dbusInterface + ".LockSessions" , 0 )
217+ }
218+
219+ // TerminateSession forcibly terminate one specific session.
220+ func (c * Conn ) TerminateSession (id string ) {
221+ c .object .Call (dbusInterface + ".TerminateSession" , 0 , id )
222+ }
223+
224+ // TerminateUser forcibly terminates all processes of a user.
225+ func (c * Conn ) TerminateUser (uid uint32 ) {
226+ c .object .Call (dbusInterface + ".TerminateUser" , 0 , uid )
227+ }
228+
88229// Reboot asks logind for a reboot optionally asking for auth.
89230func (c * Conn ) Reboot (askForAuth bool ) {
90231 c .object .Call (dbusInterface + ".Reboot" , 0 , askForAuth )
0 commit comments