1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of gum
6 * Copyright (C) 2013 Intel Corporation.
8 * Contact: Imran Zaman <imran.zaman@intel.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 #include "common/gum-defines.h"
27 #include "common/gum-log.h"
28 #include "common/gum-error.h"
29 #include "common/gum-group-types.h"
30 #include "common/dbus/gum-dbus-group-service-gen.h"
31 #include "common/dbus/gum-dbus-group-gen.h"
33 #include "gum-group.h"
34 #include "gum-group-service.h"
35 #include "gum-internals.h"
39 * @short_description: provides interface for managing group's data
40 * @include: gum/gum-group.h
42 * #GumGroup provides interface for adding, removing and updating group.
43 * Group's information can also be retrieved using this interface. Only
44 * privileged user can access the interface when system-bus is used for
45 * communication with the user management daemon.
47 * Following code snippet demonstrates how to create a new remote group object:
50 * GumGroup *group = NULL;
52 * group = gum_group_create_sync ();
56 * // destroy the object
57 * g_object_unref (group);
60 * Similarly, new group can be added as:
62 * GumGroup *group = NULL;
63 * gboolean rval = FALSE;
65 * group = gum_group_create_sync ();
67 * // set group properties
68 * g_object_set (G_OBJECT (group), "groupname", "group1", "secret", "123456",
69 * "grouptype", GUM_GROUPTYPE_USER, NULL);
72 * rval = gum_group_add_sync (user);
74 * // destroy the object
75 * g_object_unref (group);
78 * For more details, see command-line utility implementation here:
79 *<ulink url="https://github.com/01org/gumd/blob/master/src/utils/gum-utils.c">
85 * @group: (transfer none): #GumGroup object which is used in the request
86 * @error: (transfer none): #GError object. In case of error, error will be
88 * @user_data: user data passed onto the request
90 * #GumGroupCb defines the callback which is used when group object is created,
91 * added, deleted or updated or new members are added to the group.
97 * Opaque structure for the object.
102 * @parent_class: parent class object
104 * Opaque structure for the class.
114 struct _GumGroupPrivate
116 GumDbusGroupService *dbus_service;
117 GumDbusGroup *dbus_group;
118 GCancellable *cancellable;
122 G_DEFINE_TYPE (GumGroup, gum_group, G_TYPE_OBJECT)
124 #define GUM_GROUP_PRIV(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
125 GUM_TYPE_GROUP, GumGroupPrivate)
138 static GParamSpec *properties[N_PROPERTIES];
147 if (self->priv->op->error) g_error_free (self->priv->op->error);
148 g_free (self->priv->op);
149 self->priv->op = NULL;
159 GumGroupOp *op = g_malloc0 (sizeof (GumGroupOp));
160 op->callback = callback;
161 op->user_data = user_data;
170 g_return_val_if_fail (user_data && GUM_IS_GROUP (user_data), FALSE);
172 GumGroup *group = GUM_GROUP (user_data);
173 if (group->priv->op->callback) {
174 (group->priv->op->callback)(group, group->priv->op->error,
175 group->priv->op->user_data);
177 group->priv->op->cb_id = 0;
182 _setup_idle_callback (
186 if (!self->priv->op->callback) return;
188 if (self->priv->op->error) g_clear_error (&self->priv->op->error);
189 self->priv->op->error = g_error_copy (error);
191 self->priv->op->cb_id = g_idle_add (_trigger_callback, self);
195 _on_group_remote_object_destroyed (
199 g_return_if_fail (GUM_IS_GROUP (user_data));
200 GumGroup *self = GUM_GROUP (user_data);
204 GUM_OBJECT_UNREF (self->priv->dbus_group);
214 GumGroup *self = GUM_GROUP (object);
215 if (self->priv->dbus_group) {
216 g_object_set_property (G_OBJECT(self->priv->dbus_group), pspec->name,
228 GumGroup *self = GUM_GROUP (object);
229 if (self->priv->dbus_group) {
230 g_object_get_property (G_OBJECT(self->priv->dbus_group), pspec->name,
236 _dispose (GObject *object)
238 GumGroup *self = GUM_GROUP (object);
240 if (self->priv->op &&
241 self->priv->op->cb_id > 0) {
242 g_source_remove (self->priv->op->cb_id);
243 self->priv->op->cb_id = 0;
246 if (self->priv->cancellable) {
247 g_cancellable_cancel (self->priv->cancellable);
248 g_object_unref (self->priv->cancellable);
249 self->priv->cancellable = NULL;
252 if (self->priv->dbus_group) {
253 g_signal_handlers_disconnect_by_func (G_OBJECT (self->priv->dbus_group),
254 _on_group_remote_object_destroyed, self);
257 GUM_OBJECT_UNREF (self->priv->dbus_group);
259 GUM_OBJECT_UNREF (self->priv->dbus_service);
261 G_OBJECT_CLASS (gum_group_parent_class)->dispose (object);
265 _finalize (GObject *object)
267 GumGroup *self = GUM_GROUP (object);
271 G_OBJECT_CLASS (gum_group_parent_class)->finalize (object);
278 self->priv = GUM_GROUP_PRIV (self);
279 self->priv->dbus_group = NULL;
280 self->priv->cancellable = g_cancellable_new ();
281 self->priv->dbus_service = gum_group_service_get_instance ();
282 self->priv->op = NULL;
286 gum_group_class_init (
287 GumGroupClass *klass)
289 GObjectClass* object_class = G_OBJECT_CLASS (klass);
291 g_type_class_add_private (object_class, sizeof (GumGroupPrivate));
293 object_class->get_property = _get_property;
294 object_class->set_property = _set_property;
295 object_class->dispose = _dispose;
296 object_class->finalize = _finalize;
299 * GumGroup:grouptype:
301 * This property holds a group type that the object corresponds to. Valid
302 * values of group types are as specified in #GumGroupType.
303 * #GumGroup:grouptype must be specified when adding a new group.
305 properties[PROP_GROUPTYPE] = g_param_spec_uint ("grouptype",
310 GUM_GROUPTYPE_NONE /* default value */,
312 G_PARAM_STATIC_STRINGS);
317 * This property holds a unique group identity for the group as assigned by
318 * the underlying framework, which is always be in range [0, MAXUINT].
320 properties[PROP_GID] = g_param_spec_uint ("gid",
322 "Unique identifier of the group of the group",
325 GUM_GROUP_INVALID_GID /* default value */,
327 G_PARAM_STATIC_STRINGS);
330 * GumGroup:groupname:
332 * This property holds the name of given to the group when the group is
333 * added. Allowed pattern for groupname is:
334 * "^[A-Za-z_][A-Za-z0-9_.-]*[A-Za-z0-9_.$-]\\?$".
336 properties[PROP_GROUPNAME] = g_param_spec_string ("groupname",
338 "System name of the group",
339 "" /* default value */,
341 G_PARAM_STATIC_STRINGS);
346 * This property holds the secret as chosen. Secret should not
347 * contain any control chars (0x00-0x1F,0x7F) or colon (':' 0x3A).
349 properties[PROP_SECRET] = g_param_spec_string ("secret",
352 "" /* default value */,
354 G_PARAM_STATIC_STRINGS);
356 g_object_class_install_properties (object_class, N_PROPERTIES,
367 group->priv->dbus_group = gum_dbus_group_proxy_new_sync (
368 g_dbus_proxy_get_connection (G_DBUS_PROXY (
369 group->priv->dbus_service)),
370 G_DBUS_PROXY_FLAGS_NONE, g_dbus_proxy_get_name (
371 G_DBUS_PROXY (group->priv->dbus_service)), object_path,
372 group->priv->cancellable, &error);
374 g_signal_connect (G_OBJECT (group->priv->dbus_group), "unregistered",
375 G_CALLBACK (_on_group_remote_object_destroyed), group);
384 GVariantIter *iter = NULL;
385 GVariant *item = NULL;
386 g_variant_get (props, "(a{sv})", &iter);
387 while ((item = g_variant_iter_next_value (iter))) {
390 g_variant_get (item, "{sv}", &key, &value);
391 if (g_strcmp0 (key, prop) == 0) {
393 return g_variant_ref (value);
395 g_free (key); key = NULL;
396 g_variant_unref (value); value = NULL;
405 GError *error = NULL;
406 GVariant *result = NULL;
408 /* load all properties synchronously */
409 result = g_dbus_connection_call_sync (
410 g_dbus_proxy_get_connection (
411 G_DBUS_PROXY (group->priv->dbus_service)),
412 g_dbus_proxy_get_name (G_DBUS_PROXY (group->priv->dbus_service)),
413 g_dbus_proxy_get_object_path (G_DBUS_PROXY (group->priv->dbus_group)),
414 "org.freedesktop.DBus.Properties",
416 g_variant_new ("(s)",
417 g_dbus_proxy_get_interface_name (
418 G_DBUS_PROXY (group->priv->dbus_group))),
419 G_VARIANT_TYPE ("(a{sv})"),
420 G_DBUS_CALL_FLAGS_NONE,
422 group->priv->cancellable,
426 WARN ("Failed with error %d:%s", error->code, error->message);
427 g_error_free (error);
432 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(a{sv})"))) {
433 guint n_properties = 0, ind = 0;
434 GParamSpec **properties = g_object_class_list_properties (
435 G_OBJECT_GET_CLASS(group), &n_properties);
436 for (ind=0; ind < n_properties; ind++) {
437 GParamSpec *pspec = properties[ind];
438 GVariant *prop = _get_prop_value (result, pspec->name);
440 g_dbus_proxy_set_cached_property (
441 G_DBUS_PROXY (group->priv->dbus_group), pspec->name,
447 g_variant_unref (result);
457 GumGroup *group = (GumGroup*)user_data;
458 GumDbusGroupService *proxy = GUM_DBUS_GROUP_SERVICE (object);
459 gchar *object_path = NULL;
460 GError *error = NULL;
462 g_return_if_fail (group != NULL);
466 gum_dbus_group_service_call_create_new_group_finish (proxy, &object_path,
469 if (GUM_OPERATION_IS_NOT_CANCELLED (error)) {
471 _create_dbus_group (group, object_path, error);
473 _setup_idle_callback (group, error);
475 g_free (object_path);
476 g_clear_error (&error);
485 GumGroup *group = (GumGroup*)user_data;
486 GumDbusGroupService *proxy = GUM_DBUS_GROUP_SERVICE (object);
487 gchar *object_path = NULL;
488 GError *error = NULL;
490 g_return_if_fail (group != NULL);
494 gum_dbus_group_service_call_get_group_finish (proxy, &object_path,
497 if (GUM_OPERATION_IS_NOT_CANCELLED (error)) {
499 _create_dbus_group (group, object_path, error);
501 _setup_idle_callback (group, error);
503 g_free (object_path);
504 g_clear_error (&error);
508 _on_get_group_by_name_cb (
513 GumGroup *group = (GumGroup*)user_data;
514 GumDbusGroupService *proxy = GUM_DBUS_GROUP_SERVICE (object);
515 gchar *object_path = NULL;
516 GError *error = NULL;
518 g_return_if_fail (group != NULL);
522 gum_dbus_group_service_call_get_group_by_name_finish (proxy, &object_path,
525 if (GUM_OPERATION_IS_NOT_CANCELLED (error)) {
527 _create_dbus_group (group, object_path, error);
529 _setup_idle_callback (group, error);
531 g_free (object_path);
532 g_clear_error (&error);
541 GumGroup *group = (GumGroup*)user_data;
542 GumDbusGroup *proxy = GUM_DBUS_GROUP (object);
543 GError *error = NULL;
544 gid_t gid = GUM_GROUP_INVALID_GID;
546 g_return_if_fail (group != NULL);
550 gum_dbus_group_call_add_group_finish (proxy, &gid, res, &error);
552 if (GUM_OPERATION_IS_NOT_CANCELLED (error)) {
553 _setup_idle_callback (group, error);
555 g_clear_error (&error);
559 _on_group_delete_cb (
564 GumGroup *group = (GumGroup*)user_data;
565 GumDbusGroup *proxy = GUM_DBUS_GROUP (object);
566 GError *error = NULL;
568 g_return_if_fail (group != NULL);
572 gum_dbus_group_call_delete_group_finish (proxy, res, &error);
574 if (GUM_OPERATION_IS_NOT_CANCELLED (error)) {
575 _setup_idle_callback (group, error);
577 g_clear_error (&error);
581 _on_group_update_cb (
586 GumGroup *group = (GumGroup*)user_data;
587 GumDbusGroup *proxy = GUM_DBUS_GROUP (object);
588 GError *error = NULL;
590 g_return_if_fail (group != NULL);
594 gum_dbus_group_call_update_group_finish (proxy, res, &error);
596 if (GUM_OPERATION_IS_NOT_CANCELLED (error)) {
597 _setup_idle_callback (group, error);
599 g_clear_error (&error);
603 _on_group_add_member_cb (
608 GumGroup *group = (GumGroup*)user_data;
609 GumDbusGroup *proxy = GUM_DBUS_GROUP (object);
610 GError *error = NULL;
612 g_return_if_fail (group != NULL);
616 gum_dbus_group_call_add_member_finish (proxy, res, &error);
618 if (GUM_OPERATION_IS_NOT_CANCELLED (error)) {
619 _setup_idle_callback (group, error);
621 g_clear_error (&error);
625 _on_group_delete_member_cb (
630 GumGroup *group = (GumGroup*)user_data;
631 GumDbusGroup *proxy = GUM_DBUS_GROUP (object);
632 GError *error = NULL;
634 g_return_if_fail (group != NULL);
638 gum_dbus_group_call_delete_member_finish (proxy, res, &error);
640 if (GUM_OPERATION_IS_NOT_CANCELLED (error)) {
641 _setup_idle_callback (group, error);
643 g_clear_error (&error);
648 * @callback: #GumGroupCb to be invoked when new group object is created
649 * @user_data: user data
651 * This method creates a new remote group object over the DBus asynchronously.
652 * Callback is used to notify when the remote object is fully created and
655 * Returns: (transfer full): #GumGroup newly created object
662 GumGroup *group = GUM_GROUP (g_object_new (GUM_TYPE_GROUP, NULL));
663 g_return_val_if_fail (group->priv->dbus_service != NULL, NULL);
665 _create_op (group, callback, user_data);
666 gum_dbus_group_service_call_create_new_group (group->priv->dbus_service,
667 group->priv->cancellable, _on_new_group_cb, group);
672 * gum_group_create_sync:
674 * This method creates a new remote group object over the DBus synchronously.
676 * Returns: (transfer full): #GumGroup newly created object
679 gum_group_create_sync ()
681 GError *error = NULL;
682 gchar *object_path = NULL;
684 GumGroup *group = GUM_GROUP (g_object_new (GUM_TYPE_GROUP, NULL));
685 g_return_val_if_fail (group->priv->dbus_service != NULL, NULL);
687 if (gum_dbus_group_service_call_create_new_group_sync (
688 group->priv->dbus_service, &object_path, group->priv->cancellable,
690 _create_dbus_group (group, object_path, error);
693 g_free (object_path);
696 WARN ("Failed with error %d:%s", error->code, error->message);
697 g_error_free (error);
699 g_object_unref (group);
708 * @gid: group id for the group
709 * @callback: #GumGroupCb to be invoked when group object is fetched
710 * @user_data: user data
712 * This method gets the group object attached to gid over the DBus
713 * asynchronously. Callback is used to notify when the remote object is fully
714 * created and accessible.
716 * Returns: (transfer full): #GumGroup object
724 GumGroup *group = GUM_GROUP (g_object_new (GUM_TYPE_GROUP, NULL));
725 g_return_val_if_fail (group->priv->dbus_service != NULL, NULL);
727 _create_op (group, callback, user_data);
728 gum_dbus_group_service_call_get_group (group->priv->dbus_service, gid,
729 group->priv->cancellable, _on_get_group_cb, group);
735 * gum_group_get_sync:
736 * @gid: group id for the group
738 * This method gets the group object attached to gid over the DBus
741 * Returns: (transfer full): #GumGroup object
747 GError *error = NULL;
748 gchar *object_path = NULL;
750 GumGroup *group = GUM_GROUP (g_object_new (GUM_TYPE_GROUP, NULL));
751 g_return_val_if_fail (group->priv->dbus_service != NULL, NULL);
753 if (gum_dbus_group_service_call_get_group_sync (
754 group->priv->dbus_service, gid, &object_path,
755 group->priv->cancellable, &error)) {
756 _create_dbus_group (group, object_path, error);
759 g_free (object_path);
762 WARN ("Failed with error %d:%s", error->code, error->message);
763 g_error_free (error);
765 g_object_unref (group);
772 * gum_group_get_by_name:
773 * @groupname: name of the group
774 * @callback: #GumGroupCb to be invoked when group object is fetched
775 * @user_data: user data
777 * This method gets the group object attached to groupname over the DBus
778 * asynchronously. Callback is used to notify when the remote object is fully
779 * created and accessible.
781 * Returns: (transfer full): #GumGroup object
784 gum_group_get_by_name (
785 const gchar *groupname,
789 GumGroup *group = GUM_GROUP (g_object_new (GUM_TYPE_GROUP, NULL));
790 g_return_val_if_fail (group->priv->dbus_service != NULL, NULL);
793 WARN ("groupname not specified");
796 _create_op (group, callback, user_data);
797 gum_dbus_group_service_call_get_group_by_name (group->priv->dbus_service,
798 groupname, group->priv->cancellable, _on_get_group_by_name_cb,
804 * gum_group_get_by_name_sync:
805 * @groupname: name of the group
807 * This method gets the group object attached to groupname over the DBus
810 * Returns: (transfer full): #GumGroup object
813 gum_group_get_by_name_sync (
814 const gchar *groupname)
816 GError *error = NULL;
817 gchar *object_path = NULL;
819 GumGroup *group = GUM_GROUP (g_object_new (GUM_TYPE_GROUP, NULL));
820 g_return_val_if_fail (group->priv->dbus_service != NULL, NULL);
823 WARN ("groupname not specified");
827 if (gum_dbus_group_service_call_get_group_by_name_sync (
828 group->priv->dbus_service, groupname, &object_path,
829 group->priv->cancellable, &error)) {
830 _create_dbus_group (group, object_path, error);
833 g_free (object_path);
836 WARN ("Failed with error %d:%s", error->code, error->message);
837 g_error_free (error);
839 g_object_unref (group);
847 * @self: #GumGroup object to be added; object should have valid
848 * #GumGroup:groupname and #GumGroup:grouptype properties.
849 * @callback: #GumGroupCb to be invoked when group is added
850 * @user_data: user data
852 * This method adds the group over the DBus asynchronously. Callback is used to
853 * notify when the group is added.
855 * Returns: returns TRUE if the request has been pushed and is waiting for
856 * the response, FALSE otherwise. No callback is triggered, in case the
857 * function returns FALSE.
866 g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
868 if (!self->priv->dbus_group) {
869 WARN ("Remote dbus object not valid");
872 _create_op (self, callback, user_data);
873 gum_dbus_group_call_add_group (self->priv->dbus_group,
874 GUM_GROUP_INVALID_GID, self->priv->cancellable, _on_group_add_cb,
880 * gum_group_add_sync:
881 * @self: #GumGroup object to be added; object should have valid
882 * #GumGroup:groupname and #GumGroup:grouptype properties.
884 * This method adds the group over the DBus synchronously.
886 * Returns: returns TRUE if successful, FALSE otherwise.
892 GError *error = NULL;
893 gid_t gid = GUM_GROUP_INVALID_GID;
896 g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
898 if (!self->priv->dbus_group) {
899 WARN ("Remote dbus object not valid");
903 if (!gum_dbus_group_call_add_group_sync (self->priv->dbus_group,
904 GUM_GROUP_INVALID_GID, &gid, self->priv->cancellable, &error)) {
906 WARN ("Failed with error %d:%s", error->code, error->message);
907 g_error_free (error);
913 return _sync_properties (self);
918 * @self: #GumGroup object to be deleted; object should have valid
919 * #GumGroup:gid property.
920 * @callback: #GumGroupCb to be invoked when group is deleted
921 * @user_data: user data
923 * This method deletes the group over the DBus asynchronously. Callback is used
924 * to notify when the group is deleted.
926 * Returns: returns TRUE if the request has been pushed and is waiting for
927 * the response, FALSE otherwise. No callback is triggered, in case the
928 * function returns FALSE.
937 g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
939 if (!self->priv->dbus_group) {
940 WARN ("Remote dbus object not valid");
943 _create_op (self, callback, user_data);
944 gum_dbus_group_call_delete_group (self->priv->dbus_group,
945 self->priv->cancellable, _on_group_delete_cb, self);
950 * gum_group_delete_sync:
951 * @self: #GumGroup object to be deleted; object should have valid
952 * #GumGroup:gid property.
954 * This method deletes the group over the DBus synchronously.
956 * Returns: returns TRUE if successful, FALSE otherwise.
959 gum_group_delete_sync (
962 GError *error = NULL;
965 g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
967 if (!self->priv->dbus_group) {
968 WARN ("Remote dbus object not valid");
972 if (!gum_dbus_group_call_delete_group_sync (self->priv->dbus_group,
973 self->priv->cancellable, &error)) {
975 WARN ("Failed with error %d:%s", error->code, error->message);
976 g_error_free (error);
987 * @self: #GumGroup object to be updated; object should have valid
988 * #GumGroup:gid property.
989 * @callback: #GumGroupCb to be invoked when group is updated
990 * @user_data: user data
992 * This method updates the group over the DBus asynchronously. Callback is used
993 * to notify when the group is updated. The properties which can be updated
996 * Returns: returns TRUE if the request has been pushed and is waiting for
997 * the response, FALSE otherwise. No callback is triggered, in case the
998 * function returns FALSE.
1003 GumGroupCb callback,
1006 DBG ("Update Group");
1007 g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
1009 if (!self->priv->dbus_group) {
1010 WARN ("Remote dbus object not valid");
1013 _create_op (self, callback, user_data);
1014 gum_dbus_group_call_update_group (self->priv->dbus_group,
1015 self->priv->cancellable, _on_group_update_cb, self);
1020 * gum_group_update_sync:
1021 * @self: #GumGroup object to be updated; object should have valid
1022 * #GumGroup:gid property.
1024 * This method updates the group over the DBus synchronously. The properties
1025 * which can be updated are: secret.
1027 * Returns: returns TRUE if successful, FALSE otherwise.
1030 gum_group_update_sync (
1033 GError *error = NULL;
1036 g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
1038 if (!self->priv->dbus_group) {
1039 WARN ("Remote dbus object not valid");
1043 if (!gum_dbus_group_call_update_group_sync (self->priv->dbus_group,
1044 self->priv->cancellable, &error)) {
1046 WARN ("Failed with error %d:%s", error->code, error->message);
1047 g_error_free (error);
1053 return _sync_properties (self);
1057 * gum_group_add_member:
1058 * @self: #GumGroup object where new member is to be added; object should have
1059 * valid #GumGroup:gid property.
1060 * @uid: user id of the member to be added to the group
1061 * @add_as_admin: user will be added with admin privileges for the group if set
1063 * @callback: #GumGroupCb to be invoked when member is added
1064 * @user_data: user data
1066 * This method adds new member to the group over the DBus asynchronously.
1067 * Callback is used to notify when the member is added.
1069 * Returns: returns TRUE if the request has been pushed and is waiting for
1070 * the response, FALSE otherwise. No callback is triggered, in case the
1071 * function returns FALSE.
1074 gum_group_add_member (
1077 gboolean add_as_admin,
1078 GumGroupCb callback,
1082 g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
1084 if (!self->priv->dbus_group) {
1085 WARN ("Remote dbus object not valid");
1088 _create_op (self, callback, user_data);
1089 gum_dbus_group_call_add_member (self->priv->dbus_group, uid, add_as_admin,
1090 self->priv->cancellable, _on_group_add_member_cb,
1096 * gum_group_add_member_sync:
1097 * @self: #GumGroup object where new member is to be added; object should have
1098 * valid #GumGroup:gid property.
1099 * @uid: user id of the member to be added to the group
1100 * @add_as_admin: user will be added with admin privileges for the group if set
1103 * This method adds new member to the group over the DBus synchronously.
1105 * Returns: returns TRUE if successful, FALSE otherwise.
1108 gum_group_add_member_sync (
1111 gboolean add_as_admin)
1113 GError *error = NULL;
1116 g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
1118 if (!self->priv->dbus_group) {
1119 WARN ("Remote dbus object not valid");
1123 if (!gum_dbus_group_call_add_member_sync (self->priv->dbus_group, uid,
1124 add_as_admin, self->priv->cancellable, &error)) {
1126 WARN ("Failed with error %d:%s", error->code, error->message);
1127 g_error_free (error);
1137 * gum_group_delete_member:
1138 * @self: #GumGroup object where member is to be deleted from; object should
1139 * have valid #GumGroup:gid property.
1140 * @uid: user id of the member to be deleted from the group
1141 * @callback: #GumGroupCb to be invoked when member is deleted
1142 * @user_data: user data
1144 * This method deletes new member from the group over the DBus asynchronously.
1145 * Callback is used to notify when the member is deleted.
1147 * Returns: returns TRUE if the request has been pushed and is waiting for
1148 * the response, FALSE otherwise. No callback is triggered, in case the
1149 * function returns FALSE.
1152 gum_group_delete_member (
1155 GumGroupCb callback,
1159 g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
1161 if (!self->priv->dbus_group) {
1162 WARN ("Remote dbus object not valid");
1165 _create_op (self, callback, user_data);
1166 gum_dbus_group_call_delete_member (self->priv->dbus_group, uid,
1167 self->priv->cancellable, _on_group_delete_member_cb, self);
1172 * gum_group_delete_member_sync:
1173 * @self: #GumGroup object where member is to be deleted from; object should
1174 * have valid #GumGroup:gid property.
1175 * @uid: user id of the member to be deleted from the group
1177 * This method deletes new member from the group over the DBus synchronously.
1179 * Returns: returns TRUE if successful, FALSE otherwise.
1182 gum_group_delete_member_sync (
1186 GError *error = NULL;
1189 g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
1191 if (!self->priv->dbus_group) {
1192 WARN ("Remote dbus object not valid");
1196 if (!gum_dbus_group_call_delete_member_sync (self->priv->dbus_group, uid,
1197 self->priv->cancellable, &error)) {
1199 WARN ("Failed with error %d:%s", error->code, error->message);
1200 g_error_free (error);