Compare commits
11 Commits
46.3
...
wip/identi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0062544c09 | ||
|
|
d9785198a8 | ||
|
|
56d6308342 | ||
|
|
112e0cd399 | ||
|
|
53f91662b2 | ||
|
|
93cb3a470c | ||
|
|
c0e63417f9 | ||
|
|
8c2329e409 | ||
|
|
83f7135a03 | ||
|
|
f87057b4c4 | ||
|
|
24afc5e651 |
89
configure.ac
89
configure.ac
@@ -62,6 +62,11 @@ else
|
||||
SYSTEMD=
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([kerberos],
|
||||
AS_HELP_STRING([--enable-kerberos], [Use Kerberos]),
|
||||
[with_kerberos=$enableval],
|
||||
[with_kerberos=auto])
|
||||
|
||||
dnl ==============================================
|
||||
dnl Check that we meet the dependencies
|
||||
dnl ==============================================
|
||||
@@ -200,6 +205,31 @@ else
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_CHEESE, test x${have_cheese} = xyes)
|
||||
|
||||
AC_PATH_PROG([KRB5_CONFIG], krb5-config, none, $PATH:/usr/kerberos/bin)
|
||||
|
||||
if test "x$KRB5_CONFIG" != "xnone"; then
|
||||
KRB5_LIBS="`${KRB5_CONFIG} --libs krb5`"
|
||||
KRB5_CFLAGS="`${KRB5_CONFIG} --cflags krb5`"
|
||||
have_kerberos=yes
|
||||
else
|
||||
KRB5_LIBS=""
|
||||
KRB5_CFLAGS=""
|
||||
have_kerberos=no
|
||||
fi
|
||||
AC_SUBST(KRB5_CFLAGS)
|
||||
AC_SUBST(KRB5_LIBS)
|
||||
|
||||
if test "$with_kerberos" != "no" ; then
|
||||
if test "$have_kerberos" = "no" ; then
|
||||
AC_MSG_ERROR([kerberos support requested, but not available])
|
||||
fi
|
||||
AC_DEFINE(HAVE_KERBEROS, 1, [Define to 1 if kerberos is available])
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_KERBEROS, [test x$with_kerberos != xno])
|
||||
|
||||
USER_ACCOUNTS_PANEL_CFLAGS="$USER_ACCOUNTS_PANEL_CFLAGS $KRB5_CFLAGS"
|
||||
USER_ACCOUNTS_PANEL_LIBS="$USER_ACCOUNTS_PANEL_LIBS $KRB5_LIBS"
|
||||
|
||||
# wacom is disabled for s390/s390x and non Linux platforms (needs udev)
|
||||
case $host_os in
|
||||
linux*)
|
||||
@@ -270,6 +300,59 @@ AC_SUBST(PANEL_LIBS)
|
||||
PANEL_LDFLAGS="-export_dynamic -avoid-version -module -no-undefined -export-symbols-regex '^g_io_module_(load|unload)'"
|
||||
AC_SUBST(PANEL_LDFLAGS)
|
||||
|
||||
dnl ==================================================
|
||||
dnl timerfd support
|
||||
dnl ==================================================
|
||||
AC_MSG_CHECKING([for timerfd support])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
|
||||
#include <sys/timerfd.h>
|
||||
#include <unistd.h>
|
||||
],[
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
struct itimerspec timer_spec = { 0 };
|
||||
timerfd_settime (timerfd_create (CLOCK_MONOTONIC, TFD_CLOEXEC),
|
||||
TFD_TIMER_ABSTIME,
|
||||
&timer_spec,
|
||||
NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
])],
|
||||
[have_timerfd=yes],
|
||||
[have_timerfd=no])
|
||||
AC_MSG_RESULT($have_timerfd)
|
||||
if test x"$have_timerfd" = x"yes"; then
|
||||
AC_DEFINE(HAVE_TIMERFD, 1, [have timerfd support])
|
||||
|
||||
dnl libc headers tend to trail kernel support
|
||||
dnl so compensate if necessary
|
||||
AC_MSG_CHECKING([for timerfd cancel-on-set support])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
|
||||
#include <sys/timerfd.h>
|
||||
#include <unistd.h>
|
||||
],[
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
struct itimerspec timer_spec = { 0 };
|
||||
timerfd_settime (timerfd_create (CLOCK_MONOTONIC, TFD_CLOEXEC),
|
||||
TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET,
|
||||
&timer_spec,
|
||||
NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
])],
|
||||
[have_tfd_timer_cancel_on_set=yes],
|
||||
[have_tfd_timer_cancel_on_set=no])
|
||||
AC_MSG_RESULT($have_tfd_timer_cancel_on_set)
|
||||
if test x"$have_tfd_timer_cancel_on_set" = x"no"; then
|
||||
AC_DEFINE(TFD_TIMER_CANCEL_ON_SET, [(1 << 1)], [have timerfd support])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl ==============================================
|
||||
dnl libsocialweb
|
||||
dnl ==============================================
|
||||
@@ -487,6 +570,12 @@ if test "x$have_cheese" = "xyes"; then
|
||||
else
|
||||
AC_MSG_NOTICE([ Users panel webcam support disabled])
|
||||
fi
|
||||
if test "x$with_kerberos" != "xno"; then
|
||||
AC_MSG_NOTICE([** Kerberos (Users panel Kerberos support)])
|
||||
else
|
||||
AC_MSG_NOTICE([ Users panel Kerberos support disabled])
|
||||
fi
|
||||
|
||||
if test "x$with_libsocialweb" = "xyes"; then
|
||||
AC_MSG_NOTICE([** libsocialweb (Background panel Flickr support)])
|
||||
else
|
||||
|
||||
@@ -30,6 +30,13 @@ BUILT_SOURCES = \
|
||||
libuser_accounts_la_SOURCES = \
|
||||
um-account-type.h \
|
||||
um-account-type.c \
|
||||
gsd-alarm.h \
|
||||
gsd-alarm.c \
|
||||
gsd-identity-manager.h \
|
||||
gsd-identity-manager.c \
|
||||
gsd-identity.h \
|
||||
gsd-identity.c \
|
||||
$(kerberos_sources) \
|
||||
um-user.h \
|
||||
um-user.c \
|
||||
um-user-manager.h \
|
||||
@@ -62,6 +69,15 @@ libuser_accounts_la_SOURCES = \
|
||||
um-realm-manager.h \
|
||||
$(BUILT_SOURCES)
|
||||
|
||||
if BUILD_KERBEROS
|
||||
libuser_accounts_la_SOURCES += \
|
||||
gsd-kerberos-identity-manager.h \
|
||||
gsd-kerberos-identity-manager.c \
|
||||
gsd-kerberos-identity.h \
|
||||
gsd-kerberos-identity.c
|
||||
endif
|
||||
|
||||
|
||||
libuser_accounts_la_LIBADD = \
|
||||
$(PANEL_LIBS) \
|
||||
$(USER_ACCOUNTS_PANEL_LIBS) \
|
||||
|
||||
@@ -12,6 +12,16 @@
|
||||
-->
|
||||
<interface name="org.freedesktop.realmd.Provider">
|
||||
|
||||
<!--
|
||||
* The name of the provider
|
||||
-->
|
||||
<property name="Name" type="s" access="read"/>
|
||||
|
||||
<!--
|
||||
* A version number for the provider
|
||||
-->
|
||||
<property name="Version" type="s" access="read"/>
|
||||
|
||||
<!--
|
||||
* A list of known, enrolled or discovered realms.
|
||||
* Each realm is a DBus object and is represeted by a:
|
||||
@@ -29,6 +39,8 @@
|
||||
<!-- The input string -->
|
||||
<arg name="string" type="s" direction="in"/>
|
||||
|
||||
<arg name="operation_id" type="s" direction="in"/>
|
||||
|
||||
<!-- Returned match relevance -->
|
||||
<arg name="relevance" type="i" direction="out"/>
|
||||
|
||||
@@ -47,6 +59,7 @@
|
||||
<interface name="org.freedesktop.realmd.Diagnostics">
|
||||
<signal name="Diagnostics">
|
||||
<arg name="data" type="s"/>
|
||||
<arg name="operation_id" type="s"/>
|
||||
</signal>
|
||||
</interface>
|
||||
|
||||
@@ -65,6 +78,11 @@
|
||||
-->
|
||||
<property name="Domain" type="s" access="read"/>
|
||||
|
||||
<!--
|
||||
* The server software, for information only. eg: active-directory
|
||||
-->
|
||||
<property name="Details" type="a{ss}" access="read"/>
|
||||
|
||||
<!--
|
||||
* The suggested Administrator login name for this realm
|
||||
-->
|
||||
@@ -83,6 +101,7 @@
|
||||
<arg name="principal" type="s" direction="in"/>
|
||||
<arg name="password" type="s" direction="in"/>
|
||||
<arg name="options" type="a{sv}" direction="in"/>
|
||||
<arg name="operation_id" type="s" direction="in"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
@@ -95,6 +114,7 @@
|
||||
<annotation name="org.gtk.GDBus.C.ForceGVariant" value="yup"/>
|
||||
</arg>
|
||||
<arg name="options" type="a{sv}" direction="in"/>
|
||||
<arg name="operation_id" type="s" direction="in"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
@@ -105,6 +125,7 @@
|
||||
<arg name="principal" type="s" direction="in"/>
|
||||
<arg name="password" type="s" direction="in"/>
|
||||
<arg name="options" type="a{sv}" direction="in"/>
|
||||
<arg name="operation_id" type="s" direction="in"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
@@ -117,6 +138,7 @@
|
||||
<annotation name="org.gtk.GDBus.C.ForceGVariant" value="yup"/>
|
||||
</arg>
|
||||
<arg name="options" type="a{sv}" direction="in"/>
|
||||
<arg name="operation_id" type="s" direction="in"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
@@ -139,6 +161,7 @@
|
||||
<method name="ChangePermittedLogins">
|
||||
<arg name="add" type="as" direction="in"/>
|
||||
<arg name="remove" type="as" direction="in"/>
|
||||
<arg name="operation_id" type="s" direction="in"/>
|
||||
</method>
|
||||
|
||||
</interface>
|
||||
|
||||
@@ -131,11 +131,10 @@
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table1">
|
||||
<object class="GtkGrid" id="user-grid">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">7</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">10</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkNotebook" id="account-fingerprint-notebook">
|
||||
<property name="visible">True</property>
|
||||
@@ -167,10 +166,9 @@
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">6</property>
|
||||
<property name="bottom_attach">7</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
@@ -180,17 +178,18 @@
|
||||
<property name="text-column">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="account-type-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="halign">GTK_ALIGN_END</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Account _type</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">account-type-combo</property>
|
||||
@@ -199,10 +198,10 @@
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
@@ -223,15 +222,18 @@
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="login-options-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="halign">GTK_ALIGN_END</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="ypad">5</property>
|
||||
<property name="label" translatable="yes">Login Options</property>
|
||||
<attributes>
|
||||
@@ -239,16 +241,18 @@
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="password-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="halign">GTK_ALIGN_END</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">_Password</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">account-password-button</property>
|
||||
@@ -257,28 +261,66 @@
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="UmEditableButton" id="account-password-button">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="other-passwords-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="halign">GTK_ALIGN_START</property>
|
||||
<property name="hexpand">TRUE</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="other-passwords-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Other Passwords…</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">6</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="accessible-realms-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="halign">GTK_ALIGN_END</property>
|
||||
<property name="hexpand">TRUE</property>
|
||||
<property name="label" translatable="yes">Accessible Realms</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">7</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="autologin-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="halign">GTK_ALIGN_END</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">A_utomatic Login</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">autologin-switch</property>
|
||||
@@ -287,10 +329,10 @@
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">8</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
@@ -311,17 +353,18 @@
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">8</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="account-fingerprint-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="halign">GTK_ALIGN_END</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">_Fingerprint Login</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">account-fingerprint-button</property>
|
||||
@@ -330,15 +373,17 @@
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">6</property>
|
||||
<property name="bottom_attach">7</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">9</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="halign">GTK_ALIGN_END</property>
|
||||
<property name="hexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
@@ -399,14 +444,18 @@
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="language-label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="halign">GTK_ALIGN_END</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">_Language</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">account-language-combo</property>
|
||||
@@ -415,10 +464,10 @@
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
@@ -428,12 +477,10 @@
|
||||
<property name="text-column">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">0</property>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
549
panels/user-accounts/gsd-alarm.c
Normal file
549
panels/user-accounts/gsd-alarm.c
Normal file
@@ -0,0 +1,549 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Ray Strode
|
||||
* Based on work by Colin Walters
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gsd-alarm.h"
|
||||
|
||||
#ifdef HAVE_TIMERFD
|
||||
#include <sys/timerfd.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
|
||||
typedef struct {
|
||||
GSource *source;
|
||||
GInputStream *stream;
|
||||
} Timer;
|
||||
|
||||
typedef struct {
|
||||
GSource *source;
|
||||
} Timeout;
|
||||
|
||||
#define MAX_TIMEOUT_INTERVAL (10 * 1000)
|
||||
|
||||
typedef enum {
|
||||
GSD_ALARM_TYPE_UNSCHEDULED,
|
||||
GSD_ALARM_TYPE_TIMER,
|
||||
GSD_ALARM_TYPE_TIMEOUT,
|
||||
} GsdAlarmType;
|
||||
|
||||
struct _GsdAlarmPrivate
|
||||
{
|
||||
GCancellable *cancellable;
|
||||
GDateTime *time;
|
||||
GDateTime *previous_wakeup_time;
|
||||
GMainContext *context;
|
||||
GSource *immediate_wakeup_source;
|
||||
GRecMutex lock;
|
||||
|
||||
GsdAlarmType type;
|
||||
union {
|
||||
Timer timer;
|
||||
Timeout timeout;
|
||||
};
|
||||
};
|
||||
|
||||
enum {
|
||||
FIRED,
|
||||
REARMED,
|
||||
NUMBER_OF_SIGNALS,
|
||||
};
|
||||
|
||||
static void schedule_wakeups (GsdAlarm *self);
|
||||
static void schedule_wakeups_with_timeout_source (GsdAlarm *self);
|
||||
static guint signals[NUMBER_OF_SIGNALS] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (GsdAlarm, gsd_alarm, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
clear_scheduled_immediate_wakeup (GsdAlarm *self)
|
||||
{
|
||||
g_clear_pointer (&self->priv->immediate_wakeup_source,
|
||||
(GDestroyNotify)
|
||||
g_source_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_scheduled_timer_wakeups (GsdAlarm *self)
|
||||
{
|
||||
#ifdef HAVE_TIMERFD
|
||||
GError *error;
|
||||
gboolean is_closed;
|
||||
|
||||
g_clear_pointer (&self->priv->timer.source,
|
||||
(GDestroyNotify)
|
||||
g_source_destroy);
|
||||
|
||||
error = NULL;
|
||||
is_closed = g_input_stream_close (self->priv->timer.stream,
|
||||
NULL,
|
||||
&error);
|
||||
|
||||
if (!is_closed) {
|
||||
g_warning ("GsdAlarm: could not close timer stream: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_clear_object (&self->priv->timer.stream);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
clear_scheduled_timeout_wakeups (GsdAlarm *self)
|
||||
{
|
||||
g_clear_pointer (&self->priv->timeout.source,
|
||||
(GDestroyNotify)
|
||||
g_source_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_scheduled_wakeups (GsdAlarm *self)
|
||||
{
|
||||
g_rec_mutex_lock (&self->priv->lock);
|
||||
clear_scheduled_immediate_wakeup (self);
|
||||
|
||||
switch (self->priv->type) {
|
||||
case GSD_ALARM_TYPE_TIMER:
|
||||
clear_scheduled_timer_wakeups (self);
|
||||
break;
|
||||
|
||||
case GSD_ALARM_TYPE_TIMEOUT:
|
||||
clear_scheduled_timeout_wakeups (self);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_clear_object (&self->priv->cancellable);
|
||||
|
||||
g_clear_pointer (&self->priv->context,
|
||||
(GDestroyNotify)
|
||||
g_main_context_unref);
|
||||
|
||||
g_clear_pointer (&self->priv->previous_wakeup_time,
|
||||
(GDestroyNotify)
|
||||
g_date_time_unref);
|
||||
|
||||
g_clear_pointer (&self->priv->time,
|
||||
(GDestroyNotify)
|
||||
g_date_time_unref);
|
||||
|
||||
g_assert (self->priv->timeout.source == NULL);
|
||||
|
||||
self->priv->type = GSD_ALARM_TYPE_UNSCHEDULED;
|
||||
g_rec_mutex_unlock (&self->priv->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_alarm_finalize (GObject *object)
|
||||
{
|
||||
GsdAlarm *self = GSD_ALARM (object);
|
||||
|
||||
clear_scheduled_wakeups (self);
|
||||
|
||||
G_OBJECT_CLASS (gsd_alarm_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_alarm_class_init (GsdAlarmClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gsd_alarm_finalize;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GsdAlarmPrivate));
|
||||
|
||||
signals[FIRED] = g_signal_new ("fired",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
signals[REARMED] = g_signal_new ("rearmed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_alarm_init (GsdAlarm *self)
|
||||
{
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||
GSD_TYPE_ALARM,
|
||||
GsdAlarmPrivate);
|
||||
self->priv->type = GSD_ALARM_TYPE_UNSCHEDULED;
|
||||
g_rec_mutex_init (&self->priv->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
on_cancelled (GCancellable *cancellable,
|
||||
gpointer user_data)
|
||||
{
|
||||
GsdAlarm *self = GSD_ALARM (user_data);
|
||||
|
||||
clear_scheduled_wakeups (self);
|
||||
}
|
||||
|
||||
static void
|
||||
fire_alarm (GsdAlarm *self)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (self), signals[FIRED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
rearm_alarm (GsdAlarm *self)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (self), signals[REARMED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
fire_or_rearm_alarm (GsdAlarm *self)
|
||||
{
|
||||
GTimeSpan time_until_fire;
|
||||
GTimeSpan previous_time_until_fire;
|
||||
GDateTime *now;
|
||||
|
||||
now = g_date_time_new_now_local ();
|
||||
time_until_fire = g_date_time_difference (self->priv->time, now);
|
||||
|
||||
if (self->priv->previous_wakeup_time == NULL) {
|
||||
self->priv->previous_wakeup_time = now;
|
||||
|
||||
/* If, according to the time, we're past when we should have fired,
|
||||
* then fire the alarm.
|
||||
*/
|
||||
if (time_until_fire <= 0) {
|
||||
fire_alarm (self);
|
||||
}
|
||||
} else {
|
||||
previous_time_until_fire = g_date_time_difference (self->priv->time,
|
||||
self->priv->previous_wakeup_time);
|
||||
|
||||
g_date_time_unref (self->priv->previous_wakeup_time);
|
||||
self->priv->previous_wakeup_time = now;
|
||||
|
||||
/* If, according to the time, we're past when we should have fired,
|
||||
* and this is the first wakeup where that's been true then fire
|
||||
* the alarm. The first check makes sure we don't fire prematurely,
|
||||
* and the second check makes sure we don't fire more than once
|
||||
*/
|
||||
if (time_until_fire <= 0 && previous_time_until_fire > 0) {
|
||||
fire_alarm (self);
|
||||
|
||||
/* If, according to the time, we're before when we should fire,
|
||||
* and we previously fired the alarm, then we've jumped back in
|
||||
* time and need to rearm the alarm.
|
||||
*/
|
||||
} else if (time_until_fire > 0 && previous_time_until_fire <= 0) {
|
||||
rearm_alarm (self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_immediate_wakeup_source_ready (GsdAlarm *self)
|
||||
{
|
||||
g_return_val_if_fail (self->priv->type != GSD_ALARM_TYPE_UNSCHEDULED, FALSE);
|
||||
|
||||
g_rec_mutex_lock (&self->priv->lock);
|
||||
if (g_cancellable_is_cancelled (self->priv->cancellable)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
fire_or_rearm_alarm (self);
|
||||
|
||||
out:
|
||||
g_rec_mutex_unlock (&self->priv->lock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TIMERFD
|
||||
static gboolean
|
||||
on_timer_source_ready (GObject *stream,
|
||||
GsdAlarm *self)
|
||||
{
|
||||
gint64 number_of_fires;
|
||||
gssize bytes_read;
|
||||
gboolean run_again = FALSE;
|
||||
|
||||
g_return_val_if_fail (GSD_IS_ALARM (self), FALSE);
|
||||
g_return_val_if_fail (self->priv->type == GSD_ALARM_TYPE_TIMER, FALSE);
|
||||
|
||||
g_rec_mutex_lock (&self->priv->lock);
|
||||
if (g_cancellable_is_cancelled (self->priv->cancellable)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
bytes_read = g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (stream),
|
||||
&number_of_fires,
|
||||
sizeof (gint64),
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (bytes_read == sizeof (gint64)) {
|
||||
if (number_of_fires < 0 || number_of_fires > 1) {
|
||||
g_warning ("GsdAlarm: expected timerfd to report firing once,"
|
||||
"but it reported firing %ld times\n",
|
||||
(long) number_of_fires);
|
||||
}
|
||||
}
|
||||
|
||||
fire_or_rearm_alarm (self);
|
||||
run_again = TRUE;
|
||||
out:
|
||||
g_rec_mutex_unlock (&self->priv->lock);
|
||||
return run_again;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_timer_source_pointer (GsdAlarm *self)
|
||||
{
|
||||
self->priv->timer.source = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
schedule_wakeups_with_timerfd (GsdAlarm *self)
|
||||
{
|
||||
#ifdef HAVE_TIMERFD
|
||||
struct itimerspec timer_spec;
|
||||
int fd;
|
||||
int result;
|
||||
static gboolean seen_before = FALSE;
|
||||
|
||||
if (!seen_before) {
|
||||
g_debug ("GsdAlarm: trying to use kernel timer");
|
||||
seen_before = TRUE;
|
||||
}
|
||||
|
||||
fd = timerfd_create (CLOCK_REALTIME, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||
|
||||
if (fd < 0) {
|
||||
g_debug ("GsdAlarm: could not create timer fd: %m");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset (&timer_spec, 0, sizeof (timer_spec));
|
||||
timer_spec.it_value.tv_sec = g_date_time_to_unix (self->priv->time) + 1;
|
||||
|
||||
result = timerfd_settime (fd,
|
||||
TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET,
|
||||
&timer_spec,
|
||||
NULL);
|
||||
|
||||
if (result < 0) {
|
||||
g_debug ("GsdAlarm: could not set timer: %m");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->priv->type = GSD_ALARM_TYPE_TIMER;
|
||||
self->priv->timer.stream = g_unix_input_stream_new (fd, TRUE);
|
||||
|
||||
self->priv->timer.source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (self->priv->timer.stream),
|
||||
self->priv->cancellable);
|
||||
g_source_set_callback (self->priv->timer.source,
|
||||
(GSourceFunc)
|
||||
on_timer_source_ready,
|
||||
self,
|
||||
(GDestroyNotify)
|
||||
clear_timer_source_pointer);
|
||||
g_source_attach (self->priv->timer.source,
|
||||
self->priv->context);
|
||||
g_source_unref (self->priv->timer.source);
|
||||
|
||||
return TRUE;
|
||||
|
||||
#endif /* HAVE_TIMERFD */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_timeout_source_ready (GsdAlarm *self)
|
||||
{
|
||||
g_return_val_if_fail (GSD_IS_ALARM (self), FALSE);
|
||||
|
||||
g_rec_mutex_lock (&self->priv->lock);
|
||||
|
||||
if (g_cancellable_is_cancelled (self->priv->cancellable) ||
|
||||
self->priv->type == GSD_ALARM_TYPE_UNSCHEDULED) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
fire_or_rearm_alarm (self);
|
||||
|
||||
if (g_cancellable_is_cancelled (self->priv->cancellable)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
schedule_wakeups_with_timeout_source (self);
|
||||
|
||||
out:
|
||||
g_rec_mutex_unlock (&self->priv->lock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_timeout_source_pointer (GsdAlarm *self)
|
||||
{
|
||||
self->priv->timeout.source = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
schedule_wakeups_with_timeout_source (GsdAlarm *self)
|
||||
{
|
||||
GDateTime *now;
|
||||
GTimeSpan time_span;
|
||||
guint interval;
|
||||
|
||||
self->priv->type = GSD_ALARM_TYPE_TIMEOUT;
|
||||
|
||||
now = g_date_time_new_now_local ();
|
||||
time_span = g_date_time_difference (self->priv->time, now);
|
||||
g_date_time_unref (now);
|
||||
|
||||
time_span = CLAMP (time_span, 1000 * G_TIME_SPAN_MILLISECOND, G_MAXUINT * G_TIME_SPAN_MILLISECOND);
|
||||
interval = (guint) time_span / G_TIME_SPAN_MILLISECOND;
|
||||
|
||||
/* We poll every 10 seconds or so because we want to catch time skew
|
||||
*/
|
||||
interval = MIN (interval, MAX_TIMEOUT_INTERVAL);
|
||||
|
||||
self->priv->timeout.source = g_timeout_source_new (interval);
|
||||
g_source_set_callback (self->priv->timeout.source,
|
||||
(GSourceFunc)
|
||||
on_timeout_source_ready,
|
||||
self,
|
||||
(GDestroyNotify)
|
||||
clear_timeout_source_pointer);
|
||||
|
||||
g_source_attach (self->priv->timeout.source,
|
||||
self->priv->context);
|
||||
g_source_unref (self->priv->timeout.source);
|
||||
}
|
||||
|
||||
static void
|
||||
schedule_wakeups (GsdAlarm *self)
|
||||
{
|
||||
gboolean wakeup_scheduled;
|
||||
|
||||
wakeup_scheduled = schedule_wakeups_with_timerfd (self);
|
||||
|
||||
if (!wakeup_scheduled) {
|
||||
static gboolean seen_before = FALSE;
|
||||
|
||||
if (!seen_before) {
|
||||
g_debug ("GsdAlarm: falling back to polling timeout");
|
||||
seen_before = TRUE;
|
||||
}
|
||||
schedule_wakeups_with_timeout_source (self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clear_immediate_wakeup_source_pointer (GsdAlarm *self)
|
||||
{
|
||||
self->priv->immediate_wakeup_source = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
schedule_immediate_wakeup (GsdAlarm *self)
|
||||
{
|
||||
self->priv->immediate_wakeup_source = g_idle_source_new ();
|
||||
|
||||
g_source_set_callback (self->priv->immediate_wakeup_source,
|
||||
(GSourceFunc)
|
||||
on_immediate_wakeup_source_ready,
|
||||
self,
|
||||
(GDestroyNotify)
|
||||
clear_immediate_wakeup_source_pointer);
|
||||
g_source_attach (self->priv->immediate_wakeup_source,
|
||||
self->priv->context);
|
||||
g_source_unref (self->priv->immediate_wakeup_source);
|
||||
}
|
||||
|
||||
void
|
||||
gsd_alarm_set_time (GsdAlarm *self,
|
||||
GDateTime *time,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
if (g_cancellable_is_cancelled (cancellable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->priv->cancellable != NULL) {
|
||||
if (!g_cancellable_is_cancelled (self->priv->cancellable)) {
|
||||
g_cancellable_cancel (cancellable);
|
||||
}
|
||||
|
||||
g_object_unref (self->priv->cancellable);
|
||||
self->priv->cancellable = NULL;
|
||||
}
|
||||
|
||||
if (cancellable == NULL) {
|
||||
self->priv->cancellable = g_cancellable_new ();
|
||||
} else {
|
||||
self->priv->cancellable = g_object_ref (cancellable);
|
||||
}
|
||||
|
||||
g_cancellable_connect (self->priv->cancellable,
|
||||
G_CALLBACK (on_cancelled),
|
||||
self,
|
||||
NULL);
|
||||
self->priv->time = g_date_time_ref (time);
|
||||
self->priv->context = g_main_context_ref (g_main_context_default ());
|
||||
|
||||
schedule_wakeups (self);
|
||||
|
||||
/* Wake up right away, in case it's already expired leaving the gate */
|
||||
schedule_immediate_wakeup (self);
|
||||
}
|
||||
|
||||
GDateTime *
|
||||
gsd_alarm_get_time (GsdAlarm *self)
|
||||
{
|
||||
return self->priv->time;
|
||||
}
|
||||
|
||||
GsdAlarm *
|
||||
gsd_alarm_new (void)
|
||||
{
|
||||
GsdAlarm *self;
|
||||
|
||||
self = GSD_ALARM (g_object_new (GSD_TYPE_ALARM, NULL));
|
||||
|
||||
return GSD_ALARM (self);
|
||||
}
|
||||
67
panels/user-accounts/gsd-alarm.h
Normal file
67
panels/user-accounts/gsd-alarm.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors: Ray Strode
|
||||
*/
|
||||
|
||||
#ifndef __GSD_ALARM_H__
|
||||
#define __GSD_ALARM_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSD_TYPE_ALARM (gsd_alarm_get_type ())
|
||||
#define GSD_ALARM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_ALARM, GsdAlarm))
|
||||
#define GSD_ALARM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_ALARM, GsdAlarmClass))
|
||||
#define GSD_IS_ALARM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_ALARM))
|
||||
#define GSD_IS_ALARM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSD_TYPE_ALARM))
|
||||
#define GSD_ALARM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GSD_TYPE_ALARM, GsdAlarmClass))
|
||||
|
||||
typedef struct _GsdAlarm GsdAlarm;
|
||||
typedef struct _GsdAlarmClass GsdAlarmClass;
|
||||
typedef struct _GsdAlarmPrivate GsdAlarmPrivate;
|
||||
|
||||
struct _GsdAlarm
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GsdAlarmPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GsdAlarmClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* fired) (GsdAlarm *alarm);
|
||||
void (* rearmed) (GsdAlarm *alarm);
|
||||
};
|
||||
|
||||
GType gsd_alarm_get_type (void);
|
||||
|
||||
GsdAlarm *gsd_alarm_new (void);
|
||||
void gsd_alarm_set_time (GsdAlarm *alarm,
|
||||
GDateTime *time,
|
||||
GCancellable *cancellable);
|
||||
GDateTime *gsd_alarm_get_time (GsdAlarm *alarm);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSD_ALARM_H__ */
|
||||
36
panels/user-accounts/gsd-identity-inquiry-private.h
Normal file
36
panels/user-accounts/gsd-identity-inquiry-private.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors: Ray Strode
|
||||
*/
|
||||
|
||||
#ifndef __GSD_IDENTITY_INQUIRY_PRIVATE_H__
|
||||
#define __GSD_IDENTITY_INQUIRY_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "gsd-identity-inquiry.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _gsd_identity_inquiry_emit_complete (GsdIdentityInquiry *inquiry);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSD_IDENTITY_INQUIRY_PRIVATE_H__ */
|
||||
146
panels/user-accounts/gsd-identity-inquiry.c
Normal file
146
panels/user-accounts/gsd-identity-inquiry.c
Normal file
@@ -0,0 +1,146 @@
|
||||
/* -*- Mode: C; tab-width: 8; ident-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Ray Strode
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gsd-identity-inquiry.h"
|
||||
#include "gsd-identity-inquiry-private.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
enum {
|
||||
COMPLETE,
|
||||
NUMBER_OF_SIGNALS,
|
||||
};
|
||||
|
||||
static guint signals[NUMBER_OF_SIGNALS] = { 0 };
|
||||
|
||||
G_DEFINE_INTERFACE (GsdIdentityInquiry,
|
||||
gsd_identity_inquiry,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gsd_identity_inquiry_default_init (GsdIdentityInquiryInterface *interface)
|
||||
{
|
||||
signals[COMPLETE] = g_signal_new ("complete",
|
||||
G_TYPE_FROM_INTERFACE (interface),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
void
|
||||
_gsd_identity_inquiry_emit_complete (GsdIdentityInquiry *self)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (self), signals[COMPLETE], 0);
|
||||
}
|
||||
|
||||
char *
|
||||
gsd_identity_inquiry_get_name (GsdIdentityInquiry *self)
|
||||
{
|
||||
g_return_val_if_fail (GSD_IS_IDENTITY_INQUIRY (self), NULL);
|
||||
|
||||
return GSD_IDENTITY_INQUIRY_GET_IFACE (self)->get_name (self);
|
||||
}
|
||||
|
||||
char *
|
||||
gsd_identity_inquiry_get_banner (GsdIdentityInquiry *self)
|
||||
{
|
||||
g_return_val_if_fail (GSD_IS_IDENTITY_INQUIRY (self), NULL);
|
||||
|
||||
return GSD_IDENTITY_INQUIRY_GET_IFACE (self)->get_banner (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsd_identity_inquiry_is_complete (GsdIdentityInquiry *self)
|
||||
{
|
||||
g_return_val_if_fail (GSD_IS_IDENTITY_INQUIRY (self), TRUE);
|
||||
|
||||
return GSD_IDENTITY_INQUIRY_GET_IFACE (self)->is_complete (self);
|
||||
}
|
||||
|
||||
void
|
||||
gsd_identity_inquiry_iter_init (GsdIdentityInquiryIter *iter,
|
||||
GsdIdentityInquiry *inquiry)
|
||||
{
|
||||
g_return_if_fail (GSD_IS_IDENTITY_INQUIRY (inquiry));
|
||||
|
||||
GSD_IDENTITY_INQUIRY_GET_IFACE (inquiry)->iter_init (iter, inquiry);
|
||||
}
|
||||
|
||||
GsdIdentityQuery *
|
||||
gsd_identity_inquiry_iter_next (GsdIdentityInquiryIter *iter,
|
||||
GsdIdentityInquiry *inquiry)
|
||||
{
|
||||
g_return_val_if_fail (GSD_IS_IDENTITY_INQUIRY (inquiry), NULL);
|
||||
|
||||
return GSD_IDENTITY_INQUIRY_GET_IFACE (inquiry)->iter_next (iter, inquiry);
|
||||
}
|
||||
|
||||
GsdIdentity *
|
||||
gsd_identity_inquiry_get_identity (GsdIdentityInquiry *self)
|
||||
{
|
||||
g_return_val_if_fail (GSD_IS_IDENTITY_INQUIRY (self), NULL);
|
||||
|
||||
return GSD_IDENTITY_INQUIRY_GET_IFACE (self)->get_identity (self);
|
||||
}
|
||||
|
||||
GsdIdentityQueryMode
|
||||
gsd_identity_query_get_mode (GsdIdentityInquiry *self,
|
||||
GsdIdentityQuery *query)
|
||||
{
|
||||
g_return_val_if_fail (GSD_IS_IDENTITY_INQUIRY (self),
|
||||
GSD_IDENTITY_QUERY_MODE_INVISIBLE);
|
||||
|
||||
return GSD_IDENTITY_INQUIRY_GET_IFACE (self)->get_mode (self, query);
|
||||
}
|
||||
|
||||
char *
|
||||
gsd_identity_query_get_prompt (GsdIdentityInquiry *self,
|
||||
GsdIdentityQuery *query)
|
||||
{
|
||||
g_return_val_if_fail (GSD_IS_IDENTITY_INQUIRY (self), NULL);
|
||||
|
||||
return GSD_IDENTITY_INQUIRY_GET_IFACE (self)->get_prompt (self, query);
|
||||
}
|
||||
|
||||
void
|
||||
gsd_identity_inquiry_answer_query (GsdIdentityInquiry *self,
|
||||
GsdIdentityQuery *query,
|
||||
const char *answer)
|
||||
{
|
||||
g_return_if_fail (GSD_IS_IDENTITY_INQUIRY (self));
|
||||
|
||||
GSD_IDENTITY_INQUIRY_GET_IFACE (self)->answer_query (self, query, answer);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsd_identity_query_is_answered (GsdIdentityInquiry *self,
|
||||
GsdIdentityQuery *query)
|
||||
{
|
||||
g_return_val_if_fail (GSD_IS_IDENTITY_INQUIRY (self), FALSE);
|
||||
|
||||
return GSD_IDENTITY_INQUIRY_GET_IFACE (self)->is_answered (self, query);
|
||||
}
|
||||
108
panels/user-accounts/gsd-identity-inquiry.h
Normal file
108
panels/user-accounts/gsd-identity-inquiry.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/* -*- Mode: C; tab-width: 8; ident-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors: Ray Strode
|
||||
*/
|
||||
|
||||
#ifndef __GSD_IDENTITY_INQUIRY_H__
|
||||
#define __GSD_IDENTITY_INQUIRY_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gsd-identity.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSD_TYPE_IDENTITY_INQUIRY (gsd_identity_inquiry_get_type ())
|
||||
#define GSD_IDENTITY_INQUIRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_IDENTITY_INQUIRY, GsdIdentityInquiry))
|
||||
#define GSD_IDENTITY_INQUIRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_IDENTITY_INQUIRY, GsdIdentityInquiryClass))
|
||||
#define GSD_IS_IDENTITY_INQUIRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_IDENTITY_INQUIRY))
|
||||
#define GSD_IDENTITY_INQUIRY_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), GSD_TYPE_IDENTITY_INQUIRY, GsdIdentityInquiryInterface))
|
||||
typedef struct _GsdIdentityInquiry GsdIdentityInquiry;
|
||||
typedef struct _GsdIdentityInquiryInterface GsdIdentityInquiryInterface;
|
||||
typedef struct _GsdIdentityInquiryIter GsdIdentityInquiryIter;
|
||||
|
||||
typedef struct _GsdIdentityQuery GsdIdentityQuery;
|
||||
|
||||
typedef void (* GsdIdentityInquiryFunc) (GsdIdentityInquiry *inquiry,
|
||||
GCancellable *cancellable,
|
||||
gpointer user_data);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GSD_IDENTITY_QUERY_MODE_INVISIBLE,
|
||||
GSD_IDENTITY_QUERY_MODE_VISIBLE
|
||||
} GsdIdentityQueryMode;
|
||||
|
||||
struct _GsdIdentityInquiryIter
|
||||
{
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
struct _GsdIdentityInquiryInterface
|
||||
{
|
||||
GTypeInterface base_interface;
|
||||
|
||||
GsdIdentity * (* get_identity) (GsdIdentityInquiry *inquiry);
|
||||
char * (* get_name) (GsdIdentityInquiry *inquiry);
|
||||
char * (* get_banner) (GsdIdentityInquiry *inquiry);
|
||||
gboolean (* is_complete) (GsdIdentityInquiry *inquiry);
|
||||
void (* answer_query) (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query,
|
||||
const char *answer);
|
||||
|
||||
void (* iter_init) (GsdIdentityInquiryIter *iter,
|
||||
GsdIdentityInquiry *inquiry);
|
||||
GsdIdentityQuery * (* iter_next) (GsdIdentityInquiryIter *iter,
|
||||
GsdIdentityInquiry *inquiry);
|
||||
|
||||
GsdIdentityQueryMode (* get_mode) (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query);
|
||||
char * (* get_prompt) (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query);
|
||||
gboolean (* is_answered) (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query);
|
||||
};
|
||||
|
||||
GType gsd_identity_inquiry_get_type (void);
|
||||
|
||||
GsdIdentity *gsd_identity_inquiry_get_identity (GsdIdentityInquiry *inquiry);
|
||||
char *gsd_identity_inquiry_get_name (GsdIdentityInquiry *inquiry);
|
||||
char *gsd_identity_inquiry_get_banner (GsdIdentityInquiry *inquiry);
|
||||
gboolean gsd_identity_inquiry_is_complete (GsdIdentityInquiry *inquiry);
|
||||
void gsd_identity_inquiry_answer_query (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query,
|
||||
const char *answer);
|
||||
|
||||
void gsd_identity_inquiry_iter_init (GsdIdentityInquiryIter *iter,
|
||||
GsdIdentityInquiry *inquiry);
|
||||
GsdIdentityQuery *gsd_identity_inquiry_iter_next (GsdIdentityInquiryIter *iter, GsdIdentityInquiry *inquiry);
|
||||
|
||||
GsdIdentityQueryMode gsd_identity_query_get_mode (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query);
|
||||
char *gsd_identity_query_get_prompt (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query);
|
||||
gboolean gsd_identity_query_is_answered (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query);
|
||||
|
||||
#endif /* __GSD_IDENTITY_INQUIRY_H__ */
|
||||
51
panels/user-accounts/gsd-identity-manager-private.h
Normal file
51
panels/user-accounts/gsd-identity-manager-private.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors: Ray Strode
|
||||
*/
|
||||
|
||||
#ifndef __GSD_IDENTITY_MANAGER_PRIVATE_H__
|
||||
#define __GSD_IDENTITY_MANAGER_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "gsd-identity-manager.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _gsd_identity_manager_emit_identity_added (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
void _gsd_identity_manager_emit_identity_removed (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
void _gsd_identity_manager_emit_identity_refreshed (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
void _gsd_identity_manager_emit_identity_renamed (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
|
||||
void _gsd_identity_manager_emit_identity_expiring (GsdIdentityManager *self,
|
||||
GsdIdentity *identity);
|
||||
|
||||
void _gsd_identity_manager_emit_identity_needs_renewal (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
void _gsd_identity_manager_emit_identity_expired (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSD_IDENTITY_MANAGER_PRIVATE_H__ */
|
||||
238
panels/user-accounts/gsd-identity-manager.c
Normal file
238
panels/user-accounts/gsd-identity-manager.c
Normal file
@@ -0,0 +1,238 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gsd-identity-manager.h"
|
||||
#include "gsd-identity-manager-private.h"
|
||||
|
||||
enum {
|
||||
IDENTITY_ADDED,
|
||||
IDENTITY_REMOVED,
|
||||
IDENTITY_RENAMED,
|
||||
IDENTITY_REFRESHED,
|
||||
IDENTITY_NEEDS_RENEWAL,
|
||||
IDENTITY_EXPIRING,
|
||||
IDENTITY_EXPIRED,
|
||||
NUMBER_OF_SIGNALS,
|
||||
};
|
||||
|
||||
static guint signals[NUMBER_OF_SIGNALS] = { 0 };
|
||||
|
||||
G_DEFINE_INTERFACE (GsdIdentityManager, gsd_identity_manager, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gsd_identity_manager_default_init (GsdIdentityManagerInterface *interface)
|
||||
{
|
||||
signals[IDENTITY_ADDED] = g_signal_new ("identity-added",
|
||||
G_TYPE_FROM_INTERFACE (interface),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GsdIdentityManagerInterface, identity_added),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, GSD_TYPE_IDENTITY);
|
||||
signals[IDENTITY_REMOVED] = g_signal_new ("identity-removed",
|
||||
G_TYPE_FROM_INTERFACE (interface),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GsdIdentityManagerInterface, identity_removed),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, GSD_TYPE_IDENTITY);
|
||||
signals[IDENTITY_REFRESHED] = g_signal_new ("identity-refreshed",
|
||||
G_TYPE_FROM_INTERFACE (interface),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GsdIdentityManagerInterface, identity_refreshed),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, GSD_TYPE_IDENTITY);
|
||||
signals[IDENTITY_RENAMED] = g_signal_new ("identity-renamed",
|
||||
G_TYPE_FROM_INTERFACE (interface),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GsdIdentityManagerInterface, identity_renamed),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, GSD_TYPE_IDENTITY);
|
||||
signals[IDENTITY_NEEDS_RENEWAL] = g_signal_new ("identity-needs-renewal",
|
||||
G_TYPE_FROM_INTERFACE (interface),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GsdIdentityManagerInterface, identity_needs_renewal),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, GSD_TYPE_IDENTITY);
|
||||
signals[IDENTITY_EXPIRING] = g_signal_new ("identity-expiring",
|
||||
G_TYPE_FROM_INTERFACE (interface),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GsdIdentityManagerInterface, identity_expiring),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, GSD_TYPE_IDENTITY);
|
||||
signals[IDENTITY_EXPIRED] = g_signal_new ("identity-expired",
|
||||
G_TYPE_FROM_INTERFACE (interface),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GsdIdentityManagerInterface, identity_expired),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, GSD_TYPE_IDENTITY);
|
||||
}
|
||||
|
||||
GQuark
|
||||
gsd_identity_manager_error_quark (void)
|
||||
{
|
||||
static GQuark error_quark = 0;
|
||||
|
||||
if (error_quark == 0) {
|
||||
error_quark = g_quark_from_static_string ("gsd-identity-manager-error");
|
||||
}
|
||||
|
||||
return error_quark;
|
||||
}
|
||||
|
||||
void
|
||||
gsd_identity_manager_list_identities (GsdIdentityManager *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSD_IDENTITY_MANAGER_GET_IFACE (self)->list_identities (self,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
GList *
|
||||
gsd_identity_manager_list_identities_finish (GsdIdentityManager *self,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
return GSD_IDENTITY_MANAGER_GET_IFACE (self)->list_identities_finish (self,
|
||||
result,
|
||||
error);
|
||||
}
|
||||
|
||||
void
|
||||
gsd_identity_manager_renew_identity (GsdIdentityManager *self,
|
||||
GsdIdentity *identity,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSD_IDENTITY_MANAGER_GET_IFACE (self)->renew_identity (self, identity, cancellable, callback, user_data);
|
||||
}
|
||||
|
||||
void
|
||||
gsd_identity_manager_renew_identity_finish (GsdIdentityManager *self,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GSD_IDENTITY_MANAGER_GET_IFACE (self)->renew_identity_finish (self, result, error);
|
||||
}
|
||||
|
||||
void
|
||||
gsd_identity_manager_sign_identity_in (GsdIdentityManager *self,
|
||||
const char *identifier,
|
||||
GsdIdentityInquiryFunc inquiry_func,
|
||||
gpointer inquiry_data,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSD_IDENTITY_MANAGER_GET_IFACE (self)->sign_identity_in (self, identifier, inquiry_func, inquiry_data, cancellable, callback, user_data);
|
||||
}
|
||||
|
||||
GsdIdentity *
|
||||
gsd_identity_manager_sign_identity_in_finish (GsdIdentityManager *self,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
return GSD_IDENTITY_MANAGER_GET_IFACE (self)->sign_identity_in_finish (self, result, error);
|
||||
}
|
||||
|
||||
void
|
||||
gsd_identity_manager_sign_identity_out (GsdIdentityManager *self,
|
||||
GsdIdentity *identity,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSD_IDENTITY_MANAGER_GET_IFACE (self)->sign_identity_out (self, identity, cancellable, callback, user_data);
|
||||
}
|
||||
|
||||
void
|
||||
gsd_identity_manager_sign_identity_out_finish (GsdIdentityManager *self,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GSD_IDENTITY_MANAGER_GET_IFACE (self)->sign_identity_out_finish (self, result, error);
|
||||
}
|
||||
|
||||
char *
|
||||
gsd_identity_manager_name_identity (GsdIdentityManager *self,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
return GSD_IDENTITY_MANAGER_GET_IFACE (self)->name_identity (self,
|
||||
identity);
|
||||
}
|
||||
|
||||
void
|
||||
_gsd_identity_manager_emit_identity_added (GsdIdentityManager *self,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (self), signals[IDENTITY_ADDED], 0, identity);
|
||||
}
|
||||
|
||||
void
|
||||
_gsd_identity_manager_emit_identity_removed (GsdIdentityManager *self,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (self), signals[IDENTITY_REMOVED], 0, identity);
|
||||
}
|
||||
|
||||
void
|
||||
_gsd_identity_manager_emit_identity_renamed (GsdIdentityManager *self,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (self), signals[IDENTITY_RENAMED], 0, identity);
|
||||
}
|
||||
|
||||
void
|
||||
_gsd_identity_manager_emit_identity_refreshed (GsdIdentityManager *self,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (self), signals[IDENTITY_REFRESHED], 0, identity);
|
||||
}
|
||||
|
||||
void
|
||||
_gsd_identity_manager_emit_identity_needs_renewal (GsdIdentityManager *self,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (self), signals[IDENTITY_NEEDS_RENEWAL], 0, identity);
|
||||
}
|
||||
|
||||
void
|
||||
_gsd_identity_manager_emit_identity_expiring (GsdIdentityManager *self,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (self), signals[IDENTITY_EXPIRING], 0, identity);
|
||||
}
|
||||
|
||||
void
|
||||
_gsd_identity_manager_emit_identity_expired (GsdIdentityManager *self,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
g_signal_emit (G_OBJECT (self), signals[IDENTITY_EXPIRED], 0, identity);
|
||||
}
|
||||
|
||||
162
panels/user-accounts/gsd-identity-manager.h
Normal file
162
panels/user-accounts/gsd-identity-manager.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors: Ray Strode
|
||||
*/
|
||||
|
||||
#ifndef __GSD_IDENTITY_MANAGER_H__
|
||||
#define __GSD_IDENTITY_MANAGER_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gsd-identity.h"
|
||||
#include "gsd-identity-inquiry.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSD_TYPE_IDENTITY_MANAGER (gsd_identity_manager_get_type ())
|
||||
#define GSD_IDENTITY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_IDENTITY_MANAGER, GsdIdentityManager))
|
||||
#define GSD_IDENTITY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_IDENTITY_MANAGER, GsdIdentityManagerInterface))
|
||||
#define GSD_IS_IDENTITY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_IDENTITY_MANAGER))
|
||||
#define GSD_IDENTITY_MANAGER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), GSD_TYPE_IDENTITY_MANAGER, GsdIdentityManagerInterface))
|
||||
#define GSD_IDENTITY_MANAGER_ERROR (gsd_identity_manager_error_quark ())
|
||||
|
||||
typedef struct _GsdIdentityManager GsdIdentityManager;
|
||||
typedef struct _GsdIdentityManagerInterface GsdIdentityManagerInterface;
|
||||
typedef enum _GsdIdentityManagerError GsdIdentityManagerError;
|
||||
|
||||
struct _GsdIdentityManagerInterface
|
||||
{
|
||||
GTypeInterface base_interface;
|
||||
|
||||
/* Signals */
|
||||
void (* identity_added) (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
|
||||
void (* identity_removed) (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
void (* identity_renamed) (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
void (* identity_refreshed) (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
void (* identity_needs_renewal) (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
void (* identity_expiring) (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
void (* identity_expired) (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
|
||||
/* Virtual Functions */
|
||||
void (* list_identities) (GsdIdentityManager *identity_manager,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GList * (* list_identities_finish) (GsdIdentityManager *identity_manager,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
void (* sign_identity_in) (GsdIdentityManager *identity_manager,
|
||||
const char *identifier,
|
||||
GsdIdentityInquiryFunc inquiry_func,
|
||||
gpointer inquiry_data,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GsdIdentity * (* sign_identity_in_finish) (GsdIdentityManager *identity_manager,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
void (* sign_identity_out) (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void (* sign_identity_out_finish) (GsdIdentityManager *identity_manager,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
void (* renew_identity) (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void (* renew_identity_finish) (GsdIdentityManager *identity_manager,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
char * (* name_identity) (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
};
|
||||
|
||||
enum _GsdIdentityManagerError
|
||||
{
|
||||
GSD_IDENTITY_MANAGER_ERROR_INITIALIZING,
|
||||
GSD_IDENTITY_MANAGER_ERROR_MONITORING,
|
||||
GSD_IDENTITY_MANAGER_ERROR_SIGNING_IN,
|
||||
GSD_IDENTITY_MANAGER_ERROR_SIGNING_OUT
|
||||
};
|
||||
|
||||
GType gsd_identity_manager_get_type (void);
|
||||
GQuark gsd_identity_manager_error_quark (void);
|
||||
|
||||
void gsd_identity_manager_list_identities (GsdIdentityManager *identity_manager,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GList * gsd_identity_manager_list_identities_finish (GsdIdentityManager *identity_manager,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
void gsd_identity_manager_sign_identity_in (GsdIdentityManager *identity_manager,
|
||||
const char *identifier,
|
||||
GsdIdentityInquiryFunc inquiry_func,
|
||||
gpointer inquiry_data,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GsdIdentity * gsd_identity_manager_sign_identity_in_finish (GsdIdentityManager *identity_manager,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
void gsd_identity_manager_sign_identity_out (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void gsd_identity_manager_sign_identity_out_finish (GsdIdentityManager *identity_manager,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
void gsd_identity_manager_renew_identity (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void gsd_identity_manager_renew_identity_finish (GsdIdentityManager *identity_manager,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
char *gsd_identity_manager_name_identity (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSD_IDENTITY_MANAGER_H__ */
|
||||
607
panels/user-accounts/gsd-identity-plugin.c
Normal file
607
panels/user-accounts/gsd-identity-plugin.c
Normal file
@@ -0,0 +1,607 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include <libnotify/notify.h>
|
||||
#include <gcr/gcr.h>
|
||||
|
||||
#include "gnome-settings-plugin.h"
|
||||
#include "gsd-identity-plugin.h"
|
||||
#include "gsd-identity-manager.h"
|
||||
#include "gsd-kerberos-identity-manager.h"
|
||||
#include "gsd-kerberos-identity.h"
|
||||
|
||||
struct GsdIdentityPluginPrivate {
|
||||
GsdIdentityManager *identity_manager;
|
||||
};
|
||||
|
||||
#define GSD_IDENTITY_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_IDENTITY_PLUGIN, GsdIdentityPluginPrivate))
|
||||
|
||||
GNOME_SETTINGS_PLUGIN_REGISTER (GsdIdentityPlugin, gsd_identity_plugin);
|
||||
|
||||
static void
|
||||
gsd_identity_plugin_init (GsdIdentityPlugin *self)
|
||||
{
|
||||
self->priv = GSD_IDENTITY_PLUGIN_GET_PRIVATE (self);
|
||||
|
||||
g_debug ("GsdIdentityPlugin initializing");
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_identity_plugin_finalize (GObject *object)
|
||||
{
|
||||
GsdIdentityPlugin *self;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (GSD_IS_IDENTITY_PLUGIN (object));
|
||||
|
||||
g_debug ("GsdIdentityPlugin: finalizing");
|
||||
|
||||
self = GSD_IDENTITY_PLUGIN (object);
|
||||
|
||||
g_return_if_fail (self->priv != NULL);
|
||||
|
||||
g_clear_object (&self->priv->identity_manager);
|
||||
|
||||
G_OBJECT_CLASS (gsd_identity_plugin_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
on_identity_renewed (GsdIdentityManager *manager,
|
||||
GAsyncResult *result,
|
||||
GnomeSettingsPlugin *self)
|
||||
{
|
||||
GError *error;
|
||||
|
||||
error = NULL;
|
||||
gsd_identity_manager_renew_identity_finish (manager,
|
||||
result,
|
||||
&error);
|
||||
|
||||
if (error != NULL) {
|
||||
g_debug ("GsdIdentityPlugin: could not renew identity: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_debug ("GsdIdentityPlugin: identity renewed");
|
||||
}
|
||||
|
||||
static void
|
||||
on_identity_needs_renewal (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity,
|
||||
GsdIdentityPlugin *self)
|
||||
{
|
||||
g_debug ("GsdIdentityPlugin: identity needs renewal");
|
||||
gsd_identity_manager_renew_identity (GSD_IDENTITY_MANAGER (self->priv->identity_manager),
|
||||
identity,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)
|
||||
on_identity_renewed,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
on_identity_signed_in (GsdIdentityManager *manager,
|
||||
GAsyncResult *result,
|
||||
GnomeSettingsPlugin *self)
|
||||
{
|
||||
GError *error;
|
||||
|
||||
error = NULL;
|
||||
gsd_identity_manager_sign_identity_in_finish (manager,
|
||||
result,
|
||||
&error);
|
||||
|
||||
if (error != NULL) {
|
||||
g_debug ("GsdIdentityPlugin: could not sign in identity: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_debug ("GsdIdentityPlugin: identity signed in");
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GsdIdentityPlugin *plugin;
|
||||
GsdIdentity *identity;
|
||||
NotifyNotification *notification;
|
||||
GCancellable *cancellable;
|
||||
gulong refreshed_signal_id;
|
||||
} SignInRequest;
|
||||
|
||||
static SignInRequest *
|
||||
sign_in_request_new (GsdIdentityPlugin *plugin,
|
||||
GsdIdentity *identity,
|
||||
NotifyNotification *notification,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
SignInRequest *request;
|
||||
|
||||
request = g_slice_new0 (SignInRequest);
|
||||
|
||||
request->plugin = plugin;
|
||||
request->identity = g_object_ref (identity);
|
||||
request->notification = notification;
|
||||
request->cancellable = g_object_ref (cancellable);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
static void
|
||||
sign_in_request_free (SignInRequest *data)
|
||||
{
|
||||
GsdIdentityPlugin *plugin = data->plugin;
|
||||
|
||||
g_signal_handler_disconnect (plugin->priv->identity_manager,
|
||||
data->refreshed_signal_id);
|
||||
g_object_set_data (G_OBJECT (data->identity), "sign-in-request", NULL);
|
||||
g_clear_object (&data->identity);
|
||||
g_clear_object (&data->cancellable);
|
||||
g_slice_free (SignInRequest, data);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GsdIdentityPlugin *plugin;
|
||||
GsdIdentity *identity;
|
||||
GsdIdentityInquiry *inquiry;
|
||||
GsdIdentityQuery *query;
|
||||
GcrSystemPrompt *prompt;
|
||||
GCancellable *cancellable;
|
||||
} SystemPromptRequest;
|
||||
|
||||
static SystemPromptRequest *
|
||||
system_prompt_request_new (GsdIdentityPlugin *plugin,
|
||||
GcrSystemPrompt *prompt,
|
||||
GsdIdentity *identity,
|
||||
GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
SystemPromptRequest *data;
|
||||
|
||||
data = g_slice_new0 (SystemPromptRequest);
|
||||
|
||||
data->plugin = plugin;
|
||||
data->prompt = prompt;
|
||||
data->identity = g_object_ref (identity);
|
||||
data->inquiry = g_object_ref (inquiry);
|
||||
data->query = query;
|
||||
data->cancellable = g_object_ref (cancellable);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
system_prompt_request_free (SystemPromptRequest *data)
|
||||
{
|
||||
g_clear_object (&data->identity);
|
||||
g_clear_object (&data->inquiry);
|
||||
g_clear_object (&data->cancellable);
|
||||
g_slice_free (SystemPromptRequest, data);
|
||||
}
|
||||
|
||||
static void
|
||||
close_system_prompt (GsdIdentityManager *manager,
|
||||
GsdIdentity *identity,
|
||||
SystemPromptRequest *data)
|
||||
{
|
||||
GError *error;
|
||||
|
||||
/* Only close the prompt if the identity we're
|
||||
* waiting on got refreshed
|
||||
*/
|
||||
if (data->identity != identity) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (G_OBJECT (manager),
|
||||
G_CALLBACK (close_system_prompt),
|
||||
data);
|
||||
error = NULL;
|
||||
if (!gcr_system_prompt_close (data->prompt,
|
||||
NULL,
|
||||
&error)) {
|
||||
if (error != NULL) {
|
||||
g_debug ("GsdIdentityPlugin: could not close system prompt: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_password_system_prompt_answered (GcrPrompt *prompt,
|
||||
GAsyncResult *result,
|
||||
SystemPromptRequest *request)
|
||||
{
|
||||
GsdIdentityPlugin *self = request->plugin;
|
||||
GsdIdentityInquiry *inquiry = request->inquiry;
|
||||
GsdIdentity *identity = request->identity;
|
||||
GsdIdentityQuery *query = request->query;
|
||||
GCancellable *cancellable = request->cancellable;
|
||||
GError *error;
|
||||
const char *password;
|
||||
|
||||
error = NULL;
|
||||
password = gcr_prompt_password_finish (prompt, result, &error);
|
||||
|
||||
if (password == NULL) {
|
||||
if (error != NULL) {
|
||||
g_debug ("GsdIdentityPlugin: could not get password from user: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
} else {
|
||||
g_cancellable_cancel (cancellable);
|
||||
}
|
||||
} else if (!g_cancellable_is_cancelled (cancellable)) {
|
||||
gsd_identity_inquiry_answer_query (inquiry,
|
||||
query,
|
||||
password);
|
||||
}
|
||||
|
||||
close_system_prompt (self->priv->identity_manager, identity, request);
|
||||
system_prompt_request_free (request);
|
||||
}
|
||||
|
||||
static void
|
||||
query_user (GsdIdentityPlugin *self,
|
||||
GsdIdentity *identity,
|
||||
GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query,
|
||||
GcrPrompt *prompt,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
SystemPromptRequest *request;
|
||||
char *prompt_text;
|
||||
GsdIdentityQueryMode query_mode;
|
||||
char *description;
|
||||
char *name;
|
||||
|
||||
g_assert (GSD_IS_KERBEROS_IDENTITY (identity));
|
||||
|
||||
gcr_prompt_set_title (prompt, _("Sign In to Realm"));
|
||||
|
||||
name = gsd_identity_manager_name_identity (self->priv->identity_manager,
|
||||
identity);
|
||||
|
||||
description = g_strdup_printf (_("The network realm %s needs some information to sign you in."), name);
|
||||
g_free (name);
|
||||
|
||||
gcr_prompt_set_description (prompt, description);
|
||||
g_free (description);
|
||||
|
||||
prompt_text = gsd_identity_query_get_prompt (inquiry, query);
|
||||
gcr_prompt_set_message (prompt, prompt_text);
|
||||
g_free (prompt_text);
|
||||
|
||||
request = system_prompt_request_new (self,
|
||||
GCR_SYSTEM_PROMPT (prompt),
|
||||
identity,
|
||||
inquiry,
|
||||
query,
|
||||
cancellable);
|
||||
|
||||
g_signal_connect (G_OBJECT (self->priv->identity_manager),
|
||||
"identity-refreshed",
|
||||
G_CALLBACK (close_system_prompt),
|
||||
request);
|
||||
|
||||
query_mode = gsd_identity_query_get_mode (inquiry, query);
|
||||
|
||||
switch (query_mode) {
|
||||
case GSD_IDENTITY_QUERY_MODE_INVISIBLE:
|
||||
gcr_prompt_password_async (prompt,
|
||||
cancellable,
|
||||
(GAsyncReadyCallback)
|
||||
on_password_system_prompt_answered,
|
||||
request);
|
||||
break;
|
||||
case GSD_IDENTITY_QUERY_MODE_VISIBLE:
|
||||
gcr_prompt_password_async (prompt,
|
||||
cancellable,
|
||||
(GAsyncReadyCallback)
|
||||
on_password_system_prompt_answered,
|
||||
request);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GsdIdentityPlugin *plugin;
|
||||
GsdIdentityInquiry *inquiry;
|
||||
GCancellable *cancellable;
|
||||
} SystemPromptOpenRequest;
|
||||
|
||||
static SystemPromptOpenRequest *
|
||||
system_prompt_open_request_new (GsdIdentityPlugin *plugin,
|
||||
GsdIdentityInquiry *inquiry,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
SystemPromptOpenRequest *data;
|
||||
|
||||
data = g_slice_new0 (SystemPromptOpenRequest);
|
||||
|
||||
data->plugin = plugin;
|
||||
data->inquiry = g_object_ref (inquiry);
|
||||
data->cancellable = g_object_ref (cancellable);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
system_prompt_open_request_free (SystemPromptOpenRequest *data)
|
||||
{
|
||||
g_clear_object (&data->inquiry);
|
||||
g_clear_object (&data->cancellable);
|
||||
g_slice_free (SystemPromptOpenRequest, data);
|
||||
}
|
||||
|
||||
static void
|
||||
on_system_prompt_open (GcrSystemPrompt *system_prompt,
|
||||
GAsyncResult *result,
|
||||
SystemPromptOpenRequest *request)
|
||||
{
|
||||
GsdIdentityPlugin *self = request->plugin;
|
||||
GsdIdentityInquiry *inquiry = request->inquiry;
|
||||
GCancellable *cancellable = request->cancellable;
|
||||
GsdIdentity *identity;
|
||||
GsdIdentityQuery *query;
|
||||
GcrPrompt *prompt;
|
||||
GError *error;
|
||||
GsdIdentityInquiryIter iter;
|
||||
|
||||
error = NULL;
|
||||
prompt = gcr_system_prompt_open_finish (result, &error);
|
||||
|
||||
if (prompt == NULL) {
|
||||
if (error != NULL) {
|
||||
g_debug ("GsdIdentityPlugin: could not open system prompt: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
identity = gsd_identity_inquiry_get_identity (inquiry);
|
||||
gsd_identity_inquiry_iter_init (&iter, inquiry);
|
||||
while ((query = gsd_identity_inquiry_iter_next (&iter, inquiry)) != NULL) {
|
||||
query_user (self, identity, inquiry, query, prompt, cancellable);
|
||||
}
|
||||
|
||||
system_prompt_open_request_free (request);
|
||||
}
|
||||
|
||||
static void
|
||||
on_identity_inquiry (GsdIdentityInquiry *inquiry,
|
||||
GCancellable *cancellable,
|
||||
GsdIdentityPlugin *self)
|
||||
{
|
||||
SystemPromptOpenRequest *request;
|
||||
|
||||
request = system_prompt_open_request_new (self, inquiry, cancellable);
|
||||
gcr_system_prompt_open_async (-1,
|
||||
cancellable,
|
||||
(GAsyncReadyCallback)
|
||||
on_system_prompt_open,
|
||||
request);
|
||||
}
|
||||
|
||||
static void
|
||||
on_sign_in_clicked (NotifyNotification *notification,
|
||||
const char *acition_id,
|
||||
SignInRequest *request)
|
||||
{
|
||||
GsdIdentityPlugin *self = request->plugin;
|
||||
GsdIdentity *identity = request->identity;
|
||||
const char *identifier;
|
||||
|
||||
identifier = gsd_identity_get_identifier (identity);
|
||||
gsd_identity_manager_sign_identity_in (self->priv->identity_manager,
|
||||
identifier,
|
||||
(GsdIdentityInquiryFunc)
|
||||
on_identity_inquiry,
|
||||
self,
|
||||
request->cancellable,
|
||||
(GAsyncReadyCallback)
|
||||
on_identity_signed_in,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
close_notification (GCancellable *cancellable,
|
||||
NotifyNotification *notification)
|
||||
{
|
||||
notify_notification_close (notification, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_sign_in (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity,
|
||||
SignInRequest *data)
|
||||
{
|
||||
if (data->cancellable == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_cancellable_is_cancelled (data->cancellable)) {
|
||||
g_cancellable_cancel (data->cancellable);
|
||||
}
|
||||
|
||||
g_clear_object (&data->cancellable);
|
||||
}
|
||||
|
||||
static void
|
||||
ask_to_sign_in (GsdIdentityPlugin *self,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
NotifyNotification *notification;
|
||||
char *name;
|
||||
char *description;
|
||||
SignInRequest *request;
|
||||
GCancellable *cancellable;
|
||||
|
||||
request = g_object_get_data (G_OBJECT (identity), "sign-in-request");
|
||||
|
||||
if (request != NULL) {
|
||||
if (!g_cancellable_is_cancelled (request->cancellable)) {
|
||||
g_cancellable_cancel (request->cancellable);
|
||||
}
|
||||
}
|
||||
|
||||
g_debug ("GsdIdentityPlugin: asking to sign back in");
|
||||
|
||||
name = gsd_identity_manager_name_identity (self->priv->identity_manager,
|
||||
identity);
|
||||
if (gsd_identity_is_signed_in (identity)) {
|
||||
description = g_strdup_printf (_("The network realm %s will soon be inaccessible."),
|
||||
name);
|
||||
} else {
|
||||
description = g_strdup_printf (_("The network realm %s is now inaccessible."),
|
||||
name);
|
||||
}
|
||||
g_free (name);
|
||||
|
||||
notification = notify_notification_new (_("Realm Access"),
|
||||
description,
|
||||
"dialog-password-symbolic");
|
||||
g_free (description);
|
||||
notify_notification_set_app_name (notification, _("Network Realm"));
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
|
||||
request = sign_in_request_new (self, identity, notification, cancellable);
|
||||
|
||||
g_object_set_data (G_OBJECT (identity), "sign-in-request", request);
|
||||
|
||||
g_cancellable_connect (cancellable,
|
||||
G_CALLBACK (close_notification),
|
||||
notification,
|
||||
NULL);
|
||||
g_signal_connect_swapped (G_OBJECT (notification),
|
||||
"closed",
|
||||
G_CALLBACK (sign_in_request_free),
|
||||
request);
|
||||
|
||||
request->refreshed_signal_id = g_signal_connect (G_OBJECT (self->priv->identity_manager),
|
||||
"identity-refreshed",
|
||||
G_CALLBACK (cancel_sign_in),
|
||||
request);
|
||||
|
||||
notify_notification_add_action (notification,
|
||||
"sign-in",
|
||||
_("Sign In"),
|
||||
(NotifyActionCallback)
|
||||
on_sign_in_clicked,
|
||||
request,
|
||||
NULL);
|
||||
|
||||
notify_notification_show (notification, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_identity_expiring (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity,
|
||||
GsdIdentityPlugin *self)
|
||||
{
|
||||
g_debug ("GsdIdentityPlugin: identity expiring");
|
||||
ask_to_sign_in (self, identity);
|
||||
}
|
||||
|
||||
static void
|
||||
on_identity_expired (GsdIdentityManager *identity_manager,
|
||||
GsdIdentity *identity,
|
||||
GsdIdentityPlugin *self)
|
||||
{
|
||||
g_debug ("GsdIdentityPlugin: identity expired");
|
||||
ask_to_sign_in (self, identity);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_activate (GnomeSettingsPlugin *plugin)
|
||||
{
|
||||
GsdIdentityPlugin *self = GSD_IDENTITY_PLUGIN (plugin);
|
||||
|
||||
if (self->priv->identity_manager != NULL) {
|
||||
g_debug ("GsdIdentityPlugin: Not activating identity plugin, because it's "
|
||||
"already active");
|
||||
return;
|
||||
}
|
||||
|
||||
g_debug ("GsdIdentityPlugin: Activating identity plugin");
|
||||
self->priv->identity_manager = gsd_kerberos_identity_manager_new ();
|
||||
g_signal_connect (G_OBJECT (self->priv->identity_manager),
|
||||
"identity-needs-renewal",
|
||||
G_CALLBACK (on_identity_needs_renewal),
|
||||
self);
|
||||
g_signal_connect (G_OBJECT (self->priv->identity_manager),
|
||||
"identity-expiring",
|
||||
G_CALLBACK (on_identity_expiring),
|
||||
self);
|
||||
g_signal_connect (G_OBJECT (self->priv->identity_manager),
|
||||
"identity-expired",
|
||||
G_CALLBACK (on_identity_expired),
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_deactivate (GnomeSettingsPlugin *plugin)
|
||||
{
|
||||
GsdIdentityPlugin *self = GSD_IDENTITY_PLUGIN (plugin);
|
||||
|
||||
if (self->priv->identity_manager == NULL) {
|
||||
g_debug ("GsdIdentityPlugin: Not deactivating identity plugin, "
|
||||
"because it's already inactive");
|
||||
return;
|
||||
}
|
||||
|
||||
g_debug ("GsdIdentityPlugin: Deactivating identity plugin");
|
||||
g_signal_handlers_disconnect_by_func (self, on_identity_needs_renewal, self);
|
||||
g_clear_object (&self->priv->identity_manager);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_identity_plugin_class_init (GsdIdentityPluginClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GnomeSettingsPluginClass *plugin_class = GNOME_SETTINGS_PLUGIN_CLASS (klass);
|
||||
|
||||
object_class->finalize = gsd_identity_plugin_finalize;
|
||||
|
||||
plugin_class->activate = impl_activate;
|
||||
plugin_class->deactivate = impl_deactivate;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GsdIdentityPluginPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_identity_plugin_class_finalize (GsdIdentityPluginClass *klass)
|
||||
{
|
||||
}
|
||||
59
panels/user-accounts/gsd-identity-plugin.h
Normal file
59
panels/user-accounts/gsd-identity-plugin.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GSD_IDENTITY_PLUGIN_H__
|
||||
#define __GSD_IDENTITY_PLUGIN_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include "gnome-settings-plugin.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSD_TYPE_IDENTITY_PLUGIN (gsd_identity_plugin_get_type ())
|
||||
#define GSD_IDENTITY_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_IDENTITY_PLUGIN, GsdIdentityPlugin))
|
||||
#define GSD_IDENTITY_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GSD_TYPE_IDENTITY_PLUGIN, GsdIdentityPluginClass))
|
||||
#define GSD_IS_IDENTITY_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_IDENTITY_PLUGIN))
|
||||
#define GSD_IS_IDENTITY_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_IDENTITY_PLUGIN))
|
||||
#define GSD_IDENTITY_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_IDENTITY_PLUGIN, GsdIdentityPluginClass))
|
||||
|
||||
typedef struct GsdIdentityPluginPrivate GsdIdentityPluginPrivate;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GnomeSettingsPlugin parent;
|
||||
GsdIdentityPluginPrivate *priv;
|
||||
} GsdIdentityPlugin;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GnomeSettingsPluginClass parent_class;
|
||||
} GsdIdentityPluginClass;
|
||||
|
||||
GType gsd_identity_plugin_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/* All the plugins must implement this function */
|
||||
G_MODULE_EXPORT GType register_gnome_settings_plugin (GTypeModule *module);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSD_IDENTITY_PLUGIN_H__ */
|
||||
57
panels/user-accounts/gsd-identity.c
Normal file
57
panels/user-accounts/gsd-identity.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "gsd-identity.h"
|
||||
|
||||
G_DEFINE_INTERFACE (GsdIdentity, gsd_identity, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gsd_identity_default_init (GsdIdentityInterface *interface)
|
||||
{
|
||||
}
|
||||
|
||||
GQuark
|
||||
gsd_identity_error_quark (void)
|
||||
{
|
||||
static GQuark error_quark = 0;
|
||||
|
||||
if (error_quark == 0) {
|
||||
error_quark = g_quark_from_static_string ("gsd-identity-error");
|
||||
}
|
||||
|
||||
return error_quark;
|
||||
}
|
||||
|
||||
const char *
|
||||
gsd_identity_get_identifier (GsdIdentity *self)
|
||||
{
|
||||
return GSD_IDENTITY_GET_IFACE (self)->get_identifier (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsd_identity_is_signed_in (GsdIdentity *self)
|
||||
{
|
||||
return GSD_IDENTITY_GET_IFACE (self)->is_signed_in (self);
|
||||
}
|
||||
66
panels/user-accounts/gsd-identity.h
Normal file
66
panels/user-accounts/gsd-identity.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors: Ray Strode <rstrode@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __GSD_IDENTITY_H__
|
||||
#define __GSD_IDENTITY_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSD_TYPE_IDENTITY (gsd_identity_get_type ())
|
||||
#define GSD_IDENTITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_IDENTITY, GsdIdentity))
|
||||
#define GSD_IDENTITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_IDENTITY, GsdIdentityInterface))
|
||||
#define GSD_IS_IDENTITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_IDENTITY))
|
||||
#define GSD_IDENTITY_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), GSD_TYPE_IDENTITY, GsdIdentityInterface))
|
||||
#define GSD_IDENTITY_ERROR (gsd_identity_error_quark ())
|
||||
|
||||
typedef struct _GsdIdentity GsdIdentity;
|
||||
typedef struct _GsdIdentityInterface GsdIdentityInterface;
|
||||
typedef enum _GsdIdentityError GsdIdentityError;
|
||||
|
||||
struct _GsdIdentityInterface
|
||||
{
|
||||
GTypeInterface base_interface;
|
||||
|
||||
const char * (* get_identifier) (GsdIdentity *identity);
|
||||
gboolean (* is_signed_in) (GsdIdentity *identity);
|
||||
};
|
||||
|
||||
enum _GsdIdentityError
|
||||
{
|
||||
GSD_IDENTITY_ERROR_VERIFYING,
|
||||
GSD_IDENTITY_ERROR_SIGNING_IN,
|
||||
GSD_IDENTITY_ERROR_RENEWING,
|
||||
GSD_IDENTITY_ERROR_ERASING
|
||||
};
|
||||
|
||||
GType gsd_identity_get_type (void);
|
||||
GQuark gsd_identity_error_quark (void);
|
||||
|
||||
const char *gsd_identity_get_identifier (GsdIdentity *identity);
|
||||
gboolean gsd_identity_is_signed_in (GsdIdentity *identity);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSD_IDENTITY_H__ */
|
||||
363
panels/user-accounts/gsd-kerberos-identity-inquiry.c
Normal file
363
panels/user-accounts/gsd-kerberos-identity-inquiry.c
Normal file
@@ -0,0 +1,363 @@
|
||||
/* -*- Mode: C; tab-width: 8; ident-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Ray Strode
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gsd-kerberos-identity-inquiry.h"
|
||||
#include "gsd-identity-inquiry-private.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
struct _GsdKerberosIdentityInquiryPrivate
|
||||
{
|
||||
GsdIdentity *identity;
|
||||
char *name;
|
||||
char *banner;
|
||||
GList *queries;
|
||||
int number_of_queries;
|
||||
int number_of_unanswered_queries;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GsdIdentityInquiry *inquiry;
|
||||
krb5_prompt *kerberos_prompt;
|
||||
gboolean is_answered;
|
||||
} GsdKerberosIdentityQuery;
|
||||
|
||||
static void identity_inquiry_interface_init (GsdIdentityInquiryInterface *interface);
|
||||
static void initable_interface_init (GInitableIface *interface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GsdKerberosIdentityInquiry,
|
||||
gsd_kerberos_identity_inquiry,
|
||||
G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_interface_init)
|
||||
G_IMPLEMENT_INTERFACE (GSD_TYPE_IDENTITY_INQUIRY,
|
||||
identity_inquiry_interface_init));
|
||||
|
||||
static gboolean
|
||||
gsd_kerberos_identity_inquiry_initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
initable_interface_init (GInitableIface *interface)
|
||||
{
|
||||
interface->init = gsd_kerberos_identity_inquiry_initable_init;
|
||||
}
|
||||
|
||||
static GsdKerberosIdentityQuery *
|
||||
gsd_kerberos_identity_query_new (GsdIdentityInquiry *inquiry,
|
||||
krb5_prompt *kerberos_prompt)
|
||||
{
|
||||
GsdKerberosIdentityQuery *query;
|
||||
|
||||
query = g_slice_new (GsdKerberosIdentityQuery);
|
||||
query->inquiry = inquiry;
|
||||
query->kerberos_prompt = kerberos_prompt;
|
||||
query->is_answered = FALSE;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_kerberos_identity_query_free (GsdKerberosIdentityQuery *query)
|
||||
{
|
||||
g_slice_free (GsdKerberosIdentityQuery, query);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_kerberos_identity_inquiry_dispose (GObject *object)
|
||||
{
|
||||
GsdKerberosIdentityInquiry *self = GSD_KERBEROS_IDENTITY_INQUIRY (object);
|
||||
|
||||
g_clear_object (&self->priv->identity);
|
||||
g_clear_pointer (&self->priv->name, (GDestroyNotify) g_free);
|
||||
g_clear_pointer (&self->priv->banner, (GDestroyNotify) g_free);
|
||||
|
||||
g_list_foreach (self->priv->queries,
|
||||
(GFunc)
|
||||
gsd_kerberos_identity_query_free,
|
||||
NULL);
|
||||
g_clear_pointer (&self->priv->queries, (GDestroyNotify) g_list_free);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_kerberos_identity_inquiry_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (gsd_kerberos_identity_inquiry_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_kerberos_identity_inquiry_class_init (GsdKerberosIdentityInquiryClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gsd_kerberos_identity_inquiry_dispose;
|
||||
object_class->finalize = gsd_kerberos_identity_inquiry_finalize;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GsdKerberosIdentityInquiryPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_kerberos_identity_inquiry_init (GsdKerberosIdentityInquiry *self)
|
||||
{
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||
GSD_TYPE_KERBEROS_IDENTITY_INQUIRY,
|
||||
GsdKerberosIdentityInquiryPrivate);
|
||||
}
|
||||
|
||||
GsdIdentityInquiry *
|
||||
gsd_kerberos_identity_inquiry_new (GsdKerberosIdentity *identity,
|
||||
const char *name,
|
||||
const char *banner,
|
||||
krb5_prompt prompts[],
|
||||
int number_of_prompts)
|
||||
{
|
||||
GObject *object;
|
||||
GsdIdentityInquiry *inquiry;
|
||||
GsdKerberosIdentityInquiry *self;
|
||||
GError *error;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail (GSD_IS_KERBEROS_IDENTITY (identity), NULL);
|
||||
g_return_val_if_fail (number_of_prompts > 0, NULL);
|
||||
|
||||
object = g_object_new (GSD_TYPE_KERBEROS_IDENTITY_INQUIRY, NULL);
|
||||
|
||||
inquiry = GSD_IDENTITY_INQUIRY (object);
|
||||
self = GSD_KERBEROS_IDENTITY_INQUIRY (object);
|
||||
|
||||
/* FIXME: make these construct properties */
|
||||
self->priv->identity = g_object_ref (identity);
|
||||
self->priv->name = g_strdup (name);
|
||||
self->priv->banner = g_strdup (banner);
|
||||
|
||||
self->priv->number_of_queries = 0;
|
||||
for (i = 0; i < number_of_prompts; i++) {
|
||||
GsdKerberosIdentityQuery *query;
|
||||
|
||||
query = gsd_kerberos_identity_query_new (inquiry, &prompts[i]);
|
||||
|
||||
self->priv->queries = g_list_prepend (self->priv->queries, query);
|
||||
self->priv->number_of_queries++;
|
||||
}
|
||||
self->priv->queries = g_list_reverse (self->priv->queries);
|
||||
|
||||
self->priv->number_of_unanswered_queries = self->priv->number_of_queries;
|
||||
|
||||
error = NULL;
|
||||
if (!g_initable_init (G_INITABLE (self), NULL, &error)) {
|
||||
g_debug ("%s", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return inquiry;
|
||||
}
|
||||
|
||||
static GsdIdentity *
|
||||
gsd_kerberos_identity_inquiry_get_identity (GsdIdentityInquiry *inquiry)
|
||||
{
|
||||
GsdKerberosIdentityInquiry *self;
|
||||
|
||||
g_return_val_if_fail (GSD_IS_KERBEROS_IDENTITY_INQUIRY (inquiry), NULL);
|
||||
|
||||
self = GSD_KERBEROS_IDENTITY_INQUIRY (inquiry);
|
||||
|
||||
return self->priv->identity;
|
||||
}
|
||||
|
||||
static char *
|
||||
gsd_kerberos_identity_inquiry_get_name (GsdIdentityInquiry *inquiry)
|
||||
{
|
||||
GsdKerberosIdentityInquiry *self;
|
||||
|
||||
g_return_val_if_fail (GSD_IS_KERBEROS_IDENTITY_INQUIRY (inquiry), NULL);
|
||||
|
||||
self = GSD_KERBEROS_IDENTITY_INQUIRY (inquiry);
|
||||
|
||||
return g_strdup (self->priv->name);
|
||||
}
|
||||
|
||||
static char *
|
||||
gsd_kerberos_identity_inquiry_get_banner (GsdIdentityInquiry *inquiry)
|
||||
{
|
||||
GsdKerberosIdentityInquiry *self;
|
||||
|
||||
g_return_val_if_fail (GSD_IS_KERBEROS_IDENTITY_INQUIRY (inquiry), NULL);
|
||||
|
||||
self = GSD_KERBEROS_IDENTITY_INQUIRY (inquiry);
|
||||
|
||||
return g_strdup (self->priv->banner);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsd_kerberos_identity_inquiry_is_complete (GsdIdentityInquiry *inquiry)
|
||||
{
|
||||
GsdKerberosIdentityInquiry *self;
|
||||
|
||||
g_return_val_if_fail (GSD_IS_KERBEROS_IDENTITY_INQUIRY (inquiry), FALSE);
|
||||
|
||||
self = GSD_KERBEROS_IDENTITY_INQUIRY (inquiry);
|
||||
|
||||
return self->priv->number_of_unanswered_queries == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_kerberos_identity_inquiry_mark_query_answered (GsdKerberosIdentityInquiry *self,
|
||||
GsdKerberosIdentityQuery *query)
|
||||
{
|
||||
if (query->is_answered) {
|
||||
return;
|
||||
}
|
||||
|
||||
query->is_answered = TRUE;
|
||||
self->priv->number_of_unanswered_queries--;
|
||||
|
||||
if (self->priv->number_of_unanswered_queries == 0) {
|
||||
_gsd_identity_inquiry_emit_complete (GSD_IDENTITY_INQUIRY (self));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_kerberos_identity_inquiry_answer_query (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query,
|
||||
const char *answer)
|
||||
{
|
||||
GsdKerberosIdentityInquiry *self;
|
||||
GsdKerberosIdentityQuery *kerberos_query = (GsdKerberosIdentityQuery *) query;
|
||||
|
||||
g_return_if_fail (GSD_IS_KERBEROS_IDENTITY_INQUIRY (inquiry));
|
||||
g_return_if_fail (inquiry == kerberos_query->inquiry);
|
||||
g_return_if_fail (!gsd_kerberos_identity_inquiry_is_complete (inquiry));
|
||||
|
||||
self = GSD_KERBEROS_IDENTITY_INQUIRY (inquiry);
|
||||
|
||||
inquiry = kerberos_query->inquiry;
|
||||
|
||||
strncpy (kerberos_query->kerberos_prompt->reply->data,
|
||||
answer,
|
||||
kerberos_query->kerberos_prompt->reply->length);
|
||||
kerberos_query->kerberos_prompt->reply->length = (unsigned int) strlen (kerberos_query->kerberos_prompt->reply->data);
|
||||
|
||||
gsd_kerberos_identity_inquiry_mark_query_answered (self, kerberos_query);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_kerberos_identity_inquiry_iter_init (GsdIdentityInquiryIter *iter,
|
||||
GsdIdentityInquiry *inquiry)
|
||||
{
|
||||
GsdKerberosIdentityInquiry *self = GSD_KERBEROS_IDENTITY_INQUIRY (inquiry);
|
||||
|
||||
iter->data = self->priv->queries;
|
||||
}
|
||||
|
||||
static GsdIdentityQuery *
|
||||
gsd_kerberos_identity_inquiry_iter_next (GsdIdentityInquiryIter *iter,
|
||||
GsdIdentityInquiry *inquiry)
|
||||
{
|
||||
GsdIdentityQuery *query;
|
||||
GList *node;
|
||||
|
||||
node = iter->data;
|
||||
|
||||
if (node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
query = (GsdIdentityQuery *) node->data;
|
||||
|
||||
node = node->next;
|
||||
|
||||
iter->data = node;
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
static GsdIdentityQueryMode
|
||||
gsd_kerberos_identity_query_get_mode (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query)
|
||||
{
|
||||
GsdKerberosIdentityQuery *kerberos_query = (GsdKerberosIdentityQuery *) query;
|
||||
|
||||
g_return_val_if_fail (GSD_IS_KERBEROS_IDENTITY_INQUIRY (inquiry), GSD_KERBEROS_IDENTITY_QUERY_MODE_INVISIBLE);
|
||||
g_return_val_if_fail (inquiry == kerberos_query->inquiry, GSD_KERBEROS_IDENTITY_QUERY_MODE_INVISIBLE);
|
||||
|
||||
if (kerberos_query->kerberos_prompt->hidden) {
|
||||
return GSD_KERBEROS_IDENTITY_QUERY_MODE_INVISIBLE;
|
||||
} else {
|
||||
return GSD_KERBEROS_IDENTITY_QUERY_MODE_VISIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
gsd_kerberos_identity_query_get_prompt (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query)
|
||||
{
|
||||
GsdKerberosIdentityQuery *kerberos_query = (GsdKerberosIdentityQuery *) query;
|
||||
|
||||
g_return_val_if_fail (GSD_IS_KERBEROS_IDENTITY_INQUIRY (inquiry), GSD_KERBEROS_IDENTITY_QUERY_MODE_INVISIBLE);
|
||||
g_return_val_if_fail (inquiry == kerberos_query->inquiry, NULL);
|
||||
|
||||
return g_strdup (kerberos_query->kerberos_prompt->prompt);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsd_kerberos_identity_query_is_answered (GsdIdentityInquiry *inquiry,
|
||||
GsdIdentityQuery *query)
|
||||
{
|
||||
GsdKerberosIdentityQuery *kerberos_query = (GsdKerberosIdentityQuery *) query;
|
||||
|
||||
g_return_val_if_fail (GSD_IS_KERBEROS_IDENTITY_INQUIRY (inquiry), GSD_KERBEROS_IDENTITY_QUERY_MODE_INVISIBLE);
|
||||
g_return_val_if_fail (inquiry == kerberos_query->inquiry, FALSE);
|
||||
|
||||
return kerberos_query->is_answered;
|
||||
}
|
||||
|
||||
static void
|
||||
identity_inquiry_interface_init (GsdIdentityInquiryInterface *interface)
|
||||
{
|
||||
interface->get_identity = gsd_kerberos_identity_inquiry_get_identity;
|
||||
interface->get_name = gsd_kerberos_identity_inquiry_get_name;
|
||||
interface->get_banner = gsd_kerberos_identity_inquiry_get_banner;
|
||||
interface->is_complete = gsd_kerberos_identity_inquiry_is_complete;
|
||||
interface->answer_query = gsd_kerberos_identity_inquiry_answer_query;
|
||||
interface->iter_init = gsd_kerberos_identity_inquiry_iter_init;
|
||||
interface->iter_next = gsd_kerberos_identity_inquiry_iter_next;
|
||||
interface->get_mode = gsd_kerberos_identity_query_get_mode;
|
||||
interface->get_prompt = gsd_kerberos_identity_query_get_prompt;
|
||||
interface->is_answered = gsd_kerberos_identity_query_is_answered;
|
||||
}
|
||||
74
panels/user-accounts/gsd-kerberos-identity-inquiry.h
Normal file
74
panels/user-accounts/gsd-kerberos-identity-inquiry.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C; tab-width: 8; ident-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors: Ray Strode
|
||||
*/
|
||||
|
||||
#ifndef __GSD_KERBEROS_IDENTITY_INQUIRY_H__
|
||||
#define __GSD_KERBEROS_IDENTITY_INQUIRY_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "gsd-identity-inquiry.h"
|
||||
#include "gsd-kerberos-identity.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSD_TYPE_KERBEROS_IDENTITY_INQUIRY (gsd_kerberos_identity_inquiry_get_type ())
|
||||
#define GSD_KERBEROS_IDENTITY_INQUIRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_KERBEROS_IDENTITY_INQUIRY, GsdKerberosIdentityInquiry))
|
||||
#define GSD_KERBEROS_IDENTITY_INQUIRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_KERBEROS_IDENTITY_INQUIRY, GsdKerberosIdentityInquiryClass))
|
||||
#define GSD_IS_KERBEROS_IDENTITY_INQUIRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_KERBEROS_IDENTITY_INQUIRY))
|
||||
#define GSD_IS_KERBEROS_IDENTITY_INQUIRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSD_TYPE_KERBEROS_IDENTITY_INQUIRY))
|
||||
#define GSD_KERBEROS_IDENTITY_INQUIRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GSD_TYPE_KERBEROS_IDENTITY_INQUIRY, GsdKerberosIdentityInquiryClass))
|
||||
typedef struct _GsdKerberosIdentity GsdKerberosIdentity;
|
||||
typedef struct _GsdKerberosIdentityInquiry GsdKerberosIdentityInquiry;
|
||||
typedef struct _GsdKerberosIdentityInquiryClass GsdKerberosIdentityInquiryClass;
|
||||
typedef struct _GsdKerberosIdentityInquiryPrivate GsdKerberosIdentityInquiryPrivate;
|
||||
typedef struct _GsdKerberosIdentityInquiryIter GsdKerberosIdentityInquiryIter;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GSD_KERBEROS_IDENTITY_QUERY_MODE_INVISIBLE,
|
||||
GSD_KERBEROS_IDENTITY_QUERY_MODE_VISIBLE
|
||||
} GsdKerberosIdentityQueryMode;
|
||||
|
||||
struct _GsdKerberosIdentityInquiry
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GsdKerberosIdentityInquiryPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GsdKerberosIdentityInquiryClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gsd_kerberos_identity_inquiry_get_type (void);
|
||||
|
||||
GsdIdentityInquiry *gsd_kerberos_identity_inquiry_new (GsdKerberosIdentity *identity,
|
||||
const char *name,
|
||||
const char *banner,
|
||||
krb5_prompt prompts[],
|
||||
int number_of_prompts);
|
||||
|
||||
#endif /* __GSD_KERBEROS_IDENTITY_INQUIRY_H__ */
|
||||
1708
panels/user-accounts/gsd-kerberos-identity-manager.c
Normal file
1708
panels/user-accounts/gsd-kerberos-identity-manager.c
Normal file
File diff suppressed because it is too large
Load Diff
61
panels/user-accounts/gsd-kerberos-identity-manager.h
Normal file
61
panels/user-accounts/gsd-kerberos-identity-manager.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors: Ray Strode
|
||||
*/
|
||||
|
||||
#ifndef __GSD_KERBEROS_IDENTITY_MANAGER_H__
|
||||
#define __GSD_KERBEROS_IDENTITY_MANAGER_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gsd-identity-manager.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSD_TYPE_KERBEROS_IDENTITY_MANAGER (gsd_kerberos_identity_manager_get_type ())
|
||||
#define GSD_KERBEROS_IDENTITY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GSD_TYPE_KERBEROS_IDENTITY_MANAGER, GsdKerberosIdentityManager))
|
||||
#define GSD_KERBEROS_IDENTITY_MANAGER_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GSD_TYPE_KERBEROS_IDENTITY_MANAGER, GsdKerberosIdentityManagerClass))
|
||||
#define GSD_IS_KERBEROS_IDENTITY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GSD_TYPE_KERBEROS_IDENTITY_MANAGER))
|
||||
#define GSD_IS_KERBEROS_IDENTITY_MANAGER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GSD_TYPE_KERBEROS_IDENTITY_MANAGER))
|
||||
#define GSD_KERBEROS_IDENTITY_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSD_TYPE_KERBEROS_IDENTITY_MANAGER, GsdKerberosIdentityManagerClass))
|
||||
|
||||
typedef struct _GsdKerberosIdentityManager GsdKerberosIdentityManager;
|
||||
typedef struct _GsdKerberosIdentityManagerClass GsdKerberosIdentityManagerClass;
|
||||
typedef struct _GsdKerberosIdentityManagerPrivate GsdKerberosIdentityManagerPrivate; struct _GsdKerberosIdentityManager
|
||||
{
|
||||
GObject parent_instance;
|
||||
GsdKerberosIdentityManagerPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GsdKerberosIdentityManagerClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gsd_kerberos_identity_manager_get_type (void);
|
||||
GsdIdentityManager* gsd_kerberos_identity_manager_new (void);
|
||||
|
||||
void gsd_kerberos_identity_manager_start_test (GsdKerberosIdentityManager *manager,
|
||||
GError **error);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSD_KERBEROS_IDENTITY_MANAGER_H__ */
|
||||
1199
panels/user-accounts/gsd-kerberos-identity.c
Normal file
1199
panels/user-accounts/gsd-kerberos-identity.c
Normal file
File diff suppressed because it is too large
Load Diff
88
panels/user-accounts/gsd-kerberos-identity.h
Normal file
88
panels/user-accounts/gsd-kerberos-identity.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors: Ray Strode
|
||||
*/
|
||||
|
||||
#ifndef __GSD_KERBEROS_IDENTITY_H__
|
||||
#define __GSD_KERBEROS_IDENTITY_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <krb5.h>
|
||||
#include "gsd-kerberos-identity-inquiry.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSD_TYPE_KERBEROS_IDENTITY (gsd_kerberos_identity_get_type ())
|
||||
#define GSD_KERBEROS_IDENTITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_KERBEROS_IDENTITY, GsdKerberosIdentity))
|
||||
#define GSD_KERBEROS_IDENTITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_KERBEROS_IDENTITY, GsdKerberosIdentityClass))
|
||||
#define GSD_IS_KERBEROS_IDENTITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_KERBEROS_IDENTITY))
|
||||
#define GSD_IS_KERBEROS_IDENTITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSD_TYPE_KERBEROS_IDENTITY))
|
||||
#define GSD_KERBEROS_IDENTITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GSD_TYPE_KERBEROS_IDENTITY, GsdKerberosIdentityClass))
|
||||
|
||||
typedef struct _GsdKerberosIdentity GsdKerberosIdentity;
|
||||
typedef struct _GsdKerberosIdentityClass GsdKerberosIdentityClass;
|
||||
typedef struct _GsdKerberosIdentityPrivate GsdKerberosIdentityPrivate;
|
||||
typedef enum _GsdKerberosIdentityDescriptionLevel GsdKerberosIdentityDescriptionLevel;
|
||||
|
||||
enum _GsdKerberosIdentityDescriptionLevel
|
||||
{
|
||||
GSD_KERBEROS_IDENTITY_DESCRIPTION_REALM,
|
||||
GSD_KERBEROS_IDENTITY_DESCRIPTION_USERNAME_AND_REALM,
|
||||
GSD_KERBEROS_IDENTITY_DESCRIPTION_USERNAME_ROLE_AND_REALM
|
||||
};
|
||||
|
||||
struct _GsdKerberosIdentity
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GsdKerberosIdentityPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GsdKerberosIdentityClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gsd_kerberos_identity_get_type (void);
|
||||
|
||||
GsdIdentity *gsd_kerberos_identity_new (krb5_context kerberos_context,
|
||||
krb5_ccache cache);
|
||||
|
||||
gboolean gsd_kerberos_identity_sign_in (GsdKerberosIdentity *self,
|
||||
const char *principal_name,
|
||||
GsdIdentityInquiryFunc inquiry_func,
|
||||
gpointer inquiry_data,
|
||||
GDestroyNotify destroy_notify,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void gsd_kerberos_identity_update (GsdKerberosIdentity *identity,
|
||||
GsdKerberosIdentity *new_identity);
|
||||
gboolean gsd_kerberos_identity_renew (GsdKerberosIdentity *self,
|
||||
GError **error);
|
||||
gboolean gsd_kerberos_identity_erase (GsdKerberosIdentity *self,
|
||||
GError **error);
|
||||
|
||||
char *gsd_kerberos_identity_get_principal_name (GsdKerberosIdentity *self);
|
||||
char *gsd_kerberos_identity_get_realm_name (GsdKerberosIdentity *self);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSD_KERBEROS_IDENTITY_H__ */
|
||||
@@ -421,7 +421,7 @@ enterprise_permit_user_login (UmAccountDialog *self)
|
||||
remove[0] = NULL;
|
||||
|
||||
um_realm_kerberos_call_change_permitted_logins (self->selected_realm,
|
||||
add, remove,
|
||||
add, remove, "",
|
||||
self->cancellable,
|
||||
on_permit_user_login,
|
||||
g_object_ref (self));
|
||||
@@ -544,6 +544,11 @@ on_realm_joined (GObject *source,
|
||||
um_realm_join_finish (self->selected_realm,
|
||||
result, &error);
|
||||
|
||||
/* If we're already enrolled treat that as a success */
|
||||
if (g_error_matches (error, UM_REALM_ERROR, UM_REALM_ERROR_ALREADY_ENROLLED)) {
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
/* Yay, joined the domain, register the user locally */
|
||||
if (error == NULL) {
|
||||
enterprise_permit_user_login (self);
|
||||
|
||||
@@ -282,14 +282,47 @@ on_realm_diagnostics (GDBusConnection *connection,
|
||||
gpointer user_data)
|
||||
{
|
||||
const gchar *message;
|
||||
const gchar *unused;
|
||||
|
||||
if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(s)"))) {
|
||||
if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(ss)"))) {
|
||||
/* Data is already formatted appropriately for stderr */
|
||||
g_variant_get (parameters, "(&s)", &message);
|
||||
g_variant_get (parameters, "(&s&s)", &message, &unused);
|
||||
g_printerr ("%s", message);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
number_at_least (const gchar *number,
|
||||
guint minimum)
|
||||
{
|
||||
gchar *end;
|
||||
|
||||
if (strtol (number, &end, 10) < (long)minimum)
|
||||
return FALSE;
|
||||
if (!end || *end != '\0')
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
version_compare (const char *version,
|
||||
guint req_major,
|
||||
guint req_minor)
|
||||
{
|
||||
gboolean match = FALSE;
|
||||
gchar **parts;
|
||||
|
||||
parts = g_strsplit (version, ".", 2);
|
||||
|
||||
if (parts[0] && parts[1]) {
|
||||
match = number_at_least (parts[0], req_major) &&
|
||||
number_at_least (parts[1], req_minor);
|
||||
}
|
||||
|
||||
g_strfreev (parts);
|
||||
return match;
|
||||
}
|
||||
|
||||
static void
|
||||
on_realm_manager_async_init (GObject *source,
|
||||
GAsyncResult *result,
|
||||
@@ -298,6 +331,7 @@ on_realm_manager_async_init (GObject *source,
|
||||
GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
|
||||
UmRealmManager *self;
|
||||
GError *error = NULL;
|
||||
const gchar *version;
|
||||
GDBusProxy *proxy;
|
||||
GObject *object;
|
||||
guint sig;
|
||||
@@ -306,6 +340,20 @@ on_realm_manager_async_init (GObject *source,
|
||||
|
||||
if (error != NULL)
|
||||
g_simple_async_result_take_error (async, error);
|
||||
|
||||
/* This is temporary until the dbus interface stabilizes */
|
||||
if (object) {
|
||||
version = um_realm_provider_get_version (UM_REALM_PROVIDER (object));
|
||||
if (!version_compare (version, 0, 2)) {
|
||||
/* No need to bother translators with this temporary message */
|
||||
g_simple_async_result_set_error (async, UM_REALM_ERROR,
|
||||
UM_REALM_ERROR_GENERIC,
|
||||
"Unsupported version of realmd: %s", version);
|
||||
g_object_unref (object);
|
||||
object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (object != NULL) {
|
||||
proxy = G_DBUS_PROXY (object);
|
||||
sig = g_dbus_connection_signal_subscribe (g_dbus_proxy_get_connection (proxy),
|
||||
@@ -450,7 +498,7 @@ um_realm_manager_discover (UmRealmManager *self,
|
||||
discover->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
|
||||
g_simple_async_result_set_op_res_gpointer (res, discover, discover_closure_free);
|
||||
|
||||
um_realm_provider_call_discover (UM_REALM_PROVIDER (self), input, cancellable,
|
||||
um_realm_provider_call_discover (UM_REALM_PROVIDER (self), input, "", cancellable,
|
||||
on_provider_discover, g_object_ref (res));
|
||||
|
||||
g_object_unref (res);
|
||||
@@ -516,6 +564,7 @@ um_realm_join (UmRealmKerberos *realm,
|
||||
um_realm_kerberos_call_enroll_with_credential_cache (realm,
|
||||
g_variant_ref_sink (creds),
|
||||
g_variant_ref_sink (options),
|
||||
"",
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
@@ -553,6 +602,10 @@ um_realm_join_finish (UmRealmKerberos *self,
|
||||
g_set_error (error, UM_REALM_ERROR, UM_REALM_ERROR_BAD_LOGIN,
|
||||
call_error->message);
|
||||
g_error_free (call_error);
|
||||
} else if (g_str_equal (dbus_error, "org.freedesktop.realmd.Error.AlreadyEnrolled")) {
|
||||
g_set_error (error, UM_REALM_ERROR, UM_REALM_ERROR_ALREADY_ENROLLED,
|
||||
call_error->message);
|
||||
g_error_free (call_error);
|
||||
} else {
|
||||
g_propagate_error (error, call_error);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ G_BEGIN_DECLS
|
||||
typedef enum {
|
||||
UM_REALM_ERROR_BAD_LOGIN,
|
||||
UM_REALM_ERROR_BAD_PASSWORD,
|
||||
UM_REALM_ERROR_ALREADY_ENROLLED,
|
||||
UM_REALM_ERROR_GENERIC,
|
||||
} UmRealmErrors;
|
||||
|
||||
|
||||
@@ -41,8 +41,14 @@
|
||||
|
||||
#include "um-user.h"
|
||||
#include "um-user-manager.h"
|
||||
#include "gsd-identity-manager.h"
|
||||
|
||||
#ifdef HAVE_KERBEROS
|
||||
#include "gsd-kerberos-identity-manager.h"
|
||||
#endif
|
||||
|
||||
#include "cc-strength-bar.h"
|
||||
|
||||
#include "um-editable-button.h"
|
||||
#include "um-editable-combo.h"
|
||||
|
||||
@@ -57,9 +63,20 @@
|
||||
|
||||
G_DEFINE_DYNAMIC_TYPE (UmUserPanel, um_user_panel, CC_TYPE_PANEL)
|
||||
|
||||
#define OTHER_PASSWORDS_PROGRAM "seahorse"
|
||||
|
||||
#define UM_USER_PANEL_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((o), UM_TYPE_USER_PANEL, UmUserPanelPrivate))
|
||||
|
||||
typedef struct {
|
||||
UmUserPanelPrivate *d;
|
||||
char *identifier;
|
||||
GsdIdentity *identity;
|
||||
GtkWidget *box;
|
||||
GtkWidget *label;
|
||||
GtkWidget *button;
|
||||
} Realm;
|
||||
|
||||
struct _UmUserPanelPrivate {
|
||||
UmUserManager *um;
|
||||
GtkBuilder *builder;
|
||||
@@ -68,6 +85,8 @@ struct _UmUserPanelPrivate {
|
||||
GPermission *permission;
|
||||
GtkWidget *language_chooser;
|
||||
|
||||
GHashTable *accessible_realms;
|
||||
GsdIdentityManager *identity_manager;
|
||||
UmAccountDialog *account_dialog;
|
||||
UmPasswordDialog *password_dialog;
|
||||
UmPhotoDialog *photo_dialog;
|
||||
@@ -397,12 +416,8 @@ delete_user_response (GtkWidget *dialog,
|
||||
|
||||
user = get_selected_user (d);
|
||||
|
||||
um_user_manager_delete_user (d->um,
|
||||
user,
|
||||
remove_files,
|
||||
(GAsyncReadyCallback)delete_user_done,
|
||||
d,
|
||||
NULL);
|
||||
um_user_manager_delete_user (d->um, user, remove_files,
|
||||
(GAsyncReadyCallback) delete_user_done, d, NULL);
|
||||
|
||||
g_object_unref (user);
|
||||
}
|
||||
@@ -555,6 +570,87 @@ autologin_changed (GObject *object,
|
||||
g_object_unref (user);
|
||||
}
|
||||
|
||||
#ifdef HAVE_KERBEROS
|
||||
static void
|
||||
get_position_of_accessible_realms_label (UmUserPanelPrivate *d,
|
||||
int *left_position,
|
||||
int *top_position)
|
||||
{
|
||||
|
||||
GtkWidget *grid, *label;
|
||||
|
||||
grid = get_widget (d, "user-grid");
|
||||
label = get_widget (d, "accessible-realms-label");
|
||||
gtk_container_child_get (GTK_CONTAINER (grid),
|
||||
label,
|
||||
"left-attach", left_position,
|
||||
"top-attach", top_position,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
get_position_of_next_realm_box (UmUserPanelPrivate *d,
|
||||
int *left_position,
|
||||
int *top_position)
|
||||
{
|
||||
GtkWidget *grid;
|
||||
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
grid = get_widget (d, "user-grid");
|
||||
get_position_of_accessible_realms_label (d, left_position, top_position);
|
||||
*left_position += 1;
|
||||
|
||||
g_hash_table_iter_init (&iter, d->accessible_realms);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
int other_realm_top_position;
|
||||
Realm *realm = value;
|
||||
|
||||
gtk_container_child_get (GTK_CONTAINER (grid),
|
||||
realm->box,
|
||||
"top-attach", &other_realm_top_position,
|
||||
NULL);
|
||||
|
||||
*top_position = MAX (*top_position, other_realm_top_position + 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_accessible_realms_visiblity (UmUserPanelPrivate *d)
|
||||
{
|
||||
GtkWidget *label;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
UmUser *user;
|
||||
uid_t uid;
|
||||
gboolean should_show;
|
||||
|
||||
label = get_widget (d, "accessible-realms-label");
|
||||
user = get_selected_user (d);
|
||||
uid = um_user_get_uid (user);
|
||||
|
||||
if (g_hash_table_size (d->accessible_realms) > 0 && uid == geteuid ()) {
|
||||
should_show = TRUE;
|
||||
} else {
|
||||
should_show = FALSE;
|
||||
}
|
||||
|
||||
gtk_widget_set_visible (label, should_show);
|
||||
g_hash_table_iter_init (&iter, d->accessible_realms);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
Realm *realm = value;
|
||||
|
||||
gtk_widget_set_visible (realm->box, should_show);
|
||||
}
|
||||
}
|
||||
#else /* HAVE_KERBEROS */
|
||||
static void
|
||||
update_accessible_realms_visiblity (UmUserPanelPrivate *d)
|
||||
{
|
||||
}
|
||||
#endif /* HAVE_KERBEROS */
|
||||
|
||||
static void
|
||||
show_user (UmUser *user, UmUserPanelPrivate *d)
|
||||
{
|
||||
@@ -617,9 +713,26 @@ show_user (UmUser *user, UmUserPanelPrivate *d)
|
||||
gtk_widget_show (label);
|
||||
gtk_widget_show (widget);
|
||||
}
|
||||
|
||||
widget = get_widget (d, "other-passwords-button");
|
||||
if (um_user_get_uid (user) != getuid()) {
|
||||
gtk_widget_hide (widget);
|
||||
} else {
|
||||
char *other_passwords;
|
||||
|
||||
other_passwords = g_find_program_in_path (OTHER_PASSWORDS_PROGRAM);
|
||||
if (other_passwords != NULL) {
|
||||
gtk_widget_show (widget);
|
||||
g_free (other_passwords);
|
||||
} else {
|
||||
gtk_widget_hide (widget);
|
||||
}
|
||||
}
|
||||
|
||||
update_accessible_realms_visiblity (d);
|
||||
}
|
||||
|
||||
static void on_permission_changed (GPermission *permission, GParamSpec *pspec, gpointer data);
|
||||
static void on_permission_changed (GPermission *permission, GParamSpec *pspec, UmUserPanelPrivate *d);
|
||||
|
||||
static void
|
||||
selected_user_changed (GtkTreeSelection *selection, UmUserPanelPrivate *d)
|
||||
@@ -673,6 +786,7 @@ account_type_changed (UmEditableCombo *combo,
|
||||
|
||||
if (account_type != um_user_get_account_type (user)) {
|
||||
um_user_set_account_type (user, account_type);
|
||||
on_permission_changed (d->permission, NULL, d);
|
||||
}
|
||||
|
||||
g_object_unref (user);
|
||||
@@ -774,6 +888,22 @@ change_password (GtkButton *button, UmUserPanelPrivate *d)
|
||||
g_object_unref (user);
|
||||
}
|
||||
|
||||
static void
|
||||
edit_other_passwords (GtkButton *button, UmUserPanelPrivate *d)
|
||||
{
|
||||
GError *error;
|
||||
|
||||
error = NULL;
|
||||
|
||||
g_spawn_command_line_async (OTHER_PASSWORDS_PROGRAM, &error);
|
||||
|
||||
if (error != NULL) {
|
||||
g_warning ("unable to launch " OTHER_PASSWORDS_PROGRAM ": %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
change_fingerprint (GtkButton *button, UmUserPanelPrivate *d)
|
||||
{
|
||||
@@ -912,14 +1042,69 @@ remove_unlock_tooltip (GtkWidget *button)
|
||||
}
|
||||
|
||||
static void
|
||||
on_permission_changed (GPermission *permission,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
hide_administrative_tasks (UmUserPanelPrivate *d)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = get_widget (d, "userlist-vbox");
|
||||
gtk_widget_hide (widget);
|
||||
|
||||
widget = get_widget (d, "account-type-label");
|
||||
gtk_widget_hide (widget);
|
||||
|
||||
widget = get_widget (d, "account-type-combo");
|
||||
gtk_widget_hide (widget);
|
||||
|
||||
widget = get_widget (d, "language-label");
|
||||
gtk_widget_hide (widget);
|
||||
|
||||
widget = get_widget (d, "account-language-combo");
|
||||
gtk_widget_hide (widget);
|
||||
|
||||
widget = get_widget (d, "autologin-label");
|
||||
gtk_widget_hide (widget);
|
||||
|
||||
widget = get_widget (d, "autologin-switch");
|
||||
gtk_widget_hide (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
show_administrative_tasks (UmUserPanelPrivate *d)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = get_widget (d, "userlist-vbox");
|
||||
gtk_widget_show (widget);
|
||||
|
||||
widget = get_widget (d, "account-type-label");
|
||||
gtk_widget_show (widget);
|
||||
|
||||
widget = get_widget (d, "account-type-combo");
|
||||
gtk_widget_show (widget);
|
||||
|
||||
widget = get_widget (d, "language-label");
|
||||
gtk_widget_show (widget);
|
||||
|
||||
widget = get_widget (d, "account-language-combo");
|
||||
gtk_widget_show (widget);
|
||||
|
||||
widget = get_widget (d, "autologin-label");
|
||||
gtk_widget_show (widget);
|
||||
|
||||
widget = get_widget (d, "autologin-switch");
|
||||
gtk_widget_show (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
on_permission_changed (GPermission *permission,
|
||||
GParamSpec *pspec,
|
||||
UmUserPanelPrivate *d)
|
||||
{
|
||||
UmUserPanelPrivate *d = data;
|
||||
gboolean is_authorized;
|
||||
gboolean self_selected;
|
||||
UmUser *user;
|
||||
UmUser *self_user;
|
||||
UmAccountType self_account_type;
|
||||
GtkWidget *widget;
|
||||
|
||||
user = get_selected_user (d);
|
||||
@@ -930,6 +1115,9 @@ on_permission_changed (GPermission *permission,
|
||||
is_authorized = g_permission_get_allowed (G_PERMISSION (d->permission));
|
||||
self_selected = um_user_get_uid (user) == geteuid ();
|
||||
|
||||
self_user = um_user_manager_get_user_by_id (d->um, geteuid ());
|
||||
self_account_type = um_user_get_account_type (self_user);
|
||||
|
||||
widget = get_widget (d, "add-user-toolbutton");
|
||||
gtk_widget_set_sensitive (widget, is_authorized);
|
||||
if (is_authorized) {
|
||||
@@ -1015,6 +1203,12 @@ on_permission_changed (GPermission *permission,
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-fingerprint-notebook")), 0);
|
||||
}
|
||||
|
||||
if (is_authorized || self_account_type == UM_ACCOUNT_TYPE_ADMINISTRATOR) {
|
||||
show_administrative_tasks (d);
|
||||
} else {
|
||||
hide_administrative_tasks (d);
|
||||
}
|
||||
|
||||
um_password_dialog_set_privileged (d->password_dialog, is_authorized);
|
||||
|
||||
g_object_unref (user);
|
||||
@@ -1213,6 +1407,9 @@ setup_main_window (UmUserPanelPrivate *d)
|
||||
button = get_widget (d, "account-password-button");
|
||||
g_signal_connect (button, "start-editing", G_CALLBACK (change_password), d);
|
||||
|
||||
button = get_widget (d, "other-passwords-button");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (edit_other_passwords), d);
|
||||
|
||||
button = get_widget (d, "account-language-combo");
|
||||
g_signal_connect (button, "editing-done", G_CALLBACK (language_changed), d);
|
||||
|
||||
@@ -1245,6 +1442,280 @@ setup_main_window (UmUserPanelPrivate *d)
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
||||
#ifdef HAVE_KERBEROS
|
||||
static void
|
||||
remove_accessible_realm_for_identity (UmUserPanelPrivate *d,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
GtkWidget *grid;
|
||||
Realm *realm;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
int top_position;
|
||||
|
||||
realm = g_hash_table_lookup (d->accessible_realms,
|
||||
(gpointer)
|
||||
gsd_identity_get_identifier (identity));
|
||||
|
||||
if (realm == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
grid = get_widget (d, "user-grid");
|
||||
|
||||
gtk_container_child_get (GTK_CONTAINER (grid),
|
||||
realm->box,
|
||||
"top-attach", &top_position,
|
||||
NULL);
|
||||
|
||||
g_hash_table_remove (d->accessible_realms, realm->identifier);
|
||||
|
||||
g_hash_table_iter_init (&iter, d->accessible_realms);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
int other_realm_top_position;
|
||||
|
||||
realm = value;
|
||||
|
||||
gtk_container_child_get (GTK_CONTAINER (grid),
|
||||
realm->box,
|
||||
"top-attach", &other_realm_top_position,
|
||||
NULL);
|
||||
|
||||
if (other_realm_top_position > top_position) {
|
||||
other_realm_top_position--;
|
||||
gtk_container_child_set (GTK_CONTAINER (grid),
|
||||
realm->box,
|
||||
"top-attach", other_realm_top_position,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
update_accessible_realms_visiblity (d);
|
||||
}
|
||||
|
||||
static void
|
||||
rename_accessible_realm_for_identity (UmUserPanelPrivate *d,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
Realm *realm;
|
||||
char *name;
|
||||
|
||||
realm = g_hash_table_lookup (d->accessible_realms,
|
||||
(gpointer)
|
||||
gsd_identity_get_identifier (identity));
|
||||
|
||||
if (realm == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = gsd_identity_manager_name_identity (d->identity_manager,
|
||||
identity);
|
||||
gtk_label_set_text (GTK_LABEL (realm->label), name);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
static void
|
||||
on_signed_out (GsdIdentityManager *manager,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GsdIdentity *identity = GSD_IDENTITY (user_data);
|
||||
|
||||
gsd_identity_manager_sign_identity_out_finish (manager,
|
||||
result,
|
||||
NULL);
|
||||
g_object_unref (identity);
|
||||
}
|
||||
|
||||
static void
|
||||
on_sign_out_clicked (GtkButton *button,
|
||||
Realm *realm)
|
||||
{
|
||||
UmUserPanelPrivate *d = realm->d;
|
||||
|
||||
gsd_identity_manager_sign_identity_out (d->identity_manager, realm->identity, NULL,
|
||||
(GAsyncReadyCallback) on_signed_out,
|
||||
g_object_ref (realm->identity));
|
||||
}
|
||||
|
||||
static Realm *
|
||||
realm_new (UmUserPanelPrivate *d,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
Realm *realm;
|
||||
char *name;
|
||||
|
||||
realm = g_slice_new (Realm);
|
||||
realm->d = d;
|
||||
realm->identifier = g_strdup (gsd_identity_get_identifier (identity));
|
||||
realm->identity = identity;
|
||||
realm->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
|
||||
name = gsd_identity_manager_name_identity (d->identity_manager,
|
||||
identity);
|
||||
realm->label = gtk_label_new (name);
|
||||
g_free (name);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (realm->box), realm->label);
|
||||
|
||||
realm->button = gtk_button_new_with_label (_("Sign Out"));
|
||||
gtk_widget_set_halign (GTK_WIDGET (realm->button),
|
||||
GTK_ALIGN_END);
|
||||
gtk_widget_set_hexpand (GTK_WIDGET (realm->button),
|
||||
TRUE);
|
||||
|
||||
g_signal_connect (G_OBJECT (realm->button),
|
||||
"clicked",
|
||||
G_CALLBACK (on_sign_out_clicked),
|
||||
realm);
|
||||
gtk_container_add (GTK_CONTAINER (realm->box), realm->button);
|
||||
gtk_widget_show_all (realm->box);
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
||||
static void
|
||||
realm_free (Realm *realm)
|
||||
{
|
||||
gtk_widget_destroy (realm->box);
|
||||
g_free (realm->identifier);
|
||||
g_slice_free (Realm, realm);
|
||||
}
|
||||
|
||||
static void
|
||||
add_accessible_realm_for_identity (UmUserPanelPrivate *d,
|
||||
GsdIdentity *identity)
|
||||
{
|
||||
Realm *realm;
|
||||
GtkWidget *grid;
|
||||
int left_position, top_position;
|
||||
|
||||
remove_accessible_realm_for_identity (d, identity);
|
||||
|
||||
realm = realm_new (d, identity);
|
||||
|
||||
grid = get_widget (d, "user-grid");
|
||||
|
||||
get_position_of_next_realm_box (d, &left_position, &top_position);
|
||||
g_hash_table_replace (d->accessible_realms,
|
||||
realm->identifier,
|
||||
realm);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
realm->box,
|
||||
left_position,
|
||||
top_position,
|
||||
1,
|
||||
1);
|
||||
update_accessible_realms_visiblity (d);
|
||||
}
|
||||
|
||||
static void
|
||||
on_identity_added (GsdIdentityManager *manager,
|
||||
GsdIdentity *identity,
|
||||
UmUserPanelPrivate *d)
|
||||
{
|
||||
add_accessible_realm_for_identity (d, identity);
|
||||
}
|
||||
|
||||
static void
|
||||
on_identity_refreshed (GsdIdentityManager *manager,
|
||||
GsdIdentity *identity,
|
||||
UmUserPanelPrivate *d)
|
||||
{
|
||||
add_accessible_realm_for_identity (d, identity);
|
||||
}
|
||||
|
||||
static void
|
||||
on_identity_removed (GsdIdentityManager *manager,
|
||||
GsdIdentity *identity,
|
||||
UmUserPanelPrivate *d)
|
||||
{
|
||||
remove_accessible_realm_for_identity (d, identity);
|
||||
}
|
||||
|
||||
static void
|
||||
on_identity_expired (GsdIdentityManager *manager,
|
||||
GsdIdentity *identity,
|
||||
UmUserPanelPrivate *d)
|
||||
{
|
||||
remove_accessible_realm_for_identity (d, identity);
|
||||
}
|
||||
|
||||
static void
|
||||
on_identity_renamed (GsdIdentityManager *manager,
|
||||
GsdIdentity *identity,
|
||||
UmUserPanelPrivate *d)
|
||||
{
|
||||
rename_accessible_realm_for_identity (d, identity);
|
||||
}
|
||||
|
||||
static void
|
||||
on_identities_listed (GsdIdentityManager *manager,
|
||||
GAsyncResult *result,
|
||||
UmUserPanelPrivate *d)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GList *identities, *node;
|
||||
|
||||
g_signal_connect (manager,
|
||||
"identity-added",
|
||||
G_CALLBACK (on_identity_added),
|
||||
d);
|
||||
|
||||
g_signal_connect (manager,
|
||||
"identity-removed",
|
||||
G_CALLBACK (on_identity_removed),
|
||||
d);
|
||||
|
||||
g_signal_connect (manager,
|
||||
"identity-expired",
|
||||
G_CALLBACK (on_identity_expired),
|
||||
d);
|
||||
|
||||
g_signal_connect (manager,
|
||||
"identity-refreshed",
|
||||
G_CALLBACK (on_identity_refreshed),
|
||||
d);
|
||||
g_signal_connect (manager,
|
||||
"identity-renamed",
|
||||
G_CALLBACK (on_identity_renamed),
|
||||
d);
|
||||
|
||||
identities = gsd_identity_manager_list_identities_finish (manager,
|
||||
result,
|
||||
&error);
|
||||
|
||||
if (identities == NULL) {
|
||||
if (error != NULL) {
|
||||
g_warning ("UmUserPanel: Could not list identities: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (node = identities; node != NULL; node = node->next) {
|
||||
GsdIdentity *identity = node->data;
|
||||
|
||||
if (gsd_identity_is_signed_in (identity))
|
||||
add_accessible_realm_for_identity (d, identity);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_KERBEROS */
|
||||
|
||||
static void
|
||||
setup_realms (UmUserPanelPrivate *d)
|
||||
{
|
||||
#ifdef HAVE_KERBEROS
|
||||
d->accessible_realms = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify) realm_free);
|
||||
|
||||
d->identity_manager = gsd_kerberos_identity_manager_new ();
|
||||
gsd_identity_manager_list_identities (d->identity_manager, NULL,
|
||||
(GAsyncReadyCallback) on_identities_listed, d);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
um_user_panel_init (UmUserPanel *self)
|
||||
{
|
||||
@@ -1278,7 +1749,7 @@ um_user_panel_init (UmUserPanel *self)
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
setup_realms (d);
|
||||
setup_main_window (d);
|
||||
d->account_dialog = um_account_dialog_new ();
|
||||
d->password_dialog = um_password_dialog_new ();
|
||||
@@ -1326,6 +1797,17 @@ um_user_panel_dispose (GObject *object)
|
||||
g_object_unref (priv->permission);
|
||||
priv->permission = NULL;
|
||||
}
|
||||
|
||||
if (priv->accessible_realms) {
|
||||
g_hash_table_unref (priv->accessible_realms);
|
||||
priv->accessible_realms = NULL;
|
||||
}
|
||||
|
||||
if (priv->identity_manager) {
|
||||
g_object_unref (priv->identity_manager);
|
||||
priv->identity_manager = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (um_user_panel_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user