Codebase list realmd / 3bfcf58
Imported Upstream version 0.11 Laurent Bigonville 11 years ago
53 changed file(s) with 3255 addition(s) and 371 deletion(s). Raw diff Collapse all Expand all
00 # Generate automatically. Do not edit.
1
2 commit bcaf68b3bd66a16829144c362a06162e12751321
3 Author: Stef Walter <stefw@gnome.org>
4 Date: 2012-10-30
5
6 Release version 0.11
7
8 NEWS | 5 +++++
9 configure.ac | 2 +-
10 2 files changed, 6 insertions(+), 1 deletion(-)
11
12 commit f888456a6b294c4db6d9b8dc6376b38aebb703df
13 Author: Stef Walter <stefw@gnome.org>
14 Date: 2012-10-30
15
16 Fix ordering bug in option parsing of realm command
17
18 * We want to prefer arguments to --install over commands, so that
19 a command like this works:
20 $ realm --install /here join domain.com
21
22 tools/realm.c | 30 +++++++++++++++---------------
23 1 file changed, 15 insertions(+), 15 deletions(-)
24
25 commit eb62050de82fc9cce414447e1201f7ecc8b5f39d
26 Author: Stef Walter <stefw@gnome.org>
27 Date: 2012-10-29
28
29 Add assume-packages option to prevent package installation
30
31 * New assume-packages option for the Join() dbus method
32 * Set this option automatically when doing an --install style
33 join from the 'realm' command.
34
35 dbus/org.freedesktop.realmd.xml | 3 +++
36 dbus/realm-dbus-constants.h | 1 +
37 service/realm-kerberos-membership.h | 1 +
38 service/realm-kerberos.c | 4 ++++
39 service/realm-packages.c | 12 ++++++++----
40 service/realm-samba.c | 10 +++++++++-
41 service/realm-sssd-ad.c | 6 ++++++
42 tools/realm.c | 18 ++++++++++++------
43 8 files changed, 44 insertions(+), 11 deletions(-)
44
45 commit df59a0870249c54b033a5f4168180f750f0c4ad7
46 Author: Stef Walter <stefw@gnome.org>
47 Date: 2012-10-29
48
49 Fix parsing of 'operation' option
50
51 service/realm-diagnostics.c | 2 +-
52 1 file changed, 1 insertion(+), 1 deletion(-)
53
54 commit c44ef7b06c68e6754fb88a6fb7aca474b48ac15c
55 Author: Stef Walter <stefw@gnome.org>
56 Date: 2012-10-29
57
58 Add RequiredPackages property
59
60 * Each realm has this property which describes which packages must
61 be present to configure this realm.
62
63 dbus/org.freedesktop.realmd.xml | 13 +++++++++++++
64 service/realm-kerberos.c | 13 +++++++++++++
65 service/realm-kerberos.h | 3 +++
66 service/realm-packages.c | 37 ++++++++++++++++++++++++++++++-------
67 service/realm-packages.h | 2 ++
68 service/realm-samba.c | 7 +++++++
69 service/realm-sssd-ad.c | 16 ++++++++++++----
70 tools/realm-discover.c | 20 +++++++++++++-------
71 8 files changed, 93 insertions(+), 18 deletions(-)
72
73 commit 8de2508469335d0aef2854f77632b45d2b6db14a
74 Author: Stef Walter <stefw@gnome.org>
75 Date: 2012-10-26
76
77 Add ability to run in 'install' mode
78
79 * For use when no dbus daemon is running, or need to run in a
80 specific file root prefix.
81 * We spawn the daemon directly and connect to it over peer to peer
82 dbus connection on a socketpair() file descriptor.
83 * We don't run service restarts or other service bits when in
84 install mode.
85 * We don't flush caches when in install mode.
86 * No checks for polkit permissions when in install mode.
87 * Don't timeout and quit when in install mode.
88 * Had to copy GDBusObjectManagerClient and GDBusObjectProxy into
89 our project temporarily so we can get a fix for using the
90 object manager over a peer to peer connection. glib bug #686920
91
92 https://bugs.freedesktop.org/show_bug.cgi?id=56424
93
94 doc/realm.xml | 8 +
95 service/realm-daemon.c | 180 +++-
96 service/realm-daemon.h | 4 +
97 service/realm-kerberos.c | 12 +-
98 service/realm-service.c | 51 +-
99 tools/Makefile.am | 5 +
100 tools/eggdbusobjectmanagerclient.c | 1740 ++++++++++++++++++++++++++++++++++++
101 tools/eggdbusobjectmanagerclient.h | 148 +++
102 tools/eggdbusobjectproxy.c | 365 ++++++++
103 tools/eggdbusobjectproxy.h | 92 ++
104 tools/realm-client.c | 172 +++-
105 tools/realm-client.h | 3 +-
106 tools/realm.c | 21 +-
107 13 files changed, 2716 insertions(+), 85 deletions(-)
108
109 commit 3231198135bff97d82eacf441350be5bbf4660fb
110 Author: Stef Walter <stefw@gnome.org>
111 Date: 2012-10-25
112
113 Move global option parsing into realm.c
114
115 * Each command doesn't have to create their own client, and simpler
116 to add options common to all commands.
117
118 doc/realm.xml | 47 ++++++++++++-----------------------------------
119 tools/realm-discover.c | 34 +++++++++-------------------------
120 tools/realm-join.c | 24 ++++++++----------------
121 tools/realm-leave.c | 21 +++++++--------------
122 tools/realm-logins.c | 37 +++++++++++++------------------------
123 tools/realm.c | 43 ++++++++++++++++++++++++++++++++++++++-----
124 tools/realm.h | 22 ++++++++++++++++------
125 7 files changed, 103 insertions(+), 125 deletions(-)
1126
2127 commit 56ad086b908cadc75648b804916bf6488061e890
3128 Author: Stef Walter <stefw@gnome.org>
0 0.11
1 * Support install mode, where we try not to use the DBus system bus
2 * Support caller based package installation
3 * Fix various bugs
4
05 0.10
16 * Send diagnostics from subcommand to client as they come in
27 * Return configured realms back to callers
00 #! /bin/sh
11 # Guess values for system-dependent variables and create Makefiles.
2 # Generated by GNU Autoconf 2.69 for realmd 0.10.
2 # Generated by GNU Autoconf 2.69 for realmd 0.11.
33 #
44 # Report bugs to <http://bugs.freedesktop.org/enter_bug.cgi?product=realmd>.
55 #
580580 # Identity of this package.
581581 PACKAGE_NAME='realmd'
582582 PACKAGE_TARNAME='realmd'
583 PACKAGE_VERSION='0.10'
584 PACKAGE_STRING='realmd 0.10'
583 PACKAGE_VERSION='0.11'
584 PACKAGE_STRING='realmd 0.11'
585585 PACKAGE_BUGREPORT='http://bugs.freedesktop.org/enter_bug.cgi?product=realmd'
586586 PACKAGE_URL=''
587587
13841384 # Omit some internal or obsolete options to make the list less imposing.
13851385 # This message is too long to be a string in the A/UX 3.1 sh.
13861386 cat <<_ACEOF
1387 \`configure' configures realmd 0.10 to adapt to many kinds of systems.
1387 \`configure' configures realmd 0.11 to adapt to many kinds of systems.
13881388
13891389 Usage: $0 [OPTION]... [VAR=VALUE]...
13901390
14501450
14511451 if test -n "$ac_init_help"; then
14521452 case $ac_init_help in
1453 short | recursive ) echo "Configuration of realmd 0.10:";;
1453 short | recursive ) echo "Configuration of realmd 0.11:";;
14541454 esac
14551455 cat <<\_ACEOF
14561456
15811581 test -n "$ac_init_help" && exit $ac_status
15821582 if $ac_init_version; then
15831583 cat <<\_ACEOF
1584 realmd configure 0.10
1584 realmd configure 0.11
15851585 generated by GNU Autoconf 2.69
15861586
15871587 Copyright (C) 2012 Free Software Foundation, Inc.
19501950 This file contains any messages produced by compilers while
19511951 running configure, to aid debugging if configure makes a mistake.
19521952
1953 It was created by realmd $as_me 0.10, which was
1953 It was created by realmd $as_me 0.11, which was
19541954 generated by GNU Autoconf 2.69. Invocation command line was
19551955
19561956 $ $0 $@
27782778
27792779 # Define the identity of the package.
27802780 PACKAGE='realmd'
2781 VERSION='0.10'
2781 VERSION='0.11'
27822782
27832783
27842784 cat >>confdefs.h <<_ACEOF
89278927 # report actual input values of CONFIG_FILES etc. instead of their
89288928 # values after options handling.
89298929 ac_log="
8930 This file was extended by realmd $as_me 0.10, which was
8930 This file was extended by realmd $as_me 0.11, which was
89318931 generated by GNU Autoconf 2.69. Invocation command line was
89328932
89338933 CONFIG_FILES = $CONFIG_FILES
89938993 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
89948994 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
89958995 ac_cs_version="\\
8996 realmd config.status 0.10
8996 realmd config.status 0.11
89978997 configured by $0, generated by GNU Autoconf 2.69,
89988998 with options \\"\$ac_cs_config\\"
89998999
00 AC_PREREQ(2.63)
11
2 AC_INIT([realmd], [0.10],
2 AC_INIT([realmd], [0.11],
33 [http://bugs.freedesktop.org/enter_bug.cgi?product=realmd],
44 [realmd])
55
336336 </itemizedlist>
337337 -->
338338 <property name="Details" type="a(ss)" access="read"/>
339
340 <!--
341 RequiredPackages: prerequisite software
342
343 Software packages that are required in order for a join to
344 succeed. These are either simple strings like <literal>sssd</literal>,
345 or strings with an operator and version number like
346 <literal>sssd >= 1.9.0</literal>
347
348 These values are specific to the packaging system that is
349 being run.
350 -->
351 <property name="RequiredPackages" type="as" access="read"/>
339352
340353 <!--
341354 LoginFormats: supported formats for login names
587600 <listitem><para><literal>computer-ou</literal>: a string
588601 containing an LDAP DN for an organizational unit where the
589602 computer account should be created</para></listitem>
603 <listitem><para><literal>assume-packages</literal>: a boolean
604 which overrides makes the join assume that all needed
605 software packages have already been installed</para></listitem>
590606 </itemizedlist>
591607
592608 This method requires authorization for the PolicyKit action
5959 #define REALM_DBUS_OPTION_SERVER_SOFTWARE "server-software"
6060 #define REALM_DBUS_OPTION_CLIENT_SOFTWARE "client-software"
6161 #define REALM_DBUS_OPTION_MEMBERSHIP_SOFTWARE "membership-software"
62 #define REALM_DBUS_OPTION_ASSUME_PACKAGES "assume-packages"
6263
6364 #define REALM_DBUS_IDENTIFIER_ACTIVE_DIRECTORY "active-directory"
6465 #define REALM_DBUS_IDENTIFIER_WINBIND "winbind"
5656 &lt;/method&gt;
5757 &lt;property name='SupportedInterfaces' type='as' access='read'&gt;&lt;/property&gt;
5858 &lt;property name='Details' type='a(ss)' access='read'&gt;&lt;/property&gt;
59 &lt;property name='RequiredPackages' type='as' access='read'&gt;&lt;/property&gt;
5960 &lt;property name='LoginFormats' type='as' access='read'&gt;&lt;/property&gt;
6061 &lt;property name='LoginPolicy' type='s' access='read'&gt;&lt;/property&gt;
6162 &lt;property name='PermittedLogins' type='as' access='read'&gt;&lt;/property&gt;
3636 <td valign="top" align="right"></td>
3737 </tr></table></div>
3838 <div class="refsect1">
39 <a name="idp5714736"></a><h2>Properties</h2>
39 <a name="idp11402976"></a><h2>Properties</h2>
4040 <pre class="synopsis">
4141 <a class="link" href="gdbus-org.freedesktop.realmd.Kerberos.html#gdbus-property-org-freedesktop-realmd-Kerberos.RealmName" title='The "RealmName" property'>RealmName</a> readable s
4242 <a class="link" href="gdbus-org.freedesktop.realmd.Kerberos.html#gdbus-property-org-freedesktop-realmd-Kerberos.DomainName" title='The "DomainName" property'>DomainName</a> readable s
4646 </pre>
4747 </div>
4848 <div class="refsect1">
49 <a name="idp6873920"></a><h2>Properties</h2>
49 <a name="idp8661952"></a><h2>Properties</h2>
5050 <pre class="synopsis">
5151 <a class="link" href="gdbus-org.freedesktop.realmd.KerberosMembership.html#gdbus-property-org-freedesktop-realmd-KerberosMembership.SuggestedAdministrator" title='The "SuggestedAdministrator" property'>SuggestedAdministrator</a> readable s
5252 <a class="link" href="gdbus-org.freedesktop.realmd.KerberosMembership.html#gdbus-property-org-freedesktop-realmd-KerberosMembership.SupportedJoinCredentials" title='The "SupportedJoinCredentials" property'>SupportedJoinCredentials</a> readable a(ss)
9898 <li class="listitem"><p><code class="literal">computer-ou</code>: a string
9999 containing an LDAP DN for an organizational unit where the
100100 computer account should be created</p></li>
101 <li class="listitem"><p><code class="literal">assume-packages</code>: a boolean
102 which overrides makes the join assume that all needed
103 software packages have already been installed</p></li>
101104 </ul></div>
102105 <p>
103106 </p>
4646 </pre>
4747 </div>
4848 <div class="refsect1">
49 <a name="idp8500176"></a><h2>Properties</h2>
49 <a name="idp9243216"></a><h2>Properties</h2>
5050 <pre class="synopsis">
5151 <a class="link" href="gdbus-org.freedesktop.realmd.Provider.html#gdbus-property-org-freedesktop-realmd-Provider.Name" title='The "Name" property'>Name</a> readable s
5252 <a class="link" href="gdbus-org.freedesktop.realmd.Provider.html#gdbus-property-org-freedesktop-realmd-Provider.Version" title='The "Version" property'>Version</a> readable s
4747 </pre>
4848 </div>
4949 <div class="refsect1">
50 <a name="idp6374720"></a><h2>Properties</h2>
50 <a name="idp9928208"></a><h2>Properties</h2>
5151 <pre class="synopsis">
5252 <a class="link" href="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.Name" title='The "Name" property'>Name</a> readable s
5353 <a class="link" href="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.Configured" title='The "Configured" property'>Configured</a> readable s
5454 <a class="link" href="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.SupportedInterfaces" title='The "SupportedInterfaces" property'>SupportedInterfaces</a> readable as
5555 <a class="link" href="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.Details" title='The "Details" property'>Details</a> readable a(ss)
56 <a class="link" href="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.RequiredPackages" title='The "RequiredPackages" property'>RequiredPackages</a> readable as
5657 <a class="link" href="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.LoginFormats" title='The "LoginFormats" property'>LoginFormats</a> readable as
5758 <a class="link" href="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.LoginPolicy" title='The "LoginPolicy" property'>LoginPolicy</a> readable s
5859 <a class="link" href="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.PermittedLogins" title='The "PermittedLogins" property'>PermittedLogins</a> readable as
300301 </div>
301302 <hr>
302303 <div class="refsect2">
304 <a name="gdbus-property-org-freedesktop-realmd-Realm.RequiredPackages"></a><h3>The "RequiredPackages" property</h3>
305 <pre class="programlisting">
306 RequiredPackages readable as
307 </pre>
308 <p>prerequisite software</p>
309 <p> Software packages that are required in order for a join to
310 succeed. These are either simple strings like <code class="literal">sssd</code>,
311 or strings with an operator and version number like
312 <code class="literal">sssd &gt;= 1.9.0</code>
313 </p>
314 <p> These values are specific to the packaging system that is
315 being run.
316 </p>
317 </div>
318 <hr>
319 <div class="refsect2">
303320 <a name="gdbus-property-org-freedesktop-realmd-Realm.LoginFormats"></a><h3>The "LoginFormats" property</h3>
304321 <pre class="programlisting">
305322 LoginFormats readable as
4545 </pre>
4646 </div>
4747 <div class="refsect1">
48 <a name="idp8140512"></a><h2>Signals</h2>
48 <a name="idp11296128"></a><h2>Signals</h2>
4949 <pre class="synopsis">
5050 <a class="link" href="gdbus-org.freedesktop.realmd.Service.html#gdbus-signal-org-freedesktop-realmd-Service.Diagnostics" title='The "Diagnostics" signal'>Diagnostics</a> (s data,
5151 s operation);
3232 By default SSSD is used.</p>
3333 <div class="section">
3434 <div class="titlepage"><div><div><h3 class="title">
35 <a name="idp8178992"></a>Using SSSD with Active Directory</h3></div></div></div>
35 <a name="idp11380720"></a>Using SSSD with Active Directory</h3></div></div></div>
3636 <p><a class="ulink" href="https://fedorahosted.org/sssd/" target="_top">SSSD</a>
3737 provides client software for various kerberos and/or LDAP
3838 directories. Since version 1.9.x it provides good support
5050 </div>
5151 <div class="section">
5252 <div class="titlepage"><div><div><h3 class="title">
53 <a name="idp6168432"></a>Using Winbind with Active Directory</h3></div></div></div>
53 <a name="idp11306688"></a>Using Winbind with Active Directory</h3></div></div></div>
5454 <p>Samba
5555 <a class="ulink" href="http://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/winbind.html" target="_top">Winbind</a>
5656 provides client software for use with Active Directory.</p>
2525 <dt><span class="section"><a href="guide-active-directory.html#guide-active-directory-discover">Discovering Active Directory domains</a></span></dt>
2626 <dt><span class="section"><a href="guide-active-directory-client.html">Active Directory client software</a></span></dt>
2727 <dd><dl>
28 <dt><span class="section"><a href="guide-active-directory-client.html#idp8178992">Using SSSD with Active Directory</a></span></dt>
29 <dt><span class="section"><a href="guide-active-directory-client.html#idp6168432">Using Winbind with Active Directory</a></span></dt>
28 <dt><span class="section"><a href="guide-active-directory-client.html#idp11380720">Using SSSD with Active Directory</a></span></dt>
29 <dt><span class="section"><a href="guide-active-directory-client.html#idp11306688">Using Winbind with Active Directory</a></span></dt>
3030 </dl></dd>
3131 <dt><span class="section"><a href="guide-active-directory-join.html">Joining an Active Directory domain</a></span></dt>
3232 <dt><span class="section"><a href="guide-active-directory-permit.html">Logins using Domain Accounts</a></span></dt>
3535 <p>Only specify the settings you wish to override.</p>
3636 <div class="section">
3737 <div class="titlepage"><div><div><h3 class="title">
38 <a name="idp7293920"></a>computer-ou</h3></div></div></div>
38 <a name="idp7927392"></a>computer-ou</h3></div></div></div>
3939 <p>Specify this option to create directory computer accounts
4040 in a location other than the default. This currently only works
4141 with Active Directory domains.</p>
2626 specify the settings you wish to override.</p>
2727 <div class="section">
2828 <div class="titlepage"><div><div><h3 class="title">
29 <a name="idp8765568"></a>default-home</h3></div></div></div>
29 <a name="idp8774336"></a>default-home</h3></div></div></div>
3030 <p>Specify the <code class="option">default-home</code> setting in
3131 order to control how to set the home directory for accounts
3232 that have no home directory explicitly set.</p>
5858 </div>
5959 <div class="section">
6060 <div class="titlepage"><div><div><h3 class="title">
61 <a name="idp6097024"></a>default-shell</h3></div></div></div>
61 <a name="idp9756048"></a>default-shell</h3></div></div></div>
6262 <p>Specify the <code class="option">default-shell</code> setting in
6363 order to control how to set the Unix shell for accounts that
6464 have no shell explicitly set.</p>
2323 <a name="guide-configuring"></a>Configuring realmd</h2></div></div></div>
2424 <div class="toc"><dl>
2525 <dt><span class="section"><a href="guide-configuring.html#guide-configuring-active-directory">active-directory</a></span></dt>
26 <dd><dl><dt><span class="section"><a href="guide-configuring.html#idp8618752">default-client</a></span></dt></dl></dd>
26 <dd><dl><dt><span class="section"><a href="guide-configuring.html#idp8807328">default-client</a></span></dt></dl></dd>
2727 <dt><span class="section"><a href="guide-configuring-users.html">user</a></span></dt>
2828 <dd><dl>
29 <dt><span class="section"><a href="guide-configuring-users.html#idp8765568">default-home</a></span></dt>
30 <dt><span class="section"><a href="guide-configuring-users.html#idp6097024">default-shell</a></span></dt>
29 <dt><span class="section"><a href="guide-configuring-users.html#idp8774336">default-home</a></span></dt>
30 <dt><span class="section"><a href="guide-configuring-users.html#idp9756048">default-shell</a></span></dt>
3131 </dl></dd>
3232 <dt><span class="section"><a href="guide-configuring-realm.html">Realm specific settings</a></span></dt>
33 <dd><dl><dt><span class="section"><a href="guide-configuring-realm.html#idp7293920">computer-ou</a></span></dt></dl></dd>
33 <dd><dl><dt><span class="section"><a href="guide-configuring-realm.html#idp7927392">computer-ou</a></span></dt></dl></dd>
3434 </dl></div>
3535 <p><span class="command"><strong>realmd</strong></span> can be tweaked by network administrators
3636 to act in specific ways. This is done by placing settings in a
5050 specify the settings you wish to override.</p>
5151 <div class="section">
5252 <div class="titlepage"><div><div><h3 class="title">
53 <a name="idp8618752"></a>default-client</h3></div></div></div>
53 <a name="idp8807328"></a>default-client</h3></div></div></div>
5454 <p>Specify the <code class="option">default-client</code> setting in
5555 order to control which client software is the preferred default
5656 for use with Active Directory.</p>
2121 <div class="chapter">
2222 <div class="titlepage"><div><div><h2 class="title">
2323 <a name="guide-freeipa"></a>Using with other Kerberos realms</h2></div></div></div>
24 <div class="toc"><dl><dt><span class="section"><a href="guide-freeipa.html#idp5982432">Discovering Kerberos realms</a></span></dt></dl></div>
24 <div class="toc"><dl><dt><span class="section"><a href="guide-freeipa.html#idp9561696">Discovering Kerberos realms</a></span></dt></dl></div>
2525 <p><span class="command"><strong>realmd</strong></span> can discover generic Kerberos realms.
2626 Since there is no standard way to enroll a computer against a Kerberos
2727 server, it is not possible to do this with <span class="command"><strong>realmd</strong></span>.</p>
2828 <div class="section">
2929 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
30 <a name="idp5982432"></a>Discovering Kerberos realms</h2></div></div></div>
30 <a name="idp9561696"></a>Discovering Kerberos realms</h2></div></div></div>
3131 <p><span class="command"><strong>realmd</strong></span> discovers which domains or
3232 realms it can use or configure. It can discover and identify
3333 Kerberos domains by looking up the appropriate DNS SRV
3333 <dt><span class="section"><a href="guide-active-directory.html#guide-active-directory-discover">Discovering Active Directory domains</a></span></dt>
3434 <dt><span class="section"><a href="guide-active-directory-client.html">Active Directory client software</a></span></dt>
3535 <dd><dl>
36 <dt><span class="section"><a href="guide-active-directory-client.html#idp8178992">Using SSSD with Active Directory</a></span></dt>
37 <dt><span class="section"><a href="guide-active-directory-client.html#idp6168432">Using Winbind with Active Directory</a></span></dt>
36 <dt><span class="section"><a href="guide-active-directory-client.html#idp11380720">Using SSSD with Active Directory</a></span></dt>
37 <dt><span class="section"><a href="guide-active-directory-client.html#idp11306688">Using Winbind with Active Directory</a></span></dt>
3838 </dl></dd>
3939 <dt><span class="section"><a href="guide-active-directory-join.html">Joining an Active Directory domain</a></span></dt>
4040 <dt><span class="section"><a href="guide-active-directory-permit.html">Logins using Domain Accounts</a></span></dt>
4141 </dl></dd>
4242 <dt><span class="chapter"><a href="guide-freeipa.html">Using with FreeIPA</a></span></dt>
43 <dd><dl><dt><span class="section"><a href="guide-freeipa.html#idp8001472">Discovering FreeIPA domains</a></span></dt></dl></dd>
43 <dd><dl><dt><span class="section"><a href="guide-freeipa.html#idp9872464">Discovering FreeIPA domains</a></span></dt></dl></dd>
4444 <dt><span class="chapter"><a href="guide-freeipa.html">Using with other Kerberos realms</a></span></dt>
45 <dd><dl><dt><span class="section"><a href="guide-freeipa.html#idp5982432">Discovering Kerberos realms</a></span></dt></dl></dd>
45 <dd><dl><dt><span class="section"><a href="guide-freeipa.html#idp9561696">Discovering Kerberos realms</a></span></dt></dl></dd>
4646 <dt><span class="chapter"><a href="guide-configuring.html">Configuring realmd</a></span></dt>
4747 <dd><dl>
4848 <dt><span class="section"><a href="guide-configuring.html#guide-configuring-active-directory">active-directory</a></span></dt>
49 <dd><dl><dt><span class="section"><a href="guide-configuring.html#idp8618752">default-client</a></span></dt></dl></dd>
49 <dd><dl><dt><span class="section"><a href="guide-configuring.html#idp8807328">default-client</a></span></dt></dl></dd>
5050 <dt><span class="section"><a href="guide-configuring-users.html">user</a></span></dt>
5151 <dd><dl>
52 <dt><span class="section"><a href="guide-configuring-users.html#idp8765568">default-home</a></span></dt>
53 <dt><span class="section"><a href="guide-configuring-users.html#idp6097024">default-shell</a></span></dt>
52 <dt><span class="section"><a href="guide-configuring-users.html#idp8774336">default-home</a></span></dt>
53 <dt><span class="section"><a href="guide-configuring-users.html#idp9756048">default-shell</a></span></dt>
5454 </dl></dd>
5555 <dt><span class="section"><a href="guide-configuring-realm.html">Realm specific settings</a></span></dt>
56 <dd><dl><dt><span class="section"><a href="guide-configuring-realm.html#idp7293920">computer-ou</a></span></dt></dl></dd>
56 <dd><dl><dt><span class="section"><a href="guide-configuring-realm.html#idp7927392">computer-ou</a></span></dt></dl></dd>
5757 </dl></dd>
5858 <dt><span class="chapter"><a href="guide-integration.html">Integration</a></span></dt>
5959 </dl>
1313 <div class="titlepage">
1414 <div>
1515 <div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">realmd</p></th></tr></table></div>
16 <div><p class="releaseinfo">for 0.9
16 <div><p class="releaseinfo">for 0.10
1717 </p></div>
1818 </div>
1919 <hr>
3030 <dt><span class="section"><a href="guide-active-directory.html#guide-active-directory-discover">Discovering Active Directory domains</a></span></dt>
3131 <dt><span class="section"><a href="guide-active-directory-client.html">Active Directory client software</a></span></dt>
3232 <dd><dl>
33 <dt><span class="section"><a href="guide-active-directory-client.html#idp8178992">Using SSSD with Active Directory</a></span></dt>
34 <dt><span class="section"><a href="guide-active-directory-client.html#idp6168432">Using Winbind with Active Directory</a></span></dt>
33 <dt><span class="section"><a href="guide-active-directory-client.html#idp11380720">Using SSSD with Active Directory</a></span></dt>
34 <dt><span class="section"><a href="guide-active-directory-client.html#idp11306688">Using Winbind with Active Directory</a></span></dt>
3535 </dl></dd>
3636 <dt><span class="section"><a href="guide-active-directory-join.html">Joining an Active Directory domain</a></span></dt>
3737 <dt><span class="section"><a href="guide-active-directory-permit.html">Logins using Domain Accounts</a></span></dt>
3838 </dl></dd>
3939 <dt><span class="chapter"><a href="guide-freeipa.html">Using with FreeIPA</a></span></dt>
40 <dd><dl><dt><span class="section"><a href="guide-freeipa.html#idp8001472">Discovering FreeIPA domains</a></span></dt></dl></dd>
40 <dd><dl><dt><span class="section"><a href="guide-freeipa.html#idp9872464">Discovering FreeIPA domains</a></span></dt></dl></dd>
4141 <dt><span class="chapter"><a href="guide-freeipa.html">Using with other Kerberos realms</a></span></dt>
42 <dd><dl><dt><span class="section"><a href="guide-freeipa.html#idp5982432">Discovering Kerberos realms</a></span></dt></dl></dd>
42 <dd><dl><dt><span class="section"><a href="guide-freeipa.html#idp9561696">Discovering Kerberos realms</a></span></dt></dl></dd>
4343 <dt><span class="chapter"><a href="guide-configuring.html">Configuring realmd</a></span></dt>
4444 <dd><dl>
4545 <dt><span class="section"><a href="guide-configuring.html#guide-configuring-active-directory">active-directory</a></span></dt>
46 <dd><dl><dt><span class="section"><a href="guide-configuring.html#idp8618752">default-client</a></span></dt></dl></dd>
46 <dd><dl><dt><span class="section"><a href="guide-configuring.html#idp8807328">default-client</a></span></dt></dl></dd>
4747 <dt><span class="section"><a href="guide-configuring-users.html">user</a></span></dt>
4848 <dd><dl>
49 <dt><span class="section"><a href="guide-configuring-users.html#idp8765568">default-home</a></span></dt>
50 <dt><span class="section"><a href="guide-configuring-users.html#idp6097024">default-shell</a></span></dt>
49 <dt><span class="section"><a href="guide-configuring-users.html#idp8774336">default-home</a></span></dt>
50 <dt><span class="section"><a href="guide-configuring-users.html#idp9756048">default-shell</a></span></dt>
5151 </dl></dd>
5252 <dt><span class="section"><a href="guide-configuring-realm.html">Realm specific settings</a></span></dt>
53 <dd><dl><dt><span class="section"><a href="guide-configuring-realm.html#idp7293920">computer-ou</a></span></dt></dl></dd>
53 <dd><dl><dt><span class="section"><a href="guide-configuring-realm.html#idp7927392">computer-ou</a></span></dt></dl></dd>
5454 </dl></dd>
5555 <dt><span class="chapter"><a href="guide-integration.html">Integration</a></span></dt>
5656 </dl></dd>
1616 <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.Configured" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.Configured">
1717 <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.SupportedInterfaces" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.SupportedInterfaces">
1818 <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.Details" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.Details">
19 <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.RequiredPackages" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.RequiredPackages">
1920 <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.LoginFormats" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.LoginFormats">
2021 <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.LoginPolicy" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.LoginPolicy">
2122 <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.PermittedLogins" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.PermittedLogins">
3737 <div class="cmdsynopsis"><p><code class="command">realm deny [-a] [-R realm] {user} ...</code> </p></div>
3838 </div>
3939 <div class="refsect1">
40 <a name="idp7756624"></a><h2>Description</h2>
40 <a name="idp7785392"></a><h2>Description</h2>
4141 <p><span class="command"><strong>realm</strong></span> is a command line tool that
4242 can be used to manage enrollment in kerberos realms, like Active
4343 Directory domains or IPA domains.</p>
44 </div>
45 <div class="refsect1">
46 <a name="idp7758640"></a><h2>Discover</h2>
44 <p>See the various sub commands below. The following global options
45 can be used:</p>
46 <div class="variablelist"><table border="0" class="variablelist">
47 <colgroup>
48 <col align="left" valign="top">
49 <col>
50 </colgroup>
51 <tbody>
52 <tr>
53 <td><p><span class="term"><code class="option">--install=/path</code></span></p></td>
54 <td><p>Run in install mode. This makes realmd
55 chroot into the specified directory and place files in
56 appropriate locations for use during an installer. No
57 packages will be installed or services will be started
58 when running in this mode.</p></td>
59 </tr>
60 <tr>
61 <td><p><span class="term"><code class="option">--verbose, -v</code></span></p></td>
62 <td><p>Display verbose diagnostics while doing
63 running commands.</p></td>
64 </tr>
65 </tbody>
66 </table></div>
67 </div>
68 <div class="refsect1">
69 <a name="idp7791664"></a><h2>Discover</h2>
4770 <p>Discover a realm and its capabilities.</p>
4871 <div class="informalexample">
4972 <pre class="programlisting">
78101 <em class="replaceable"><code>active-directory</code></em> or
79102 <em class="replaceable"><code>freeipa</code></em>.</p></td>
80103 </tr>
81 <tr>
82 <td><p><span class="term"><code class="option">--verbose, -v</code></span></p></td>
83 <td><p>Display verbose diagnostics while doing
84 the discovery.</p></td>
85 </tr>
86 </tbody>
87 </table></div>
88 </div>
89 <div class="refsect1">
90 <a name="idp7770256"></a><h2>Join</h2>
104 </tbody>
105 </table></div>
106 </div>
107 <div class="refsect1">
108 <a name="idp7801712"></a><h2>Join</h2>
91109 <p>Configure the local machine for use with a realm.</p>
92110 <div class="informalexample">
93111 <pre class="programlisting">
159177 with when joining the machine to the realm. You will
160178 be prompted for a password.</p></td>
161179 </tr>
162 <tr>
163 <td><p><span class="term"><code class="option">--verbose, -v</code></span></p></td>
164 <td><p>Display verbose diagnostics while doing
165 the discovery and join.</p></td>
166 </tr>
167 </tbody>
168 </table></div>
169 </div>
170 <div class="refsect1">
171 <a name="idp7792768"></a><h2>Leave</h2>
180 </tbody>
181 </table></div>
182 </div>
183 <div class="refsect1">
184 <a name="idp7822368"></a><h2>Leave</h2>
172185 <p>Deconfigure the local machine for use with a realm.</p>
173186 <div class="informalexample">
174187 <pre class="programlisting">
213226 with when leaving the realm. You will be prompted for a
214227 password. Implies <code class="option">--remove</code>.</p></td>
215228 </tr>
216 <tr>
217 <td><p><span class="term"><code class="option">--verbose, -v</code></span></p></td>
218 <td><p>Display verbose diagnostics while doing
219 the leave operation.</p></td>
220 </tr>
221 </tbody>
222 </table></div>
223 </div>
224 <div class="refsect1">
225 <a name="idp9900960"></a><h2>List</h2>
229 </tbody>
230 </table></div>
231 </div>
232 <div class="refsect1">
233 <a name="idp10251840"></a><h2>List</h2>
226234 <p>List all the discovered and configured realms.</p>
227235 <div class="informalexample">
228236 <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
235243 </table>
236244 </div>
237245
238 <p>The following options can be used:</p>
239 <div class="variablelist"><table border="0" class="variablelist">
240 <colgroup>
241 <col align="left" valign="top">
242 <col>
243 </colgroup>
244 <tbody><tr>
245 <td><p><span class="term"><code class="option">--verbose, -v</code></span></p></td>
246 <td><p>Display verbose diagnostics while
247 listing.</p></td>
248 </tr></tbody>
249 </table></div>
250 </div>
251 <div class="refsect1">
252 <a name="idp9905296"></a><h2>Permit</h2>
246 </div>
247 <div class="refsect1">
248 <a name="idp10254000"></a><h2>Permit</h2>
253249 <p>Permit local login by users of the realm.</p>
254250 <div class="informalexample">
255251 <pre class="programlisting">
280276 <td><p>Specify the name of the realm to permit
281277 users to log into.</p></td>
282278 </tr>
283 <tr>
284 <td><p><span class="term"><code class="option">--verbose, -v</code></span></p></td>
285 <td><p>Display verbose diagnostics while
286 doing the operation.</p></td>
287 </tr>
288 </tbody>
289 </table></div>
290 </div>
291 <div class="refsect1">
292 <a name="idp9914608"></a><h2>Deny</h2>
279 </tbody>
280 </table></div>
281 </div>
282 <div class="refsect1">
283 <a name="idp10261904"></a><h2>Deny</h2>
293284 <p>Deny local login by users of the realm.</p>
294285 <div class="informalexample">
295286 <pre class="programlisting">
319310 <td><p><span class="term"><code class="option">--realm, -R</code></span></p></td>
320311 <td><p>Specify the name of the realm to deny
321312 users login to.</p></td>
322 </tr>
323 <tr>
324 <td><p><span class="term"><code class="option">--verbose, -v</code></span></p></td>
325 <td><p>Display verbose diagnostics while
326 doing the operation.</p></td>
327313 </tr>
328314 </tbody>
329315 </table></div>
88 <sub name="Using with Active Directory" link="guide-active-directory.html">
99 <sub name="Discovering Active Directory domains" link="guide-active-directory.html#guide-active-directory-discover"/>
1010 <sub name="Active Directory client software" link="guide-active-directory-client.html">
11 <sub name="Using SSSD with Active Directory" link="guide-active-directory-client.html#idp8178992"/>
12 <sub name="Using Winbind with Active Directory" link="guide-active-directory-client.html#idp6168432"/>
11 <sub name="Using SSSD with Active Directory" link="guide-active-directory-client.html#idp11380720"/>
12 <sub name="Using Winbind with Active Directory" link="guide-active-directory-client.html#idp11306688"/>
1313 </sub>
1414 <sub name="Joining an Active Directory domain" link="guide-active-directory-join.html"/>
1515 <sub name="Logins using Domain Accounts" link="guide-active-directory-permit.html"/>
1616 </sub>
1717 <sub name="Using with FreeIPA" link="guide-freeipa.html">
18 <sub name="Discovering FreeIPA domains" link="guide-freeipa.html#idp8001472"/>
18 <sub name="Discovering FreeIPA domains" link="guide-freeipa.html#idp9872464"/>
1919 </sub>
2020 <sub name="Using with other Kerberos realms" link="guide-freeipa.html">
21 <sub name="Discovering Kerberos realms" link="guide-freeipa.html#idp5982432"/>
21 <sub name="Discovering Kerberos realms" link="guide-freeipa.html#idp9561696"/>
2222 </sub>
2323 <sub name="Configuring realmd" link="guide-configuring.html">
2424 <sub name="active-directory" link="guide-configuring.html#guide-configuring-active-directory">
25 <sub name="default-client" link="guide-configuring.html#idp8618752"/>
25 <sub name="default-client" link="guide-configuring.html#idp8807328"/>
2626 </sub>
2727 <sub name="user" link="guide-configuring-users.html">
28 <sub name="default-home" link="guide-configuring-users.html#idp8765568"/>
29 <sub name="default-shell" link="guide-configuring-users.html#idp6097024"/>
28 <sub name="default-home" link="guide-configuring-users.html#idp8774336"/>
29 <sub name="default-shell" link="guide-configuring-users.html#idp9756048"/>
3030 </sub>
3131 <sub name="Realm specific settings" link="guide-configuring-realm.html">
32 <sub name="computer-ou" link="guide-configuring-realm.html#idp7293920"/>
32 <sub name="computer-ou" link="guide-configuring-realm.html#idp7927392"/>
3333 </sub>
3434 </sub>
3535 <sub name="Integration" link="guide-integration.html"/>
5656 <keyword type="property" name="The &quot;Configured&quot; property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.Configured"/>
5757 <keyword type="property" name="The &quot;SupportedInterfaces&quot; property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.SupportedInterfaces"/>
5858 <keyword type="property" name="The &quot;Details&quot; property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.Details"/>
59 <keyword type="property" name="The &quot;RequiredPackages&quot; property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.RequiredPackages"/>
5960 <keyword type="property" name="The &quot;LoginFormats&quot; property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.LoginFormats"/>
6061 <keyword type="property" name="The &quot;LoginPolicy&quot; property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.LoginPolicy"/>
6162 <keyword type="property" name="The &quot;PermittedLogins&quot; property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.PermittedLogins"/>
5353 <para><command>realm</command> is a command line tool that
5454 can be used to manage enrollment in kerberos realms, like Active
5555 Directory domains or IPA domains.</para>
56
57 <para>See the various sub commands below. The following global options
58 can be used:</para>
59
60 <variablelist>
61 <varlistentry>
62 <term><option>--install=/path</option></term>
63 <listitem><para>Run in install mode. This makes realmd
64 chroot into the specified directory and place files in
65 appropriate locations for use during an installer. No
66 packages will be installed or services will be started
67 when running in this mode.</para></listitem>
68 </varlistentry>
69 <varlistentry>
70 <term><option>--verbose, -v</option></term>
71 <listitem><para>Display verbose diagnostics while doing
72 running commands.</para></listitem>
73 </varlistentry>
74 </variablelist>
75
5676 </refsect1>
5777
5878 <refsect1>
91111 given server software. Possible values include
92112 <replaceable>active-directory</replaceable> or
93113 <replaceable>freeipa</replaceable>.</para></listitem>
94 </varlistentry>
95 <varlistentry>
96 <term><option>--verbose, -v</option></term>
97 <listitem><para>Display verbose diagnostics while doing
98 the discovery.</para></listitem>
99114 </varlistentry>
100115 </variablelist>
101116
177192 with when joining the machine to the realm. You will
178193 be prompted for a password.</para></listitem>
179194 </varlistentry>
180 <varlistentry>
181 <term><option>--verbose, -v</option></term>
182 <listitem><para>Display verbose diagnostics while doing
183 the discovery and join.</para></listitem>
184 </varlistentry>
185195 </variablelist>
186196
187197 </refsect1>
232242 with when leaving the realm. You will be prompted for a
233243 password. Implies <option>--remove</option>.</para></listitem>
234244 </varlistentry>
235 <varlistentry>
236 <term><option>--verbose, -v</option></term>
237 <listitem><para>Display verbose diagnostics while doing
238 the leave operation.</para></listitem>
239 </varlistentry>
240245 </variablelist>
241246
242247 </refsect1>
251256 $ realm list
252257 </programlisting>
253258 </informalexample>
254
255 <para>The following options can be used:</para>
256
257 <variablelist>
258 <varlistentry>
259 <term><option>--verbose, -v</option></term>
260 <listitem><para>Display verbose diagnostics while
261 listing.</para></listitem>
262 </varlistentry>
263 </variablelist>
264259
265260 </refsect1>
266261
297292 <listitem><para>Specify the name of the realm to permit
298293 users to log into.</para></listitem>
299294 </varlistentry>
300 <varlistentry>
301 <term><option>--verbose, -v</option></term>
302 <listitem><para>Display verbose diagnostics while
303 doing the operation.</para></listitem>
304 </varlistentry>
305295 </variablelist>
306296
307297 </refsect1>
339329 <listitem><para>Specify the name of the realm to deny
340330 users login to.</para></listitem>
341331 </varlistentry>
342 <varlistentry>
343 <term><option>--verbose, -v</option></term>
344 <listitem><para>Display verbose diagnostics while
345 doing the operation.</para></listitem>
346 </varlistentry>
347332 </variablelist>
348333
349334 </refsect1>
6161 <listitem><para><literal>computer-ou</literal>: a string
6262 containing an LDAP DN for an organizational unit where the
6363 computer account should be created</para></listitem>
64 <listitem><para><literal>assume-packages</literal>: a boolean
65 which overrides makes the join assume that all needed
66 software packages have already been installed</para></listitem>
6467 </itemizedlist>
6568 </para><para> This method requires authorization for the PolicyKit action
6669 called <literal>org.freedesktop.realmd.configure-realm</literal>.
2121 <link linkend="gdbus-property-org-freedesktop-realmd-Realm.Configured">Configured</link> readable s
2222 <link linkend="gdbus-property-org-freedesktop-realmd-Realm.SupportedInterfaces">SupportedInterfaces</link> readable as
2323 <link linkend="gdbus-property-org-freedesktop-realmd-Realm.Details">Details</link> readable a(ss)
24 <link linkend="gdbus-property-org-freedesktop-realmd-Realm.RequiredPackages">RequiredPackages</link> readable as
2425 <link linkend="gdbus-property-org-freedesktop-realmd-Realm.LoginFormats">LoginFormats</link> readable as
2526 <link linkend="gdbus-property-org-freedesktop-realmd-Realm.LoginPolicy">LoginPolicy</link> readable s
2627 <link linkend="gdbus-property-org-freedesktop-realmd-Realm.PermittedLogins">PermittedLogins</link> readable as
231232 </itemizedlist>
232233 </para></para>
233234 </refsect2>
235 <refsect2 role="property" id="gdbus-property-org-freedesktop-realmd-Realm.RequiredPackages">
236 <title>The "RequiredPackages" property</title>
237 <indexterm zone="gdbus-property-org-freedesktop-realmd-Realm.RequiredPackages"><primary sortas="Realm:RequiredPackages">org.freedesktop.realmd.Realm:RequiredPackages</primary></indexterm>
238 <programlisting>
239 RequiredPackages readable as
240 </programlisting>
241 <para><para>prerequisite software</para><para> Software packages that are required in order for a join to
242 succeed. These are either simple strings like <literal>sssd</literal>,
243 or strings with an operator and version number like
244 <literal>sssd >= 1.9.0</literal>
245 </para><para> These values are specific to the packaging system that is
246 being run.
247 </para></para>
248 </refsect2>
234249 <refsect2 role="property" id="gdbus-property-org-freedesktop-realmd-Realm.LoginFormats">
235250 <title>The "LoginFormats" property</title>
236251 <indexterm zone="gdbus-property-org-freedesktop-realmd-Realm.LoginFormats"><primary sortas="Realm:LoginFormats">org.freedesktop.realmd.Realm:LoginFormats</primary></indexterm>
3232 &lt;/method&gt;
3333 &lt;property name='SupportedInterfaces' type='as' access='read'&gt;&lt;/property&gt;
3434 &lt;property name='Details' type='a(ss)' access='read'&gt;&lt;/property&gt;
35 &lt;property name='RequiredPackages' type='as' access='read'&gt;&lt;/property&gt;
3536 &lt;property name='LoginFormats' type='as' access='read'&gt;&lt;/property&gt;
3637 &lt;property name='LoginPolicy' type='s' access='read'&gt;&lt;/property&gt;
3738 &lt;property name='PermittedLogins' type='as' access='read'&gt;&lt;/property&gt;
0 0.10
0 0.11
3030 #include <polkit/polkit.h>
3131
3232 #include <stdio.h>
33 #include <errno.h>
3334
3435 #define TIMEOUT 60 /* seconds */
3536 #define HOLD_INTERNAL (GUINT_TO_POINTER (~0))
4546 static gboolean service_bus_name_claimed = FALSE;
4647 static GDBusObjectManagerServer *object_server = NULL;
4748 static gboolean service_debug = FALSE;
49 static gchar *service_install = NULL;
50 static gint service_dbus_fd = -1;
4851
4952 typedef struct {
5053 guint watch;
104107 }
105108
106109 gboolean
110 realm_daemon_is_dbus_peer (void)
111 {
112 return service_dbus_fd != -1;
113 }
114
115 gboolean
116 realm_daemon_is_install_mode (void)
117 {
118 return service_install != NULL;
119 }
120
121 gboolean
107122 realm_daemon_has_debug_flag (void)
108123 {
109124 return service_debug;
117132
118133 gboolean
119134 realm_daemon_check_dbus_action (const gchar *sender,
120 const gchar *action_id)
135 const gchar *action_id)
121136 {
122137 PolkitAuthorizationResult *result;
123138 PolkitAuthority *authority;
124139 PolkitSubject *subject;
125140 GError *error = NULL;
126141 gboolean ret;
142
143 /* If we're a dbus peer, just allow all calls */
144 if (realm_daemon_is_dbus_peer ())
145 return TRUE;
127146
128147 g_return_val_if_fail (sender != NULL, FALSE);
129148 g_return_val_if_fail (action_id != NULL, FALSE);
366385 static void
367386 on_name_acquired (GDBusConnection *connection,
368387 const gchar *name,
369 gpointer user_data)
388 gpointer unused)
370389 {
371390 service_bus_name_claimed = TRUE;
372391 g_debug ("claimed name on bus: %s", name);
376395 static void
377396 on_name_lost (GDBusConnection *connection,
378397 const gchar *name,
379 gpointer user_data)
398 gpointer unused)
380399 {
381400 if (!service_bus_name_claimed)
382401 g_message ("couldn't claim service name on DBus bus: %s", name);
393412 }
394413
395414 static void
415 initialize_service (GDBusConnection *connection)
416 {
417 RealmProvider *all_provider;
418 RealmProvider *provider;
419
420 realm_diagnostics_initialize (connection);
421
422 object_server = g_dbus_object_manager_server_new (REALM_DBUS_SERVICE_PATH);
423
424 all_provider = realm_all_provider_new_and_export (connection);
425
426 provider = realm_sssd_provider_new ();
427 g_dbus_object_manager_server_export (object_server, G_DBUS_OBJECT_SKELETON (provider));
428 realm_all_provider_register (all_provider, provider);
429 g_object_unref (provider);
430
431 provider = realm_samba_provider_new ();
432 g_dbus_object_manager_server_export (object_server, G_DBUS_OBJECT_SKELETON (provider));
433 realm_all_provider_register (all_provider, provider);
434 g_object_unref (provider);
435
436 provider = realm_kerberos_provider_new ();
437 g_dbus_object_manager_server_export (object_server, G_DBUS_OBJECT_SKELETON (provider));
438 realm_all_provider_register (all_provider, provider);
439 g_object_unref (provider);
440
441 g_dbus_object_manager_server_set_connection (object_server, connection);
442
443 /* Use this to control the life time of the providers */
444 g_object_set_data_full (G_OBJECT (object_server), "the-provider",
445 all_provider, g_object_unref);
446
447 /* Matches the hold() in main() */
448 realm_daemon_release ("main");
449 }
450
451 static void
396452 on_bus_get_connection (GObject *source,
397453 GAsyncResult *result,
398454 gpointer unused)
400456 GError *error = NULL;
401457 GDBusConnection *connection;
402458 const gchar *self_name;
403 RealmProvider *all_provider;
404 RealmProvider *provider;
405459 guint owner_id;
406460
407461 connection = g_bus_get_finish (result, &error);
418472 g_dbus_connection_add_filter (connection, on_connection_filter,
419473 (gchar *)self_name, NULL);
420474
421 realm_diagnostics_initialize (connection);
422
423 object_server = g_dbus_object_manager_server_new (REALM_DBUS_SERVICE_PATH);
424
425 all_provider = realm_all_provider_new_and_export (connection);
426
427 provider = realm_sssd_provider_new ();
428 g_dbus_object_manager_server_export (object_server, G_DBUS_OBJECT_SKELETON (provider));
429 realm_all_provider_register (all_provider, provider);
430 g_object_unref (provider);
431
432 provider = realm_samba_provider_new ();
433 g_dbus_object_manager_server_export (object_server, G_DBUS_OBJECT_SKELETON (provider));
434 realm_all_provider_register (all_provider, provider);
435 g_object_unref (provider);
436
437 provider = realm_kerberos_provider_new ();
438 g_dbus_object_manager_server_export (object_server, G_DBUS_OBJECT_SKELETON (provider));
439 realm_all_provider_register (all_provider, provider);
440 g_object_unref (provider);
441
442 g_dbus_object_manager_server_set_connection (object_server, connection);
475 initialize_service (connection);
443476
444477 owner_id = g_bus_own_name_on_connection (connection,
445478 REALM_DBUS_BUS_NAME,
446479 G_BUS_NAME_OWNER_FLAGS_NONE,
447480 on_name_acquired, on_name_lost,
448 all_provider, g_object_unref);
481 NULL, NULL);
482
449483 service_bus_name_owner_id = owner_id;
450484 g_object_unref (connection);
451485 }
452
453 /* Matches the hold() in main() */
454 realm_daemon_release ("main");
486 }
487
488 static void
489 on_peer_connection_new (GObject *source,
490 GAsyncResult *result,
491 gpointer unused)
492 {
493 GDBusConnection *connection;
494 GError *error = NULL;
495
496 connection = g_dbus_connection_new_finish (result, &error);
497 if (error != NULL) {
498 g_warning ("Couldn't connect to peer: %s", error->message);
499 g_main_loop_quit (main_loop);
500 g_error_free (error);
501
502 } else {
503 g_debug ("connected to peer");
504 initialize_service (connection);
505 g_object_unref (connection);
506 }
507 }
508
509 static gboolean
510 connect_to_bus_or_peer (void)
511 {
512 GSocketConnection *stream;
513 GSocket *socket;
514 GError *error = NULL;
515 gchar *guid;
516
517 if (service_dbus_fd == -1) {
518 g_bus_get (G_BUS_TYPE_SYSTEM, NULL, on_bus_get_connection, NULL);
519 return TRUE;
520 }
521
522 socket = g_socket_new_from_fd (service_dbus_fd, &error);
523 if (error != NULL) {
524 g_warning ("Couldn't create socket: %s", error->message);
525 g_error_free (error);
526 return FALSE;
527 }
528
529 stream = g_socket_connection_factory_create_connection (socket);
530 g_return_val_if_fail (stream != NULL, FALSE);
531 g_object_unref (socket);
532
533 guid = g_dbus_generate_guid ();
534 g_dbus_connection_new (G_IO_STREAM (stream), guid,
535 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER |
536 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
537 NULL, NULL, on_peer_connection_new, NULL);
538
539 g_free (guid);
540 g_object_unref (stream);
541 return TRUE;
455542 }
456543
457544 static void
494581 GOptionEntry option_entries[] = {
495582 { "debug", 'd', 0, G_OPTION_ARG_NONE, &service_debug,
496583 "Turn on debug output, prevent timeout exit", NULL },
584 { "install", 0, 0, G_OPTION_ARG_STRING, &service_install,
585 "Turn on installer mode, install to this prefix", NULL },
586 { "dbus-peer", 0, 0, G_OPTION_ARG_INT, &service_dbus_fd,
587 "Use a peer to peer dbus connection on this fd", NULL },
497588 { NULL }
498589 };
499590
517608 context = g_option_context_new ("realmd");
518609 g_option_context_add_main_entries (context, option_entries, NULL);
519610 if (!g_option_context_parse (context, &argc, &argv, &error)) {
520 g_printerr ("%s", error->message);
611 g_message ("%s", error->message);
521612 g_option_context_free (context);
522613 g_error_free (error);
523614 return 2;
524615 }
525616
617 g_option_context_free (context);
618
619 /* Load the platform specific data */
620 realm_settings_init ();
621
622 if (service_install) {
623 if (chdir (service_install) < 0) {
624 g_message ("Couldn't use install prefix: %s: %s",
625 service_install, g_strerror (errno));
626 return 1;
627 }
628 if (chroot (service_install) < 0) {
629 g_message ("Couldn't chroot into install prefix: %s: %s",
630 service_install, g_strerror (errno));
631 return 1;
632 }
633 }
634
526635 if (g_getenv ("REALM_DEBUG"))
527636 service_debug = TRUE;
528 if (g_getenv ("REALM_PERSIST") || service_debug)
637 if (g_getenv ("REALM_PERSIST") || service_debug || service_install)
529638 service_persist = TRUE;
530639
531640 if (service_debug) {
538647 g_free, realm_client_unwatch_and_free);
539648 realm_daemon_hold ("main");
540649
541 /* Load the platform specific data */
542 realm_settings_init ();
543
544650 service = realm_dbus_service_skeleton_new ();
545651 g_signal_connect (service, "handle-release", G_CALLBACK (on_service_release), NULL);
546652 g_signal_connect (service, "handle-set-locale", G_CALLBACK (on_service_set_locale), NULL);
547653 g_signal_connect (service, "handle-cancel", G_CALLBACK (on_service_cancel), NULL);
548654
549655 g_debug ("starting service");
550 g_bus_get (G_BUS_TYPE_SYSTEM, NULL, on_bus_get_connection, &object_server);
656 connect_to_bus_or_peer ();
551657
552658 main_loop = g_main_loop_new (NULL, FALSE);
553659
567673 g_debug ("stopping service");
568674 realm_settings_uninit ();
569675 g_main_loop_unref (main_loop);
570 g_option_context_free (context);
571676
572677 g_object_unref (service);
573678 g_hash_table_unref (service_clients);
679 g_free (service_install);
574680 return 0;
575681 }
3434 const gchar *locale,
3535 const gchar *operation_id);
3636
37 gboolean realm_daemon_is_dbus_peer (void);
38
39 gboolean realm_daemon_is_install_mode (void);
40
3741 gboolean realm_daemon_has_debug_flag (void);
3842
3943 void realm_daemon_poke (void);
5353 g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
5454 g_return_if_fail (options != NULL);
5555
56 if (g_variant_lookup (options, REALM_DBUS_OPTION_OPERATION, "(s)", &operation_id)) {
56 if (g_variant_lookup (options, REALM_DBUS_OPTION_OPERATION, "s", &operation_id)) {
5757 g_object_set_qdata_full (G_OBJECT (invocation), operation_id_quark,
5858 operation_id, g_free);
5959 }
2929 REALM_KERBEROS_OWNER_USER = 1 << 2,
3030 REALM_KERBEROS_OWNER_COMPUTER = 1 << 3,
3131 REALM_KERBEROS_OWNER_NONE = 1 << 4,
32 REALM_KERBEROS_ASSUME_PACKAGES = 1 << 5,
3233 } RealmKerberosFlags;
3334
3435 #define REALM_KERBEROS_OWNER_MASK \
2323 #include "realm-kerberos.h"
2424 #include "realm-kerberos-membership.h"
2525 #include "realm-login-name.h"
26 #include "realm-packages.h"
2627 #include "realm-provider.h"
2728 #include "realm-settings.h"
2829
151152
152153 (iface->enroll_finish) (REALM_KERBEROS_MEMBERSHIP (closure->self), result, &error);
153154
154 if (error == NULL) {
155 realm_command_run_known_async ("name-caches-flush", NULL, closure->invocation,
156 NULL, on_name_caches_flush, closure);
157
158 } else {
155 if (error != NULL) {
159156 enroll_method_reply (closure->invocation, error);
160157 method_closure_free (closure);
161158 g_clear_error (&error);
159
160 /* Only flush the name caches if not in install mode */
161 } else if (!realm_daemon_is_install_mode ()) {
162 realm_command_run_known_async ("name-caches-flush", NULL, closure->invocation,
163 NULL, on_name_caches_flush, closure);
164
165 } else {
166 enroll_method_reply (closure->invocation, NULL);
162167 }
163168 }
164169
466471 RealmKerberosFlags flags = 0;
467472 GVariant *creds;
468473 RealmKerberosCredential cred_type;
474 gboolean assume = FALSE;
469475 gint ret;
470476
471477 /* Make note of the current operation id, for diagnostics */
482488 "This computer's host name is not set correctly.");
483489 return TRUE;
484490 }
491
492 if (g_variant_lookup (options, REALM_DBUS_OPTION_ASSUME_PACKAGES, "b", &assume) && assume)
493 flags |= REALM_KERBEROS_ASSUME_PACKAGES;
485494
486495 switch (cred_type) {
487496 case REALM_KERBEROS_CREDENTIAL_CCACHE:
13261335 configured ? REALM_DBUS_KERBEROS_MEMBERSHIP_INTERFACE : "");
13271336 }
13281337
1338 void
1339 realm_kerberos_set_required_package_sets (RealmKerberos *self,
1340 const gchar **package_sets)
1341 {
1342 gchar **packages;
1343
1344 g_return_if_fail (REALM_IS_KERBEROS (self));
1345 packages = realm_packages_expand_sets (package_sets);
1346 realm_dbus_realm_set_required_packages (self->pv->realm_iface, (const gchar **)packages);
1347 g_strfreev (packages);
1348 }
1349
13291350 gchar *
13301351 realm_kerberos_calculate_join_computer_ou (RealmKerberos *self,
13311352 GVariant *options)
132132 void realm_kerberos_set_configured (RealmKerberos *self,
133133 gboolean configured);
134134
135 void realm_kerberos_set_required_package_sets (RealmKerberos *self,
136 const gchar **package_sets);
137
135138 gchar * realm_kerberos_calculate_join_computer_ou (RealmKerberos *self,
136139 GVariant *options);
137140
192192 lookup_required_files_and_packages (const gchar **package_sets,
193193 gchar ***result_packages,
194194 gchar ***result_files,
195 gboolean *unconditional)
195 gboolean *result_unconditional)
196196 {
197197 GHashTable *settings;
198198 GHashTableIter iter;
199199 GPtrArray *packages;
200200 GPtrArray *files;
201 gboolean unconditional;
201202 gchar *section;
202203 gchar *package;
203204 gchar *file;
204205 gint i;
205206
206 *unconditional = FALSE;
207 unconditional = FALSE;
207208 packages = g_ptr_array_new_with_free_func (g_free);
208209 files = g_ptr_array_new_with_free_func (g_free);
209210
217218 file = g_strstrip (g_strdup (file));
218219 if (g_str_equal (file, "")) {
219220 g_free (file);
220 *unconditional = TRUE;
221 unconditional = TRUE;
221222 } else {
222223 g_ptr_array_add (files, file);
223224 }
229230 }
230231 }
231232
232 g_ptr_array_add (packages, NULL);
233 *result_packages = (gchar **)g_ptr_array_free (packages, FALSE);
234
235 g_ptr_array_add (files, NULL);
236 *result_files = (gchar **)g_ptr_array_free (files, FALSE);
233 if (result_packages) {
234 g_ptr_array_add (packages, NULL);
235 *result_packages = (gchar **)g_ptr_array_free (packages, FALSE);
236 } else {
237 g_ptr_array_free (files, TRUE);
238 }
239
240 if (result_files) {
241 g_ptr_array_add (files, NULL);
242 *result_files = (gchar **)g_ptr_array_free (files, FALSE);
243 } else {
244 g_ptr_array_free (files, TRUE);
245 }
246
247 if (result_unconditional)
248 *result_unconditional = unconditional;
249 }
250
251 gchar **
252 realm_packages_expand_sets (const gchar **package_sets)
253 {
254 gchar **packages = NULL;
255
256 g_return_val_if_fail (package_sets != NULL, NULL);
257
258 lookup_required_files_and_packages (package_sets, &packages, NULL, NULL);
259 return packages;
237260 }
238261
239262 void
269292
270293 } else {
271294 have = realm_packages_check_paths ((const gchar **)required_files, invocation);
272 string = g_strjoinv (", ", required_files);
273 realm_diagnostics_info (invocation, "Required files %s: %s",
274 have ? "present" : "not present, installing", string);
275 g_free (string);
295 if (required_files[0] != NULL) {
296 realm_diagnostics_info (invocation, "Assuming packages installed");
297 } else {
298 string = g_strjoinv (", ", required_files);
299 realm_diagnostics_info (invocation, "Required files %s: %s",
300 have ? "present" : "not present, installing", string);
301 g_free (string);
302 }
276303 }
277304
278305 g_strfreev (required_files);
2020
2121 G_BEGIN_DECLS
2222
23 gchar ** realm_packages_expand_sets (const gchar **package_sets);
24
2325 gboolean realm_packages_check_paths (const gchar **paths,
2426 GDBusMethodInvocation *invocation);
2527
5050 PROP_PROVIDER,
5151 };
5252
53 static const gchar *SAMBA_PACKAGES[] = {
54 REALM_DBUS_IDENTIFIER_WINBIND,
55 REALM_DBUS_IDENTIFIER_SAMBA,
56 NULL
57 };
58
59 const gchar *NO_PACKAGES[] = {
60 NULL
61 };
62
5363 static void realm_samba_kerberos_membership_iface (RealmKerberosMembershipIface *iface);
5464
5565 G_DEFINE_TYPE_WITH_CODE (RealmSamba, realm_samba, REALM_TYPE_KERBEROS,
92102
93103 realm_kerberos_set_suggested_admin (kerberos, "Administrator");
94104 realm_kerberos_set_login_policy (kerberos, REALM_KERBEROS_ALLOW_ANY_LOGIN);
105 realm_kerberos_set_required_package_sets (kerberos, SAMBA_PACKAGES);
95106 }
96107
97108 static gchar *
275286 GAsyncReadyCallback callback,
276287 gpointer user_data)
277288 {
278 const gchar *packages[] = { REALM_DBUS_IDENTIFIER_WINBIND, REALM_DBUS_IDENTIFIER_SAMBA, NULL };
279289 RealmKerberos *realm = REALM_KERBEROS (membership);
280290 RealmSamba *self = REALM_SAMBA (realm);
281291 GSimpleAsyncResult *res;
282292 EnrollClosure *enroll;
293 const gchar **packages;
283294 GError *error = NULL;
284295 gchar *enrolled;
285296
305316 g_simple_async_result_complete_in_idle (res);
306317
307318 } else {
319 if (flags & REALM_KERBEROS_ASSUME_PACKAGES)
320 packages = NO_PACKAGES;
321 else
322 packages = SAMBA_PACKAGES;
308323 realm_packages_install_async (packages, enroll->invocation,
309324 on_install_do_join, g_object_ref (res));
310325 }
1414 #include "config.h"
1515
1616 #include "realm-command.h"
17 #include "realm-daemon.h"
1718 #include "realm-service.h"
1819 #include "realm-settings.h"
1920
2021 #include <glib/gi18n.h>
22
23 static void
24 begin_service_command (const gchar *command,
25 GDBusMethodInvocation *invocation,
26 GAsyncReadyCallback callback,
27 gpointer user_data)
28 {
29 GSimpleAsyncResult *async;
30
31 /* If install mode, never do any service stuff */
32 if (realm_daemon_is_install_mode ()) {
33 g_debug ("skipping %s command in install mode", command);
34 async = g_simple_async_result_new (NULL, callback, user_data,
35 begin_service_command);
36 g_simple_async_result_complete_in_idle (async);
37 g_object_unref (async);
38 return;
39 }
40
41 realm_command_run_known_async (command, NULL, invocation, NULL, callback, user_data);
42 }
43
44 static gboolean
45 finish_service_command (GAsyncResult *result,
46 GError **error)
47 {
48 if (g_simple_async_result_is_valid (result, NULL, begin_service_command)) {
49 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
50 return FALSE;
51 return TRUE;
52 }
53
54 return realm_command_run_finish (result, NULL, error) != -1;
55 }
2156
2257 void
2358 realm_service_enable (const gchar *service_name,
2863 gchar *command;
2964
3065 command = g_strdup_printf ("%s-enable-service", service_name);
31 realm_command_run_known_async (command, NULL, invocation, NULL, callback, user_data);
66 begin_service_command (command, invocation, callback, user_data);
3267 g_free (command);
3368 }
3469
3671 realm_service_enable_finish (GAsyncResult *result,
3772 GError **error)
3873 {
39 return realm_command_run_finish (result, NULL, error) != -1;
74 return finish_service_command (result, error);
4075 }
4176
4277 void
4883 gchar *command;
4984
5085 command = g_strdup_printf ("%s-disable-service", service_name);
51 realm_command_run_known_async (command, NULL, invocation, NULL, callback, user_data);
86 begin_service_command (command, invocation, callback, user_data);
5287 g_free (command);
5388 }
5489
5691 realm_service_disable_finish (GAsyncResult *result,
5792 GError **error)
5893 {
59 return realm_command_run_finish (result, NULL, error) != -1;
94 return finish_service_command (result, error);
6095 }
6196
6297 void
68103 gchar *command;
69104
70105 command = g_strdup_printf ("%s-restart-service", service_name);
71 realm_command_run_known_async (command, NULL, invocation, NULL, callback, user_data);
106 begin_service_command (command, invocation, callback, user_data);
72107 g_free (command);
73108 }
74109
76111 realm_service_restart_finish (GAsyncResult *result,
77112 GError **error)
78113 {
79 return realm_command_run_finish (result, NULL, error) != -1;
114 return finish_service_command (result, error);
80115 }
81116
82117 void
88123 gchar *command;
89124
90125 command = g_strdup_printf ("%s-stop-service", service_name);
91 realm_command_run_known_async (command, NULL, invocation, NULL, callback, user_data);
126 begin_service_command (command, invocation, callback, user_data);
92127 g_free (command);
93128 }
94129
96131 realm_service_stop_finish (GAsyncResult *result,
97132 GError **error)
98133 {
99 return realm_command_run_finish (result, NULL, error) != -1;
134 return finish_service_command (result, error);
100135 }
101136
102137 typedef struct {
4141 RealmSssdClass parent_class;
4242 } RealmSssdAdClass;
4343
44 static const gchar *adcli_packages[] = {
44 static const gchar *ADCLI_PACKAGES[] = {
4545 REALM_DBUS_IDENTIFIER_SSSD,
4646 REALM_DBUS_IDENTIFIER_ADCLI,
4747 NULL
4848 };
4949
50 static const gchar *samba_packages[] = {
50 static const gchar *SAMBA_PACKAGES[] = {
5151 REALM_DBUS_IDENTIFIER_SSSD,
5252 REALM_DBUS_IDENTIFIER_SAMBA,
5353 NULL
54 };
55
56 static const gchar *ALL_PACKAGES[] = {
57 REALM_DBUS_IDENTIFIER_SSSD,
58 REALM_DBUS_IDENTIFIER_ADCLI,
59 REALM_DBUS_IDENTIFIER_SAMBA,
60 NULL
61 };
62
63 static const gchar *NO_PACKAGES[] = {
64 NULL,
5465 };
5566
5667 static void realm_sssd_ad_kerberos_membership_iface (RealmKerberosMembershipIface *iface);
101112
102113 realm_kerberos_set_suggested_admin (kerberos, "Administrator");
103114 realm_kerberos_set_login_policy (kerberos, REALM_KERBEROS_ALLOW_ANY_LOGIN);
115 realm_kerberos_set_required_package_sets (kerberos, ALL_PACKAGES);
104116 }
105117
106118 typedef struct {
431443
432444 if (g_str_equal (software, REALM_DBUS_IDENTIFIER_ADCLI)) {
433445 join->use_adcli = TRUE;
434 join->packages = adcli_packages;
446 join->packages = ADCLI_PACKAGES;
435447 } else {
436448 join->use_adcli = FALSE;
437 join->packages = samba_packages;
449 join->packages = SAMBA_PACKAGES;
438450 }
439451
440452 return TRUE;
480492
481493 /* Prepared successfully without an error */
482494 } else {
495 if (flags & REALM_KERBEROS_ASSUME_PACKAGES)
496 join->packages = NO_PACKAGES;
483497 return async;
484498 }
485499
1010 realm-join.c \
1111 realm-leave.c \
1212 realm-logins.c \
13 eggdbusobjectmanagerclient.c \
14 eggdbusobjectmanagerclient.h \
15 eggdbusobjectproxy.c \
16 eggdbusobjectproxy.h \
1317 $(NULL)
1418
1519 AM_CFLAGS = \
1620 -I$(top_srcdir)/dbus \
1721 -I$(top_builddir)/dbus \
1822 -DLOCALEDIR=\""$(datadir)/locale"\" \
23 -DREALMD_EXECUTABLE=\""$(privatedir)/realmd"\" \
1924 $(GLIB_CFLAGS) \
2025 $(KRB5_CFLAGS) \
2126 $(NULL)
6565 am__objects_1 =
6666 am_realm_OBJECTS = realm.$(OBJEXT) realm-client.$(OBJEXT) \
6767 realm-discover.$(OBJEXT) realm-join.$(OBJEXT) \
68 realm-leave.$(OBJEXT) realm-logins.$(OBJEXT) $(am__objects_1)
68 realm-leave.$(OBJEXT) realm-logins.$(OBJEXT) \
69 eggdbusobjectmanagerclient.$(OBJEXT) \
70 eggdbusobjectproxy.$(OBJEXT) $(am__objects_1)
6971 realm_OBJECTS = $(am_realm_OBJECTS)
7072 realm_LDADD = $(LDADD)
7173 am__DEPENDENCIES_1 =
290292 realm-join.c \
291293 realm-leave.c \
292294 realm-logins.c \
295 eggdbusobjectmanagerclient.c \
296 eggdbusobjectmanagerclient.h \
297 eggdbusobjectproxy.c \
298 eggdbusobjectproxy.h \
293299 $(NULL)
294300
295301 AM_CFLAGS = \
296302 -I$(top_srcdir)/dbus \
297303 -I$(top_builddir)/dbus \
298304 -DLOCALEDIR=\""$(datadir)/locale"\" \
305 -DREALMD_EXECUTABLE=\""$(privatedir)/realmd"\" \
299306 $(GLIB_CFLAGS) \
300307 $(KRB5_CFLAGS) \
301308 $(NULL)
391398 distclean-compile:
392399 -rm -f *.tab.c
393400
401 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eggdbusobjectmanagerclient.Po@am__quote@
402 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eggdbusobjectproxy.Po@am__quote@
394403 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realm-client.Po@am__quote@
395404 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realm-discover.Po@am__quote@
396405 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realm-join.Po@am__quote@
0 /*
1 * This file is copied from glib in order to fix:
2 * https://bugzilla.gnome.org/show_bug.cgi?id=686920
3 */
4
5 /* GDBus - GLib D-Bus Library
6 *
7 * Copyright (C) 2008-2010 Red Hat, Inc.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General
20 * Public License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22 * Boston, MA 02111-1307, USA.
23 *
24 * Author: David Zeuthen <davidz@redhat.com>
25 */
26
27 #include "config.h"
28
29 #include <gio/gio.h>
30
31 #include "eggdbusobjectproxy.h"
32 #include "eggdbusobjectmanagerclient.h"
33
34 #if GLIB_CHECK_VERSION(2,36,0)
35 #warning Switch back to glib implementation
36 #endif
37
38 /**
39 * SECTION:gdbusobjectmanagerclient
40 * @short_description: Client-side object manager
41 * @include: gio/gio.h
42 *
43 * #EggDBusObjectManagerClient is used to create, monitor and delete object
44 * proxies for remote objects exported by a #GDBusObjectManagerServer (or any
45 * code implementing the <ulink
46 * url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">org.freedesktop.DBus.ObjectManager</ulink>
47 * interface).
48 *
49 * Once an instance of this type has been created, you can connect to
50 * the #GDBusObjectManager::object-added and
51 * #GDBusObjectManager::object-removed signals and inspect the
52 * #GDBusObjectProxy objects returned by
53 * g_dbus_object_manager_get_objects().
54 *
55 * If the name for a #EggDBusObjectManagerClient is not owned by anyone at
56 * object construction time, the default behavior is to request the
57 * message bus to launch an owner for the name. This behavior can be
58 * disabled using the %EGG_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START
59 * flag. It's also worth noting that this only works if the name of
60 * interest is activatable in the first place. E.g. in some cases it
61 * is not possible to launch an owner for the requested name. In this
62 * case, #EggDBusObjectManagerClient object construction still succeeds but
63 * there will be no object proxies
64 * (e.g. g_dbus_object_manager_get_objects() returns the empty list) and
65 * the #EggDBusObjectManagerClient:name-owner property is %NULL.
66 *
67 * The owner of the requested name can come and go (for example
68 * consider a system service being restarted) – #EggDBusObjectManagerClient
69 * handles this case too; simply connect to the #GObject::notify
70 * signal to watch for changes on the #EggDBusObjectManagerClient:name-owner
71 * property. When the name owner vanishes, the behavior is that
72 * #EggDBusObjectManagerClient:name-owner is set to %NULL (this includes
73 * emission of the #GObject::notify signal) and then
74 * #GDBusObjectManager::object-removed signals are synthesized
75 * for all currently existing object proxies. Since
76 * #EggDBusObjectManagerClient:name-owner is %NULL when this happens, you can
77 * use this information to disambiguate a synthesized signal from a
78 * genuine signal caused by object removal on the remote
79 * #GDBusObjectManager. Similarly, when a new name owner appears,
80 * #GDBusObjectManager::object-added signals are synthesized
81 * while #EggDBusObjectManagerClient:name-owner is still %NULL. Only when all
82 * object proxies have been added, the #EggDBusObjectManagerClient:name-owner
83 * is set to the new name owner (this includes emission of the
84 * #GObject::notify signal). Furthermore, you are guaranteed that
85 * #EggDBusObjectManagerClient:name-owner will alternate between a name owner
86 * (e.g. <literal>:1.42</literal>) and %NULL even in the case where
87 * the name of interest is atomically replaced
88 *
89 * Ultimately, #EggDBusObjectManagerClient is used to obtain #GDBusProxy
90 * instances. All signals (including the
91 * <literal>org.freedesktop.DBus.Properties::PropertiesChanged</literal>
92 * signal) delivered to #GDBusProxy instances are guaranteed to
93 * originate from the name owner. This guarantee along with the
94 * behavior described above, means that certain race conditions
95 * including the <emphasis><quote>half the proxy is from the old owner
96 * and the other half is from the new owner</quote></emphasis> problem
97 * cannot happen.
98 *
99 * To avoid having the application connect to signals on the returned
100 * #GDBusObjectProxy and #GDBusProxy objects, the
101 * #GDBusObject::interface-added,
102 * #GDBusObject::interface-removed,
103 * #GDBusProxy::g-properties-changed and
104 * #GDBusProxy::g-signal signals
105 * are also emitted on the #EggDBusObjectManagerClient instance managing these
106 * objects. The signals emitted are
107 * #GDBusObjectManager::interface-added,
108 * #GDBusObjectManager::interface-removed,
109 * #EggDBusObjectManagerClient::interface-proxy-properties-changed and
110 * #EggDBusObjectManagerClient::interface-proxy-signal.
111 *
112 * Note that all callbacks and signals are emitted in the
113 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
114 * that the #EggDBusObjectManagerClient object was constructed
115 * in. Additionally, the #GDBusObjectProxy and #GDBusProxy objects
116 * originating from the #EggDBusObjectManagerClient object will be created in
117 * the same context and, consequently, will deliver signals in the
118 * same main loop.
119 */
120
121 struct _EggDBusObjectManagerClientPrivate
122 {
123 GMutex lock;
124
125 GBusType bus_type;
126 GDBusConnection *connection;
127 gchar *object_path;
128 gchar *name;
129 gchar *name_owner;
130 GDBusObjectManagerClientFlags flags;
131
132 GDBusProxy *control_proxy;
133
134 GHashTable *map_object_path_to_object_proxy;
135
136 guint signal_subscription_id;
137 gchar *match_rule;
138
139 EggDBusProxyTypeFunc get_proxy_type_func;
140 gpointer get_proxy_type_user_data;
141 GDestroyNotify get_proxy_type_destroy_notify;
142 };
143
144 enum
145 {
146 PROP_0,
147 PROP_BUS_TYPE,
148 PROP_CONNECTION,
149 PROP_FLAGS,
150 PROP_OBJECT_PATH,
151 PROP_NAME,
152 PROP_NAME_OWNER,
153 PROP_GET_PROXY_TYPE_FUNC,
154 PROP_GET_PROXY_TYPE_USER_DATA,
155 PROP_GET_PROXY_TYPE_DESTROY_NOTIFY
156 };
157
158 enum
159 {
160 INTERFACE_PROXY_SIGNAL_SIGNAL,
161 INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL,
162 LAST_SIGNAL
163 };
164
165 static guint signals[LAST_SIGNAL] = { 0 };
166
167 static void initable_iface_init (GInitableIface *initable_iface);
168 static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface);
169 static void dbus_object_manager_interface_init (GDBusObjectManagerIface *iface);
170
171 G_DEFINE_TYPE_WITH_CODE (EggDBusObjectManagerClient, egg_dbus_object_manager_client, G_TYPE_OBJECT,
172 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
173 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
174 G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT_MANAGER, dbus_object_manager_interface_init));
175
176 static void maybe_unsubscribe_signals (EggDBusObjectManagerClient *manager);
177
178 static void on_control_proxy_g_signal (GDBusProxy *proxy,
179 const gchar *sender_name,
180 const gchar *signal_name,
181 GVariant *parameters,
182 gpointer user_data);
183
184 static void process_get_all_result (EggDBusObjectManagerClient *manager,
185 GVariant *value,
186 const gchar *name_owner);
187
188 static void
189 egg_dbus_object_manager_client_finalize (GObject *object)
190 {
191 EggDBusObjectManagerClient *manager = EGG_DBUS_OBJECT_MANAGER_CLIENT (object);
192
193 maybe_unsubscribe_signals (manager);
194
195 g_hash_table_unref (manager->priv->map_object_path_to_object_proxy);
196
197 if (manager->priv->control_proxy != NULL)
198 {
199 g_signal_handlers_disconnect_by_func (manager->priv->control_proxy,
200 on_control_proxy_g_signal,
201 manager);
202 g_object_unref (manager->priv->control_proxy);
203 }
204 g_object_unref (manager->priv->connection);
205 g_free (manager->priv->object_path);
206 g_free (manager->priv->name);
207 g_free (manager->priv->name_owner);
208
209 if (manager->priv->get_proxy_type_destroy_notify != NULL)
210 manager->priv->get_proxy_type_destroy_notify (manager->priv->get_proxy_type_user_data);
211
212 g_mutex_clear (&manager->priv->lock);
213
214 if (G_OBJECT_CLASS (egg_dbus_object_manager_client_parent_class)->finalize != NULL)
215 G_OBJECT_CLASS (egg_dbus_object_manager_client_parent_class)->finalize (object);
216 }
217
218 static void
219 egg_dbus_object_manager_client_get_property (GObject *object,
220 guint prop_id,
221 GValue *value,
222 GParamSpec *pspec)
223 {
224 EggDBusObjectManagerClient *manager = EGG_DBUS_OBJECT_MANAGER_CLIENT (object);
225
226 switch (prop_id)
227 {
228 case PROP_CONNECTION:
229 g_value_set_object (value, egg_dbus_object_manager_client_get_connection (manager));
230 break;
231
232 case PROP_OBJECT_PATH:
233 g_value_set_string (value, g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (manager)));
234 break;
235
236 case PROP_NAME:
237 g_value_set_string (value, egg_dbus_object_manager_client_get_name (manager));
238 break;
239
240 case PROP_FLAGS:
241 g_value_set_flags (value, egg_dbus_object_manager_client_get_flags (manager));
242 break;
243
244 case PROP_NAME_OWNER:
245 g_value_take_string (value, egg_dbus_object_manager_client_get_name_owner (manager));
246 break;
247
248 default:
249 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
250 break;
251 }
252 }
253
254 static void
255 egg_dbus_object_manager_client_set_property (GObject *object,
256 guint prop_id,
257 const GValue *value,
258 GParamSpec *pspec)
259 {
260 EggDBusObjectManagerClient *manager = EGG_DBUS_OBJECT_MANAGER_CLIENT (object);
261 const gchar *name;
262
263 switch (prop_id)
264 {
265 case PROP_BUS_TYPE:
266 manager->priv->bus_type = g_value_get_enum (value);
267 break;
268
269 case PROP_CONNECTION:
270 if (g_value_get_object (value) != NULL)
271 {
272 g_return_if_fail (manager->priv->connection == NULL);
273 g_return_if_fail (G_IS_DBUS_CONNECTION (g_value_get_object (value)));
274 manager->priv->connection = g_value_dup_object (value);
275 }
276 break;
277
278 case PROP_OBJECT_PATH:
279 g_return_if_fail (manager->priv->object_path == NULL);
280 g_return_if_fail (g_variant_is_object_path (g_value_get_string (value)));
281 manager->priv->object_path = g_value_dup_string (value);
282 break;
283
284 case PROP_NAME:
285 g_return_if_fail (manager->priv->name == NULL);
286 name = g_value_get_string (value);
287 g_return_if_fail (name == NULL || g_dbus_is_name (name));
288 manager->priv->name = g_strdup (name);
289 break;
290
291 case PROP_FLAGS:
292 manager->priv->flags = g_value_get_flags (value);
293 break;
294
295 case PROP_GET_PROXY_TYPE_FUNC:
296 manager->priv->get_proxy_type_func = g_value_get_pointer (value);
297 break;
298
299 case PROP_GET_PROXY_TYPE_USER_DATA:
300 manager->priv->get_proxy_type_user_data = g_value_get_pointer (value);
301 break;
302
303 case PROP_GET_PROXY_TYPE_DESTROY_NOTIFY:
304 manager->priv->get_proxy_type_destroy_notify = g_value_get_pointer (value);
305 break;
306
307 default:
308 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
309 break;
310 }
311 }
312
313 static void
314 egg_dbus_object_manager_client_class_init (EggDBusObjectManagerClientClass *klass)
315 {
316 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
317
318 gobject_class->finalize = egg_dbus_object_manager_client_finalize;
319 gobject_class->set_property = egg_dbus_object_manager_client_set_property;
320 gobject_class->get_property = egg_dbus_object_manager_client_get_property;
321
322 /**
323 * EggDBusObjectManagerClient:connection:
324 *
325 * The #GDBusConnection to use.
326 *
327 * Since: 2.30
328 */
329 g_object_class_install_property (gobject_class,
330 PROP_CONNECTION,
331 g_param_spec_object ("connection",
332 "Connection",
333 "The connection to use",
334 G_TYPE_DBUS_CONNECTION,
335 G_PARAM_READABLE |
336 G_PARAM_WRITABLE |
337 G_PARAM_CONSTRUCT_ONLY |
338 G_PARAM_STATIC_STRINGS));
339
340 /**
341 * EggDBusObjectManagerClient:bus-type:
342 *
343 * If this property is not %G_BUS_TYPE_NONE, then
344 * #EggDBusObjectManagerClient:connection must be %NULL and will be set to the
345 * #GDBusConnection obtained by calling g_bus_get() with the value
346 * of this property.
347 *
348 * Since: 2.30
349 */
350 g_object_class_install_property (gobject_class,
351 PROP_BUS_TYPE,
352 g_param_spec_enum ("bus-type",
353 "Bus Type",
354 "The bus to connect to, if any",
355 G_TYPE_BUS_TYPE,
356 G_BUS_TYPE_NONE,
357 G_PARAM_WRITABLE |
358 G_PARAM_CONSTRUCT_ONLY |
359 G_PARAM_STATIC_NAME |
360 G_PARAM_STATIC_BLURB |
361 G_PARAM_STATIC_NICK));
362
363 /**
364 * EggDBusObjectManagerClient:flags:
365 *
366 * Flags from the #GDBusObjectManagerClientFlags enumeration.
367 *
368 * Since: 2.30
369 */
370 g_object_class_install_property (gobject_class,
371 PROP_FLAGS,
372 g_param_spec_flags ("flags",
373 "Flags",
374 "Flags for the proxy manager",
375 G_TYPE_DBUS_OBJECT_MANAGER_CLIENT_FLAGS,
376 G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
377 G_PARAM_READABLE |
378 G_PARAM_WRITABLE |
379 G_PARAM_CONSTRUCT_ONLY |
380 G_PARAM_STATIC_NAME |
381 G_PARAM_STATIC_BLURB |
382 G_PARAM_STATIC_NICK));
383
384 /**
385 * EggDBusObjectManagerClient:object-path:
386 *
387 * The object path the manager is for.
388 *
389 * Since: 2.30
390 */
391 g_object_class_install_property (gobject_class,
392 PROP_OBJECT_PATH,
393 g_param_spec_string ("object-path",
394 "Object Path",
395 "The object path of the control object",
396 NULL,
397 G_PARAM_READABLE |
398 G_PARAM_WRITABLE |
399 G_PARAM_CONSTRUCT_ONLY |
400 G_PARAM_STATIC_STRINGS));
401
402 /**
403 * EggDBusObjectManagerClient:name:
404 *
405 * The well-known name or unique name that the manager is for.
406 *
407 * Since: 2.30
408 */
409 g_object_class_install_property (gobject_class,
410 PROP_NAME,
411 g_param_spec_string ("name",
412 "Name",
413 "Name that the manager is for",
414 NULL,
415 G_PARAM_READABLE |
416 G_PARAM_WRITABLE |
417 G_PARAM_CONSTRUCT_ONLY |
418 G_PARAM_STATIC_STRINGS));
419
420 /**
421 * EggDBusObjectManagerClient:name-owner:
422 *
423 * The unique name that owns #EggDBusObjectManagerClient:name or %NULL if
424 * no-one is currently owning the name. Connect to the
425 * #GObject::notify signal to track changes to this property.
426 *
427 * Since: 2.30
428 */
429 g_object_class_install_property (gobject_class,
430 PROP_NAME_OWNER,
431 g_param_spec_string ("name-owner",
432 "Name Owner",
433 "The owner of the name we are watching",
434 NULL,
435 G_PARAM_READABLE |
436 G_PARAM_STATIC_STRINGS));
437
438 /**
439 * EggDBusObjectManagerClient:get-proxy-type-func:
440 *
441 * The #GDBusProxyTypeFunc to use when determining what #GType to
442 * use for interface proxies or %NULL.
443 *
444 * Since: 2.30
445 */
446 g_object_class_install_property (gobject_class,
447 PROP_GET_PROXY_TYPE_FUNC,
448 g_param_spec_pointer ("get-proxy-type-func",
449 "GDBusProxyTypeFunc Function Pointer",
450 "The GDBusProxyTypeFunc pointer to use",
451 G_PARAM_READABLE |
452 G_PARAM_WRITABLE |
453 G_PARAM_CONSTRUCT_ONLY |
454 G_PARAM_STATIC_STRINGS));
455
456 /**
457 * EggDBusObjectManagerClient:get-proxy-type-user-data:
458 *
459 * The #gpointer user_data to pass to #EggDBusObjectManagerClient:get-proxy-type-func.
460 *
461 * Since: 2.30
462 */
463 g_object_class_install_property (gobject_class,
464 PROP_GET_PROXY_TYPE_USER_DATA,
465 g_param_spec_pointer ("get-proxy-type-user-data",
466 "GDBusProxyTypeFunc User Data",
467 "The GDBusProxyTypeFunc user_data",
468 G_PARAM_READABLE |
469 G_PARAM_WRITABLE |
470 G_PARAM_CONSTRUCT_ONLY |
471 G_PARAM_STATIC_STRINGS));
472
473 /**
474 * EggDBusObjectManagerClient:get-proxy-type-destroy-notify:
475 *
476 * A #GDestroyNotify for the #gpointer user_data in #EggDBusObjectManagerClient:get-proxy-type-user-data.
477 *
478 * Since: 2.30
479 */
480 g_object_class_install_property (gobject_class,
481 PROP_GET_PROXY_TYPE_DESTROY_NOTIFY,
482 g_param_spec_pointer ("get-proxy-type-destroy-notify",
483 "GDBusProxyTypeFunc user data free function",
484 "The GDBusProxyTypeFunc user data free function",
485 G_PARAM_READABLE |
486 G_PARAM_WRITABLE |
487 G_PARAM_CONSTRUCT_ONLY |
488 G_PARAM_STATIC_STRINGS));
489
490 /**
491 * EggDBusObjectManagerClient::interface-proxy-signal:
492 * @manager: The #EggDBusObjectManagerClient emitting the signal.
493 * @object_proxy: The #GDBusObjectProxy on which an interface is emitting a D-Bus signal.
494 * @interface_proxy: The #GDBusProxy that is emitting a D-Bus signal.
495 * @sender_name: The sender of the signal or NULL if the connection is not a bus connection.
496 * @signal_name: The signal name.
497 * @parameters: A #GVariant tuple with parameters for the signal.
498 *
499 * Emitted when a D-Bus signal is received on @interface_proxy.
500 *
501 * This signal exists purely as a convenience to avoid having to
502 * connect signals to all interface proxies managed by @manager.
503 *
504 * This signal is emitted in the
505 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
506 * that @manager was constructed in.
507 *
508 * Since: 2.30
509 */
510 signals[INTERFACE_PROXY_SIGNAL_SIGNAL] =
511 g_signal_new ("interface-proxy-signal",
512 EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
513 G_SIGNAL_RUN_LAST,
514 G_STRUCT_OFFSET (EggDBusObjectManagerClientClass, interface_proxy_signal),
515 NULL,
516 NULL,
517 NULL,
518 G_TYPE_NONE,
519 5,
520 EGG_TYPE_DBUS_OBJECT_PROXY,
521 G_TYPE_DBUS_PROXY,
522 G_TYPE_STRING,
523 G_TYPE_STRING,
524 G_TYPE_VARIANT);
525
526 /**
527 * EggDBusObjectManagerClient::interface-proxy-properties-changed:
528 * @manager: The #EggDBusObjectManagerClient emitting the signal.
529 * @object_proxy: The #GDBusObjectProxy on which an interface has properties that are changing.
530 * @interface_proxy: The #GDBusProxy that has properties that are changing.
531 * @changed_properties: A #GVariant containing the properties that changed.
532 * @invalidated_properties: A %NULL terminated array of properties that was invalidated.
533 *
534 * Emitted when one or more D-Bus properties on proxy changes. The
535 * local cache has already been updated when this signal fires. Note
536 * that both @changed_properties and @invalidated_properties are
537 * guaranteed to never be %NULL (either may be empty though).
538 *
539 * This signal exists purely as a convenience to avoid having to
540 * connect signals to all interface proxies managed by @manager.
541 *
542 * This signal is emitted in the
543 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
544 * that @manager was constructed in.
545 *
546 * Since: 2.30
547 */
548 signals[INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL] =
549 g_signal_new ("interface-proxy-properties-changed",
550 EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
551 G_SIGNAL_RUN_LAST,
552 G_STRUCT_OFFSET (EggDBusObjectManagerClientClass, interface_proxy_properties_changed),
553 NULL,
554 NULL,
555 NULL,
556 G_TYPE_NONE,
557 4,
558 EGG_TYPE_DBUS_OBJECT_PROXY,
559 G_TYPE_DBUS_PROXY,
560 G_TYPE_VARIANT,
561 G_TYPE_STRV);
562
563 g_type_class_add_private (klass, sizeof (EggDBusObjectManagerClientPrivate));
564 }
565
566 static void
567 egg_dbus_object_manager_client_init (EggDBusObjectManagerClient *manager)
568 {
569 manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
570 EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
571 EggDBusObjectManagerClientPrivate);
572 g_mutex_init (&manager->priv->lock);
573 manager->priv->map_object_path_to_object_proxy = g_hash_table_new_full (g_str_hash,
574 g_str_equal,
575 g_free,
576 (GDestroyNotify) g_object_unref);
577 }
578
579 /* ---------------------------------------------------------------------------------------------------- */
580
581 /**
582 * egg_dbus_object_manager_client_new_sync:
583 * @connection: A #GDBusConnection.
584 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
585 * @name: (allow-none): The owner of the control object (unique or well-known name), or %NULL when not using a message bus connection.
586 * @object_path: The object path of the control object.
587 * @get_proxy_type_func: (allow-none): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
588 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
589 * @get_proxy_type_destroy_notify: (allow-none): Free function for @get_proxy_type_user_data or %NULL.
590 * @cancellable: (allow-none): A #GCancellable or %NULL
591 * @error: Return location for error or %NULL.
592 *
593 * Creates a new #EggDBusObjectManagerClient object.
594 *
595 * This is a synchronous failable constructor - the calling thread is
596 * blocked until a reply is received. See egg_dbus_object_manager_client_new()
597 * for the asynchronous version.
598 *
599 * Returns: (transfer full) (type EggDBusObjectManagerClient): A
600 * #EggDBusObjectManagerClient object or %NULL if @error is set. Free
601 * with g_object_unref().
602 *
603 * Since: 2.30
604 */
605 GDBusObjectManager *
606 egg_dbus_object_manager_client_new_sync (GDBusConnection *connection,
607 GDBusObjectManagerClientFlags flags,
608 const gchar *name,
609 const gchar *object_path,
610 EggDBusProxyTypeFunc get_proxy_type_func,
611 gpointer get_proxy_type_user_data,
612 GDestroyNotify get_proxy_type_destroy_notify,
613 GCancellable *cancellable,
614 GError **error)
615 {
616 GInitable *initable;
617
618 g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
619 g_return_val_if_fail ((name == NULL && g_dbus_connection_get_unique_name (connection) == NULL) ||
620 g_dbus_is_name (name), NULL);
621 g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
622 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
623
624 initable = g_initable_new (EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
625 cancellable,
626 error,
627 "connection", connection,
628 "flags", flags,
629 "name", name,
630 "object-path", object_path,
631 "get-proxy-type-func", get_proxy_type_func,
632 "get-proxy-type-user-data", get_proxy_type_user_data,
633 "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify,
634 NULL);
635 if (initable != NULL)
636 return G_DBUS_OBJECT_MANAGER (initable);
637 else
638 return NULL;
639 }
640
641 /**
642 * egg_dbus_object_manager_client_new:
643 * @connection: A #GDBusConnection.
644 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
645 * @name: The owner of the control object (unique or well-known name).
646 * @object_path: The object path of the control object.
647 * @get_proxy_type_func: (allow-none): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
648 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
649 * @get_proxy_type_destroy_notify: (allow-none): Free function for @get_proxy_type_user_data or %NULL.
650 * @cancellable: (allow-none): A #GCancellable or %NULL
651 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
652 * @user_data: The data to pass to @callback.
653 *
654 * Asynchronously creates a new #EggDBusObjectManagerClient object.
655 *
656 * This is an asynchronous failable constructor. When the result is
657 * ready, @callback will be invoked in the
658 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
659 * of the thread you are calling this method from. You can
660 * then call egg_dbus_object_manager_client_new_finish() to get the result. See
661 * egg_dbus_object_manager_client_new_sync() for the synchronous version.
662 *
663 * Since: 2.30
664 */
665 void
666 egg_dbus_object_manager_client_new (GDBusConnection *connection,
667 GDBusObjectManagerClientFlags flags,
668 const gchar *name,
669 const gchar *object_path,
670 EggDBusProxyTypeFunc get_proxy_type_func,
671 gpointer get_proxy_type_user_data,
672 GDestroyNotify get_proxy_type_destroy_notify,
673 GCancellable *cancellable,
674 GAsyncReadyCallback callback,
675 gpointer user_data)
676 {
677 g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
678 g_return_if_fail ((name == NULL && g_dbus_connection_get_unique_name (connection) == NULL) ||
679 g_dbus_is_name (name));
680 g_return_if_fail (g_variant_is_object_path (object_path));
681
682 g_async_initable_new_async (EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
683 G_PRIORITY_DEFAULT,
684 cancellable,
685 callback,
686 user_data,
687 "connection", connection,
688 "flags", flags,
689 "name", name,
690 "object-path", object_path,
691 "get-proxy-type-func", get_proxy_type_func,
692 "get-proxy-type-user-data", get_proxy_type_user_data,
693 "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify,
694 NULL);
695 }
696
697 /**
698 * egg_dbus_object_manager_client_new_finish:
699 * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to egg_dbus_object_manager_client_new().
700 * @error: Return location for error or %NULL.
701 *
702 * Finishes an operation started with egg_dbus_object_manager_client_new().
703 *
704 * Returns: (transfer full) (type EggDBusObjectManagerClient): A
705 * #EggDBusObjectManagerClient object or %NULL if @error is set. Free
706 * with g_object_unref().
707 *
708 * Since: 2.30
709 */
710 GDBusObjectManager *
711 egg_dbus_object_manager_client_new_finish (GAsyncResult *res,
712 GError **error)
713 {
714 GObject *object;
715 GObject *source_object;
716
717 source_object = g_async_result_get_source_object (res);
718 g_assert (source_object != NULL);
719
720 object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
721 res,
722 error);
723 g_object_unref (source_object);
724
725 if (object != NULL)
726 return G_DBUS_OBJECT_MANAGER (object);
727 else
728 return NULL;
729 }
730
731 /* ---------------------------------------------------------------------------------------------------- */
732
733 /**
734 * egg_dbus_object_manager_client_new_for_bus_sync:
735 * @bus_type: A #GBusType.
736 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
737 * @name: The owner of the control object (unique or well-known name).
738 * @object_path: The object path of the control object.
739 * @get_proxy_type_func: (allow-none): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
740 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
741 * @get_proxy_type_destroy_notify: (allow-none): Free function for @get_proxy_type_user_data or %NULL.
742 * @cancellable: (allow-none): A #GCancellable or %NULL
743 * @error: Return location for error or %NULL.
744 *
745 * Like egg_dbus_object_manager_client_new_sync() but takes a #GBusType instead
746 * of a #GDBusConnection.
747 *
748 * This is a synchronous failable constructor - the calling thread is
749 * blocked until a reply is received. See egg_dbus_object_manager_client_new_for_bus()
750 * for the asynchronous version.
751 *
752 * Returns: (transfer full) (type EggDBusObjectManagerClient): A
753 * #EggDBusObjectManagerClient object or %NULL if @error is set. Free
754 * with g_object_unref().
755 *
756 * Since: 2.30
757 */
758 GDBusObjectManager *
759 egg_dbus_object_manager_client_new_for_bus_sync (GBusType bus_type,
760 GDBusObjectManagerClientFlags flags,
761 const gchar *name,
762 const gchar *object_path,
763 EggDBusProxyTypeFunc get_proxy_type_func,
764 gpointer get_proxy_type_user_data,
765 GDestroyNotify get_proxy_type_destroy_notify,
766 GCancellable *cancellable,
767 GError **error)
768 {
769 GInitable *initable;
770
771 g_return_val_if_fail (bus_type != G_BUS_TYPE_NONE, NULL);
772 g_return_val_if_fail (g_dbus_is_name (name), NULL);
773 g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
774 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
775
776 initable = g_initable_new (EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
777 cancellable,
778 error,
779 "bus-type", bus_type,
780 "flags", flags,
781 "name", name,
782 "object-path", object_path,
783 "get-proxy-type-func", get_proxy_type_func,
784 "get-proxy-type-user-data", get_proxy_type_user_data,
785 "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify,
786 NULL);
787 if (initable != NULL)
788 return G_DBUS_OBJECT_MANAGER (initable);
789 else
790 return NULL;
791 }
792
793 /**
794 * egg_dbus_object_manager_client_new_for_bus:
795 * @bus_type: A #GBusType.
796 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
797 * @name: The owner of the control object (unique or well-known name).
798 * @object_path: The object path of the control object.
799 * @get_proxy_type_func: (allow-none): A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
800 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
801 * @get_proxy_type_destroy_notify: (allow-none): Free function for @get_proxy_type_user_data or %NULL.
802 * @cancellable: (allow-none): A #GCancellable or %NULL
803 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
804 * @user_data: The data to pass to @callback.
805 *
806 * Like egg_dbus_object_manager_client_new() but takes a #GBusType instead of a
807 * #GDBusConnection.
808 *
809 * This is an asynchronous failable constructor. When the result is
810 * ready, @callback will be invoked in the
811 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
812 * of the thread you are calling this method from. You can
813 * then call egg_dbus_object_manager_client_new_for_bus_finish() to get the result. See
814 * egg_dbus_object_manager_client_new_for_bus_sync() for the synchronous version.
815 *
816 * Since: 2.30
817 */
818 void
819 egg_dbus_object_manager_client_new_for_bus (GBusType bus_type,
820 GDBusObjectManagerClientFlags flags,
821 const gchar *name,
822 const gchar *object_path,
823 EggDBusProxyTypeFunc get_proxy_type_func,
824 gpointer get_proxy_type_user_data,
825 GDestroyNotify get_proxy_type_destroy_notify,
826 GCancellable *cancellable,
827 GAsyncReadyCallback callback,
828 gpointer user_data)
829 {
830 g_return_if_fail (bus_type != G_BUS_TYPE_NONE);
831 g_return_if_fail (g_dbus_is_name (name));
832 g_return_if_fail (g_variant_is_object_path (object_path));
833
834 g_async_initable_new_async (EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
835 G_PRIORITY_DEFAULT,
836 cancellable,
837 callback,
838 user_data,
839 "bus-type", bus_type,
840 "flags", flags,
841 "name", name,
842 "object-path", object_path,
843 "get-proxy-type-func", get_proxy_type_func,
844 "get-proxy-type-user-data", get_proxy_type_user_data,
845 "get-proxy-type-destroy-notify", get_proxy_type_destroy_notify,
846 NULL);
847 }
848
849 /**
850 * egg_dbus_object_manager_client_new_for_bus_finish:
851 * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to egg_dbus_object_manager_client_new_for_bus().
852 * @error: Return location for error or %NULL.
853 *
854 * Finishes an operation started with egg_dbus_object_manager_client_new_for_bus().
855 *
856 * Returns: (transfer full) (type EggDBusObjectManagerClient): A
857 * #EggDBusObjectManagerClient object or %NULL if @error is set. Free
858 * with g_object_unref().
859 *
860 * Since: 2.30
861 */
862 GDBusObjectManager *
863 egg_dbus_object_manager_client_new_for_bus_finish (GAsyncResult *res,
864 GError **error)
865 {
866 GObject *object;
867 GObject *source_object;
868
869 source_object = g_async_result_get_source_object (res);
870 g_assert (source_object != NULL);
871
872 object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
873 res,
874 error);
875 g_object_unref (source_object);
876
877 if (object != NULL)
878 return G_DBUS_OBJECT_MANAGER (object);
879 else
880 return NULL;
881 }
882
883 /* ---------------------------------------------------------------------------------------------------- */
884
885 /**
886 * egg_dbus_object_manager_client_get_connection:
887 * @manager: A #EggDBusObjectManagerClient
888 *
889 * Gets the #GDBusConnection used by @manager.
890 *
891 * Returns: (transfer none): A #GDBusConnection object. Do not free,
892 * the object belongs to @manager.
893 *
894 * Since: 2.30
895 */
896 GDBusConnection *
897 egg_dbus_object_manager_client_get_connection (EggDBusObjectManagerClient *manager)
898 {
899 GDBusConnection *ret;
900 g_return_val_if_fail (EGG_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
901 g_mutex_lock (&manager->priv->lock);
902 ret = manager->priv->connection;
903 g_mutex_unlock (&manager->priv->lock);
904 return ret;
905 }
906
907 /**
908 * egg_dbus_object_manager_client_get_name:
909 * @manager: A #EggDBusObjectManagerClient
910 *
911 * Gets the name that @manager is for, or %NULL if not a message bus
912 * connection.
913 *
914 * Returns: A unique or well-known name. Do not free, the string
915 * belongs to @manager.
916 *
917 * Since: 2.30
918 */
919 const gchar *
920 egg_dbus_object_manager_client_get_name (EggDBusObjectManagerClient *manager)
921 {
922 const gchar *ret;
923 g_return_val_if_fail (EGG_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
924 g_mutex_lock (&manager->priv->lock);
925 ret = manager->priv->name;
926 g_mutex_unlock (&manager->priv->lock);
927 return ret;
928 }
929
930 /**
931 * egg_dbus_object_manager_client_get_flags:
932 * @manager: A #EggDBusObjectManagerClient
933 *
934 * Gets the flags that @manager was constructed with.
935 *
936 * Returns: Zero of more flags from the #GDBusObjectManagerClientFlags
937 * enumeration.
938 *
939 * Since: 2.30
940 */
941 GDBusObjectManagerClientFlags
942 egg_dbus_object_manager_client_get_flags (EggDBusObjectManagerClient *manager)
943 {
944 GDBusObjectManagerClientFlags ret;
945 g_return_val_if_fail (EGG_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE);
946 g_mutex_lock (&manager->priv->lock);
947 ret = manager->priv->flags;
948 g_mutex_unlock (&manager->priv->lock);
949 return ret;
950 }
951
952 /**
953 * egg_dbus_object_manager_client_get_name_owner:
954 * @manager: A #EggDBusObjectManagerClient.
955 *
956 * The unique name that owns the name that @manager is for or %NULL if
957 * no-one currently owns that name. You can connect to the
958 * #GObject::notify signal to track changes to the
959 * #EggDBusObjectManagerClient:name-owner property.
960 *
961 * Returns: The name owner or %NULL if no name owner exists. Free with
962 * g_free().
963 *
964 * Since: 2.30
965 */
966 gchar *
967 egg_dbus_object_manager_client_get_name_owner (EggDBusObjectManagerClient *manager)
968 {
969 gchar *ret;
970 g_return_val_if_fail (EGG_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
971 g_mutex_lock (&manager->priv->lock);
972 ret = g_strdup (manager->priv->name_owner);
973 g_mutex_unlock (&manager->priv->lock);
974 return ret;
975 }
976
977 /* ---------------------------------------------------------------------------------------------------- */
978
979 /* signal handler for all objects we manage - we dispatch signals
980 * from here to the objects
981 */
982 static void
983 signal_cb (GDBusConnection *connection,
984 const gchar *sender_name,
985 const gchar *object_path,
986 const gchar *interface_name,
987 const gchar *signal_name,
988 GVariant *parameters,
989 gpointer user_data)
990 {
991 EggDBusObjectManagerClient *manager = EGG_DBUS_OBJECT_MANAGER_CLIENT (user_data);
992 EggDBusObjectProxy *object_proxy;
993 GDBusInterface *interface;
994
995 g_mutex_lock (&manager->priv->lock);
996 object_proxy = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
997 if (object_proxy == NULL)
998 {
999 g_mutex_unlock (&manager->priv->lock);
1000 goto out;
1001 }
1002 g_object_ref (object_proxy);
1003 g_mutex_unlock (&manager->priv->lock);
1004
1005 //g_debug ("yay, signal_cb %s %s: %s\n", signal_name, object_path, g_variant_print (parameters, TRUE));
1006
1007 if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Properties") == 0)
1008 {
1009 if (g_strcmp0 (signal_name, "PropertiesChanged") == 0)
1010 {
1011 const gchar *interface_name;
1012 GVariant *changed_properties;
1013 const gchar **invalidated_properties;
1014
1015 g_variant_get (parameters,
1016 "(&s@a{sv}^a&s)",
1017 &interface_name,
1018 &changed_properties,
1019 &invalidated_properties);
1020
1021 interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object_proxy), interface_name);
1022 if (interface != NULL)
1023 {
1024 GVariantIter property_iter;
1025 const gchar *property_name;
1026 GVariant *property_value;
1027 guint n;
1028
1029 /* update caches... */
1030 g_variant_iter_init (&property_iter, changed_properties);
1031 while (g_variant_iter_next (&property_iter,
1032 "{&sv}",
1033 &property_name,
1034 &property_value))
1035 {
1036 g_dbus_proxy_set_cached_property (G_DBUS_PROXY (interface),
1037 property_name,
1038 property_value);
1039 g_variant_unref (property_value);
1040 }
1041
1042 for (n = 0; invalidated_properties[n] != NULL; n++)
1043 {
1044 g_dbus_proxy_set_cached_property (G_DBUS_PROXY (interface),
1045 invalidated_properties[n],
1046 NULL);
1047 }
1048 /* ... and then synthesize the signal */
1049 g_signal_emit_by_name (interface,
1050 "g-properties-changed",
1051 changed_properties,
1052 invalidated_properties);
1053 g_signal_emit (manager,
1054 signals[INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL],
1055 0,
1056 object_proxy,
1057 interface,
1058 changed_properties,
1059 invalidated_properties);
1060 g_object_unref (interface);
1061 }
1062 g_variant_unref (changed_properties);
1063 g_free (invalidated_properties);
1064 }
1065 }
1066 else
1067 {
1068 /* regular signal - just dispatch it */
1069 interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object_proxy), interface_name);
1070 if (interface != NULL)
1071 {
1072 g_signal_emit_by_name (interface,
1073 "g-signal",
1074 sender_name,
1075 signal_name,
1076 parameters);
1077 g_signal_emit (manager,
1078 signals[INTERFACE_PROXY_SIGNAL_SIGNAL],
1079 0,
1080 object_proxy,
1081 interface,
1082 sender_name,
1083 signal_name,
1084 parameters);
1085 g_object_unref (interface);
1086 }
1087 }
1088
1089 out:
1090 g_clear_object (&object_proxy);
1091 }
1092
1093 static void
1094 subscribe_signals (EggDBusObjectManagerClient *manager,
1095 const gchar *name_owner)
1096 {
1097 GError *error = NULL;
1098 GVariant *ret;
1099
1100 g_return_if_fail (EGG_IS_DBUS_OBJECT_MANAGER_CLIENT (manager));
1101 g_return_if_fail (manager->priv->signal_subscription_id == 0);
1102 g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner));
1103
1104 if (name_owner)
1105 {
1106 /* the bus daemon may not implement path_prefix so gracefully
1107 * handle this by using a fallback
1108 */
1109 manager->priv->match_rule = g_strdup_printf ("type='signal',sender='%s',path_namespace='%s'",
1110 name_owner, manager->priv->object_path);
1111
1112 ret = g_dbus_connection_call_sync (manager->priv->connection,
1113 "org.freedesktop.DBus",
1114 "/org/freedeskop/DBus",
1115 "org.freedesktop.DBus",
1116 "AddMatch",
1117 g_variant_new ("(s)",
1118 manager->priv->match_rule),
1119 NULL, /* reply_type */
1120 G_DBUS_CALL_FLAGS_NONE,
1121 -1, /* default timeout */
1122 NULL, /* TODO: Cancellable */
1123 &error);
1124
1125 /* yay, bus daemon supports path_namespace */
1126 if (ret != NULL)
1127 g_variant_unref (ret);
1128 }
1129
1130 if (error == NULL)
1131 {
1132 /* still need to ask GDBusConnection for the callbacks */
1133 manager->priv->signal_subscription_id =
1134 g_dbus_connection_signal_subscribe (manager->priv->connection,
1135 name_owner,
1136 NULL, /* interface */
1137 NULL, /* member */
1138 NULL, /* path - TODO: really want wilcard support here */
1139 NULL, /* arg0 */
1140 G_DBUS_SIGNAL_FLAGS_NONE |
1141 G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
1142 signal_cb,
1143 manager,
1144 NULL); /* user_data_free_func */
1145
1146 }
1147 else
1148 {
1149 /* TODO: we could report this to the user
1150 g_warning ("Message bus daemon does not support path_namespace: %s (%s %d)",
1151 error->message,
1152 g_quark_to_string (error->domain),
1153 error->code);
1154 */
1155
1156 g_error_free (error);
1157
1158 /* no need to call RemoveMatch when done since it didn't work */
1159 g_free (manager->priv->match_rule);
1160 manager->priv->match_rule = NULL;
1161
1162 /* Fallback is to subscribe to *all* signals from the name owner which
1163 * is rather wasteful. It's probably not a big practical problem because
1164 * users typically want all objects that the name owner supplies.
1165 */
1166 manager->priv->signal_subscription_id =
1167 g_dbus_connection_signal_subscribe (manager->priv->connection,
1168 name_owner,
1169 NULL, /* interface */
1170 NULL, /* member */
1171 NULL, /* path - TODO: really want wilcard support here */
1172 NULL, /* arg0 */
1173 G_DBUS_SIGNAL_FLAGS_NONE,
1174 signal_cb,
1175 manager,
1176 NULL); /* user_data_free_func */
1177 }
1178 }
1179
1180 static void
1181 maybe_unsubscribe_signals (EggDBusObjectManagerClient *manager)
1182 {
1183 g_return_if_fail (EGG_IS_DBUS_OBJECT_MANAGER_CLIENT (manager));
1184
1185 if (manager->priv->signal_subscription_id > 0)
1186 {
1187 g_dbus_connection_signal_unsubscribe (manager->priv->connection,
1188 manager->priv->signal_subscription_id);
1189 manager->priv->signal_subscription_id = 0;
1190 }
1191
1192 if (manager->priv->match_rule != NULL)
1193 {
1194 /* Since the AddMatch call succeeded this is guaranteed to not
1195 * fail - therefore, don't bother checking the return value
1196 */
1197 g_dbus_connection_call (manager->priv->connection,
1198 "org.freedesktop.DBus",
1199 "/org/freedeskop/DBus",
1200 "org.freedesktop.DBus",
1201 "RemoveMatch",
1202 g_variant_new ("(s)",
1203 manager->priv->match_rule),
1204 NULL, /* reply_type */
1205 G_DBUS_CALL_FLAGS_NONE,
1206 -1, /* default timeout */
1207 NULL, /* GCancellable */
1208 NULL, /* GAsyncReadyCallback */
1209 NULL); /* user data */
1210 g_free (manager->priv->match_rule);
1211 manager->priv->match_rule = NULL;
1212 }
1213
1214 }
1215
1216 /* ---------------------------------------------------------------------------------------------------- */
1217
1218 static void
1219 on_notify_g_name_owner (GObject *object,
1220 GParamSpec *pspec,
1221 gpointer user_data)
1222 {
1223 EggDBusObjectManagerClient *manager = EGG_DBUS_OBJECT_MANAGER_CLIENT (user_data);
1224 gchar *old_name_owner;
1225 gchar *new_name_owner;
1226
1227 g_mutex_lock (&manager->priv->lock);
1228 old_name_owner = manager->priv->name_owner;
1229 new_name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy);
1230 manager->priv->name_owner = NULL;
1231
1232 if (g_strcmp0 (old_name_owner, new_name_owner) != 0)
1233 {
1234 GList *l;
1235 GList *proxies;
1236
1237 /* remote manager changed; nuke all local proxies */
1238 proxies = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy);
1239 g_list_foreach (proxies, (GFunc) g_object_ref, NULL);
1240 g_hash_table_remove_all (manager->priv->map_object_path_to_object_proxy);
1241
1242 g_mutex_unlock (&manager->priv->lock);
1243
1244 /* do the :name-owner notify with a NULL name - this way the user knows
1245 * the ::object-proxy-removed following is because the name owner went
1246 * away
1247 */
1248 g_object_notify (G_OBJECT (manager), "name-owner");
1249
1250 for (l = proxies; l != NULL; l = l->next)
1251 {
1252 EggDBusObjectProxy *object_proxy = EGG_DBUS_OBJECT_PROXY (l->data);
1253 g_signal_emit_by_name (manager, "object-removed", object_proxy);
1254 }
1255 g_list_free_full (proxies, g_object_unref);
1256
1257 /* nuke local filter */
1258 maybe_unsubscribe_signals (manager);
1259 }
1260 else
1261 {
1262 g_mutex_unlock (&manager->priv->lock);
1263 }
1264
1265 if (new_name_owner != NULL)
1266 {
1267 GError *error;
1268 GVariant *value;
1269
1270 //g_debug ("repopulating for %s", new_name_owner);
1271
1272 /* TODO: do this async! */
1273 subscribe_signals (manager,
1274 new_name_owner);
1275 error = NULL;
1276 value = g_dbus_proxy_call_sync (manager->priv->control_proxy,
1277 "GetManagedObjects",
1278 NULL, /* parameters */
1279 G_DBUS_CALL_FLAGS_NONE,
1280 -1,
1281 NULL,
1282 &error);
1283 if (value == NULL)
1284 {
1285 maybe_unsubscribe_signals (manager);
1286 g_warning ("Error calling GetManagedObjects() when name owner %s for name %s came back: %s",
1287 new_name_owner,
1288 manager->priv->name,
1289 error->message);
1290 g_error_free (error);
1291 }
1292 else
1293 {
1294 process_get_all_result (manager, value, new_name_owner);
1295 g_variant_unref (value);
1296 }
1297
1298 /* do the :name-owner notify *AFTER* emitting ::object-proxy-added signals - this
1299 * way the user knows that the signals were emitted because the name owner came back
1300 */
1301 g_mutex_lock (&manager->priv->lock);
1302 manager->priv->name_owner = new_name_owner;
1303 g_mutex_unlock (&manager->priv->lock);
1304 g_object_notify (G_OBJECT (manager), "name-owner");
1305
1306 }
1307 g_free (old_name_owner);
1308 }
1309
1310 static gboolean
1311 initable_init (GInitable *initable,
1312 GCancellable *cancellable,
1313 GError **error)
1314 {
1315 EggDBusObjectManagerClient *manager = EGG_DBUS_OBJECT_MANAGER_CLIENT (initable);
1316 gboolean ret;
1317 GVariant *value;
1318 GDBusProxyFlags proxy_flags;
1319
1320 ret = FALSE;
1321
1322 if (manager->priv->bus_type != G_BUS_TYPE_NONE)
1323 {
1324 g_assert (manager->priv->connection == NULL);
1325 manager->priv->connection = g_bus_get_sync (manager->priv->bus_type, cancellable, error);
1326 if (manager->priv->connection == NULL)
1327 goto out;
1328 }
1329
1330 proxy_flags = G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
1331 if (manager->priv->flags & G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START)
1332 proxy_flags |= G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
1333
1334 manager->priv->control_proxy = g_dbus_proxy_new_sync (manager->priv->connection,
1335 proxy_flags,
1336 NULL, /* GDBusInterfaceInfo* */
1337 manager->priv->name,
1338 manager->priv->object_path,
1339 "org.freedesktop.DBus.ObjectManager",
1340 cancellable,
1341 error);
1342 if (manager->priv->control_proxy == NULL)
1343 goto out;
1344
1345 g_signal_connect (G_OBJECT (manager->priv->control_proxy),
1346 "notify::g-name-owner",
1347 G_CALLBACK (on_notify_g_name_owner),
1348 manager);
1349
1350 manager->priv->name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy);
1351 if (manager->priv->name_owner == NULL && manager->priv->name != NULL)
1352 {
1353 /* it's perfectly fine if there's no name owner.. we're just going to
1354 * wait until one is ready
1355 */
1356 }
1357 else
1358 {
1359 /* yay, we can get the objects */
1360 g_signal_connect (manager->priv->control_proxy,
1361 "g-signal",
1362 G_CALLBACK (on_control_proxy_g_signal),
1363 manager);
1364 subscribe_signals (manager,
1365 manager->priv->name_owner);
1366 value = g_dbus_proxy_call_sync (manager->priv->control_proxy,
1367 "GetManagedObjects",
1368 NULL, /* parameters */
1369 G_DBUS_CALL_FLAGS_NONE,
1370 -1,
1371 cancellable,
1372 error);
1373 if (value == NULL)
1374 {
1375 maybe_unsubscribe_signals (manager);
1376 g_warn_if_fail (g_signal_handlers_disconnect_by_func (manager->priv->control_proxy,
1377 on_control_proxy_g_signal,
1378 manager) == 1);
1379 g_object_unref (manager->priv->control_proxy);
1380 manager->priv->control_proxy = NULL;
1381 goto out;
1382 }
1383
1384 process_get_all_result (manager, value, manager->priv->name_owner);
1385 g_variant_unref (value);
1386 }
1387
1388 ret = TRUE;
1389
1390 out:
1391 return ret;
1392 }
1393
1394 static void
1395 initable_iface_init (GInitableIface *initable_iface)
1396 {
1397 initable_iface->init = initable_init;
1398 }
1399
1400 static void
1401 async_initable_iface_init (GAsyncInitableIface *async_initable_iface)
1402 {
1403 /* for now, just use default: run GInitable code in thread */
1404 }
1405
1406 /* ---------------------------------------------------------------------------------------------------- */
1407
1408 static void
1409 add_interfaces (EggDBusObjectManagerClient *manager,
1410 const gchar *object_path,
1411 GVariant *ifaces_and_properties,
1412 const gchar *name_owner)
1413 {
1414 EggDBusObjectProxy *op;
1415 gboolean added;
1416 GVariantIter iter;
1417 const gchar *interface_name;
1418 GVariant *properties;
1419 GList *interface_added_signals, *l;
1420 GDBusProxy *interface_proxy;
1421
1422 g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner));
1423
1424 g_mutex_lock (&manager->priv->lock);
1425
1426 interface_added_signals = NULL;
1427 added = FALSE;
1428
1429 op = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
1430 if (op == NULL)
1431 {
1432 GType object_proxy_type;
1433 if (manager->priv->get_proxy_type_func != NULL)
1434 {
1435 object_proxy_type = manager->priv->get_proxy_type_func (manager,
1436 object_path,
1437 NULL,
1438 manager->priv->get_proxy_type_user_data);
1439 g_warn_if_fail (g_type_is_a (object_proxy_type, EGG_TYPE_DBUS_OBJECT_PROXY));
1440 }
1441 else
1442 {
1443 object_proxy_type = EGG_TYPE_DBUS_OBJECT_PROXY;
1444 }
1445 op = g_object_new (object_proxy_type,
1446 "g-connection", manager->priv->connection,
1447 "g-object-path", object_path,
1448 NULL);
1449 added = TRUE;
1450 }
1451 g_object_ref (op);
1452
1453 g_variant_iter_init (&iter, ifaces_and_properties);
1454 while (g_variant_iter_next (&iter,
1455 "{&s@a{sv}}",
1456 &interface_name,
1457 &properties))
1458 {
1459 GError *error;
1460 GType interface_proxy_type;
1461
1462 if (manager->priv->get_proxy_type_func != NULL)
1463 {
1464 interface_proxy_type = manager->priv->get_proxy_type_func (manager,
1465 object_path,
1466 interface_name,
1467 manager->priv->get_proxy_type_user_data);
1468 g_warn_if_fail (g_type_is_a (interface_proxy_type, G_TYPE_DBUS_PROXY));
1469 }
1470 else
1471 {
1472 interface_proxy_type = G_TYPE_DBUS_PROXY;
1473 }
1474
1475 /* this is fine - there is no blocking IO because we pass DO_NOT_LOAD_PROPERTIES and
1476 * DO_NOT_CONNECT_SIGNALS and use a unique name
1477 */
1478 error = NULL;
1479 interface_proxy = g_initable_new (interface_proxy_type,
1480 NULL, /* GCancellable */
1481 &error,
1482 "g-connection", manager->priv->connection,
1483 "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
1484 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
1485 "g-name", name_owner,
1486 "g-object-path", object_path,
1487 "g-interface-name", interface_name,
1488 NULL);
1489 if (interface_proxy == NULL)
1490 {
1491 g_warning ("%s: Error constructing proxy for path %s and interface %s: %s",
1492 G_STRLOC,
1493 object_path,
1494 interface_name,
1495 error->message);
1496 g_error_free (error);
1497 }
1498 else
1499 {
1500 GVariantIter property_iter;
1501 const gchar *property_name;
1502 GVariant *property_value;
1503
1504 /* associate the interface proxy with the object */
1505 g_dbus_interface_set_object (G_DBUS_INTERFACE (interface_proxy),
1506 G_DBUS_OBJECT (op));
1507
1508 g_variant_iter_init (&property_iter, properties);
1509 while (g_variant_iter_next (&property_iter,
1510 "{&sv}",
1511 &property_name,
1512 &property_value))
1513 {
1514 g_dbus_proxy_set_cached_property (interface_proxy,
1515 property_name,
1516 property_value);
1517 g_variant_unref (property_value);
1518 }
1519
1520 egg_dbus_object_proxy_add_interface (op, interface_proxy);
1521 if (!added)
1522 interface_added_signals = g_list_append (interface_added_signals, g_object_ref (interface_proxy));
1523 g_object_unref (interface_proxy);
1524 }
1525 g_variant_unref (properties);
1526 }
1527
1528 g_mutex_unlock (&manager->priv->lock);
1529
1530 /* now that we don't hold the lock any more, emit signals */
1531 for (l = interface_added_signals; l != NULL; l = l->next)
1532 {
1533 interface_proxy = G_DBUS_PROXY (l->data);
1534 g_signal_emit_by_name (manager, "interface-added", op, interface_proxy);
1535 g_object_unref (interface_proxy);
1536 }
1537 g_list_free (interface_added_signals);
1538
1539 if (added)
1540 {
1541 g_hash_table_insert (manager->priv->map_object_path_to_object_proxy,
1542 g_strdup (object_path),
1543 op);
1544 g_signal_emit_by_name (manager, "object-added", op);
1545 }
1546 g_object_unref (op);
1547
1548 }
1549
1550 static void
1551 remove_interfaces (EggDBusObjectManagerClient *manager,
1552 const gchar *object_path,
1553 const gchar *const *interface_names)
1554 {
1555 EggDBusObjectProxy *op;
1556 GList *interfaces;
1557 guint n;
1558 guint num_interfaces;
1559 guint num_interfaces_to_remove;
1560
1561 g_mutex_lock (&manager->priv->lock);
1562
1563 op = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
1564 if (op == NULL)
1565 {
1566 g_warning ("%s: Processing InterfaceRemoved signal for path %s but no object proxy exists",
1567 G_STRLOC,
1568 object_path);
1569 g_mutex_unlock (&manager->priv->lock);
1570 goto out;
1571 }
1572
1573 interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (op));
1574 num_interfaces = g_list_length (interfaces);
1575 g_list_free_full (interfaces, g_object_unref);
1576
1577 num_interfaces_to_remove = g_strv_length ((gchar **) interface_names);
1578
1579 /* see if we are going to completety remove the object */
1580 if (num_interfaces_to_remove == num_interfaces)
1581 {
1582 g_object_ref (op);
1583 g_warn_if_fail (g_hash_table_remove (manager->priv->map_object_path_to_object_proxy, object_path));
1584 g_mutex_unlock (&manager->priv->lock);
1585 g_signal_emit_by_name (manager, "object-removed", op);
1586 g_object_unref (op);
1587 }
1588 else
1589 {
1590 g_object_ref (op);
1591 g_mutex_unlock (&manager->priv->lock);
1592 for (n = 0; interface_names != NULL && interface_names[n] != NULL; n++)
1593 {
1594 GDBusInterface *interface;
1595 interface = g_dbus_object_get_interface (G_DBUS_OBJECT (op), interface_names[n]);
1596 egg_dbus_object_proxy_remove_interface (op, interface_names[n]);
1597 if (interface != NULL)
1598 {
1599 g_signal_emit_by_name (manager, "interface-removed", op, interface);
1600 g_object_unref (interface);
1601 }
1602 }
1603 g_object_unref (op);
1604 }
1605 out:
1606 ;
1607 }
1608
1609 static void
1610 process_get_all_result (EggDBusObjectManagerClient *manager,
1611 GVariant *value,
1612 const gchar *name_owner)
1613 {
1614 GVariant *arg0;
1615 const gchar *object_path;
1616 GVariant *ifaces_and_properties;
1617 GVariantIter iter;
1618
1619 g_return_if_fail (name_owner == NULL || g_dbus_is_unique_name (name_owner));
1620
1621 arg0 = g_variant_get_child_value (value, 0);
1622 g_variant_iter_init (&iter, arg0);
1623 while (g_variant_iter_next (&iter,
1624 "{&o@a{sa{sv}}}",
1625 &object_path,
1626 &ifaces_and_properties))
1627 {
1628 add_interfaces (manager, object_path, ifaces_and_properties, name_owner);
1629 g_variant_unref (ifaces_and_properties);
1630 }
1631 g_variant_unref (arg0);
1632 }
1633
1634 static void
1635 on_control_proxy_g_signal (GDBusProxy *proxy,
1636 const gchar *sender_name,
1637 const gchar *signal_name,
1638 GVariant *parameters,
1639 gpointer user_data)
1640 {
1641 EggDBusObjectManagerClient *manager = EGG_DBUS_OBJECT_MANAGER_CLIENT (user_data);
1642 const gchar *object_path;
1643
1644 //g_debug ("yay, g_signal %s: %s\n", signal_name, g_variant_print (parameters, TRUE));
1645
1646 if (g_strcmp0 (signal_name, "InterfacesAdded") == 0)
1647 {
1648 GVariant *ifaces_and_properties;
1649 g_variant_get (parameters,
1650 "(&o@a{sa{sv}})",
1651 &object_path,
1652 &ifaces_and_properties);
1653 add_interfaces (manager, object_path, ifaces_and_properties, manager->priv->name_owner);
1654 g_variant_unref (ifaces_and_properties);
1655 }
1656 else if (g_strcmp0 (signal_name, "InterfacesRemoved") == 0)
1657 {
1658 const gchar **ifaces;
1659 g_variant_get (parameters,
1660 "(&o^a&s)",
1661 &object_path,
1662 &ifaces);
1663 remove_interfaces (manager, object_path, ifaces);
1664 g_free (ifaces);
1665 }
1666 }
1667
1668 /* ---------------------------------------------------------------------------------------------------- */
1669
1670 static const gchar *
1671 egg_dbus_object_manager_client_get_object_path (GDBusObjectManager *_manager)
1672 {
1673 EggDBusObjectManagerClient *manager = EGG_DBUS_OBJECT_MANAGER_CLIENT (_manager);
1674 return manager->priv->object_path;
1675 }
1676
1677 static GDBusObject *
1678 egg_dbus_object_manager_client_get_object (GDBusObjectManager *_manager,
1679 const gchar *object_path)
1680 {
1681 EggDBusObjectManagerClient *manager = EGG_DBUS_OBJECT_MANAGER_CLIENT (_manager);
1682 GDBusObject *ret;
1683
1684 g_mutex_lock (&manager->priv->lock);
1685 ret = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
1686 if (ret != NULL)
1687 g_object_ref (ret);
1688 g_mutex_unlock (&manager->priv->lock);
1689 return ret;
1690 }
1691
1692 static GDBusInterface *
1693 egg_dbus_object_manager_client_get_interface (GDBusObjectManager *_manager,
1694 const gchar *object_path,
1695 const gchar *interface_name)
1696 {
1697 GDBusInterface *ret;
1698 GDBusObject *object;
1699
1700 ret = NULL;
1701
1702 object = g_dbus_object_manager_get_object (_manager, object_path);
1703 if (object == NULL)
1704 goto out;
1705
1706 ret = g_dbus_object_get_interface (object, interface_name);
1707 g_object_unref (object);
1708
1709 out:
1710 return ret;
1711 }
1712
1713 static GList *
1714 egg_dbus_object_manager_client_get_objects (GDBusObjectManager *_manager)
1715 {
1716 EggDBusObjectManagerClient *manager = EGG_DBUS_OBJECT_MANAGER_CLIENT (_manager);
1717 GList *ret;
1718
1719 g_return_val_if_fail (EGG_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
1720
1721 g_mutex_lock (&manager->priv->lock);
1722 ret = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy);
1723 g_list_foreach (ret, (GFunc) g_object_ref, NULL);
1724 g_mutex_unlock (&manager->priv->lock);
1725
1726 return ret;
1727 }
1728
1729
1730 static void
1731 dbus_object_manager_interface_init (GDBusObjectManagerIface *iface)
1732 {
1733 iface->get_object_path = egg_dbus_object_manager_client_get_object_path;
1734 iface->get_objects = egg_dbus_object_manager_client_get_objects;
1735 iface->get_object = egg_dbus_object_manager_client_get_object;
1736 iface->get_interface = egg_dbus_object_manager_client_get_interface;
1737 }
1738
1739 /* ---------------------------------------------------------------------------------------------------- */
0 /*
1 * This file is copied from glib in order to fix:
2 * https://bugzilla.gnome.org/show_bug.cgi?id=686920
3 */
4
5 /* GDBus - GLib D-Bus Library
6 *
7 * Copyright (C) 2008-2010 Red Hat, Inc.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General
20 * Public License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22 * Boston, MA 02111-1307, USA.
23 *
24 * Author: David Zeuthen <davidz@redhat.com>
25 */
26
27 #ifndef __EGG_DBUS_OBJECT_MANAGER_CLIENT_H__
28 #define __EGG_DBUS_OBJECT_MANAGER_CLIENT_H__
29
30 #include <gio/gio.h>
31
32 G_BEGIN_DECLS
33
34 #define EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT (egg_dbus_object_manager_client_get_type ())
35 #define EGG_DBUS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT, EggDBusObjectManagerClient))
36 #define EGG_DBUS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT, EggDBusObjectManagerClientClass))
37 #define EGG_DBUS_OBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT, EggDBusObjectManagerClientClass))
38 #define EGG_IS_DBUS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT))
39 #define EGG_IS_DBUS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT))
40
41 typedef struct _EggDBusObjectManagerClient EggDBusObjectManagerClient;
42 typedef struct _EggDBusObjectManagerClientClass EggDBusObjectManagerClientClass;
43 typedef struct _EggDBusObjectManagerClientPrivate EggDBusObjectManagerClientPrivate;
44
45 /**
46 * EggDBusObjectManagerClient:
47 *
48 * The #EggDBusObjectManagerClient structure contains private data and should
49 * only be accessed using the provided API.
50 *
51 * Since: 2.30
52 */
53 struct _EggDBusObjectManagerClient
54 {
55 /*< private >*/
56 GObject parent_instance;
57 EggDBusObjectManagerClientPrivate *priv;
58 };
59
60 /**
61 * EggDBusObjectManagerClientClass:
62 * @parent_class: The parent class.
63 * @interface_proxy_signal: Signal class handler for the #EggDBusObjectManagerClient::interface-proxy-signal signal.
64 * @interface_proxy_properties_changed: Signal class handler for the #EggDBusObjectManagerClient::interface-proxy-properties-changed signal.
65 *
66 * Class structure for #EggDBusObjectManagerClient.
67 *
68 * Since: 2.30
69 */
70 struct _EggDBusObjectManagerClientClass
71 {
72 GObjectClass parent_class;
73
74 /* signals */
75 void (*interface_proxy_signal) (EggDBusObjectManagerClient *manager,
76 GDBusObjectProxy *object_proxy,
77 GDBusProxy *interface_proxy,
78 const gchar *sender_name,
79 const gchar *signal_name,
80 GVariant *parameters);
81
82 void (*interface_proxy_properties_changed) (EggDBusObjectManagerClient *manager,
83 GDBusObjectProxy *object_proxy,
84 GDBusProxy *interface_proxy,
85 GVariant *changed_properties,
86 const gchar* const *invalidated_properties);
87
88 /*< private >*/
89 gpointer padding[8];
90 };
91
92 typedef GType (*EggDBusProxyTypeFunc) (EggDBusObjectManagerClient *manager,
93 const gchar *object_path,
94 const gchar *interface_name,
95 gpointer user_data);
96
97 GType egg_dbus_object_manager_client_get_type (void) G_GNUC_CONST;
98 void egg_dbus_object_manager_client_new (GDBusConnection *connection,
99 GDBusObjectManagerClientFlags flags,
100 const gchar *name,
101 const gchar *object_path,
102 EggDBusProxyTypeFunc get_proxy_type_func,
103 gpointer get_proxy_type_user_data,
104 GDestroyNotify get_proxy_type_destroy_notify,
105 GCancellable *cancellable,
106 GAsyncReadyCallback callback,
107 gpointer user_data);
108 GDBusObjectManager *egg_dbus_object_manager_client_new_finish (GAsyncResult *res,
109 GError **error);
110 GDBusObjectManager *egg_dbus_object_manager_client_new_sync (GDBusConnection *connection,
111 GDBusObjectManagerClientFlags flags,
112 const gchar *name,
113 const gchar *object_path,
114 EggDBusProxyTypeFunc get_proxy_type_func,
115 gpointer get_proxy_type_user_data,
116 GDestroyNotify get_proxy_type_destroy_notify,
117 GCancellable *cancellable,
118 GError **error);
119 void egg_dbus_object_manager_client_new_for_bus (GBusType bus_type,
120 GDBusObjectManagerClientFlags flags,
121 const gchar *name,
122 const gchar *object_path,
123 EggDBusProxyTypeFunc get_proxy_type_func,
124 gpointer get_proxy_type_user_data,
125 GDestroyNotify get_proxy_type_destroy_notify,
126 GCancellable *cancellable,
127 GAsyncReadyCallback callback,
128 gpointer user_data);
129 GDBusObjectManager *egg_dbus_object_manager_client_new_for_bus_finish (GAsyncResult *res,
130 GError **error);
131 GDBusObjectManager *egg_dbus_object_manager_client_new_for_bus_sync (GBusType bus_type,
132 GDBusObjectManagerClientFlags flags,
133 const gchar *name,
134 const gchar *object_path,
135 EggDBusProxyTypeFunc get_proxy_type_func,
136 gpointer get_proxy_type_user_data,
137 GDestroyNotify get_proxy_type_destroy_notify,
138 GCancellable *cancellable,
139 GError **error);
140 GDBusConnection *egg_dbus_object_manager_client_get_connection (EggDBusObjectManagerClient *manager);
141 GDBusObjectManagerClientFlags egg_dbus_object_manager_client_get_flags (EggDBusObjectManagerClient *manager);
142 const gchar *egg_dbus_object_manager_client_get_name (EggDBusObjectManagerClient *manager);
143 gchar *egg_dbus_object_manager_client_get_name_owner (EggDBusObjectManagerClient *manager);
144
145 G_END_DECLS
146
147 #endif /* __EGG_DBUS_OBJECT_MANAGER_CLIENT_H */
0 /*
1 * This file is copied from glib in order to fix:
2 * https://bugzilla.gnome.org/show_bug.cgi?id=686920
3 */
4
5 /* GDBus - GLib D-Bus Library
6 *
7 * Copyright (C) 2008-2010 Red Hat, Inc.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General
20 * Public License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22 * Boston, MA 02111-1307, USA.
23 *
24 * Author: David Zeuthen <davidz@redhat.com>
25 */
26
27 #include "config.h"
28
29 #include <gio/gio.h>
30
31 #include "eggdbusobjectproxy.h"
32
33 #if GLIB_CHECK_VERSION(2,36,0)
34 #warning Switch back to glib implementation
35 #endif
36
37 /**
38 * SECTION:gdbusobjectproxy
39 * @short_description: Client-side D-Bus object
40 * @include: gio/gio.h
41 *
42 * A #EggDBusObjectProxy is an object used to represent a remote object
43 * with one or more D-Bus interfaces. Normally, you don't instantiate
44 * a #EggDBusObjectProxy yourself - typically #GDBusObjectManagerClient
45 * is used to obtain it.
46 *
47 * Since: 2.30
48 */
49
50 struct _EggDBusObjectProxyPrivate
51 {
52 GMutex lock;
53 GHashTable *map_name_to_iface;
54 gchar *object_path;
55 GDBusConnection *connection;
56 };
57
58 enum
59 {
60 PROP_0,
61 PROP_G_OBJECT_PATH,
62 PROP_G_CONNECTION
63 };
64
65 static void dbus_object_interface_init (GDBusObjectIface *iface);
66
67 G_DEFINE_TYPE_WITH_CODE (EggDBusObjectProxy, egg_dbus_object_proxy, G_TYPE_OBJECT,
68 G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, dbus_object_interface_init));
69
70 static void
71 egg_dbus_object_proxy_finalize (GObject *object)
72 {
73 EggDBusObjectProxy *proxy = EGG_DBUS_OBJECT_PROXY (object);
74
75 g_hash_table_unref (proxy->priv->map_name_to_iface);
76
77 g_clear_object (&proxy->priv->connection);
78
79 g_free (proxy->priv->object_path);
80
81 g_mutex_clear (&proxy->priv->lock);
82
83 if (G_OBJECT_CLASS (egg_dbus_object_proxy_parent_class)->finalize != NULL)
84 G_OBJECT_CLASS (egg_dbus_object_proxy_parent_class)->finalize (object);
85 }
86
87 static void
88 egg_dbus_object_proxy_get_property (GObject *object,
89 guint prop_id,
90 GValue *value,
91 GParamSpec *pspec)
92 {
93 EggDBusObjectProxy *proxy = EGG_DBUS_OBJECT_PROXY (object);
94
95 switch (prop_id)
96 {
97 case PROP_G_OBJECT_PATH:
98 g_mutex_lock (&proxy->priv->lock);
99 g_value_set_string (value, proxy->priv->object_path);
100 g_mutex_unlock (&proxy->priv->lock);
101 break;
102
103 case PROP_G_CONNECTION:
104 g_value_set_object (value, egg_dbus_object_proxy_get_connection (proxy));
105 break;
106
107 default:
108 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
109 break;
110 }
111 }
112
113 static void
114 egg_dbus_object_proxy_set_property (GObject *object,
115 guint prop_id,
116 const GValue *value,
117 GParamSpec *pspec)
118 {
119 EggDBusObjectProxy *proxy = EGG_DBUS_OBJECT_PROXY (object);
120
121 switch (prop_id)
122 {
123 case PROP_G_OBJECT_PATH:
124 g_mutex_lock (&proxy->priv->lock);
125 proxy->priv->object_path = g_value_dup_string (value);
126 g_mutex_unlock (&proxy->priv->lock);
127 break;
128
129 case PROP_G_CONNECTION:
130 g_mutex_lock (&proxy->priv->lock);
131 proxy->priv->connection = g_value_dup_object (value);
132 g_mutex_unlock (&proxy->priv->lock);
133 break;
134
135 default:
136 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
137 break;
138 }
139 }
140
141 static void
142 egg_dbus_object_proxy_class_init (EggDBusObjectProxyClass *klass)
143 {
144 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
145
146 gobject_class->finalize = egg_dbus_object_proxy_finalize;
147 gobject_class->set_property = egg_dbus_object_proxy_set_property;
148 gobject_class->get_property = egg_dbus_object_proxy_get_property;
149
150 /**
151 * EggDBusObjectProxy:g-object-path:
152 *
153 * The object path of the proxy.
154 *
155 * Since: 2.30
156 */
157 g_object_class_install_property (gobject_class,
158 PROP_G_OBJECT_PATH,
159 g_param_spec_string ("g-object-path",
160 "Object Path",
161 "The object path of the proxy",
162 NULL,
163 G_PARAM_READWRITE |
164 G_PARAM_CONSTRUCT_ONLY |
165 G_PARAM_STATIC_STRINGS));
166
167 /**
168 * EggDBusObjectProxy:g-connection:
169 *
170 * The connection of the proxy.
171 *
172 * Since: 2.30
173 */
174 g_object_class_install_property (gobject_class,
175 PROP_G_CONNECTION,
176 g_param_spec_object ("g-connection",
177 "Connection",
178 "The connection of the proxy",
179 G_TYPE_DBUS_CONNECTION,
180 G_PARAM_READWRITE |
181 G_PARAM_CONSTRUCT_ONLY |
182 G_PARAM_STATIC_STRINGS));
183
184 g_type_class_add_private (klass, sizeof (EggDBusObjectProxyPrivate));
185 }
186
187 static void
188 egg_dbus_object_proxy_init (EggDBusObjectProxy *proxy)
189 {
190 proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy,
191 EGG_TYPE_DBUS_OBJECT_PROXY,
192 EggDBusObjectProxyPrivate);
193 g_mutex_init (&proxy->priv->lock);
194 proxy->priv->map_name_to_iface = g_hash_table_new_full (g_str_hash,
195 g_str_equal,
196 g_free,
197 (GDestroyNotify) g_object_unref);
198 }
199
200 static const gchar *
201 egg_dbus_object_proxy_get_object_path (GDBusObject *object)
202 {
203 EggDBusObjectProxy *proxy = EGG_DBUS_OBJECT_PROXY (object);
204 const gchar *ret;
205 g_mutex_lock (&proxy->priv->lock);
206 ret = proxy->priv->object_path;
207 g_mutex_unlock (&proxy->priv->lock);
208 return ret;
209 }
210
211 /**
212 * egg_dbus_object_proxy_get_connection:
213 * @proxy: a #EggDBusObjectProxy
214 *
215 * Gets the connection that @proxy is for.
216 *
217 * Returns: (transfer none): A #GDBusConnection. Do not free, the
218 * object is owned by @proxy.
219 *
220 * Since: 2.30
221 */
222 GDBusConnection *
223 egg_dbus_object_proxy_get_connection (EggDBusObjectProxy *proxy)
224 {
225 GDBusConnection *ret;
226 g_return_val_if_fail (EGG_IS_DBUS_OBJECT_PROXY (proxy), NULL);
227 g_mutex_lock (&proxy->priv->lock);
228 ret = proxy->priv->connection;
229 g_mutex_unlock (&proxy->priv->lock);
230 return ret;
231 }
232
233 static GDBusInterface *
234 egg_dbus_object_proxy_get_interface (GDBusObject *object,
235 const gchar *interface_name)
236 {
237 EggDBusObjectProxy *proxy = EGG_DBUS_OBJECT_PROXY (object);
238 GDBusProxy *ret;
239
240 g_return_val_if_fail (EGG_IS_DBUS_OBJECT_PROXY (proxy), NULL);
241 g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL);
242
243 g_mutex_lock (&proxy->priv->lock);
244 ret = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name);
245 if (ret != NULL)
246 g_object_ref (ret);
247 g_mutex_unlock (&proxy->priv->lock);
248
249 return (GDBusInterface *) ret; /* TODO: proper cast */
250 }
251
252 static GList *
253 egg_dbus_object_proxy_get_interfaces (GDBusObject *object)
254 {
255 EggDBusObjectProxy *proxy = EGG_DBUS_OBJECT_PROXY (object);
256 GList *ret;
257
258 g_return_val_if_fail (EGG_IS_DBUS_OBJECT_PROXY (proxy), NULL);
259
260 ret = NULL;
261
262 g_mutex_lock (&proxy->priv->lock);
263 ret = g_hash_table_get_values (proxy->priv->map_name_to_iface);
264 g_list_foreach (ret, (GFunc) g_object_ref, NULL);
265 g_mutex_unlock (&proxy->priv->lock);
266
267 return ret;
268 }
269
270 /* ---------------------------------------------------------------------------------------------------- */
271
272 /**
273 * egg_dbus_object_proxy_new:
274 * @connection: a #GDBusConnection
275 * @object_path: the object path
276 *
277 * Creates a new #EggDBusObjectProxy for the given connection and
278 * object path.
279 *
280 * Returns: a new #EggDBusObjectProxy
281 *
282 * Since: 2.30
283 */
284 EggDBusObjectProxy *
285 egg_dbus_object_proxy_new (GDBusConnection *connection,
286 const gchar *object_path)
287 {
288 g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
289 g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
290 return EGG_DBUS_OBJECT_PROXY (g_object_new (EGG_TYPE_DBUS_OBJECT_PROXY,
291 "g-object-path", object_path,
292 "g-connection", connection,
293 NULL));
294 }
295
296 void
297 egg_dbus_object_proxy_add_interface (EggDBusObjectProxy *proxy,
298 GDBusProxy *interface_proxy)
299 {
300 const gchar *interface_name;
301 GDBusProxy *interface_proxy_to_remove;
302
303 g_return_if_fail (EGG_IS_DBUS_OBJECT_PROXY (proxy));
304 g_return_if_fail (G_IS_DBUS_PROXY (interface_proxy));
305
306 g_mutex_lock (&proxy->priv->lock);
307
308 interface_name = g_dbus_proxy_get_interface_name (interface_proxy);
309 interface_proxy_to_remove = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name);
310 if (interface_proxy_to_remove != NULL)
311 {
312 g_object_ref (interface_proxy_to_remove);
313 g_warn_if_fail (g_hash_table_remove (proxy->priv->map_name_to_iface, interface_name));
314 }
315 g_hash_table_insert (proxy->priv->map_name_to_iface,
316 g_strdup (interface_name),
317 g_object_ref (interface_proxy));
318 g_object_ref (interface_proxy);
319
320 g_mutex_unlock (&proxy->priv->lock);
321
322 if (interface_proxy_to_remove != NULL)
323 {
324 g_signal_emit_by_name (proxy, "interface-removed", interface_proxy_to_remove);
325 g_object_unref (interface_proxy_to_remove);
326 }
327
328 g_signal_emit_by_name (proxy, "interface-added", interface_proxy);
329 g_object_unref (interface_proxy);
330 }
331
332 void
333 egg_dbus_object_proxy_remove_interface (EggDBusObjectProxy *proxy,
334 const gchar *interface_name)
335 {
336 GDBusProxy *interface_proxy;
337
338 g_return_if_fail (EGG_IS_DBUS_OBJECT_PROXY (proxy));
339 g_return_if_fail (g_dbus_is_interface_name (interface_name));
340
341 g_mutex_lock (&proxy->priv->lock);
342
343 interface_proxy = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name);
344 if (interface_proxy != NULL)
345 {
346 g_object_ref (interface_proxy);
347 g_warn_if_fail (g_hash_table_remove (proxy->priv->map_name_to_iface, interface_name));
348 g_mutex_unlock (&proxy->priv->lock);
349 g_signal_emit_by_name (proxy, "interface-removed", interface_proxy);
350 g_object_unref (interface_proxy);
351 }
352 else
353 {
354 g_mutex_unlock (&proxy->priv->lock);
355 }
356 }
357
358 static void
359 dbus_object_interface_init (GDBusObjectIface *iface)
360 {
361 iface->get_object_path = egg_dbus_object_proxy_get_object_path;
362 iface->get_interfaces = egg_dbus_object_proxy_get_interfaces;
363 iface->get_interface = egg_dbus_object_proxy_get_interface;
364 }
0 /*
1 * This file is copied from glib in order to fix:
2 * https://bugzilla.gnome.org/show_bug.cgi?id=686920
3 */
4
5 /* GDBus - GLib D-Bus Library
6 *
7 * Copyright (C) 2008-2010 Red Hat, Inc.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General
20 * Public License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22 * Boston, MA 02111-1307, USA.
23 *
24 * Author: David Zeuthen <davidz@redhat.com>
25 */
26
27 #ifndef __EGG_DBUS_OBJECT_PROXY_H__
28 #define __EGG_DBUS_OBJECT_PROXY_H__
29
30 #include <gio/gio.h>
31
32 G_BEGIN_DECLS
33
34 #define EGG_TYPE_DBUS_OBJECT_PROXY (egg_dbus_object_proxy_get_type ())
35 #define EGG_DBUS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EGG_TYPE_DBUS_OBJECT_PROXY, EggDBusObjectProxy))
36 #define EGG_DBUS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EGG_TYPE_DBUS_OBJECT_PROXY, EggDBusObjectProxyClass))
37 #define EGG_DBUS_OBJECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EGG_TYPE_DBUS_OBJECT_PROXY, EggDBusObjectProxyClass))
38 #define EGG_IS_DBUS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EGG_TYPE_DBUS_OBJECT_PROXY))
39 #define EGG_IS_DBUS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EGG_TYPE_DBUS_OBJECT_PROXY))
40
41 typedef struct _EggDBusObjectProxy EggDBusObjectProxy;
42 typedef struct _EggDBusObjectProxyClass EggDBusObjectProxyClass;
43 typedef struct _EggDBusObjectProxyPrivate EggDBusObjectProxyPrivate;
44
45 /**
46 * EggDBusObjectProxy:
47 *
48 * The #EggDBusObjectProxy structure contains private data and should
49 * only be accessed using the provided API.
50 *
51 * Since: 2.30
52 */
53 struct _EggDBusObjectProxy
54 {
55 /*< private >*/
56 GObject parent_instance;
57 EggDBusObjectProxyPrivate *priv;
58 };
59
60 /**
61 * EggDBusObjectProxyClass:
62 * @parent_class: The parent class.
63 *
64 * Class structure for #EggDBusObjectProxy.
65 *
66 * Since: 2.30
67 */
68 struct _EggDBusObjectProxyClass
69 {
70 GObjectClass parent_class;
71
72 /*< private >*/
73 gpointer padding[8];
74 };
75
76 GType egg_dbus_object_proxy_get_type (void) G_GNUC_CONST;
77 EggDBusObjectProxy *egg_dbus_object_proxy_new (GDBusConnection *connection,
78 const gchar *object_path);
79 GDBusConnection *egg_dbus_object_proxy_get_connection (EggDBusObjectProxy *proxy);
80
81 void
82 egg_dbus_object_proxy_add_interface (EggDBusObjectProxy *proxy,
83 GDBusProxy *interface_proxy);
84
85 void
86 egg_dbus_object_proxy_remove_interface (EggDBusObjectProxy *proxy,
87 const gchar *interface_name);
88
89 G_END_DECLS
90
91 #endif /* __EGG_DBUS_OBJECT_PROXY_H */
1717 #include "realm-client.h"
1818 #include "realm-dbus-constants.h"
1919
20 #include "eggdbusobjectproxy.h"
21 #include "eggdbusobjectmanagerclient.h"
22
2023 #include <glib/gi18n.h>
24
25 #include <sys/socket.h>
2126
2227 #include <errno.h>
2328 #include <string.h>
2429
2530 struct _RealmClient {
26 GDBusObjectManagerClient parent;
31 EggDBusObjectManagerClient parent;
2732 RealmDbusProvider *provider;
33 GPid peer_pid;
2834 };
2935
3036 struct _RealmClientClass {
31 GDBusObjectManagerClientClass parent;
37 EggDBusObjectManagerClientClass parent;
3238 };
3339
34 G_DEFINE_TYPE (RealmClient, realm_client, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT);
40 G_DEFINE_TYPE (RealmClient, realm_client, EGG_TYPE_DBUS_OBJECT_MANAGER_CLIENT);
3541
3642 typedef struct {
3743 GAsyncResult *result;
5965 {
6066 RealmClient *self = REALM_CLIENT (obj);
6167
68 if (self->peer_pid) {
69 kill (self->peer_pid, SIGTERM);
70 g_spawn_close_pid (self->peer_pid);
71 }
72
6273 if (self->provider)
6374 g_object_unref (self->provider);
6475
7485 }
7586
7687 static GType
77 realm_object_client_get_proxy_type (GDBusObjectManagerClient *manager,
88 realm_object_client_get_proxy_type (EggDBusObjectManagerClient *manager,
7889 const gchar *object_path,
7990 const gchar *interface_name,
8091 gpointer user_data)
8495 GType ret;
8596
8697 if (interface_name == NULL)
87 return G_TYPE_DBUS_OBJECT_PROXY;
98 return EGG_TYPE_DBUS_OBJECT_PROXY;
8899
89100 if (g_once_init_enter (&once_init_value)) {
90101 lookup_hash = g_hash_table_new (g_str_hash, g_str_equal);
98109
99110 ret = GPOINTER_TO_SIZE (g_hash_table_lookup (lookup_hash, interface_name));
100111 if (ret == 0)
101 ret = G_TYPE_DBUS_OBJECT_PROXY;
112 ret = EGG_TYPE_DBUS_OBJECT_PROXY;
102113 return ret;
103114 }
104115
118129 g_printerr ("%s", data);
119130 }
120131
121 RealmClient *
122 realm_client_new (gboolean verbose)
123 {
124 GDBusConnection *connection;
132 static RealmClient *
133 realm_client_new_on_connection (GDBusConnection *connection,
134 gboolean verbose,
135 const gchar *bus_name)
136 {
125137 RealmDbusProvider *provider;
126138 GError *error = NULL;
127 RealmClient *client = NULL;
128139 GInitable *ret;
129
130 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
131 if (error == NULL) {
132 if (verbose) {
133 g_dbus_connection_signal_subscribe (connection, REALM_DBUS_BUS_NAME,
134 REALM_DBUS_SERVICE_INTERFACE,
135 REALM_DBUS_DIAGNOSTICS_SIGNAL,
136 REALM_DBUS_SERVICE_PATH,
137 NULL, G_DBUS_SIGNAL_FLAGS_NONE,
138 on_diagnostics_signal, NULL, NULL);
139 }
140
141 } else {
142 realm_handle_error (error, _("Couldn't connect to system bus"));
143 return NULL;
140 RealmClient *client;
141 GDBusSignalFlags flags;
142
143 flags = G_DBUS_SIGNAL_FLAGS_NONE;
144 if (bus_name == NULL)
145 flags |= G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE;
146
147 if (verbose) {
148 g_dbus_connection_signal_subscribe (connection, bus_name,
149 REALM_DBUS_SERVICE_INTERFACE,
150 REALM_DBUS_DIAGNOSTICS_SIGNAL,
151 REALM_DBUS_SERVICE_PATH,
152 NULL, flags,
153 on_diagnostics_signal, NULL, NULL);
144154 }
145155
146156 provider = realm_dbus_provider_proxy_new_sync (connection,
147157 G_DBUS_PROXY_FLAGS_NONE,
148 REALM_DBUS_BUS_NAME,
158 bus_name,
149159 REALM_DBUS_SERVICE_PATH,
150160 NULL, &error);
151161 if (error != NULL) {
152162 realm_handle_error (error, _("Couldn't connect to realm service"));
153 g_object_unref (connection);
154163 return NULL;
155164 }
156165
157166 ret = g_initable_new (REALM_TYPE_CLIENT, NULL, &error,
158167 "flags", G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
159 "name", REALM_DBUS_BUS_NAME,
168 "name", bus_name,
160169 "connection", connection,
161170 "object-path", REALM_DBUS_SERVICE_PATH,
162171 "get-proxy-type-func", realm_object_client_get_proxy_type,
169178 }
170179
171180 g_object_unref (provider);
172 g_object_unref (connection);
173181
174182 if (error != NULL) {
175183 realm_handle_error (error, _("Couldn't load the realm service"));
176 return NULL;
177 }
184 g_object_unref (client);
185 return NULL;
186 }
187
178188
179189 return client;
190 }
191
192 static RealmClient *
193 realm_client_new_system (gboolean verbose)
194 {
195 GDBusConnection *connection;
196 GError *error = NULL;
197 RealmClient *client = NULL;
198
199 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
200 if (error != NULL) {
201 realm_handle_error (error, _("Couldn't connect to system bus"));
202 return NULL;
203 }
204
205 client = realm_client_new_on_connection (connection, verbose, REALM_DBUS_BUS_NAME);
206 g_object_unref (connection);
207 return client;
208 }
209
210 static RealmClient *
211 realm_client_new_installer (gboolean verbose,
212 const gchar *prefix)
213 {
214 GDBusConnection *connection;
215 GSocketConnection *stream;
216 RealmClient *client;
217 GSocket *socket;
218 GError *error = NULL;
219 gchar buffer[16];
220 GPid pid = 0;
221 int pair[2];
222
223 const gchar *args[] = {
224 REALMD_EXECUTABLE,
225 "--install", prefix,
226 "--dbus-peer", buffer,
227 NULL
228 };
229
230 if (socketpair (AF_UNIX, SOCK_STREAM, 0, pair) < 0) {
231 realm_handle_error (NULL, _("Couldn't create socket pair: %s"), g_strerror (errno));
232 return NULL;
233 }
234
235 g_snprintf (buffer, sizeof (buffer), "%d", pair[1]);
236
237 socket = g_socket_new_from_fd (pair[0], &error);
238 if (error != NULL) {
239 realm_handle_error (error, _("Couldn't create socket"));
240 close(pair[0]);
241 close(pair[1]);
242 return NULL;
243 }
244
245 g_spawn_async (prefix ? prefix : "/", (gchar **)args, NULL,
246 G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD,
247 NULL, NULL, &pid, &error);
248
249 close(pair[1]);
250
251 if (error != NULL) {
252 realm_handle_error (error, _("Couldn't run realmd"));
253 close(pair[0]);
254 return NULL;
255 }
256
257 stream = g_socket_connection_factory_create_connection (socket);
258 g_return_val_if_fail (stream != NULL, NULL);
259 g_object_unref (socket);
260
261 connection = g_dbus_connection_new_sync (G_IO_STREAM (stream), NULL,
262 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
263 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
264 NULL, NULL, &error);
265 g_object_unref (stream);
266
267 if (error == NULL) {
268 client = realm_client_new_on_connection (connection, verbose, NULL);
269 g_object_unref (connection);
270 } else {
271 realm_handle_error (error, _("Couldn't create socket"));
272 client = NULL;
273 }
274
275 /* Make sure the process is owned */
276 if (client) {
277 client->peer_pid = pid;
278 } else {
279 kill (pid, SIGTERM);
280 g_spawn_close_pid (pid);
281 }
282
283 return client;
284 }
285
286 RealmClient *
287 realm_client_new (gboolean verbose,
288 const gchar *prefix)
289 {
290 if (prefix)
291 return realm_client_new_installer (verbose, prefix);
292 else
293 return realm_client_new_system (verbose);
180294 }
181295
182296 RealmDbusProvider *
3232
3333 GType realm_client_get_type (void) G_GNUC_CONST;
3434
35 RealmClient * realm_client_new (gboolean verbose);
35 RealmClient * realm_client_new (gboolean verbose,
36 const gchar *prefix);
3637
3738 RealmDbusProvider * realm_client_get_provider (RealmClient *self);
3839
5252 gchar *string;
5353 const gchar *policy;
5454 GVariantIter iter;
55 const gchar *const *packages;
56 gint i;
5557
5658 g_return_if_fail (REALM_DBUS_IS_REALM (realm));
5759 g_print ("%s\n", realm_dbus_realm_get_name (realm));
58
59 is_configured = TRUE;
60 configured = realm_dbus_realm_get_configured (realm);
61 if (configured == NULL || g_str_equal (configured, "")) {
62 configured = "no";
63 is_configured = FALSE;
64
65 } else if (g_str_equal (configured, REALM_DBUS_KERBEROS_MEMBERSHIP_INTERFACE)) {
66 configured = "kerberos-member";
67 }
68
69 g_print (" configured: %s\n", configured);
70
71 details = realm_dbus_realm_get_details (realm);
72 if (details) {
73 g_variant_iter_init (&iter, details);
74 while (g_variant_iter_loop (&iter, "(&s&s)", &name, &value))
75 g_print (" %s: %s\n", name, value);
76 }
7760
7861 kerberos = realm_client_to_kerberos (client, realm);
7962 if (kerberos) {
8265 } else {
8366 g_print (" type: unknown\n");
8467 }
68
69 is_configured = TRUE;
70 configured = realm_dbus_realm_get_configured (realm);
71 if (configured == NULL || g_str_equal (configured, "")) {
72 configured = "no";
73 is_configured = FALSE;
74
75 } else if (g_str_equal (configured, REALM_DBUS_KERBEROS_MEMBERSHIP_INTERFACE)) {
76 configured = "kerberos-member";
77 }
78
79 g_print (" configured: %s\n", configured);
80
81 details = realm_dbus_realm_get_details (realm);
82 if (details) {
83 g_variant_iter_init (&iter, details);
84 while (g_variant_iter_loop (&iter, "(&s&s)", &name, &value))
85 g_print (" %s: %s\n", name, value);
86 }
87
88 packages = realm_dbus_realm_get_required_packages (realm);
89 for (i = 0; packages != NULL && packages[i] != NULL; i++)
90 g_print (" required-package: %s\n", packages[i]);
8591
8692 if (is_configured) {
8793 string = g_strjoinv (", ", (gchar **)realm_dbus_realm_get_login_formats (realm));
145151 }
146152
147153 int
148 realm_discover (int argc,
154 realm_discover (RealmClient *client,
155 int argc,
149156 char *argv[])
150157 {
151 RealmClient *client;
152158 GOptionContext *context;
153 gboolean arg_verbose = FALSE;
154159 gchar *arg_client_software = NULL;
155160 gchar *arg_server_software = NULL;
156161 GError *error = NULL;
161166
162167 GOptionEntry option_entries[] = {
163168 { "all", 'a', 0, G_OPTION_ARG_NONE, &arg_all, N_("Show all discovered realms"), NULL },
164 { "verbose", 'v', 0, G_OPTION_ARG_NONE, &arg_verbose, N_("Verbose output"), NULL },
165169 { "client-software", 0, 0, G_OPTION_ARG_STRING, &arg_client_software, N_("Use specific client software"), NULL },
166170 { "server-software", 0, 0, G_OPTION_ARG_STRING, &arg_server_software, N_("Use specific server software"), NULL },
167171 { NULL, }
172176 context = g_option_context_new ("realm-or-domain");
173177 g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
174178 g_option_context_add_main_entries (context, option_entries, NULL);
179 g_option_context_add_main_entries (context, realm_global_options, NULL);
175180
176181 if (!g_option_context_parse (context, &argc, &argv, &error)) {
177182 g_printerr ("%s: %s\n", g_get_prgname (), error->message);
178183 g_error_free (error);
179184 ret = 2;
180 }
181
182 client = realm_client_new (arg_verbose);
183 if (!client) {
184 ret = 1;
185185
186186 /* The default realm? */
187187 } else if (argc == 1) {
188188 ret = perform_discover (client, NULL, arg_all,
189189 arg_server_software, arg_client_software);
190 g_object_unref (client);
191190
192191 /* Specific realms */
193192 } else {
197196 if (ret != 0)
198197 result = ret;
199198 }
200 g_object_unref (client);
201199 }
202200
203201 g_free (arg_server_software);
208206
209207 static int
210208 perform_list (RealmClient *client,
211 gboolean all,
212 gboolean verbose)
209 gboolean all)
213210 {
214211 RealmDbusProvider *provider;
215212 const gchar *const *realms;
231228 g_object_unref (realm);
232229 }
233230
234 if (verbose && !printed) {
231 if (realm_verbose && !printed) {
235232 if (all)
236233 g_printerr ("No known realms\n");
237234 else
242239 }
243240
244241 int
245 realm_list (int argc,
242 realm_list (RealmClient *client,
243 int argc,
246244 char *argv[])
247245 {
248 RealmClient *client;
249246 GOptionContext *context;
250 gboolean arg_verbose = FALSE;
251247 gboolean arg_all = FALSE;
252248 GError *error = NULL;
253249 gint ret = 0;
254250
255251 GOptionEntry option_entries[] = {
256252 { "all", 'a', 0, G_OPTION_ARG_NONE, &arg_all, N_("Show all realms"), NULL },
257 { "verbose", 'v', 0, G_OPTION_ARG_NONE, &arg_verbose, N_("Verbose output"), NULL },
258253 { NULL, }
259254 };
260255
261256 context = g_option_context_new ("realm");
262257 g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
263258 g_option_context_add_main_entries (context, option_entries, NULL);
259 g_option_context_add_main_entries (context, realm_global_options, NULL);
264260
265261 if (!g_option_context_parse (context, &argc, &argv, &error)) {
266262 g_printerr ("%s: %s\n", g_get_prgname (), error->message);
272268 ret = 2;
273269
274270 } else {
275 client = realm_client_new (arg_verbose);
276 if (client) {
277 ret = perform_list (client, arg_all, arg_verbose);
278 g_object_unref (client);
279 } else {
280 ret = 1;
281 }
271 return perform_list (client, arg_all);
282272 }
283273
284274 g_option_context_free (context);
212212 }
213213
214214 int
215 realm_join (int argc,
215 realm_join (RealmClient *client,
216 int argc,
216217 char *argv[])
217218 {
218219 GOptionContext *context;
219 RealmClient *client;
220220 gchar *arg_user = NULL;
221 gboolean arg_verbose = FALSE;
222221 GError *error = NULL;
223222 const gchar *realm_name;
224223 gchar *arg_computer_ou = NULL;
231230 GOptionEntry option_entries[] = {
232231 { "user", 'U', 0, G_OPTION_ARG_STRING, &arg_user,
233232 N_("User name to use for enrollment"), NULL },
234 { "verbose", 'v', 0, G_OPTION_ARG_NONE, &arg_verbose,
235 N_("Verbose output"), NULL },
236233 { "computer-ou", 0, 0, G_OPTION_ARG_STRING, &arg_computer_ou,
237234 N_("Computer OU DN to join"), NULL },
238235 { "client-software", 0, 0, G_OPTION_ARG_STRING, &arg_client_software,
249246 context = g_option_context_new ("realm");
250247 g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
251248 g_option_context_add_main_entries (context, option_entries, NULL);
249 g_option_context_add_main_entries (context, realm_global_options, NULL);
252250
253251 if (!g_option_context_parse (context, &argc, &argv, &error)) {
254252 g_printerr ("%s: %s\n", g_get_prgname (), error->message);
260258 ret = 2;
261259
262260 } else {
263 client = realm_client_new (arg_verbose);
264 if (client) {
265 realm_name = argc < 2 ? "" : argv[1];
266 ret = perform_join (client, realm_name, arg_user,
267 arg_computer_ou, arg_client_software,
268 arg_server_software, arg_membership_software,
269 arg_one_time_password);
270 g_object_unref (client);
271 } else {
272 ret = 1;
273 }
261 realm_name = argc < 2 ? "" : argv[1];
262 ret = perform_join (client, realm_name, arg_user,
263 arg_computer_ou, arg_client_software,
264 arg_server_software, arg_membership_software,
265 arg_one_time_password);
274266 }
275267
276268 g_free (arg_user);
249249 }
250250
251251 int
252 realm_leave (int argc,
253 char *argv[])
254 {
255 RealmClient *client;
252 realm_leave (RealmClient *client,
253 int argc,
254 char *argv[])
255 {
256256 GOptionContext *context;
257257 gchar *arg_user = NULL;
258 gboolean arg_verbose = FALSE;
259258 gboolean arg_remove = FALSE;
260259 gchar *arg_client_software = NULL;
261260 gchar *arg_server_software = NULL;
270269 { "server-software", 0, 0, G_OPTION_ARG_STRING, &arg_server_software,
271270 N_("Use specific server software"), NULL },
272271 { "user", 'U', 0, G_OPTION_ARG_STRING, &arg_user, N_("User name to use for removal"), NULL },
273 { "verbose", 'v', 0, G_OPTION_ARG_NONE, &arg_verbose, N_("Verbose output"), NULL },
274272 { NULL, }
275273 };
276274
277275 context = g_option_context_new ("realm");
278276 g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
279277 g_option_context_add_main_entries (context, option_entries, NULL);
278 g_option_context_add_main_entries (context, realm_global_options, NULL);
280279
281280 if (!g_option_context_parse (context, &argc, &argv, &error)) {
282281 g_printerr ("%s: %s\n", g_get_prgname (), error->message);
284283 ret = 2;
285284
286285 } else {
287 client = realm_client_new (arg_verbose);
288 if (client) {
289 realm_name = argc < 2 ? NULL : argv[1];
290 ret = perform_leave (client, realm_name, arg_remove, arg_user,
291 arg_client_software, arg_server_software);
292 g_object_unref (client);
293 } else {
294 ret = 1;
295 }
286 realm_name = argc < 2 ? NULL : argv[1];
287 ret = perform_leave (client, realm_name, arg_remove, arg_user,
288 arg_client_software, arg_server_software);
296289 }
297290
298291 g_free (arg_user);
181181 }
182182
183183 static int
184 realm_permit_or_deny (gboolean permit,
184 realm_permit_or_deny (RealmClient *client,
185 gboolean permit,
185186 int argc,
186187 char *argv[])
187188 {
188 RealmClient *client;
189189 GOptionContext *context;
190190 gboolean arg_all = FALSE;
191 gboolean arg_verbose = FALSE;
192191 gchar *realm_name = NULL;
193192 GError *error = NULL;
194193 gint ret = 0;
197196 { "all", 'a', 0, G_OPTION_ARG_NONE, &arg_all,
198197 permit ? N_("Permit any domain user login") : N_("Deny any domain user login"), NULL },
199198 { "realm", 'R', 0, G_OPTION_ARG_STRING, &realm_name, N_("Realm to permit/deny logins for"), NULL },
200 { "verbose", 'v', 0, G_OPTION_ARG_NONE, &arg_verbose, N_("Verbose output"), NULL },
201199 { NULL, }
202200 };
203201
204202 context = g_option_context_new ("realm");
205203 g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
206204 g_option_context_add_main_entries (context, option_entries, NULL);
205 g_option_context_add_main_entries (context, realm_global_options, NULL);
207206
208207 if (!g_option_context_parse (context, &argc, &argv, &error)) {
209208 g_printerr ("%s: %s\n", g_get_prgname (), error->message);
218217 g_printerr ("%s: %s\n", _("No users should be specified with -a or --all"), g_get_prgname ());
219218 ret = 2;
220219 } else {
221 client = realm_client_new (arg_verbose);
222 if (client) {
223 ret = perform_permit_or_deny_all (client, realm_name, permit);
224 g_object_unref (client);
225 } else {
226 ret = 1;
227 }
220 ret = perform_permit_or_deny_all (client, realm_name, permit);
228221 }
229222 } else if (argc < 2) {
230223 g_printerr ("%s: %s\n", g_get_prgname (),
232225 ret = 2;
233226
234227 } else {
235 client = realm_client_new (arg_verbose);
236 if (client) {
237 ret = perform_permit_or_deny_logins (client, realm_name,
238 (const gchar **)(argv + 1),
239 argc - 1, permit);
240 g_object_unref (client);
241 } else {
242 ret = 1;
243 }
228 ret = perform_permit_or_deny_logins (client, realm_name,
229 (const gchar **)(argv + 1),
230 argc - 1, permit);
244231 }
245232
246233 g_free (realm_name);
249236 }
250237
251238 int
252 realm_permit (int argc,
239 realm_permit (RealmClient *client,
240 int argc,
253241 char *argv[])
254242 {
255 return realm_permit_or_deny (TRUE, argc, argv);
243 return realm_permit_or_deny (client, TRUE, argc, argv);
256244 }
257245
258246 int
259 realm_deny (int argc,
247 realm_deny (RealmClient *client,
248 int argc,
260249 char *argv[])
261250 {
262 return realm_permit_or_deny (FALSE, argc, argv);
263 }
251 return realm_permit_or_deny (client, FALSE, argc, argv);
252 }
2727 #include <fcntl.h>
2828 #include <locale.h>
2929
30 static gchar *arg_install = NULL;
31 gboolean realm_verbose = FALSE;
32
3033 struct {
3134 const char *name;
32 int (* function) (int argc, char *argv[]);
35 int (* function) (RealmClient *client, int argc, char *argv[]);
3336 const char *usage;
3437 const char *description;
3538 } realm_commands[] = {
115118
116119 va_end (va);
117120
121 if (arg_install) {
122 option = g_variant_new ("{sv}", "assume-packages", g_variant_new_boolean (TRUE));
123 g_ptr_array_add (opts, option);
124 }
125
118126 options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), (GVariant * const*)opts->pdata, opts->len);
119127 g_ptr_array_free (opts, TRUE);
120128
282290 return code;
283291 }
284292
293 GOptionEntry realm_global_options[] = {
294 { "install", 'i', 0, G_OPTION_ARG_STRING, &arg_install, N_("Install mode to a specific prefix"), NULL },
295 { "verbose", 'v', 0, G_OPTION_ARG_NONE, &realm_verbose, N_("Verbose output"), NULL },
296 { NULL, }
297 };
298
285299 int
286300 main (int argc,
287301 char *argv[])
288302 {
289303 const gchar *command = NULL;
304 GOptionContext *context;
305 RealmClient *client;
306 GError *error = NULL;
307 gint ret;
290308 gint i;
291309
292310 setlocale (LC_ALL, "");
298316 #endif
299317
300318 g_type_init ();
319
320 /* Parse the global options, don't display help or failure here */
321 context = g_option_context_new ("realm");
322 g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
323 g_option_context_add_main_entries (context, realm_global_options, NULL);
324 g_option_context_set_help_enabled (context, FALSE);
325 g_option_context_set_ignore_unknown_options (context, TRUE);
326
327 if (!g_option_context_parse (context, &argc, &argv, &error)) {
328 g_warning ("Unexpected error: %s", error->message);
329 g_error_free (error);
330 }
331
332 g_option_context_free (context);
301333
302334 /* Find/remove the first non-flag argument: the command */
303335 for (i = 1; i < argc; i++) {
314346 if (command == NULL)
315347 return usage (2);
316348
349 ret = 2;
317350 for (i = 0; i < G_N_ELEMENTS (realm_commands); i++) {
318 if (g_str_equal (realm_commands[i].name, command))
319 return (realm_commands[i].function) (argc, argv);
320 }
321
322 return usage(2);
323 }
351 if (g_str_equal (realm_commands[i].name, command)) {
352 client = realm_client_new (realm_verbose, arg_install);
353 if (!client) {
354 ret = 1;
355 break;
356 }
357
358 ret = (realm_commands[i].function) (client, argc, argv);
359 g_object_unref (client);
360
361 break;
362 }
363 }
364
365 if (ret == 2)
366 usage(2);
367
368 g_free (arg_install);
369 return ret;
370
371 }
2424
2525 #define realm_operation_id "realm-enroll"
2626
27 int realm_join (int argc,
27 extern GOptionEntry realm_global_options[];
28
29 extern gboolean realm_verbose;
30
31 int realm_join (RealmClient *client,
32 int argc,
2833 char *argv[]);
2934
30 int realm_leave (int argc,
35 int realm_leave (RealmClient *client,
36 int argc,
3137 char *argv[]);
3238
33 int realm_discover (int argc,
39 int realm_discover (RealmClient *client,
40 int argc,
3441 char *argv[]);
3542
36 int realm_list (int argc,
43 int realm_list (RealmClient *client,
44 int argc,
3745 char *argv[]);
3846
39 int realm_permit (int argc,
47 int realm_permit (RealmClient *client,
48 int argc,
4049 char *argv[]);
4150
42 int realm_deny (int argc,
51 int realm_deny (RealmClient *client,
52 int argc,
4353 char *argv[]);
4454
4555 GVariant * realm_build_options (const gchar *first,