1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "qemu/osdep.h"
22#include "authz/pamacct.h"
23#include "trace.h"
24#include "qemu/module.h"
25#include "qom/object_interfaces.h"
26
27#include <security/pam_appl.h>
28
29
30static bool qauthz_pam_is_allowed(QAuthZ *authz,
31 const char *identity,
32 Error **errp)
33{
34 QAuthZPAM *pauthz = QAUTHZ_PAM(authz);
35 const struct pam_conv pam_conversation = { 0 };
36 pam_handle_t *pamh = NULL;
37 int ret;
38
39 trace_qauthz_pam_check(authz, identity, pauthz->service);
40 ret = pam_start(pauthz->service,
41 identity,
42 &pam_conversation,
43 &pamh);
44 if (ret != PAM_SUCCESS) {
45 error_setg(errp, "Unable to start PAM transaction: %s",
46 pam_strerror(NULL, ret));
47 return false;
48 }
49
50 ret = pam_acct_mgmt(pamh, PAM_SILENT);
51 pam_end(pamh, ret);
52 if (ret != PAM_SUCCESS) {
53 error_setg(errp, "Unable to authorize user '%s': %s",
54 identity, pam_strerror(pamh, ret));
55 return false;
56 }
57
58 return true;
59}
60
61
62static void
63qauthz_pam_prop_set_service(Object *obj,
64 const char *service,
65 Error **errp G_GNUC_UNUSED)
66{
67 QAuthZPAM *pauthz = QAUTHZ_PAM(obj);
68
69 g_free(pauthz->service);
70 pauthz->service = g_strdup(service);
71}
72
73
74static char *
75qauthz_pam_prop_get_service(Object *obj,
76 Error **errp G_GNUC_UNUSED)
77{
78 QAuthZPAM *pauthz = QAUTHZ_PAM(obj);
79
80 return g_strdup(pauthz->service);
81}
82
83
84static void
85qauthz_pam_complete(UserCreatable *uc, Error **errp)
86{
87}
88
89
90static void
91qauthz_pam_finalize(Object *obj)
92{
93 QAuthZPAM *pauthz = QAUTHZ_PAM(obj);
94
95 g_free(pauthz->service);
96}
97
98
99static void
100qauthz_pam_class_init(ObjectClass *oc, void *data)
101{
102 UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
103 QAuthZClass *authz = QAUTHZ_CLASS(oc);
104
105 ucc->complete = qauthz_pam_complete;
106 authz->is_allowed = qauthz_pam_is_allowed;
107
108 object_class_property_add_str(oc, "service",
109 qauthz_pam_prop_get_service,
110 qauthz_pam_prop_set_service,
111 NULL);
112}
113
114
115QAuthZPAM *qauthz_pam_new(const char *id,
116 const char *service,
117 Error **errp)
118{
119 return QAUTHZ_PAM(
120 object_new_with_props(TYPE_QAUTHZ_PAM,
121 object_get_objects_root(),
122 id, errp,
123 "service", service,
124 NULL));
125}
126
127
128static const TypeInfo qauthz_pam_info = {
129 .parent = TYPE_QAUTHZ,
130 .name = TYPE_QAUTHZ_PAM,
131 .instance_size = sizeof(QAuthZPAM),
132 .instance_finalize = qauthz_pam_finalize,
133 .class_size = sizeof(QAuthZPAMClass),
134 .class_init = qauthz_pam_class_init,
135 .interfaces = (InterfaceInfo[]) {
136 { TYPE_USER_CREATABLE },
137 { }
138 }
139};
140
141
142static void
143qauthz_pam_register_types(void)
144{
145 type_register_static(&qauthz_pam_info);
146}
147
148
149type_init(qauthz_pam_register_types);
150