Imported Upstream version 0.11
Laurent Bigonville
11 years ago
0 | 0 | # 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(-) | |
1 | 126 | |
2 | 127 | commit 56ad086b908cadc75648b804916bf6488061e890 |
3 | 128 | 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 | ||
0 | 5 | 0.10 |
1 | 6 | * Send diagnostics from subcommand to client as they come in |
2 | 7 | * Return configured realms back to callers |
0 | 0 | #! /bin/sh |
1 | 1 | # 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. | |
3 | 3 | # |
4 | 4 | # Report bugs to <http://bugs.freedesktop.org/enter_bug.cgi?product=realmd>. |
5 | 5 | # |
580 | 580 | # Identity of this package. |
581 | 581 | PACKAGE_NAME='realmd' |
582 | 582 | 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' | |
585 | 585 | PACKAGE_BUGREPORT='http://bugs.freedesktop.org/enter_bug.cgi?product=realmd' |
586 | 586 | PACKAGE_URL='' |
587 | 587 | |
1384 | 1384 | # Omit some internal or obsolete options to make the list less imposing. |
1385 | 1385 | # This message is too long to be a string in the A/UX 3.1 sh. |
1386 | 1386 | 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. | |
1388 | 1388 | |
1389 | 1389 | Usage: $0 [OPTION]... [VAR=VALUE]... |
1390 | 1390 | |
1450 | 1450 | |
1451 | 1451 | if test -n "$ac_init_help"; then |
1452 | 1452 | case $ac_init_help in |
1453 | short | recursive ) echo "Configuration of realmd 0.10:";; | |
1453 | short | recursive ) echo "Configuration of realmd 0.11:";; | |
1454 | 1454 | esac |
1455 | 1455 | cat <<\_ACEOF |
1456 | 1456 | |
1581 | 1581 | test -n "$ac_init_help" && exit $ac_status |
1582 | 1582 | if $ac_init_version; then |
1583 | 1583 | cat <<\_ACEOF |
1584 | realmd configure 0.10 | |
1584 | realmd configure 0.11 | |
1585 | 1585 | generated by GNU Autoconf 2.69 |
1586 | 1586 | |
1587 | 1587 | Copyright (C) 2012 Free Software Foundation, Inc. |
1950 | 1950 | This file contains any messages produced by compilers while |
1951 | 1951 | running configure, to aid debugging if configure makes a mistake. |
1952 | 1952 | |
1953 | It was created by realmd $as_me 0.10, which was | |
1953 | It was created by realmd $as_me 0.11, which was | |
1954 | 1954 | generated by GNU Autoconf 2.69. Invocation command line was |
1955 | 1955 | |
1956 | 1956 | $ $0 $@ |
2778 | 2778 | |
2779 | 2779 | # Define the identity of the package. |
2780 | 2780 | PACKAGE='realmd' |
2781 | VERSION='0.10' | |
2781 | VERSION='0.11' | |
2782 | 2782 | |
2783 | 2783 | |
2784 | 2784 | cat >>confdefs.h <<_ACEOF |
8927 | 8927 | # report actual input values of CONFIG_FILES etc. instead of their |
8928 | 8928 | # values after options handling. |
8929 | 8929 | 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 | |
8931 | 8931 | generated by GNU Autoconf 2.69. Invocation command line was |
8932 | 8932 | |
8933 | 8933 | CONFIG_FILES = $CONFIG_FILES |
8993 | 8993 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 |
8994 | 8994 | ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" |
8995 | 8995 | ac_cs_version="\\ |
8996 | realmd config.status 0.10 | |
8996 | realmd config.status 0.11 | |
8997 | 8997 | configured by $0, generated by GNU Autoconf 2.69, |
8998 | 8998 | with options \\"\$ac_cs_config\\" |
8999 | 8999 |
0 | 0 | AC_PREREQ(2.63) |
1 | 1 | |
2 | AC_INIT([realmd], [0.10], | |
2 | AC_INIT([realmd], [0.11], | |
3 | 3 | [http://bugs.freedesktop.org/enter_bug.cgi?product=realmd], |
4 | 4 | [realmd]) |
5 | 5 |
336 | 336 | </itemizedlist> |
337 | 337 | --> |
338 | 338 | <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"/> | |
339 | 352 | |
340 | 353 | <!-- |
341 | 354 | LoginFormats: supported formats for login names |
587 | 600 | <listitem><para><literal>computer-ou</literal>: a string |
588 | 601 | containing an LDAP DN for an organizational unit where the |
589 | 602 | 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> | |
590 | 606 | </itemizedlist> |
591 | 607 | |
592 | 608 | This method requires authorization for the PolicyKit action |
59 | 59 | #define REALM_DBUS_OPTION_SERVER_SOFTWARE "server-software" |
60 | 60 | #define REALM_DBUS_OPTION_CLIENT_SOFTWARE "client-software" |
61 | 61 | #define REALM_DBUS_OPTION_MEMBERSHIP_SOFTWARE "membership-software" |
62 | #define REALM_DBUS_OPTION_ASSUME_PACKAGES "assume-packages" | |
62 | 63 | |
63 | 64 | #define REALM_DBUS_IDENTIFIER_ACTIVE_DIRECTORY "active-directory" |
64 | 65 | #define REALM_DBUS_IDENTIFIER_WINBIND "winbind" |
56 | 56 | </method> |
57 | 57 | <property name='SupportedInterfaces' type='as' access='read'></property> |
58 | 58 | <property name='Details' type='a(ss)' access='read'></property> |
59 | <property name='RequiredPackages' type='as' access='read'></property> | |
59 | 60 | <property name='LoginFormats' type='as' access='read'></property> |
60 | 61 | <property name='LoginPolicy' type='s' access='read'></property> |
61 | 62 | <property name='PermittedLogins' type='as' access='read'></property> |
36 | 36 | <td valign="top" align="right"></td> |
37 | 37 | </tr></table></div> |
38 | 38 | <div class="refsect1"> |
39 | <a name="idp5714736"></a><h2>Properties</h2> | |
39 | <a name="idp11402976"></a><h2>Properties</h2> | |
40 | 40 | <pre class="synopsis"> |
41 | 41 | <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 |
42 | 42 | <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 |
46 | 46 | </pre> |
47 | 47 | </div> |
48 | 48 | <div class="refsect1"> |
49 | <a name="idp6873920"></a><h2>Properties</h2> | |
49 | <a name="idp8661952"></a><h2>Properties</h2> | |
50 | 50 | <pre class="synopsis"> |
51 | 51 | <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 |
52 | 52 | <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) |
98 | 98 | <li class="listitem"><p><code class="literal">computer-ou</code>: a string |
99 | 99 | containing an LDAP DN for an organizational unit where the |
100 | 100 | 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> | |
101 | 104 | </ul></div> |
102 | 105 | <p> |
103 | 106 | </p> |
46 | 46 | </pre> |
47 | 47 | </div> |
48 | 48 | <div class="refsect1"> |
49 | <a name="idp8500176"></a><h2>Properties</h2> | |
49 | <a name="idp9243216"></a><h2>Properties</h2> | |
50 | 50 | <pre class="synopsis"> |
51 | 51 | <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 |
52 | 52 | <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 |
47 | 47 | </pre> |
48 | 48 | </div> |
49 | 49 | <div class="refsect1"> |
50 | <a name="idp6374720"></a><h2>Properties</h2> | |
50 | <a name="idp9928208"></a><h2>Properties</h2> | |
51 | 51 | <pre class="synopsis"> |
52 | 52 | <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 |
53 | 53 | <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 |
54 | 54 | <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 |
55 | 55 | <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 | |
56 | 57 | <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 |
57 | 58 | <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 |
58 | 59 | <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 |
300 | 301 | </div> |
301 | 302 | <hr> |
302 | 303 | <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 >= 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"> | |
303 | 320 | <a name="gdbus-property-org-freedesktop-realmd-Realm.LoginFormats"></a><h3>The "LoginFormats" property</h3> |
304 | 321 | <pre class="programlisting"> |
305 | 322 | LoginFormats readable as |
45 | 45 | </pre> |
46 | 46 | </div> |
47 | 47 | <div class="refsect1"> |
48 | <a name="idp8140512"></a><h2>Signals</h2> | |
48 | <a name="idp11296128"></a><h2>Signals</h2> | |
49 | 49 | <pre class="synopsis"> |
50 | 50 | <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, |
51 | 51 | s operation); |
32 | 32 | By default SSSD is used.</p> |
33 | 33 | <div class="section"> |
34 | 34 | <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> | |
36 | 36 | <p><a class="ulink" href="https://fedorahosted.org/sssd/" target="_top">SSSD</a> |
37 | 37 | provides client software for various kerberos and/or LDAP |
38 | 38 | directories. Since version 1.9.x it provides good support |
50 | 50 | </div> |
51 | 51 | <div class="section"> |
52 | 52 | <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> | |
54 | 54 | <p>Samba |
55 | 55 | <a class="ulink" href="http://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/winbind.html" target="_top">Winbind</a> |
56 | 56 | provides client software for use with Active Directory.</p> |
25 | 25 | <dt><span class="section"><a href="guide-active-directory.html#guide-active-directory-discover">Discovering Active Directory domains</a></span></dt> |
26 | 26 | <dt><span class="section"><a href="guide-active-directory-client.html">Active Directory client software</a></span></dt> |
27 | 27 | <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> | |
30 | 30 | </dl></dd> |
31 | 31 | <dt><span class="section"><a href="guide-active-directory-join.html">Joining an Active Directory domain</a></span></dt> |
32 | 32 | <dt><span class="section"><a href="guide-active-directory-permit.html">Logins using Domain Accounts</a></span></dt> |
35 | 35 | <p>Only specify the settings you wish to override.</p> |
36 | 36 | <div class="section"> |
37 | 37 | <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> | |
39 | 39 | <p>Specify this option to create directory computer accounts |
40 | 40 | in a location other than the default. This currently only works |
41 | 41 | with Active Directory domains.</p> |
26 | 26 | specify the settings you wish to override.</p> |
27 | 27 | <div class="section"> |
28 | 28 | <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> | |
30 | 30 | <p>Specify the <code class="option">default-home</code> setting in |
31 | 31 | order to control how to set the home directory for accounts |
32 | 32 | that have no home directory explicitly set.</p> |
58 | 58 | </div> |
59 | 59 | <div class="section"> |
60 | 60 | <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> | |
62 | 62 | <p>Specify the <code class="option">default-shell</code> setting in |
63 | 63 | order to control how to set the Unix shell for accounts that |
64 | 64 | have no shell explicitly set.</p> |
23 | 23 | <a name="guide-configuring"></a>Configuring realmd</h2></div></div></div> |
24 | 24 | <div class="toc"><dl> |
25 | 25 | <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> | |
27 | 27 | <dt><span class="section"><a href="guide-configuring-users.html">user</a></span></dt> |
28 | 28 | <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> | |
31 | 31 | </dl></dd> |
32 | 32 | <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> | |
34 | 34 | </dl></div> |
35 | 35 | <p><span class="command"><strong>realmd</strong></span> can be tweaked by network administrators |
36 | 36 | to act in specific ways. This is done by placing settings in a |
50 | 50 | specify the settings you wish to override.</p> |
51 | 51 | <div class="section"> |
52 | 52 | <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> | |
54 | 54 | <p>Specify the <code class="option">default-client</code> setting in |
55 | 55 | order to control which client software is the preferred default |
56 | 56 | for use with Active Directory.</p> |
21 | 21 | <div class="chapter"> |
22 | 22 | <div class="titlepage"><div><div><h2 class="title"> |
23 | 23 | <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> | |
25 | 25 | <p><span class="command"><strong>realmd</strong></span> can discover generic Kerberos realms. |
26 | 26 | Since there is no standard way to enroll a computer against a Kerberos |
27 | 27 | server, it is not possible to do this with <span class="command"><strong>realmd</strong></span>.</p> |
28 | 28 | <div class="section"> |
29 | 29 | <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> | |
31 | 31 | <p><span class="command"><strong>realmd</strong></span> discovers which domains or |
32 | 32 | realms it can use or configure. It can discover and identify |
33 | 33 | Kerberos domains by looking up the appropriate DNS SRV |
33 | 33 | <dt><span class="section"><a href="guide-active-directory.html#guide-active-directory-discover">Discovering Active Directory domains</a></span></dt> |
34 | 34 | <dt><span class="section"><a href="guide-active-directory-client.html">Active Directory client software</a></span></dt> |
35 | 35 | <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> | |
38 | 38 | </dl></dd> |
39 | 39 | <dt><span class="section"><a href="guide-active-directory-join.html">Joining an Active Directory domain</a></span></dt> |
40 | 40 | <dt><span class="section"><a href="guide-active-directory-permit.html">Logins using Domain Accounts</a></span></dt> |
41 | 41 | </dl></dd> |
42 | 42 | <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> | |
44 | 44 | <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> | |
46 | 46 | <dt><span class="chapter"><a href="guide-configuring.html">Configuring realmd</a></span></dt> |
47 | 47 | <dd><dl> |
48 | 48 | <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> | |
50 | 50 | <dt><span class="section"><a href="guide-configuring-users.html">user</a></span></dt> |
51 | 51 | <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> | |
54 | 54 | </dl></dd> |
55 | 55 | <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> | |
57 | 57 | </dl></dd> |
58 | 58 | <dt><span class="chapter"><a href="guide-integration.html">Integration</a></span></dt> |
59 | 59 | </dl> |
13 | 13 | <div class="titlepage"> |
14 | 14 | <div> |
15 | 15 | <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 | |
17 | 17 | </p></div> |
18 | 18 | </div> |
19 | 19 | <hr> |
30 | 30 | <dt><span class="section"><a href="guide-active-directory.html#guide-active-directory-discover">Discovering Active Directory domains</a></span></dt> |
31 | 31 | <dt><span class="section"><a href="guide-active-directory-client.html">Active Directory client software</a></span></dt> |
32 | 32 | <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> | |
35 | 35 | </dl></dd> |
36 | 36 | <dt><span class="section"><a href="guide-active-directory-join.html">Joining an Active Directory domain</a></span></dt> |
37 | 37 | <dt><span class="section"><a href="guide-active-directory-permit.html">Logins using Domain Accounts</a></span></dt> |
38 | 38 | </dl></dd> |
39 | 39 | <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> | |
41 | 41 | <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> | |
43 | 43 | <dt><span class="chapter"><a href="guide-configuring.html">Configuring realmd</a></span></dt> |
44 | 44 | <dd><dl> |
45 | 45 | <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> | |
47 | 47 | <dt><span class="section"><a href="guide-configuring-users.html">user</a></span></dt> |
48 | 48 | <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> | |
51 | 51 | </dl></dd> |
52 | 52 | <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> | |
54 | 54 | </dl></dd> |
55 | 55 | <dt><span class="chapter"><a href="guide-integration.html">Integration</a></span></dt> |
56 | 56 | </dl></dd> |
16 | 16 | <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.Configured" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.Configured"> |
17 | 17 | <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.SupportedInterfaces" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.SupportedInterfaces"> |
18 | 18 | <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"> | |
19 | 20 | <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.LoginFormats" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.LoginFormats"> |
20 | 21 | <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.LoginPolicy" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.LoginPolicy"> |
21 | 22 | <ANCHOR id="gdbus-property-org-freedesktop-realmd-Realm.PermittedLogins" href="realmd/gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.PermittedLogins"> |
37 | 37 | <div class="cmdsynopsis"><p><code class="command">realm deny [-a] [-R realm] {user} ...</code> </p></div> |
38 | 38 | </div> |
39 | 39 | <div class="refsect1"> |
40 | <a name="idp7756624"></a><h2>Description</h2> | |
40 | <a name="idp7785392"></a><h2>Description</h2> | |
41 | 41 | <p><span class="command"><strong>realm</strong></span> is a command line tool that |
42 | 42 | can be used to manage enrollment in kerberos realms, like Active |
43 | 43 | 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> | |
47 | 70 | <p>Discover a realm and its capabilities.</p> |
48 | 71 | <div class="informalexample"> |
49 | 72 | <pre class="programlisting"> |
78 | 101 | <em class="replaceable"><code>active-directory</code></em> or |
79 | 102 | <em class="replaceable"><code>freeipa</code></em>.</p></td> |
80 | 103 | </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> | |
91 | 109 | <p>Configure the local machine for use with a realm.</p> |
92 | 110 | <div class="informalexample"> |
93 | 111 | <pre class="programlisting"> |
159 | 177 | with when joining the machine to the realm. You will |
160 | 178 | be prompted for a password.</p></td> |
161 | 179 | </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> | |
172 | 185 | <p>Deconfigure the local machine for use with a realm.</p> |
173 | 186 | <div class="informalexample"> |
174 | 187 | <pre class="programlisting"> |
213 | 226 | with when leaving the realm. You will be prompted for a |
214 | 227 | password. Implies <code class="option">--remove</code>.</p></td> |
215 | 228 | </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> | |
226 | 234 | <p>List all the discovered and configured realms.</p> |
227 | 235 | <div class="informalexample"> |
228 | 236 | <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> |
235 | 243 | </table> |
236 | 244 | </div> |
237 | 245 | |
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> | |
253 | 249 | <p>Permit local login by users of the realm.</p> |
254 | 250 | <div class="informalexample"> |
255 | 251 | <pre class="programlisting"> |
280 | 276 | <td><p>Specify the name of the realm to permit |
281 | 277 | users to log into.</p></td> |
282 | 278 | </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> | |
293 | 284 | <p>Deny local login by users of the realm.</p> |
294 | 285 | <div class="informalexample"> |
295 | 286 | <pre class="programlisting"> |
319 | 310 | <td><p><span class="term"><code class="option">--realm, -R</code></span></p></td> |
320 | 311 | <td><p>Specify the name of the realm to deny |
321 | 312 | 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> | |
327 | 313 | </tr> |
328 | 314 | </tbody> |
329 | 315 | </table></div> |
8 | 8 | <sub name="Using with Active Directory" link="guide-active-directory.html"> |
9 | 9 | <sub name="Discovering Active Directory domains" link="guide-active-directory.html#guide-active-directory-discover"/> |
10 | 10 | <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"/> | |
13 | 13 | </sub> |
14 | 14 | <sub name="Joining an Active Directory domain" link="guide-active-directory-join.html"/> |
15 | 15 | <sub name="Logins using Domain Accounts" link="guide-active-directory-permit.html"/> |
16 | 16 | </sub> |
17 | 17 | <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"/> | |
19 | 19 | </sub> |
20 | 20 | <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"/> | |
22 | 22 | </sub> |
23 | 23 | <sub name="Configuring realmd" link="guide-configuring.html"> |
24 | 24 | <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"/> | |
26 | 26 | </sub> |
27 | 27 | <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"/> | |
30 | 30 | </sub> |
31 | 31 | <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"/> | |
33 | 33 | </sub> |
34 | 34 | </sub> |
35 | 35 | <sub name="Integration" link="guide-integration.html"/> |
56 | 56 | <keyword type="property" name="The "Configured" property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.Configured"/> |
57 | 57 | <keyword type="property" name="The "SupportedInterfaces" property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.SupportedInterfaces"/> |
58 | 58 | <keyword type="property" name="The "Details" property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.Details"/> |
59 | <keyword type="property" name="The "RequiredPackages" property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.RequiredPackages"/> | |
59 | 60 | <keyword type="property" name="The "LoginFormats" property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.LoginFormats"/> |
60 | 61 | <keyword type="property" name="The "LoginPolicy" property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.LoginPolicy"/> |
61 | 62 | <keyword type="property" name="The "PermittedLogins" property" link="gdbus-org.freedesktop.realmd.Realm.html#gdbus-property-org-freedesktop-realmd-Realm.PermittedLogins"/> |
53 | 53 | <para><command>realm</command> is a command line tool that |
54 | 54 | can be used to manage enrollment in kerberos realms, like Active |
55 | 55 | 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 | ||
56 | 76 | </refsect1> |
57 | 77 | |
58 | 78 | <refsect1> |
91 | 111 | given server software. Possible values include |
92 | 112 | <replaceable>active-directory</replaceable> or |
93 | 113 | <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> | |
99 | 114 | </varlistentry> |
100 | 115 | </variablelist> |
101 | 116 | |
177 | 192 | with when joining the machine to the realm. You will |
178 | 193 | be prompted for a password.</para></listitem> |
179 | 194 | </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> | |
185 | 195 | </variablelist> |
186 | 196 | |
187 | 197 | </refsect1> |
232 | 242 | with when leaving the realm. You will be prompted for a |
233 | 243 | password. Implies <option>--remove</option>.</para></listitem> |
234 | 244 | </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> | |
240 | 245 | </variablelist> |
241 | 246 | |
242 | 247 | </refsect1> |
251 | 256 | $ realm list |
252 | 257 | </programlisting> |
253 | 258 | </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> | |
264 | 259 | |
265 | 260 | </refsect1> |
266 | 261 | |
297 | 292 | <listitem><para>Specify the name of the realm to permit |
298 | 293 | users to log into.</para></listitem> |
299 | 294 | </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> | |
305 | 295 | </variablelist> |
306 | 296 | |
307 | 297 | </refsect1> |
339 | 329 | <listitem><para>Specify the name of the realm to deny |
340 | 330 | users login to.</para></listitem> |
341 | 331 | </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> | |
347 | 332 | </variablelist> |
348 | 333 | |
349 | 334 | </refsect1> |
61 | 61 | <listitem><para><literal>computer-ou</literal>: a string |
62 | 62 | containing an LDAP DN for an organizational unit where the |
63 | 63 | 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> | |
64 | 67 | </itemizedlist> |
65 | 68 | </para><para> This method requires authorization for the PolicyKit action |
66 | 69 | called <literal>org.freedesktop.realmd.configure-realm</literal>. |
21 | 21 | <link linkend="gdbus-property-org-freedesktop-realmd-Realm.Configured">Configured</link> readable s |
22 | 22 | <link linkend="gdbus-property-org-freedesktop-realmd-Realm.SupportedInterfaces">SupportedInterfaces</link> readable as |
23 | 23 | <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 | |
24 | 25 | <link linkend="gdbus-property-org-freedesktop-realmd-Realm.LoginFormats">LoginFormats</link> readable as |
25 | 26 | <link linkend="gdbus-property-org-freedesktop-realmd-Realm.LoginPolicy">LoginPolicy</link> readable s |
26 | 27 | <link linkend="gdbus-property-org-freedesktop-realmd-Realm.PermittedLogins">PermittedLogins</link> readable as |
231 | 232 | </itemizedlist> |
232 | 233 | </para></para> |
233 | 234 | </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> | |
234 | 249 | <refsect2 role="property" id="gdbus-property-org-freedesktop-realmd-Realm.LoginFormats"> |
235 | 250 | <title>The "LoginFormats" property</title> |
236 | 251 | <indexterm zone="gdbus-property-org-freedesktop-realmd-Realm.LoginFormats"><primary sortas="Realm:LoginFormats">org.freedesktop.realmd.Realm:LoginFormats</primary></indexterm> |
32 | 32 | </method> |
33 | 33 | <property name='SupportedInterfaces' type='as' access='read'></property> |
34 | 34 | <property name='Details' type='a(ss)' access='read'></property> |
35 | <property name='RequiredPackages' type='as' access='read'></property> | |
35 | 36 | <property name='LoginFormats' type='as' access='read'></property> |
36 | 37 | <property name='LoginPolicy' type='s' access='read'></property> |
37 | 38 | <property name='PermittedLogins' type='as' access='read'></property> |
30 | 30 | #include <polkit/polkit.h> |
31 | 31 | |
32 | 32 | #include <stdio.h> |
33 | #include <errno.h> | |
33 | 34 | |
34 | 35 | #define TIMEOUT 60 /* seconds */ |
35 | 36 | #define HOLD_INTERNAL (GUINT_TO_POINTER (~0)) |
45 | 46 | static gboolean service_bus_name_claimed = FALSE; |
46 | 47 | static GDBusObjectManagerServer *object_server = NULL; |
47 | 48 | static gboolean service_debug = FALSE; |
49 | static gchar *service_install = NULL; | |
50 | static gint service_dbus_fd = -1; | |
48 | 51 | |
49 | 52 | typedef struct { |
50 | 53 | guint watch; |
104 | 107 | } |
105 | 108 | |
106 | 109 | 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 | |
107 | 122 | realm_daemon_has_debug_flag (void) |
108 | 123 | { |
109 | 124 | return service_debug; |
117 | 132 | |
118 | 133 | gboolean |
119 | 134 | realm_daemon_check_dbus_action (const gchar *sender, |
120 | const gchar *action_id) | |
135 | const gchar *action_id) | |
121 | 136 | { |
122 | 137 | PolkitAuthorizationResult *result; |
123 | 138 | PolkitAuthority *authority; |
124 | 139 | PolkitSubject *subject; |
125 | 140 | GError *error = NULL; |
126 | 141 | gboolean ret; |
142 | ||
143 | /* If we're a dbus peer, just allow all calls */ | |
144 | if (realm_daemon_is_dbus_peer ()) | |
145 | return TRUE; | |
127 | 146 | |
128 | 147 | g_return_val_if_fail (sender != NULL, FALSE); |
129 | 148 | g_return_val_if_fail (action_id != NULL, FALSE); |
366 | 385 | static void |
367 | 386 | on_name_acquired (GDBusConnection *connection, |
368 | 387 | const gchar *name, |
369 | gpointer user_data) | |
388 | gpointer unused) | |
370 | 389 | { |
371 | 390 | service_bus_name_claimed = TRUE; |
372 | 391 | g_debug ("claimed name on bus: %s", name); |
376 | 395 | static void |
377 | 396 | on_name_lost (GDBusConnection *connection, |
378 | 397 | const gchar *name, |
379 | gpointer user_data) | |
398 | gpointer unused) | |
380 | 399 | { |
381 | 400 | if (!service_bus_name_claimed) |
382 | 401 | g_message ("couldn't claim service name on DBus bus: %s", name); |
393 | 412 | } |
394 | 413 | |
395 | 414 | 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 | |
396 | 452 | on_bus_get_connection (GObject *source, |
397 | 453 | GAsyncResult *result, |
398 | 454 | gpointer unused) |
400 | 456 | GError *error = NULL; |
401 | 457 | GDBusConnection *connection; |
402 | 458 | const gchar *self_name; |
403 | RealmProvider *all_provider; | |
404 | RealmProvider *provider; | |
405 | 459 | guint owner_id; |
406 | 460 | |
407 | 461 | connection = g_bus_get_finish (result, &error); |
418 | 472 | g_dbus_connection_add_filter (connection, on_connection_filter, |
419 | 473 | (gchar *)self_name, NULL); |
420 | 474 | |
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); | |
443 | 476 | |
444 | 477 | owner_id = g_bus_own_name_on_connection (connection, |
445 | 478 | REALM_DBUS_BUS_NAME, |
446 | 479 | G_BUS_NAME_OWNER_FLAGS_NONE, |
447 | 480 | on_name_acquired, on_name_lost, |
448 | all_provider, g_object_unref); | |
481 | NULL, NULL); | |
482 | ||
449 | 483 | service_bus_name_owner_id = owner_id; |
450 | 484 | g_object_unref (connection); |
451 | 485 | } |
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; | |
455 | 542 | } |
456 | 543 | |
457 | 544 | static void |
494 | 581 | GOptionEntry option_entries[] = { |
495 | 582 | { "debug", 'd', 0, G_OPTION_ARG_NONE, &service_debug, |
496 | 583 | "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 }, | |
497 | 588 | { NULL } |
498 | 589 | }; |
499 | 590 | |
517 | 608 | context = g_option_context_new ("realmd"); |
518 | 609 | g_option_context_add_main_entries (context, option_entries, NULL); |
519 | 610 | if (!g_option_context_parse (context, &argc, &argv, &error)) { |
520 | g_printerr ("%s", error->message); | |
611 | g_message ("%s", error->message); | |
521 | 612 | g_option_context_free (context); |
522 | 613 | g_error_free (error); |
523 | 614 | return 2; |
524 | 615 | } |
525 | 616 | |
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 | ||
526 | 635 | if (g_getenv ("REALM_DEBUG")) |
527 | 636 | service_debug = TRUE; |
528 | if (g_getenv ("REALM_PERSIST") || service_debug) | |
637 | if (g_getenv ("REALM_PERSIST") || service_debug || service_install) | |
529 | 638 | service_persist = TRUE; |
530 | 639 | |
531 | 640 | if (service_debug) { |
538 | 647 | g_free, realm_client_unwatch_and_free); |
539 | 648 | realm_daemon_hold ("main"); |
540 | 649 | |
541 | /* Load the platform specific data */ | |
542 | realm_settings_init (); | |
543 | ||
544 | 650 | service = realm_dbus_service_skeleton_new (); |
545 | 651 | g_signal_connect (service, "handle-release", G_CALLBACK (on_service_release), NULL); |
546 | 652 | g_signal_connect (service, "handle-set-locale", G_CALLBACK (on_service_set_locale), NULL); |
547 | 653 | g_signal_connect (service, "handle-cancel", G_CALLBACK (on_service_cancel), NULL); |
548 | 654 | |
549 | 655 | 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 (); | |
551 | 657 | |
552 | 658 | main_loop = g_main_loop_new (NULL, FALSE); |
553 | 659 | |
567 | 673 | g_debug ("stopping service"); |
568 | 674 | realm_settings_uninit (); |
569 | 675 | g_main_loop_unref (main_loop); |
570 | g_option_context_free (context); | |
571 | 676 | |
572 | 677 | g_object_unref (service); |
573 | 678 | g_hash_table_unref (service_clients); |
679 | g_free (service_install); | |
574 | 680 | return 0; |
575 | 681 | } |
34 | 34 | const gchar *locale, |
35 | 35 | const gchar *operation_id); |
36 | 36 | |
37 | gboolean realm_daemon_is_dbus_peer (void); | |
38 | ||
39 | gboolean realm_daemon_is_install_mode (void); | |
40 | ||
37 | 41 | gboolean realm_daemon_has_debug_flag (void); |
38 | 42 | |
39 | 43 | void realm_daemon_poke (void); |
53 | 53 | g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); |
54 | 54 | g_return_if_fail (options != NULL); |
55 | 55 | |
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)) { | |
57 | 57 | g_object_set_qdata_full (G_OBJECT (invocation), operation_id_quark, |
58 | 58 | operation_id, g_free); |
59 | 59 | } |
29 | 29 | REALM_KERBEROS_OWNER_USER = 1 << 2, |
30 | 30 | REALM_KERBEROS_OWNER_COMPUTER = 1 << 3, |
31 | 31 | REALM_KERBEROS_OWNER_NONE = 1 << 4, |
32 | REALM_KERBEROS_ASSUME_PACKAGES = 1 << 5, | |
32 | 33 | } RealmKerberosFlags; |
33 | 34 | |
34 | 35 | #define REALM_KERBEROS_OWNER_MASK \ |
23 | 23 | #include "realm-kerberos.h" |
24 | 24 | #include "realm-kerberos-membership.h" |
25 | 25 | #include "realm-login-name.h" |
26 | #include "realm-packages.h" | |
26 | 27 | #include "realm-provider.h" |
27 | 28 | #include "realm-settings.h" |
28 | 29 | |
151 | 152 | |
152 | 153 | (iface->enroll_finish) (REALM_KERBEROS_MEMBERSHIP (closure->self), result, &error); |
153 | 154 | |
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) { | |
159 | 156 | enroll_method_reply (closure->invocation, error); |
160 | 157 | method_closure_free (closure); |
161 | 158 | 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); | |
162 | 167 | } |
163 | 168 | } |
164 | 169 | |
466 | 471 | RealmKerberosFlags flags = 0; |
467 | 472 | GVariant *creds; |
468 | 473 | RealmKerberosCredential cred_type; |
474 | gboolean assume = FALSE; | |
469 | 475 | gint ret; |
470 | 476 | |
471 | 477 | /* Make note of the current operation id, for diagnostics */ |
482 | 488 | "This computer's host name is not set correctly."); |
483 | 489 | return TRUE; |
484 | 490 | } |
491 | ||
492 | if (g_variant_lookup (options, REALM_DBUS_OPTION_ASSUME_PACKAGES, "b", &assume) && assume) | |
493 | flags |= REALM_KERBEROS_ASSUME_PACKAGES; | |
485 | 494 | |
486 | 495 | switch (cred_type) { |
487 | 496 | case REALM_KERBEROS_CREDENTIAL_CCACHE: |
1326 | 1335 | configured ? REALM_DBUS_KERBEROS_MEMBERSHIP_INTERFACE : ""); |
1327 | 1336 | } |
1328 | 1337 | |
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 | ||
1329 | 1350 | gchar * |
1330 | 1351 | realm_kerberos_calculate_join_computer_ou (RealmKerberos *self, |
1331 | 1352 | GVariant *options) |
132 | 132 | void realm_kerberos_set_configured (RealmKerberos *self, |
133 | 133 | gboolean configured); |
134 | 134 | |
135 | void realm_kerberos_set_required_package_sets (RealmKerberos *self, | |
136 | const gchar **package_sets); | |
137 | ||
135 | 138 | gchar * realm_kerberos_calculate_join_computer_ou (RealmKerberos *self, |
136 | 139 | GVariant *options); |
137 | 140 |
192 | 192 | lookup_required_files_and_packages (const gchar **package_sets, |
193 | 193 | gchar ***result_packages, |
194 | 194 | gchar ***result_files, |
195 | gboolean *unconditional) | |
195 | gboolean *result_unconditional) | |
196 | 196 | { |
197 | 197 | GHashTable *settings; |
198 | 198 | GHashTableIter iter; |
199 | 199 | GPtrArray *packages; |
200 | 200 | GPtrArray *files; |
201 | gboolean unconditional; | |
201 | 202 | gchar *section; |
202 | 203 | gchar *package; |
203 | 204 | gchar *file; |
204 | 205 | gint i; |
205 | 206 | |
206 | *unconditional = FALSE; | |
207 | unconditional = FALSE; | |
207 | 208 | packages = g_ptr_array_new_with_free_func (g_free); |
208 | 209 | files = g_ptr_array_new_with_free_func (g_free); |
209 | 210 | |
217 | 218 | file = g_strstrip (g_strdup (file)); |
218 | 219 | if (g_str_equal (file, "")) { |
219 | 220 | g_free (file); |
220 | *unconditional = TRUE; | |
221 | unconditional = TRUE; | |
221 | 222 | } else { |
222 | 223 | g_ptr_array_add (files, file); |
223 | 224 | } |
229 | 230 | } |
230 | 231 | } |
231 | 232 | |
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; | |
237 | 260 | } |
238 | 261 | |
239 | 262 | void |
269 | 292 | |
270 | 293 | } else { |
271 | 294 | 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 | } | |
276 | 303 | } |
277 | 304 | |
278 | 305 | g_strfreev (required_files); |
20 | 20 | |
21 | 21 | G_BEGIN_DECLS |
22 | 22 | |
23 | gchar ** realm_packages_expand_sets (const gchar **package_sets); | |
24 | ||
23 | 25 | gboolean realm_packages_check_paths (const gchar **paths, |
24 | 26 | GDBusMethodInvocation *invocation); |
25 | 27 |
50 | 50 | PROP_PROVIDER, |
51 | 51 | }; |
52 | 52 | |
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 | ||
53 | 63 | static void realm_samba_kerberos_membership_iface (RealmKerberosMembershipIface *iface); |
54 | 64 | |
55 | 65 | G_DEFINE_TYPE_WITH_CODE (RealmSamba, realm_samba, REALM_TYPE_KERBEROS, |
92 | 102 | |
93 | 103 | realm_kerberos_set_suggested_admin (kerberos, "Administrator"); |
94 | 104 | realm_kerberos_set_login_policy (kerberos, REALM_KERBEROS_ALLOW_ANY_LOGIN); |
105 | realm_kerberos_set_required_package_sets (kerberos, SAMBA_PACKAGES); | |
95 | 106 | } |
96 | 107 | |
97 | 108 | static gchar * |
275 | 286 | GAsyncReadyCallback callback, |
276 | 287 | gpointer user_data) |
277 | 288 | { |
278 | const gchar *packages[] = { REALM_DBUS_IDENTIFIER_WINBIND, REALM_DBUS_IDENTIFIER_SAMBA, NULL }; | |
279 | 289 | RealmKerberos *realm = REALM_KERBEROS (membership); |
280 | 290 | RealmSamba *self = REALM_SAMBA (realm); |
281 | 291 | GSimpleAsyncResult *res; |
282 | 292 | EnrollClosure *enroll; |
293 | const gchar **packages; | |
283 | 294 | GError *error = NULL; |
284 | 295 | gchar *enrolled; |
285 | 296 | |
305 | 316 | g_simple_async_result_complete_in_idle (res); |
306 | 317 | |
307 | 318 | } else { |
319 | if (flags & REALM_KERBEROS_ASSUME_PACKAGES) | |
320 | packages = NO_PACKAGES; | |
321 | else | |
322 | packages = SAMBA_PACKAGES; | |
308 | 323 | realm_packages_install_async (packages, enroll->invocation, |
309 | 324 | on_install_do_join, g_object_ref (res)); |
310 | 325 | } |
14 | 14 | #include "config.h" |
15 | 15 | |
16 | 16 | #include "realm-command.h" |
17 | #include "realm-daemon.h" | |
17 | 18 | #include "realm-service.h" |
18 | 19 | #include "realm-settings.h" |
19 | 20 | |
20 | 21 | #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 | } | |
21 | 56 | |
22 | 57 | void |
23 | 58 | realm_service_enable (const gchar *service_name, |
28 | 63 | gchar *command; |
29 | 64 | |
30 | 65 | 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); | |
32 | 67 | g_free (command); |
33 | 68 | } |
34 | 69 | |
36 | 71 | realm_service_enable_finish (GAsyncResult *result, |
37 | 72 | GError **error) |
38 | 73 | { |
39 | return realm_command_run_finish (result, NULL, error) != -1; | |
74 | return finish_service_command (result, error); | |
40 | 75 | } |
41 | 76 | |
42 | 77 | void |
48 | 83 | gchar *command; |
49 | 84 | |
50 | 85 | 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); | |
52 | 87 | g_free (command); |
53 | 88 | } |
54 | 89 | |
56 | 91 | realm_service_disable_finish (GAsyncResult *result, |
57 | 92 | GError **error) |
58 | 93 | { |
59 | return realm_command_run_finish (result, NULL, error) != -1; | |
94 | return finish_service_command (result, error); | |
60 | 95 | } |
61 | 96 | |
62 | 97 | void |
68 | 103 | gchar *command; |
69 | 104 | |
70 | 105 | 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); | |
72 | 107 | g_free (command); |
73 | 108 | } |
74 | 109 | |
76 | 111 | realm_service_restart_finish (GAsyncResult *result, |
77 | 112 | GError **error) |
78 | 113 | { |
79 | return realm_command_run_finish (result, NULL, error) != -1; | |
114 | return finish_service_command (result, error); | |
80 | 115 | } |
81 | 116 | |
82 | 117 | void |
88 | 123 | gchar *command; |
89 | 124 | |
90 | 125 | 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); | |
92 | 127 | g_free (command); |
93 | 128 | } |
94 | 129 | |
96 | 131 | realm_service_stop_finish (GAsyncResult *result, |
97 | 132 | GError **error) |
98 | 133 | { |
99 | return realm_command_run_finish (result, NULL, error) != -1; | |
134 | return finish_service_command (result, error); | |
100 | 135 | } |
101 | 136 | |
102 | 137 | typedef struct { |
41 | 41 | RealmSssdClass parent_class; |
42 | 42 | } RealmSssdAdClass; |
43 | 43 | |
44 | static const gchar *adcli_packages[] = { | |
44 | static const gchar *ADCLI_PACKAGES[] = { | |
45 | 45 | REALM_DBUS_IDENTIFIER_SSSD, |
46 | 46 | REALM_DBUS_IDENTIFIER_ADCLI, |
47 | 47 | NULL |
48 | 48 | }; |
49 | 49 | |
50 | static const gchar *samba_packages[] = { | |
50 | static const gchar *SAMBA_PACKAGES[] = { | |
51 | 51 | REALM_DBUS_IDENTIFIER_SSSD, |
52 | 52 | REALM_DBUS_IDENTIFIER_SAMBA, |
53 | 53 | 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, | |
54 | 65 | }; |
55 | 66 | |
56 | 67 | static void realm_sssd_ad_kerberos_membership_iface (RealmKerberosMembershipIface *iface); |
101 | 112 | |
102 | 113 | realm_kerberos_set_suggested_admin (kerberos, "Administrator"); |
103 | 114 | realm_kerberos_set_login_policy (kerberos, REALM_KERBEROS_ALLOW_ANY_LOGIN); |
115 | realm_kerberos_set_required_package_sets (kerberos, ALL_PACKAGES); | |
104 | 116 | } |
105 | 117 | |
106 | 118 | typedef struct { |
431 | 443 | |
432 | 444 | if (g_str_equal (software, REALM_DBUS_IDENTIFIER_ADCLI)) { |
433 | 445 | join->use_adcli = TRUE; |
434 | join->packages = adcli_packages; | |
446 | join->packages = ADCLI_PACKAGES; | |
435 | 447 | } else { |
436 | 448 | join->use_adcli = FALSE; |
437 | join->packages = samba_packages; | |
449 | join->packages = SAMBA_PACKAGES; | |
438 | 450 | } |
439 | 451 | |
440 | 452 | return TRUE; |
480 | 492 | |
481 | 493 | /* Prepared successfully without an error */ |
482 | 494 | } else { |
495 | if (flags & REALM_KERBEROS_ASSUME_PACKAGES) | |
496 | join->packages = NO_PACKAGES; | |
483 | 497 | return async; |
484 | 498 | } |
485 | 499 |
10 | 10 | realm-join.c \ |
11 | 11 | realm-leave.c \ |
12 | 12 | realm-logins.c \ |
13 | eggdbusobjectmanagerclient.c \ | |
14 | eggdbusobjectmanagerclient.h \ | |
15 | eggdbusobjectproxy.c \ | |
16 | eggdbusobjectproxy.h \ | |
13 | 17 | $(NULL) |
14 | 18 | |
15 | 19 | AM_CFLAGS = \ |
16 | 20 | -I$(top_srcdir)/dbus \ |
17 | 21 | -I$(top_builddir)/dbus \ |
18 | 22 | -DLOCALEDIR=\""$(datadir)/locale"\" \ |
23 | -DREALMD_EXECUTABLE=\""$(privatedir)/realmd"\" \ | |
19 | 24 | $(GLIB_CFLAGS) \ |
20 | 25 | $(KRB5_CFLAGS) \ |
21 | 26 | $(NULL) |
65 | 65 | am__objects_1 = |
66 | 66 | am_realm_OBJECTS = realm.$(OBJEXT) realm-client.$(OBJEXT) \ |
67 | 67 | 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) | |
69 | 71 | realm_OBJECTS = $(am_realm_OBJECTS) |
70 | 72 | realm_LDADD = $(LDADD) |
71 | 73 | am__DEPENDENCIES_1 = |
290 | 292 | realm-join.c \ |
291 | 293 | realm-leave.c \ |
292 | 294 | realm-logins.c \ |
295 | eggdbusobjectmanagerclient.c \ | |
296 | eggdbusobjectmanagerclient.h \ | |
297 | eggdbusobjectproxy.c \ | |
298 | eggdbusobjectproxy.h \ | |
293 | 299 | $(NULL) |
294 | 300 | |
295 | 301 | AM_CFLAGS = \ |
296 | 302 | -I$(top_srcdir)/dbus \ |
297 | 303 | -I$(top_builddir)/dbus \ |
298 | 304 | -DLOCALEDIR=\""$(datadir)/locale"\" \ |
305 | -DREALMD_EXECUTABLE=\""$(privatedir)/realmd"\" \ | |
299 | 306 | $(GLIB_CFLAGS) \ |
300 | 307 | $(KRB5_CFLAGS) \ |
301 | 308 | $(NULL) |
391 | 398 | distclean-compile: |
392 | 399 | -rm -f *.tab.c |
393 | 400 | |
401 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eggdbusobjectmanagerclient.Po@am__quote@ | |
402 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eggdbusobjectproxy.Po@am__quote@ | |
394 | 403 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realm-client.Po@am__quote@ |
395 | 404 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realm-discover.Po@am__quote@ |
396 | 405 | @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 */ |
17 | 17 | #include "realm-client.h" |
18 | 18 | #include "realm-dbus-constants.h" |
19 | 19 | |
20 | #include "eggdbusobjectproxy.h" | |
21 | #include "eggdbusobjectmanagerclient.h" | |
22 | ||
20 | 23 | #include <glib/gi18n.h> |
24 | ||
25 | #include <sys/socket.h> | |
21 | 26 | |
22 | 27 | #include <errno.h> |
23 | 28 | #include <string.h> |
24 | 29 | |
25 | 30 | struct _RealmClient { |
26 | GDBusObjectManagerClient parent; | |
31 | EggDBusObjectManagerClient parent; | |
27 | 32 | RealmDbusProvider *provider; |
33 | GPid peer_pid; | |
28 | 34 | }; |
29 | 35 | |
30 | 36 | struct _RealmClientClass { |
31 | GDBusObjectManagerClientClass parent; | |
37 | EggDBusObjectManagerClientClass parent; | |
32 | 38 | }; |
33 | 39 | |
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); | |
35 | 41 | |
36 | 42 | typedef struct { |
37 | 43 | GAsyncResult *result; |
59 | 65 | { |
60 | 66 | RealmClient *self = REALM_CLIENT (obj); |
61 | 67 | |
68 | if (self->peer_pid) { | |
69 | kill (self->peer_pid, SIGTERM); | |
70 | g_spawn_close_pid (self->peer_pid); | |
71 | } | |
72 | ||
62 | 73 | if (self->provider) |
63 | 74 | g_object_unref (self->provider); |
64 | 75 | |
74 | 85 | } |
75 | 86 | |
76 | 87 | static GType |
77 | realm_object_client_get_proxy_type (GDBusObjectManagerClient *manager, | |
88 | realm_object_client_get_proxy_type (EggDBusObjectManagerClient *manager, | |
78 | 89 | const gchar *object_path, |
79 | 90 | const gchar *interface_name, |
80 | 91 | gpointer user_data) |
84 | 95 | GType ret; |
85 | 96 | |
86 | 97 | if (interface_name == NULL) |
87 | return G_TYPE_DBUS_OBJECT_PROXY; | |
98 | return EGG_TYPE_DBUS_OBJECT_PROXY; | |
88 | 99 | |
89 | 100 | if (g_once_init_enter (&once_init_value)) { |
90 | 101 | lookup_hash = g_hash_table_new (g_str_hash, g_str_equal); |
98 | 109 | |
99 | 110 | ret = GPOINTER_TO_SIZE (g_hash_table_lookup (lookup_hash, interface_name)); |
100 | 111 | if (ret == 0) |
101 | ret = G_TYPE_DBUS_OBJECT_PROXY; | |
112 | ret = EGG_TYPE_DBUS_OBJECT_PROXY; | |
102 | 113 | return ret; |
103 | 114 | } |
104 | 115 | |
118 | 129 | g_printerr ("%s", data); |
119 | 130 | } |
120 | 131 | |
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 | { | |
125 | 137 | RealmDbusProvider *provider; |
126 | 138 | GError *error = NULL; |
127 | RealmClient *client = NULL; | |
128 | 139 | 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); | |
144 | 154 | } |
145 | 155 | |
146 | 156 | provider = realm_dbus_provider_proxy_new_sync (connection, |
147 | 157 | G_DBUS_PROXY_FLAGS_NONE, |
148 | REALM_DBUS_BUS_NAME, | |
158 | bus_name, | |
149 | 159 | REALM_DBUS_SERVICE_PATH, |
150 | 160 | NULL, &error); |
151 | 161 | if (error != NULL) { |
152 | 162 | realm_handle_error (error, _("Couldn't connect to realm service")); |
153 | g_object_unref (connection); | |
154 | 163 | return NULL; |
155 | 164 | } |
156 | 165 | |
157 | 166 | ret = g_initable_new (REALM_TYPE_CLIENT, NULL, &error, |
158 | 167 | "flags", G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, |
159 | "name", REALM_DBUS_BUS_NAME, | |
168 | "name", bus_name, | |
160 | 169 | "connection", connection, |
161 | 170 | "object-path", REALM_DBUS_SERVICE_PATH, |
162 | 171 | "get-proxy-type-func", realm_object_client_get_proxy_type, |
169 | 178 | } |
170 | 179 | |
171 | 180 | g_object_unref (provider); |
172 | g_object_unref (connection); | |
173 | 181 | |
174 | 182 | if (error != NULL) { |
175 | 183 | realm_handle_error (error, _("Couldn't load the realm service")); |
176 | return NULL; | |
177 | } | |
184 | g_object_unref (client); | |
185 | return NULL; | |
186 | } | |
187 | ||
178 | 188 | |
179 | 189 | 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); | |
180 | 294 | } |
181 | 295 | |
182 | 296 | RealmDbusProvider * |
32 | 32 | |
33 | 33 | GType realm_client_get_type (void) G_GNUC_CONST; |
34 | 34 | |
35 | RealmClient * realm_client_new (gboolean verbose); | |
35 | RealmClient * realm_client_new (gboolean verbose, | |
36 | const gchar *prefix); | |
36 | 37 | |
37 | 38 | RealmDbusProvider * realm_client_get_provider (RealmClient *self); |
38 | 39 |
52 | 52 | gchar *string; |
53 | 53 | const gchar *policy; |
54 | 54 | GVariantIter iter; |
55 | const gchar *const *packages; | |
56 | gint i; | |
55 | 57 | |
56 | 58 | g_return_if_fail (REALM_DBUS_IS_REALM (realm)); |
57 | 59 | 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 | } | |
77 | 60 | |
78 | 61 | kerberos = realm_client_to_kerberos (client, realm); |
79 | 62 | if (kerberos) { |
82 | 65 | } else { |
83 | 66 | g_print (" type: unknown\n"); |
84 | 67 | } |
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]); | |
85 | 91 | |
86 | 92 | if (is_configured) { |
87 | 93 | string = g_strjoinv (", ", (gchar **)realm_dbus_realm_get_login_formats (realm)); |
145 | 151 | } |
146 | 152 | |
147 | 153 | int |
148 | realm_discover (int argc, | |
154 | realm_discover (RealmClient *client, | |
155 | int argc, | |
149 | 156 | char *argv[]) |
150 | 157 | { |
151 | RealmClient *client; | |
152 | 158 | GOptionContext *context; |
153 | gboolean arg_verbose = FALSE; | |
154 | 159 | gchar *arg_client_software = NULL; |
155 | 160 | gchar *arg_server_software = NULL; |
156 | 161 | GError *error = NULL; |
161 | 166 | |
162 | 167 | GOptionEntry option_entries[] = { |
163 | 168 | { "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 }, | |
165 | 169 | { "client-software", 0, 0, G_OPTION_ARG_STRING, &arg_client_software, N_("Use specific client software"), NULL }, |
166 | 170 | { "server-software", 0, 0, G_OPTION_ARG_STRING, &arg_server_software, N_("Use specific server software"), NULL }, |
167 | 171 | { NULL, } |
172 | 176 | context = g_option_context_new ("realm-or-domain"); |
173 | 177 | g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); |
174 | 178 | g_option_context_add_main_entries (context, option_entries, NULL); |
179 | g_option_context_add_main_entries (context, realm_global_options, NULL); | |
175 | 180 | |
176 | 181 | if (!g_option_context_parse (context, &argc, &argv, &error)) { |
177 | 182 | g_printerr ("%s: %s\n", g_get_prgname (), error->message); |
178 | 183 | g_error_free (error); |
179 | 184 | ret = 2; |
180 | } | |
181 | ||
182 | client = realm_client_new (arg_verbose); | |
183 | if (!client) { | |
184 | ret = 1; | |
185 | 185 | |
186 | 186 | /* The default realm? */ |
187 | 187 | } else if (argc == 1) { |
188 | 188 | ret = perform_discover (client, NULL, arg_all, |
189 | 189 | arg_server_software, arg_client_software); |
190 | g_object_unref (client); | |
191 | 190 | |
192 | 191 | /* Specific realms */ |
193 | 192 | } else { |
197 | 196 | if (ret != 0) |
198 | 197 | result = ret; |
199 | 198 | } |
200 | g_object_unref (client); | |
201 | 199 | } |
202 | 200 | |
203 | 201 | g_free (arg_server_software); |
208 | 206 | |
209 | 207 | static int |
210 | 208 | perform_list (RealmClient *client, |
211 | gboolean all, | |
212 | gboolean verbose) | |
209 | gboolean all) | |
213 | 210 | { |
214 | 211 | RealmDbusProvider *provider; |
215 | 212 | const gchar *const *realms; |
231 | 228 | g_object_unref (realm); |
232 | 229 | } |
233 | 230 | |
234 | if (verbose && !printed) { | |
231 | if (realm_verbose && !printed) { | |
235 | 232 | if (all) |
236 | 233 | g_printerr ("No known realms\n"); |
237 | 234 | else |
242 | 239 | } |
243 | 240 | |
244 | 241 | int |
245 | realm_list (int argc, | |
242 | realm_list (RealmClient *client, | |
243 | int argc, | |
246 | 244 | char *argv[]) |
247 | 245 | { |
248 | RealmClient *client; | |
249 | 246 | GOptionContext *context; |
250 | gboolean arg_verbose = FALSE; | |
251 | 247 | gboolean arg_all = FALSE; |
252 | 248 | GError *error = NULL; |
253 | 249 | gint ret = 0; |
254 | 250 | |
255 | 251 | GOptionEntry option_entries[] = { |
256 | 252 | { "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 }, | |
258 | 253 | { NULL, } |
259 | 254 | }; |
260 | 255 | |
261 | 256 | context = g_option_context_new ("realm"); |
262 | 257 | g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); |
263 | 258 | g_option_context_add_main_entries (context, option_entries, NULL); |
259 | g_option_context_add_main_entries (context, realm_global_options, NULL); | |
264 | 260 | |
265 | 261 | if (!g_option_context_parse (context, &argc, &argv, &error)) { |
266 | 262 | g_printerr ("%s: %s\n", g_get_prgname (), error->message); |
272 | 268 | ret = 2; |
273 | 269 | |
274 | 270 | } 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); | |
282 | 272 | } |
283 | 273 | |
284 | 274 | g_option_context_free (context); |
212 | 212 | } |
213 | 213 | |
214 | 214 | int |
215 | realm_join (int argc, | |
215 | realm_join (RealmClient *client, | |
216 | int argc, | |
216 | 217 | char *argv[]) |
217 | 218 | { |
218 | 219 | GOptionContext *context; |
219 | RealmClient *client; | |
220 | 220 | gchar *arg_user = NULL; |
221 | gboolean arg_verbose = FALSE; | |
222 | 221 | GError *error = NULL; |
223 | 222 | const gchar *realm_name; |
224 | 223 | gchar *arg_computer_ou = NULL; |
231 | 230 | GOptionEntry option_entries[] = { |
232 | 231 | { "user", 'U', 0, G_OPTION_ARG_STRING, &arg_user, |
233 | 232 | N_("User name to use for enrollment"), NULL }, |
234 | { "verbose", 'v', 0, G_OPTION_ARG_NONE, &arg_verbose, | |
235 | N_("Verbose output"), NULL }, | |
236 | 233 | { "computer-ou", 0, 0, G_OPTION_ARG_STRING, &arg_computer_ou, |
237 | 234 | N_("Computer OU DN to join"), NULL }, |
238 | 235 | { "client-software", 0, 0, G_OPTION_ARG_STRING, &arg_client_software, |
249 | 246 | context = g_option_context_new ("realm"); |
250 | 247 | g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); |
251 | 248 | g_option_context_add_main_entries (context, option_entries, NULL); |
249 | g_option_context_add_main_entries (context, realm_global_options, NULL); | |
252 | 250 | |
253 | 251 | if (!g_option_context_parse (context, &argc, &argv, &error)) { |
254 | 252 | g_printerr ("%s: %s\n", g_get_prgname (), error->message); |
260 | 258 | ret = 2; |
261 | 259 | |
262 | 260 | } 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); | |
274 | 266 | } |
275 | 267 | |
276 | 268 | g_free (arg_user); |
249 | 249 | } |
250 | 250 | |
251 | 251 | 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 | { | |
256 | 256 | GOptionContext *context; |
257 | 257 | gchar *arg_user = NULL; |
258 | gboolean arg_verbose = FALSE; | |
259 | 258 | gboolean arg_remove = FALSE; |
260 | 259 | gchar *arg_client_software = NULL; |
261 | 260 | gchar *arg_server_software = NULL; |
270 | 269 | { "server-software", 0, 0, G_OPTION_ARG_STRING, &arg_server_software, |
271 | 270 | N_("Use specific server software"), NULL }, |
272 | 271 | { "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 }, | |
274 | 272 | { NULL, } |
275 | 273 | }; |
276 | 274 | |
277 | 275 | context = g_option_context_new ("realm"); |
278 | 276 | g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); |
279 | 277 | g_option_context_add_main_entries (context, option_entries, NULL); |
278 | g_option_context_add_main_entries (context, realm_global_options, NULL); | |
280 | 279 | |
281 | 280 | if (!g_option_context_parse (context, &argc, &argv, &error)) { |
282 | 281 | g_printerr ("%s: %s\n", g_get_prgname (), error->message); |
284 | 283 | ret = 2; |
285 | 284 | |
286 | 285 | } 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); | |
296 | 289 | } |
297 | 290 | |
298 | 291 | g_free (arg_user); |
181 | 181 | } |
182 | 182 | |
183 | 183 | static int |
184 | realm_permit_or_deny (gboolean permit, | |
184 | realm_permit_or_deny (RealmClient *client, | |
185 | gboolean permit, | |
185 | 186 | int argc, |
186 | 187 | char *argv[]) |
187 | 188 | { |
188 | RealmClient *client; | |
189 | 189 | GOptionContext *context; |
190 | 190 | gboolean arg_all = FALSE; |
191 | gboolean arg_verbose = FALSE; | |
192 | 191 | gchar *realm_name = NULL; |
193 | 192 | GError *error = NULL; |
194 | 193 | gint ret = 0; |
197 | 196 | { "all", 'a', 0, G_OPTION_ARG_NONE, &arg_all, |
198 | 197 | permit ? N_("Permit any domain user login") : N_("Deny any domain user login"), NULL }, |
199 | 198 | { "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 }, | |
201 | 199 | { NULL, } |
202 | 200 | }; |
203 | 201 | |
204 | 202 | context = g_option_context_new ("realm"); |
205 | 203 | g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); |
206 | 204 | g_option_context_add_main_entries (context, option_entries, NULL); |
205 | g_option_context_add_main_entries (context, realm_global_options, NULL); | |
207 | 206 | |
208 | 207 | if (!g_option_context_parse (context, &argc, &argv, &error)) { |
209 | 208 | g_printerr ("%s: %s\n", g_get_prgname (), error->message); |
218 | 217 | g_printerr ("%s: %s\n", _("No users should be specified with -a or --all"), g_get_prgname ()); |
219 | 218 | ret = 2; |
220 | 219 | } 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); | |
228 | 221 | } |
229 | 222 | } else if (argc < 2) { |
230 | 223 | g_printerr ("%s: %s\n", g_get_prgname (), |
232 | 225 | ret = 2; |
233 | 226 | |
234 | 227 | } 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); | |
244 | 231 | } |
245 | 232 | |
246 | 233 | g_free (realm_name); |
249 | 236 | } |
250 | 237 | |
251 | 238 | int |
252 | realm_permit (int argc, | |
239 | realm_permit (RealmClient *client, | |
240 | int argc, | |
253 | 241 | char *argv[]) |
254 | 242 | { |
255 | return realm_permit_or_deny (TRUE, argc, argv); | |
243 | return realm_permit_or_deny (client, TRUE, argc, argv); | |
256 | 244 | } |
257 | 245 | |
258 | 246 | int |
259 | realm_deny (int argc, | |
247 | realm_deny (RealmClient *client, | |
248 | int argc, | |
260 | 249 | char *argv[]) |
261 | 250 | { |
262 | return realm_permit_or_deny (FALSE, argc, argv); | |
263 | } | |
251 | return realm_permit_or_deny (client, FALSE, argc, argv); | |
252 | } |
27 | 27 | #include <fcntl.h> |
28 | 28 | #include <locale.h> |
29 | 29 | |
30 | static gchar *arg_install = NULL; | |
31 | gboolean realm_verbose = FALSE; | |
32 | ||
30 | 33 | struct { |
31 | 34 | const char *name; |
32 | int (* function) (int argc, char *argv[]); | |
35 | int (* function) (RealmClient *client, int argc, char *argv[]); | |
33 | 36 | const char *usage; |
34 | 37 | const char *description; |
35 | 38 | } realm_commands[] = { |
115 | 118 | |
116 | 119 | va_end (va); |
117 | 120 | |
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 | ||
118 | 126 | options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), (GVariant * const*)opts->pdata, opts->len); |
119 | 127 | g_ptr_array_free (opts, TRUE); |
120 | 128 | |
282 | 290 | return code; |
283 | 291 | } |
284 | 292 | |
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 | ||
285 | 299 | int |
286 | 300 | main (int argc, |
287 | 301 | char *argv[]) |
288 | 302 | { |
289 | 303 | const gchar *command = NULL; |
304 | GOptionContext *context; | |
305 | RealmClient *client; | |
306 | GError *error = NULL; | |
307 | gint ret; | |
290 | 308 | gint i; |
291 | 309 | |
292 | 310 | setlocale (LC_ALL, ""); |
298 | 316 | #endif |
299 | 317 | |
300 | 318 | 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); | |
301 | 333 | |
302 | 334 | /* Find/remove the first non-flag argument: the command */ |
303 | 335 | for (i = 1; i < argc; i++) { |
314 | 346 | if (command == NULL) |
315 | 347 | return usage (2); |
316 | 348 | |
349 | ret = 2; | |
317 | 350 | 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 | } |
24 | 24 | |
25 | 25 | #define realm_operation_id "realm-enroll" |
26 | 26 | |
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, | |
28 | 33 | char *argv[]); |
29 | 34 | |
30 | int realm_leave (int argc, | |
35 | int realm_leave (RealmClient *client, | |
36 | int argc, | |
31 | 37 | char *argv[]); |
32 | 38 | |
33 | int realm_discover (int argc, | |
39 | int realm_discover (RealmClient *client, | |
40 | int argc, | |
34 | 41 | char *argv[]); |
35 | 42 | |
36 | int realm_list (int argc, | |
43 | int realm_list (RealmClient *client, | |
44 | int argc, | |
37 | 45 | char *argv[]); |
38 | 46 | |
39 | int realm_permit (int argc, | |
47 | int realm_permit (RealmClient *client, | |
48 | int argc, | |
40 | 49 | char *argv[]); |
41 | 50 | |
42 | int realm_deny (int argc, | |
51 | int realm_deny (RealmClient *client, | |
52 | int argc, | |
43 | 53 | char *argv[]); |
44 | 54 | |
45 | 55 | GVariant * realm_build_options (const gchar *first, |