Commit 0cde8d85 authored by David Zeuthen's avatar David Zeuthen

implement EnumerateUsers()

parent f1026325
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/">
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<!-- User defined struct -->
<annotation name="org.gtk.EggDBus.DeclareStruct" value="Subject">
<annotation name="org.gtk.EggDBus.Struct.Signature" value="(sa{sv})"/>
</annotation>
<interface name="org.freedesktop.PolicyKit1.Authority">
<method name="SayHello">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="message" direction="in" type="s"/>
<arg name="result" direction="out" type="s"/>
</method>
<method name="CheckClaims">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="claims" direction="in" type="a(ssa{ss})"/>
<arg name="result" direction="out" type="s"/>
<method name="EnumerateUsers">
<arg name="users" direction="out" type="a(sa{sv})"/>
</method>
</interface>
......
......@@ -69,8 +69,6 @@
<xi:include href="xml/polkitactiondescription.xml"/>
<xi:include href="xml/polkiterror.xml"/>
<xi:include href="xml/polkitsubject.xml"/>
<xi:include href="xml/polkituser.xml"/>
<xi:include href="xml/polkitprocess.xml"/>
<chapter id="extending">
<title>Extending PolicyKit</title>
<xi:include href="../polkitbackend/xml/polkitbackendlocal.xml"/>
......
......@@ -42,8 +42,6 @@ libpolkit_gobject_1include_HEADERS = \
polkitauthorizationresult.h \
polkiterror.h \
polkitsubject.h \
polkituser.h \
polkitprocess.h \
polkitbindings.h \
polkitbindingstypes.h \
polkitauthority.h \
......@@ -57,8 +55,6 @@ libpolkit_gobject_1_la_SOURCES = \
polkitauthorizationresult.h polkitauthorizationresult.c \
polkiterror.h polkiterror.c \
polkitsubject.h polkitsubject.c \
polkituser.h polkituser.c \
polkitprocess.h polkitprocess.c \
$(BUILT_SOURCES) \
$(NULL)
......
......@@ -32,8 +32,6 @@
#include <polkit/polkitsubject.h>
#include <polkit/polkitauthorizationclaim.h>
#include <polkit/polkitauthorizationresult.h>
#include <polkit/polkituser.h>
#include <polkit/polkitprocess.h>
#include <polkit/polkitactiondescription.h>
#undef _POLKIT_INSIDE_POLKIT_H
......
......@@ -25,12 +25,12 @@
#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents."
#endif
#ifndef __POLKIT_AUTHORIZATION_CLAIM_H__
#define __POLKIT_AUTHORIZATION_CLAIM_H__
#include <glib-object.h>
#include <polkit/polkitsubject.h>
#ifndef __POLKIT_AUTHORIZATION_CLAIM_H__
#define __POLKIT_AUTHORIZATION_CLAIM_H__
G_BEGIN_DECLS
#define POLKIT_TYPE_AUTHORIZATION_CLAIM (polkit_authorization_claim_get_type ())
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2008 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: David Zeuthen <davidz@redhat.com>
*/
#include "config.h"
#include <string.h>
#include "polkitprocess.h"
/**
* SECTION:polkitprocess
* @short_description: Process
* @include: polkit/polkit.h
*
* Represents a process.
*/
/*--------------------------------------------------------------------------------------------------------------*/
struct _PolkitProcessPrivate
{
GPid pid;
};
enum {
PROP_0,
PROP_PID,
};
static void polkit_process_subject_iface_init (PolkitSubjectIface *iface);
G_DEFINE_TYPE_WITH_CODE (PolkitProcess, polkit_process, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (POLKIT_TYPE_SUBJECT,
polkit_process_subject_iface_init))
#define POLKIT_PROCESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_TYPE_PROCESS, PolkitProcessPrivate))
static void
polkit_process_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
PolkitProcess *process = POLKIT_PROCESS (object);
switch (prop_id) {
case PROP_PID:
g_value_set_int (value, process->priv->pid);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
polkit_process_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
PolkitProcess *process = POLKIT_PROCESS (object);
switch (prop_id) {
case PROP_PID:
polkit_process_set_pid (process, g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
polkit_process_init (PolkitProcess *process)
{
process->priv = POLKIT_PROCESS_GET_PRIVATE (process);
}
static void
polkit_process_finalize (GObject *object)
{
PolkitProcess *process;
g_return_if_fail (object != NULL);
g_return_if_fail (POLKIT_IS_PROCESS (object));
process = POLKIT_PROCESS (object);
G_OBJECT_CLASS (polkit_process_parent_class)->finalize (object);
}
static void
polkit_process_class_init (PolkitProcessClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = polkit_process_get_property;
object_class->set_property = polkit_process_set_property;
object_class->finalize = polkit_process_finalize;
/**
* PolkitProcess:pid:
*
* The process id.
*/
g_object_class_install_property (object_class,
PROP_PID,
g_param_spec_int ("pid",
"pid",
"The process id",
-1,
G_MAXINT, /* TODO: maybe there's a MAX_PID? */
-1,
G_PARAM_CONSTRUCT |
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
g_type_class_add_private (klass, sizeof (PolkitProcessPrivate));
}
pid_t
polkit_process_get_pid (PolkitProcess *process)
{
g_return_val_if_fail (POLKIT_IS_PROCESS (process), -1);
return process->priv->pid;
}
void
polkit_process_set_pid (PolkitProcess *process,
pid_t pid)
{
g_return_if_fail (POLKIT_IS_PROCESS (process));
if (pid != process->priv->pid) {
process->priv->pid = pid;
g_object_notify (G_OBJECT (process), "pid");
}
}
PolkitSubject *
polkit_process_new (pid_t pid)
{
return POLKIT_SUBJECT (g_object_new (POLKIT_TYPE_PROCESS,
"pid", pid,
NULL));
}
static gboolean
polkit_process_equal (PolkitSubject *subject1,
PolkitSubject *subject2)
{
PolkitProcess *process1 = POLKIT_PROCESS (subject1);
PolkitProcess *process2 = POLKIT_PROCESS (subject2);
return process1->priv->pid == process2->priv->pid;
}
static void
polkit_process_subject_iface_init (PolkitSubjectIface *iface)
{
iface->equal = polkit_process_equal;
}
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2008 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: David Zeuthen <davidz@redhat.com>
*/
#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents."
#endif
#ifndef __POLKIT_PROCESS_H__
#define __POLKIT_PROCESS_H__
#include <sys/types.h>
#include <glib-object.h>
#include <polkit/polkitsubject.h>
G_BEGIN_DECLS
#define POLKIT_TYPE_PROCESS (polkit_process_get_type ())
#define POLKIT_PROCESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_PROCESS, PolkitProcess))
#define POLKIT_PROCESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_TYPE_PROCESS, PolkitProcessClass))
#define POLKIT_IS_PROCESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_PROCESS))
#define POLKIT_IS_PROCESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_PROCESS))
#define POLKIT_PROCESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_PROCESS, PolkitProcessClass))
typedef struct _PolkitProcess PolkitProcess;
typedef struct _PolkitProcessClass PolkitProcessClass;
typedef struct _PolkitProcessPrivate PolkitProcessPrivate;
struct _PolkitProcess
{
GObject parent_instance;
PolkitProcessPrivate *priv;
};
struct _PolkitProcessClass
{
GObjectClass parent_class;
};
GType polkit_process_get_type (void) G_GNUC_CONST;
PolkitSubject *polkit_process_new (pid_t pid);
pid_t polkit_process_get_pid (PolkitProcess *process);
void polkit_process_set_pid (PolkitProcess *process,
pid_t pid);
G_END_DECLS
#endif /* __POLKIT_PROCESS_H__ */
This diff is collapsed.
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2008 Red Hat, Inc.
*
......@@ -21,52 +19,49 @@
* Author: David Zeuthen <davidz@redhat.com>
*/
#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents."
#endif
#ifndef __POLKIT_SUBJECT_H__
#define __POLKIT_SUBJECT_H__
#ifndef __POLKIT_SUBJECT_H
#define __POLKIT_SUBJECT_H
#include <sys/types.h>
#include <unistd.h>
#include <glib-object.h>
#include <polkit/polkitbindings.h>
G_BEGIN_DECLS
#define POLKIT_TYPE_SUBJECT (polkit_subject_get_type ())
#define POLKIT_SUBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), POLKIT_TYPE_SUBJECT, PolkitSubject))
#define POLKIT_IS_SUBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POLKIT_TYPE_SUBJECT))
#define POLKIT_SUBJECT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), POLKIT_TYPE_SUBJECT, PolkitSubjectIface))
#define POLKIT_TYPE_SUBJECT (polkit_subject_get_type())
#define POLKIT_SUBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_SUBJECT, PolkitSubject))
#define POLKIT_IS_SUBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_SUBJECT))
#define POLKIT_SUBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE((o), POLKIT_TYPE_SUBJECT, PolkitSubjectIface))
/**
* PolkitSubject:
*
* An abstract type that specifies a subject.
**/
typedef struct _PolkitSubject PolkitSubject;
#if 0
typedef struct _PolkitSubject PolkitSubject; /* Dummy typedef */
#endif
typedef struct _PolkitSubjectIface PolkitSubjectIface;
/**
* PolkitSubjectIface:
* @g_iface: The parent interface.
* @equal: Checks if two #PolkitSubject<!-- -->s are equal.
*
* #PolkitSubjectIface is used to implement #PolkitSubject types for various
* different subjects
*/
struct _PolkitSubjectIface
typedef enum
{
GTypeInterface g_iface;
/* Virtual Table */
POLKIT_SUBJECT_KIND_UNIX_PROCESS,
POLKIT_SUBJECT_KIND_UNIX_USER,
POLKIT_SUBJECT_KIND_UNIX_GROUP,
} PolkitSubjectKind;
gboolean (* equal) (PolkitSubject *subject1,
PolkitSubject *subject2);
struct _PolkitSubjectIface
{
GTypeInterface g_iface;
};
GType polkit_subject_get_type (void) G_GNUC_CONST;
gboolean polkit_subject_equal (PolkitSubject *subject1,
PolkitSubject *subject2);
GType polkit_subject_get_type (void) G_GNUC_CONST;
PolkitSubject *polkit_subject_new_for_unix_process (pid_t unix_process_id);
PolkitSubject *polkit_subject_new_for_unix_user (uid_t unix_user_id);
PolkitSubject *polkit_subject_new_for_unix_group (gid_t unix_group_id);
PolkitSubjectKind polkit_subject_get_kind (PolkitSubject *subject);
pid_t polkit_subject_unix_process_get_id (PolkitSubject *subject);
uid_t polkit_subject_unix_user_get_id (PolkitSubject *subject);
gid_t polkit_subject_unix_group_get_id (PolkitSubject *subject);
gboolean polkit_subject_equal (PolkitSubject *a,
PolkitSubject *b);
G_END_DECLS
#endif /* __POLKIT_SUBJECT_H__ */
#endif /* __POLKIT_SUBJECT_H */
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2008 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: David Zeuthen <davidz@redhat.com>
*/
#include "config.h"
#include <string.h>
#include "polkituser.h"
/**
* SECTION:polkituser
* @short_description: User
* @include: polkit/polkit.h
*
* Represents a user.
*/
/*--------------------------------------------------------------------------------------------------------------*/
struct _PolkitUserPrivate
{
char *user_name;
};
enum {
PROP_0,
PROP_USER_NAME,
};
static void polkit_user_subject_iface_init (PolkitSubjectIface *iface);
G_DEFINE_TYPE_WITH_CODE (PolkitUser, polkit_user, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (POLKIT_TYPE_SUBJECT,
polkit_user_subject_iface_init))
#define POLKIT_USER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_TYPE_USER, PolkitUserPrivate))
static void
polkit_user_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
PolkitUser *user = POLKIT_USER (object);
switch (prop_id) {
case PROP_USER_NAME:
g_value_set_string (value, user->priv->user_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
polkit_user_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
PolkitUser *user = POLKIT_USER (object);
switch (prop_id) {
case PROP_USER_NAME:
polkit_user_set_user_name (user, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
polkit_user_init (PolkitUser *user)
{
user->priv = POLKIT_USER_GET_PRIVATE (user);
}
static void
polkit_user_finalize (GObject *object)
{
PolkitUser *user;
g_return_if_fail (object != NULL);
g_return_if_fail (POLKIT_IS_USER (object));
user = POLKIT_USER (object);
g_free (user->priv->user_name);
G_OBJECT_CLASS (polkit_user_parent_class)->finalize (object);
}
static void
polkit_user_class_init (PolkitUserClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = polkit_user_get_property;
object_class->set_property = polkit_user_set_property;
object_class->finalize = polkit_user_finalize;
/**
* PolkitUser:user-name:
*
* The user name.
*/
g_object_class_install_property (object_class,
PROP_USER_NAME,
g_param_spec_string ("user-name",
"user-name",
"The user name",
NULL,
G_PARAM_CONSTRUCT |
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
g_type_class_add_private (klass, sizeof (PolkitUserPrivate));
}
gchar *
polkit_user_get_user_name (PolkitUser *user)
{
g_return_val_if_fail (POLKIT_IS_USER (user), NULL);
return g_strdup (user->priv->user_name);
}
void
polkit_user_set_user_name (PolkitUser *user,
const char *user_name)
{
g_return_if_fail (POLKIT_IS_USER (user));
g_return_if_fail (user_name != NULL);
if (user->priv->user_name == NULL || strcmp (user_name, user->priv->user_name) != 0) {
g_free (user->priv->user_name);
user->priv->user_name = g_strdup (user_name);
g_object_notify (G_OBJECT (user), "user-name");
}
}
PolkitSubject *
polkit_user_new (const gchar *user_name)
{
return POLKIT_SUBJECT (g_object_new (POLKIT_TYPE_USER,
"user-name", user_name,
NULL));
}
static gboolean
polkit_user_equal (PolkitSubject *subject1,
PolkitSubject *subject2)
{
PolkitUser *user1 = POLKIT_USER (subject1);
PolkitUser *user2 = POLKIT_USER (subject2);
return strcmp (user1->priv->user_name, user2->priv->user_name) == 0;
}
static void
polkit_user_subject_iface_init (PolkitSubjectIface *iface)
{
iface->equal = polkit_user_equal;
}
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2008 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: David Zeuthen <davidz@redhat.com>
*/
#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents."
#endif
#ifndef __POLKIT_USER_H__
#define __POLKIT_USER_H__
#include <glib-object.h>
#include <polkit/polkitsubject.h>
G_BEGIN_DECLS
#define POLKIT_TYPE_USER (polkit_user_get_type ())
#define POLKIT_USER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_USER, PolkitUser))
#define POLKIT_USER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_TYPE_USER, PolkitUserClass))
#define POLKIT_IS_USER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_USER))
#define POLKIT_IS_USER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_USER))
#define POLKIT_USER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_USER, PolkitUserClass))
typedef struct _PolkitUser PolkitUser;
typedef struct _PolkitUserClass PolkitUserClass;
typedef struct _PolkitUserPrivate PolkitUserPrivate;
struct _PolkitUser
{
GObject parent_instance;
PolkitUserPrivate *priv;
};
struct _PolkitUserClass
{
GObjectClass parent_class;
};
GType polkit_user_get_type (void) G_GNUC_CONST;
PolkitSubject *polkit_user_new (const char *user_name);
gchar *polkit_user_get_user_name (PolkitUser *user);
void polkit_user_set_user_name (PolkitUser *user,
const gchar *user_name);
G_END_DECLS
#endif /* __POLKIT_USER_H__ */
......@@ -22,6 +22,9 @@
*/
#include "config.h"
#include <errno.h>
#include <pwd.h>
#include <string.h>
#include <polkit/polkit.h>
#include "polkitbackendlocal.h"
......@@ -100,10 +103,49 @@ authority_iface_handle_say_hello (PolkitAuthority *instance,
g_free (result);
}
static void
authority_iface_handle_enumerate_users (PolkitAuthority *instance,
EggDBusMethodInvocation *method_invocation)
{
struct passwd *passwd;
GList *list;
list = NULL;
passwd = getpwent ();
if (passwd == NULL) {
egg_dbus_method_invocation_return_error (method_invocation,
POLKIT_ERROR,
POLKIT_ERROR_FAILED,
"getpwent failed: %s",
strerror (errno));
goto out;
}
do {
PolkitSubject *subject;
subject = polkit_subject_new_for_unix_user (passwd->pw_uid);
list = g_list_prepend (list, subject);
} while ((passwd = getpwent ()) != NULL);
endpwent ();
list = g_list_reverse (list);
polkit_authority_handle_enumerate_users_finish (instance,
list,
method_invocation);
out:
g_list_foreach (list, (GFunc) g_object_unref, NULL);
g_list_free (list);
}
static void
authority_iface_init (PolkitAuthorityIface *authority_iface,
gpointer iface_data)
{
authority_iface->handle_say_hello = authority_iface_handle_say_hello;
authority_iface->handle_say_hello = authority_iface_handle_say_hello;
authority_iface->handle_enumerate_users = authority_iface_handle_enumerate_users;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment