Line data Source code
1 : /*
2 : SSSD
3 :
4 : Data Provider Helpers
5 :
6 : Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : /* Needed for res_init() */
23 : #include <netinet/in.h>
24 : #include <arpa/nameser.h>
25 : #include <resolv.h>
26 :
27 : #include "util/util.h"
28 : #include "confdb/confdb.h"
29 : #include "sbus/sssd_dbus.h"
30 : #include "sbus/sbus_client.h"
31 : #include "monitor/monitor_interfaces.h"
32 :
33 0 : int monitor_get_sbus_address(TALLOC_CTX *mem_ctx, char **address)
34 : {
35 : char *default_address;
36 :
37 0 : *address = NULL;
38 0 : default_address = talloc_asprintf(mem_ctx, "unix:path=%s/%s",
39 : PIPE_PATH, SSSD_SERVICE_PIPE);
40 0 : if (default_address == NULL) {
41 0 : return ENOMEM;
42 : }
43 :
44 0 : *address = default_address;
45 0 : return EOK;
46 : }
47 :
48 0 : static void id_callback(DBusPendingCall *pending, void *ptr)
49 : {
50 : DBusMessage *reply;
51 : DBusError dbus_error;
52 : dbus_bool_t ret;
53 : dbus_uint16_t mon_ver;
54 : int type;
55 :
56 0 : dbus_error_init(&dbus_error);
57 :
58 0 : reply = dbus_pending_call_steal_reply(pending);
59 0 : if (!reply) {
60 : /* reply should never be null. This function shouldn't be called
61 : * until reply is valid or timeout has occurred. If reply is NULL
62 : * here, something is seriously wrong and we should bail out.
63 : */
64 0 : DEBUG(SSSDBG_FATAL_FAILURE,
65 : "Severe error. A reply callback was called but no"
66 : " reply was received and no timeout occurred\n");
67 :
68 : /* FIXME: Destroy this connection ? */
69 0 : goto done;
70 : }
71 :
72 0 : type = dbus_message_get_type(reply);
73 0 : switch (type) {
74 : case DBUS_MESSAGE_TYPE_METHOD_RETURN:
75 0 : ret = dbus_message_get_args(reply, &dbus_error,
76 : DBUS_TYPE_UINT16, &mon_ver,
77 : DBUS_TYPE_INVALID);
78 0 : if (!ret) {
79 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse message\n");
80 0 : if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
81 : /* FIXME: Destroy this connection ? */
82 0 : goto done;
83 : }
84 :
85 0 : DEBUG(SSSDBG_CONF_SETTINGS,
86 : "Got id ack and version (%d) from Monitor\n", mon_ver);
87 :
88 0 : break;
89 :
90 : case DBUS_MESSAGE_TYPE_ERROR:
91 0 : DEBUG(SSSDBG_FATAL_FAILURE,"The Monitor returned an error [%s]\n",
92 : dbus_message_get_error_name(reply));
93 : /* Falling through to default intentionally*/
94 : default:
95 : /*
96 : * Timeout or other error occurred or something
97 : * unexpected happened.
98 : * It doesn't matter which, because either way we
99 : * know that this connection isn't trustworthy.
100 : * We'll destroy it now.
101 : */
102 :
103 : /* FIXME: Destroy this connection ? */
104 0 : break;
105 : }
106 :
107 : done:
108 0 : dbus_pending_call_unref(pending);
109 0 : dbus_message_unref(reply);
110 0 : }
111 :
112 0 : int monitor_common_send_id(struct sbus_connection *conn,
113 : const char *name, uint16_t version)
114 : {
115 : DBusMessage *msg;
116 : dbus_bool_t ret;
117 : int retval;
118 :
119 : /* create the message */
120 0 : msg = dbus_message_new_method_call(NULL,
121 : MON_SRV_PATH,
122 : MON_SRV_IFACE,
123 : MON_SRV_IFACE_REGISTERSERVICE);
124 0 : if (msg == NULL) {
125 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?!\n");
126 0 : return ENOMEM;
127 : }
128 :
129 0 : DEBUG(SSSDBG_CONF_SETTINGS, "Sending ID: (%s,%d)\n", name, version);
130 :
131 0 : ret = dbus_message_append_args(msg,
132 : DBUS_TYPE_STRING, &name,
133 : DBUS_TYPE_UINT16, &version,
134 : DBUS_TYPE_INVALID);
135 0 : if (!ret) {
136 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n");
137 0 : return EIO;
138 : }
139 :
140 0 : retval = sbus_conn_send(conn, msg, 3000,
141 : id_callback,
142 : NULL, NULL);
143 0 : dbus_message_unref(msg);
144 0 : return retval;
145 : }
146 :
147 0 : int monitor_common_pong(struct sbus_request *dbus_req, void *data)
148 : {
149 0 : return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID);
150 : }
151 :
152 0 : int monitor_common_res_init(struct sbus_request *dbus_req, void *data)
153 : {
154 : int ret;
155 :
156 0 : ret = res_init();
157 0 : if(ret != 0) {
158 0 : return EIO;
159 : }
160 :
161 : /* Send an empty reply to acknowledge receipt */
162 0 : return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID);
163 : }
164 :
165 0 : errno_t sss_monitor_init(TALLOC_CTX *mem_ctx,
166 : struct tevent_context *ev,
167 : struct mon_cli_iface *mon_iface,
168 : const char *svc_name,
169 : uint16_t svc_version,
170 : void *pvt,
171 : struct sbus_connection **mon_conn)
172 : {
173 : errno_t ret;
174 : char *sbus_address;
175 : struct sbus_connection *conn;
176 :
177 : /* Set up SBUS connection to the monitor */
178 0 : ret = monitor_get_sbus_address(NULL, &sbus_address);
179 0 : if (ret != EOK) {
180 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Could not locate monitor address.\n");
181 0 : return ret;
182 : }
183 :
184 0 : ret = sbus_client_init(mem_ctx, ev, sbus_address, &conn);
185 0 : if (ret != EOK) {
186 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Failed to connect to monitor services.\n");
187 0 : talloc_free(sbus_address);
188 0 : return ret;
189 : }
190 0 : talloc_free(sbus_address);
191 :
192 0 : ret = sbus_conn_register_iface(conn, &mon_iface->vtable, MONITOR_PATH, pvt);
193 0 : if (ret != EOK) {
194 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Failed to export monitor client.\n");
195 0 : return ret;
196 : }
197 :
198 : /* Identify ourselves to the monitor */
199 0 : ret = monitor_common_send_id(conn, svc_name, svc_version);
200 0 : if (ret != EOK) {
201 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Failed to identify to the monitor!\n");
202 0 : return ret;
203 : }
204 :
205 0 : *mon_conn = conn;
206 :
207 0 : return EOK;
208 : }
|