]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus-socket.c
move _cleanup_ attribute in front of the type
[thirdparty/systemd.git] / src / core / dbus-socket.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23
24 #include "dbus-unit.h"
25 #include "dbus-socket.h"
26 #include "dbus-execute.h"
27 #include "dbus-kill.h"
28 #include "dbus-common.h"
29 #include "selinux-access.h"
30
31 #define BUS_SOCKET_INTERFACE \
32 " <interface name=\"org.freedesktop.systemd1.Socket\">\n" \
33 " <property name=\"BindIPv6Only\" type=\"b\" access=\"read\"/>\n" \
34 " <property name=\"Backlog\" type=\"u\" access=\"read\"/>\n" \
35 " <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
36 BUS_EXEC_COMMAND_INTERFACE("ExecStartPre") \
37 BUS_EXEC_COMMAND_INTERFACE("ExecStartPost") \
38 BUS_EXEC_COMMAND_INTERFACE("ExecStopPre") \
39 BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \
40 BUS_EXEC_CONTEXT_INTERFACE \
41 BUS_KILL_CONTEXT_INTERFACE \
42 BUS_UNIT_CGROUP_INTERFACE \
43 " <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
44 " <property name=\"BindToDevice\" type=\"s\" access=\"read\"/>\n" \
45 " <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
46 " <property name=\"SocketMode\" type=\"u\" access=\"read\"/>\n" \
47 " <property name=\"Accept\" type=\"b\" access=\"read\"/>\n" \
48 " <property name=\"KeepAlive\" type=\"b\" access=\"read\"/>\n" \
49 " <property name=\"Priority\" type=\"i\" access=\"read\"/>\n" \
50 " <property name=\"ReceiveBuffer\" type=\"t\" access=\"read\"/>\n" \
51 " <property name=\"SendBuffer\" type=\"t\" access=\"read\"/>\n" \
52 " <property name=\"IPTOS\" type=\"i\" access=\"read\"/>\n" \
53 " <property name=\"IPTTL\" type=\"i\" access=\"read\"/>\n" \
54 " <property name=\"PipeSize\" type=\"t\" access=\"read\"/>\n" \
55 " <property name=\"FreeBind\" type=\"b\" access=\"read\"/>\n" \
56 " <property name=\"Transparent\" type=\"b\" access=\"read\"/>\n" \
57 " <property name=\"Broadcast\" type=\"b\" access=\"read\"/>\n" \
58 " <property name=\"PassCredentials\" type=\"b\" access=\"read\"/>\n" \
59 " <property name=\"PassSecurity\" type=\"b\" access=\"read\"/>\n" \
60 " <property name=\"Mark\" type=\"i\" access=\"read\"/>\n" \
61 " <property name=\"MaxConnections\" type=\"u\" access=\"read\"/>\n" \
62 " <property name=\"NAccepted\" type=\"u\" access=\"read\"/>\n" \
63 " <property name=\"NConnections\" type=\"u\" access=\"read\"/>\n" \
64 " <property name=\"MessageQueueMaxMessages\" type=\"x\" access=\"read\"/>\n" \
65 " <property name=\"MessageQueueMessageSize\" type=\"x\" access=\"read\"/>\n" \
66 " <property name=\"Listen\" type=\"a(ss)\" access=\"read\"/>\n" \
67 " <property name=\"Result\" type=\"s\" access=\"read\"/>\n" \
68 " <property name=\"SmackLabel\" type=\"s\" access=\"read\"/>\n" \
69 " <property name=\"SmackLabelIPIn\" type=\"s\" access=\"read\"/>\n" \
70 " <property name=\"SmackLabelIPOut\" type=\"s\" access=\"read\"/>\n" \
71 " </interface>\n" \
72
73 #define INTROSPECTION \
74 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
75 "<node>\n" \
76 BUS_UNIT_INTERFACE \
77 BUS_SOCKET_INTERFACE \
78 BUS_PROPERTIES_INTERFACE \
79 BUS_PEER_INTERFACE \
80 BUS_INTROSPECTABLE_INTERFACE \
81 "</node>\n"
82
83 #define INTERFACES_LIST \
84 BUS_UNIT_INTERFACES_LIST \
85 "org.freedesktop.systemd1.Socket\0"
86
87 const char bus_socket_interface[] _introspect_("Socket") = BUS_SOCKET_INTERFACE;
88
89 const char bus_socket_invalidating_properties[] =
90 "ExecStartPre\0"
91 "ExecStartPost\0"
92 "ExecStopPre\0"
93 "ExecStopPost\0"
94 "ControlPID\0"
95 "NAccepted\0"
96 "NConnections\0"
97 "Result\0";
98
99 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
100 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_socket_result, socket_result, SocketResult);
101
102 static int bus_socket_append_listen(DBusMessageIter *i, const char *property, void *data) {
103
104 Socket *s = SOCKET(data);
105 SocketPort *p;
106 DBusMessageIter array, stru;
107
108 assert(data);
109 assert(property);
110 assert(s);
111
112 if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(ss)", &array))
113 return log_oom();
114
115 LIST_FOREACH(port, p, s->ports) {
116 const char *type = socket_port_type_to_string(p);
117 _cleanup_free_ char *address = NULL;
118 const char *a;
119
120 if (!dbus_message_iter_open_container(&array, DBUS_TYPE_STRUCT, NULL, &stru))
121 return log_oom();
122
123 if (!dbus_message_iter_append_basic(&stru, DBUS_TYPE_STRING, &type))
124 return log_oom();
125
126 switch (p->type) {
127 case SOCKET_SOCKET: {
128 int r;
129
130 r = socket_address_print(&p->address, &address);
131 if (r) {
132 log_error("socket_address_print failed: %s", strerror(-r));
133 return r;
134 }
135 a = address;
136 break;
137 }
138
139 case SOCKET_SPECIAL:
140 case SOCKET_MQUEUE:
141 case SOCKET_FIFO:
142 a = p->path;
143 break;
144
145 default:
146 a = type;
147 }
148
149 if (!dbus_message_iter_append_basic(&stru, DBUS_TYPE_STRING, &a))
150 return -ENOMEM;
151
152 if (!dbus_message_iter_close_container(&array, &stru))
153 return -ENOMEM;
154 }
155
156 if (!dbus_message_iter_close_container(i, &array))
157 return -ENOMEM;
158
159 return 0;
160 }
161
162 static const BusProperty bus_socket_properties[] = {
163 { "BindIPv6Only", bus_socket_append_bind_ipv6_only, "s", offsetof(Socket, bind_ipv6_only) },
164 { "Backlog", bus_property_append_unsigned, "u", offsetof(Socket, backlog) },
165 { "TimeoutUSec", bus_property_append_usec, "t", offsetof(Socket, timeout_usec) },
166 BUS_EXEC_COMMAND_PROPERTY("ExecStartPre", offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]), true ),
167 BUS_EXEC_COMMAND_PROPERTY("ExecStartPost", offsetof(Socket, exec_command[SOCKET_EXEC_START_POST]), true ),
168 BUS_EXEC_COMMAND_PROPERTY("ExecStopPre", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_PRE]), true ),
169 BUS_EXEC_COMMAND_PROPERTY("ExecStopPost", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_POST]), true ),
170 { "ControlPID", bus_property_append_pid, "u", offsetof(Socket, control_pid) },
171 { "BindToDevice", bus_property_append_string, "s", offsetof(Socket, bind_to_device), true },
172 { "DirectoryMode", bus_property_append_mode, "u", offsetof(Socket, directory_mode) },
173 { "SocketMode", bus_property_append_mode, "u", offsetof(Socket, socket_mode) },
174 { "Accept", bus_property_append_bool, "b", offsetof(Socket, accept) },
175 { "KeepAlive", bus_property_append_bool, "b", offsetof(Socket, keep_alive) },
176 { "Priority", bus_property_append_int, "i", offsetof(Socket, priority) },
177 { "ReceiveBuffer", bus_property_append_size, "t", offsetof(Socket, receive_buffer) },
178 { "SendBuffer", bus_property_append_size, "t", offsetof(Socket, send_buffer) },
179 { "IPTOS", bus_property_append_int, "i", offsetof(Socket, ip_tos) },
180 { "IPTTL", bus_property_append_int, "i", offsetof(Socket, ip_ttl) },
181 { "PipeSize", bus_property_append_size, "t", offsetof(Socket, pipe_size) },
182 { "FreeBind", bus_property_append_bool, "b", offsetof(Socket, free_bind) },
183 { "Transparent", bus_property_append_bool, "b", offsetof(Socket, transparent) },
184 { "Broadcast", bus_property_append_bool, "b", offsetof(Socket, broadcast) },
185 { "PassCredentials",bus_property_append_bool, "b", offsetof(Socket, pass_cred) },
186 { "PassSecurity", bus_property_append_bool, "b", offsetof(Socket, pass_sec) },
187 { "Listen", bus_socket_append_listen, "a(ss)", 0, },
188 { "Mark", bus_property_append_int, "i", offsetof(Socket, mark) },
189 { "MaxConnections", bus_property_append_unsigned, "u", offsetof(Socket, max_connections) },
190 { "NConnections", bus_property_append_unsigned, "u", offsetof(Socket, n_connections) },
191 { "NAccepted", bus_property_append_unsigned, "u", offsetof(Socket, n_accepted) },
192 { "MessageQueueMaxMessages", bus_property_append_long, "x", offsetof(Socket, mq_maxmsg) },
193 { "MessageQueueMessageSize", bus_property_append_long, "x", offsetof(Socket, mq_msgsize) },
194 { "Result", bus_socket_append_socket_result, "s", offsetof(Socket, result) },
195 { "SmackLabel", bus_property_append_string, "s", offsetof(Socket, smack), true },
196 { "SmackLabelIPIn", bus_property_append_string, "s", offsetof(Socket, smack_ip_in), true },
197 { "SmackLabelIPOut",bus_property_append_string, "s", offsetof(Socket, smack_ip_out), true },
198 { NULL, }
199 };
200
201 DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
202 Socket *s = SOCKET(u);
203 const BusBoundProperties bps[] = {
204 { "org.freedesktop.systemd1.Unit", bus_unit_properties, u },
205 { "org.freedesktop.systemd1.Socket", bus_socket_properties, s },
206 { "org.freedesktop.systemd1.Socket", bus_exec_context_properties, &s->exec_context },
207 { "org.freedesktop.systemd1.Socket", bus_kill_context_properties, &s->kill_context },
208 { "org.freedesktop.systemd1.Socket", bus_unit_properties, u },
209 { NULL, }
210 };
211
212 SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
213
214 return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps);
215 }