X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-api-dbus.c;h=2d03269f95ef4312df104f2f40a08f653481a593;hb=770ca7e254bba07bb7d1ade4fa95afed7a7f7693;hp=a9f50109c4387d9ac892ac5fa279f491081160c4;hpb=43d031e1833c5d373600cf44c05d760ade9a150d;p=src%2Fapp-framework-binder.git diff --git a/src/afb-api-dbus.c b/src/afb-api-dbus.c index a9f50109..2d03269f 100644 --- a/src/afb-api-dbus.c +++ b/src/afb-api-dbus.c @@ -19,6 +19,7 @@ #define NO_PLUGIN_VERBOSE_MACRO #include +#include #include #include #include @@ -26,15 +27,17 @@ #include #include -#include +#include #include "afb-common.h" #include "afb-session.h" #include "afb-msg-json.h" -#include "afb-apis.h" -#include "afb-api-so.h" +#include "afb-api.h" +#include "afb-apiset.h" +#include "afb-api-dbus.h" #include "afb-context.h" +#include "afb-cred.h" #include "afb-evt.h" #include "afb-xreq.h" #include "verbose.h" @@ -68,6 +71,7 @@ struct api_dbus struct sd_bus_slot *slot_call; struct afb_evt_listener *listener; /* listener for broadcasted events */ struct origin *origins; + struct afb_apiset *apiset; } server; }; }; @@ -109,7 +113,7 @@ static struct api_dbus *make_api_dbus_3(int system, const char *path, size_t pat goto error2; } api->api++; - if (!afb_apis_is_valid_api_name(api->api)) { + if (!afb_api_is_valid_name(api->api)) { errno = EINVAL; goto error2; } @@ -234,7 +238,7 @@ static struct dbus_memo *api_dbus_client_memo_make(struct api_dbus *api, struct memo = malloc(sizeof *memo); if (memo != NULL) { - afb_xreq_addref(xreq); + afb_xreq_unhooked_addref(xreq); memo->xreq = xreq; memo->msgid = 0; memo->api = api; @@ -258,7 +262,7 @@ static void api_dbus_client_memo_destroy(struct dbus_memo *memo) prv = &(*prv)->next; } - afb_xreq_unref(memo->xreq); + afb_xreq_unhooked_unref(memo->xreq); free(memo); } @@ -357,19 +361,6 @@ end: sd_bus_message_unref(msg); } -static int api_dbus_service_start(void *closure, int share_session, int onneed) -{ - struct api_dbus *api = closure; - - /* not an error when onneed */ - if (onneed != 0) - return 0; - - /* already started: it is an error */ - ERROR("The Dbus binding %s is not a startable service", api->name); - return -1; -} - /* receives broadcasted events */ static int api_dbus_client_on_broadcast_event(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { @@ -577,12 +568,11 @@ static int api_dbus_client_on_manage_event(sd_bus_message *m, void *userdata, sd } static struct afb_api_itf dbus_api_itf = { - .call = api_dbus_client_call, - .service_start = api_dbus_service_start + .call = api_dbus_client_call }; /* adds a afb-dbus-service client api */ -int afb_api_dbus_add_client(const char *path) +int afb_api_dbus_add_client(const char *path, struct afb_apiset *apiset) { int rc; struct api_dbus *api; @@ -620,7 +610,8 @@ int afb_api_dbus_add_client(const char *path) /* record it as an API */ afb_api.closure = api; afb_api.itf = &dbus_api_itf; - if (afb_apis_add(api->api, afb_api) < 0) + afb_api.noconcurrency = 0; + if (afb_apiset_add(apiset, api->api, afb_api) < 0) goto error2; return 0; @@ -663,10 +654,39 @@ struct origin /* count of references */ int refcount; + /* credentials of the origin */ + struct afb_cred *cred; + /* the origin */ char name[1]; }; +/* get the credentials for the message */ +static void init_origin_creds(struct origin *origin) +{ + int rc; + sd_bus_creds *c; + uid_t uid; + gid_t gid; + pid_t pid; + const char *context; + + rc = sd_bus_get_name_creds(origin->api->sdbus, origin->name, + SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT, + &c); + if (rc < 0) + origin->cred = NULL; + else { + afb_cred_unref(origin->cred); + sd_bus_creds_get_uid(c, &uid); + sd_bus_creds_get_gid(c, &gid); + sd_bus_creds_get_pid(c, &pid); + sd_bus_creds_get_selinux_context(c, &context); + origin->cred = afb_cred_create(uid, gid, pid, context); + sd_bus_creds_unref(c); + } +} + static struct origin *afb_api_dbus_server_origin_get(struct api_dbus *api, const char *sender) { struct origin *origin; @@ -689,6 +709,7 @@ static struct origin *afb_api_dbus_server_origin_get(struct api_dbus *api, const origin->api = api; origin->refcount = 1; strcpy(origin->name, sender); + init_origin_creds(origin); origin->next = api->server.origins; api->server.origins = origin; } @@ -704,6 +725,7 @@ static void afb_api_dbus_server_origin_unref(struct origin *origin) while(*prv != origin) prv = &(*prv)->next; *prv = origin->next; + afb_cred_unref(origin->cred); free(origin); } } @@ -724,7 +746,7 @@ static void afb_api_dbus_server_listener_free(struct listener *listener) free(listener); } -static struct listener *afb_api_dbus_server_listerner_get(struct api_dbus *api, const char *sender, struct afb_session *session) +static struct listener *afb_api_dbus_server_listener_get(struct api_dbus *api, const char *sender, struct afb_session *session) { int rc; struct listener *listener; @@ -776,9 +798,9 @@ struct dbus_req { }; /* decrement the reference count of the request and free/release it on falling to null */ -static void dbus_req_destroy(void *closure) +static void dbus_req_destroy(struct afb_xreq *xreq) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); afb_context_disconnect(&dreq->xreq.context); json_object_put(dreq->json); @@ -787,9 +809,9 @@ static void dbus_req_destroy(void *closure) } /* get the object of the request */ -static struct json_object *dbus_req_json(void *closure) +static struct json_object *dbus_req_json(struct afb_xreq *xreq) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); return dreq->json; } @@ -804,25 +826,25 @@ static void dbus_req_reply(struct dbus_req *dreq, uint8_t type, const char *firs ERROR("sending the reply failed"); } -static void dbus_req_success(void *closure, struct json_object *obj, const char *info) +static void dbus_req_success(struct afb_xreq *xreq, struct json_object *obj, const char *info) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); dbus_req_reply(dreq, RETOK, json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN), info); } -static void dbus_req_fail(void *closure, const char *status, const char *info) +static void dbus_req_fail(struct afb_xreq *xreq, const char *status, const char *info) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); dbus_req_reply(dreq, RETERR, status, info); } static void afb_api_dbus_server_event_send(struct origin *origin, char order, const char *event, int eventid, const char *data, uint64_t msgid); -static int dbus_req_subscribe(void *closure, struct afb_event event) +static int dbus_req_subscribe(struct afb_xreq *xreq, struct afb_event event) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); uint64_t msgid; int rc; @@ -832,9 +854,9 @@ static int dbus_req_subscribe(void *closure, struct afb_event event) return rc; } -static int dbus_req_unsubscribe(void *closure, struct afb_event event) +static int dbus_req_unsubscribe(struct afb_xreq *xreq, struct afb_event event) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); uint64_t msgid; int rc; @@ -944,12 +966,13 @@ static int api_dbus_server_on_object_called(sd_bus_message *message, void *userd } /* connect to the context */ + afb_xreq_init(&dreq->xreq, &afb_api_dbus_xreq_itf); if (afb_context_connect(&dreq->xreq.context, uuid, NULL) < 0) goto out_of_memory; session = dreq->xreq.context.session; /* get the listener */ - listener = afb_api_dbus_server_listerner_get(api, sd_bus_message_get_sender(message), session); + listener = afb_api_dbus_server_listener_get(api, sd_bus_message_get_sender(message), session); if (listener == NULL) goto out_of_memory; @@ -962,13 +985,9 @@ static int api_dbus_server_on_object_called(sd_bus_message *message, void *userd dreq->json = json_object_new_string(dreq->request); } dreq->listener = listener; - dreq->xreq.refcount = 1; - dreq->xreq.query = dreq; - dreq->xreq.queryitf = &afb_api_dbus_xreq_itf; dreq->xreq.api = api->api; dreq->xreq.verb = method; - afb_apis_call(&dreq->xreq); - afb_xreq_unref(&dreq->xreq); + afb_xreq_process(&dreq->xreq, api->server.apiset); return 1; out_of_memory: @@ -979,7 +998,7 @@ error: } /* create the service */ -int afb_api_dbus_add_server(const char *path) +int afb_api_dbus_add_server(const char *path, struct afb_apiset *apiset) { int rc; struct api_dbus *api; @@ -1007,6 +1026,7 @@ int afb_api_dbus_add_server(const char *path) INFO("afb service over dbus installed, name %s, path %s", api->name, api->path); api->server.listener = afb_evt_listener_create(&evt_broadcast_itf, api); + api->server.apiset = afb_apiset_addref(apiset); return 0; error3: sd_bus_release_name(api->sdbus, api->name);