15 #include <sys/capability.h>
18 #include "kdbus-util.h"
19 #include "kdbus-enum.h"
21 #include "kdbus-util.h"
22 #include "kdbus-enum.h"
23 #include "kdbus-test.h"
25 int kdbus_test_monitor(struct kdbus_test_env *env)
27 struct kdbus_conn *monitor, *conn;
28 unsigned int cookie = 0xdeadbeef;
29 struct kdbus_msg *msg;
33 conn = kdbus_hello(env->buspath, 0, NULL, 0);
36 /* add matches to make sure the monitor do not trigger an item add or
37 * remove on connect and disconnect, respectively.
39 ret = kdbus_add_match_id(conn, 0x1, KDBUS_ITEM_ID_ADD,
41 ASSERT_RETURN(ret == 0);
43 ret = kdbus_add_match_id(conn, 0x2, KDBUS_ITEM_ID_REMOVE,
45 ASSERT_RETURN(ret == 0);
47 /* register a monitor */
48 monitor = kdbus_hello(env->buspath, KDBUS_HELLO_MONITOR, NULL, 0);
49 ASSERT_RETURN(monitor);
51 /* make sure we did not receive a monitor connect notification */
52 ret = kdbus_msg_recv(conn, &msg, &offset);
53 ASSERT_RETURN(ret == -EAGAIN);
55 /* check that a monitor cannot acquire a name */
56 ret = kdbus_name_acquire(monitor, "foo.bar.baz", NULL);
57 ASSERT_RETURN(ret == -EOPNOTSUPP);
59 ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0, conn->id,
61 ASSERT_RETURN(ret == 0);
63 /* the recipient should have gotten the message */
64 ret = kdbus_msg_recv(conn, &msg, &offset);
65 ASSERT_RETURN(ret == 0);
66 ASSERT_RETURN(msg->cookie == cookie);
68 kdbus_free(conn, offset);
70 /* and so should the monitor */
71 ret = kdbus_msg_recv(monitor, &msg, &offset);
72 ASSERT_RETURN(ret == 0);
73 ASSERT_RETURN(msg->cookie == cookie);
76 kdbus_free(monitor, offset);
78 /* Installing matches for monitors must fais must fail */
79 ret = kdbus_add_match_empty(monitor);
80 ASSERT_RETURN(ret == -EOPNOTSUPP);
83 ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
84 KDBUS_DST_ID_BROADCAST, 0, NULL);
85 ASSERT_RETURN(ret == 0);
87 /* The monitor should get the message. */
88 ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset);
89 ASSERT_RETURN(ret == 0);
90 ASSERT_RETURN(msg->cookie == cookie);
93 kdbus_free(monitor, offset);
96 * Since we are the only monitor, update the attach flags
97 * and tell we are not interessted in attach flags recv
100 ret = kdbus_conn_update_attach_flags(monitor,
103 ASSERT_RETURN(ret == 0);
106 ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
107 KDBUS_DST_ID_BROADCAST, 0, NULL);
108 ASSERT_RETURN(ret == 0);
110 ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset);
111 ASSERT_RETURN(ret == 0);
112 ASSERT_RETURN(msg->cookie == cookie);
114 ret = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP);
115 ASSERT_RETURN(ret == 0);
118 kdbus_free(monitor, offset);
121 * Now we are interested in KDBUS_ITEM_TIMESTAMP and
124 ret = kdbus_conn_update_attach_flags(monitor,
126 KDBUS_ATTACH_TIMESTAMP |
128 ASSERT_RETURN(ret == 0);
131 ret = kdbus_msg_send(env->conn, NULL, cookie, 0, 0, 0,
132 KDBUS_DST_ID_BROADCAST, 0, NULL);
133 ASSERT_RETURN(ret == 0);
135 ret = kdbus_msg_recv_poll(monitor, 100, &msg, &offset);
136 ASSERT_RETURN(ret == 0);
137 ASSERT_RETURN(msg->cookie == cookie);
139 ret = kdbus_item_in_message(msg, KDBUS_ITEM_TIMESTAMP);
140 ASSERT_RETURN(ret == 1);
142 ret = kdbus_item_in_message(msg, KDBUS_ITEM_CREDS);
143 ASSERT_RETURN(ret == 1);
145 /* the KDBUS_ITEM_PID_COMM was not requested */
146 ret = kdbus_item_in_message(msg, KDBUS_ITEM_PID_COMM);
147 ASSERT_RETURN(ret == 0);
150 kdbus_free(monitor, offset);
152 kdbus_conn_free(monitor);
153 /* make sure we did not receive a monitor disconnect notification */
154 ret = kdbus_msg_recv(conn, &msg, &offset);
155 ASSERT_RETURN(ret == -EAGAIN);
157 kdbus_conn_free(conn);
159 /* Make sure that monitor as unprivileged is not allowed */
160 ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1);
161 ASSERT_RETURN(ret >= 0);
163 if (ret && all_uids_gids_are_mapped()) {
164 ret = RUN_UNPRIVILEGED(UNPRIV_UID, UNPRIV_UID, ({
165 monitor = kdbus_hello(env->buspath,
168 ASSERT_EXIT(!monitor && errno == EPERM);
173 ASSERT_RETURN(ret == 0);