1 /*
2  * admin_server.c: admin methods to manage daemons and clients
3  *
4  * Copyright (C) 2016 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library.  If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 
23 #include "admin_server.h"
24 #include "datatypes.h"
25 #include "viralloc.h"
26 #include "virerror.h"
27 #include "viridentity.h"
28 #include "virlog.h"
29 #include "rpc/virnetdaemon.h"
30 #include "rpc/virnetserver.h"
31 #include "virstring.h"
32 #include "virthreadpool.h"
33 #include "virtypedparam.h"
34 
35 #define VIR_FROM_THIS VIR_FROM_ADMIN
36 
37 VIR_LOG_INIT("daemon.admin_server");
38 
39 int
adminConnectListServers(virNetDaemon * dmn,virNetServer *** servers,unsigned int flags)40 adminConnectListServers(virNetDaemon *dmn,
41                         virNetServer ***servers,
42                         unsigned int flags)
43 {
44     int ret = -1;
45     virNetServer **srvs = NULL;
46 
47     virCheckFlags(0, -1);
48 
49     if ((ret = virNetDaemonGetServers(dmn, &srvs)) < 0)
50         return ret;
51 
52     if (servers) {
53         *servers = g_steal_pointer(&srvs);
54     }
55 
56     if (ret > 0)
57         virObjectListFreeCount(srvs, ret);
58     return ret;
59 }
60 
61 virNetServer *
adminConnectLookupServer(virNetDaemon * dmn,const char * name,unsigned int flags)62 adminConnectLookupServer(virNetDaemon *dmn,
63                          const char *name,
64                          unsigned int flags)
65 {
66     virCheckFlags(flags, NULL);
67 
68     return virNetDaemonGetServer(dmn, name);
69 }
70 
71 int
adminServerGetThreadPoolParameters(virNetServer * srv,virTypedParameterPtr * params,int * nparams,unsigned int flags)72 adminServerGetThreadPoolParameters(virNetServer *srv,
73                                    virTypedParameterPtr *params,
74                                    int *nparams,
75                                    unsigned int flags)
76 {
77     size_t minWorkers;
78     size_t maxWorkers;
79     size_t nWorkers;
80     size_t freeWorkers;
81     size_t nPrioWorkers;
82     size_t jobQueueDepth;
83     g_autoptr(virTypedParamList) paramlist = g_new0(virTypedParamList, 1);
84 
85     virCheckFlags(0, -1);
86 
87     if (virNetServerGetThreadPoolParameters(srv, &minWorkers, &maxWorkers,
88                                             &nWorkers, &freeWorkers,
89                                             &nPrioWorkers,
90                                             &jobQueueDepth) < 0) {
91         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
92                        _("Unable to retrieve threadpool parameters"));
93         return -1;
94     }
95 
96     if (virTypedParamListAddUInt(paramlist, minWorkers,
97                                  "%s", VIR_THREADPOOL_WORKERS_MIN) < 0)
98         return -1;
99 
100     if (virTypedParamListAddUInt(paramlist, maxWorkers,
101                                  "%s", VIR_THREADPOOL_WORKERS_MAX) < 0)
102         return -1;
103 
104     if (virTypedParamListAddUInt(paramlist, nWorkers,
105                                  "%s", VIR_THREADPOOL_WORKERS_CURRENT) < 0)
106         return -1;
107 
108     if (virTypedParamListAddUInt(paramlist, freeWorkers,
109                                  "%s", VIR_THREADPOOL_WORKERS_FREE) < 0)
110         return -1;
111 
112     if (virTypedParamListAddUInt(paramlist, nPrioWorkers,
113                                  "%s", VIR_THREADPOOL_WORKERS_PRIORITY) < 0)
114         return -1;
115 
116     if (virTypedParamListAddUInt(paramlist, jobQueueDepth,
117                                  "%s", VIR_THREADPOOL_JOB_QUEUE_DEPTH) < 0)
118         return -1;
119 
120     *nparams = virTypedParamListStealParams(paramlist, params);
121 
122     return 0;
123 }
124 
125 int
adminServerSetThreadPoolParameters(virNetServer * srv,virTypedParameterPtr params,int nparams,unsigned int flags)126 adminServerSetThreadPoolParameters(virNetServer *srv,
127                                    virTypedParameterPtr params,
128                                    int nparams,
129                                    unsigned int flags)
130 {
131     long long int minWorkers = -1;
132     long long int maxWorkers = -1;
133     long long int prioWorkers = -1;
134     virTypedParameterPtr param = NULL;
135 
136     virCheckFlags(0, -1);
137 
138     if (virTypedParamsValidate(params, nparams,
139                                VIR_THREADPOOL_WORKERS_MIN,
140                                VIR_TYPED_PARAM_UINT,
141                                VIR_THREADPOOL_WORKERS_MAX,
142                                VIR_TYPED_PARAM_UINT,
143                                VIR_THREADPOOL_WORKERS_PRIORITY,
144                                VIR_TYPED_PARAM_UINT,
145                                NULL) < 0)
146         return -1;
147 
148     if ((param = virTypedParamsGet(params, nparams,
149                                    VIR_THREADPOOL_WORKERS_MIN)))
150         minWorkers = param->value.ui;
151 
152     if ((param = virTypedParamsGet(params, nparams,
153                                    VIR_THREADPOOL_WORKERS_MAX)))
154         maxWorkers = param->value.ui;
155 
156     if ((param = virTypedParamsGet(params, nparams,
157                                    VIR_THREADPOOL_WORKERS_PRIORITY)))
158         prioWorkers = param->value.ui;
159 
160     if (virNetServerSetThreadPoolParameters(srv, minWorkers,
161                                             maxWorkers, prioWorkers) < 0)
162         return -1;
163 
164     return 0;
165 }
166 
167 int
adminServerListClients(virNetServer * srv,virNetServerClient *** clients,unsigned int flags)168 adminServerListClients(virNetServer *srv,
169                        virNetServerClient ***clients,
170                        unsigned int flags)
171 {
172     int ret = -1;
173     virNetServerClient **clts;
174 
175     virCheckFlags(0, -1);
176 
177     if ((ret = virNetServerGetClients(srv, &clts)) < 0)
178         return -1;
179 
180     if (clients) {
181         *clients = g_steal_pointer(&clts);
182     }
183 
184     virObjectListFreeCount(clts, ret);
185     return ret;
186 }
187 
188 virNetServerClient *
adminServerLookupClient(virNetServer * srv,unsigned long long id,unsigned int flags)189 adminServerLookupClient(virNetServer *srv,
190                         unsigned long long id,
191                         unsigned int flags)
192 {
193     virCheckFlags(0, NULL);
194 
195     return virNetServerGetClient(srv, id);
196 }
197 
198 int
adminClientGetInfo(virNetServerClient * client,virTypedParameterPtr * params,int * nparams,unsigned int flags)199 adminClientGetInfo(virNetServerClient *client,
200                    virTypedParameterPtr *params,
201                    int *nparams,
202                    unsigned int flags)
203 {
204     bool readonly;
205     g_autofree char *sock_addr = NULL;
206     const char *attr = NULL;
207     g_autoptr(virTypedParamList) paramlist = g_new0(virTypedParamList, 1);
208     g_autoptr(virIdentity) identity = NULL;
209     int rc;
210 
211     virCheckFlags(0, -1);
212 
213     if (virNetServerClientGetInfo(client, &readonly,
214                                   &sock_addr, &identity) < 0)
215         return -1;
216 
217     if (virTypedParamListAddBoolean(paramlist, readonly,
218                                     "%s", VIR_CLIENT_INFO_READONLY) < 0)
219         return -1;
220 
221     if ((rc = virIdentityGetSASLUserName(identity, &attr)) < 0)
222         return -1;
223     if (rc == 1 &&
224         virTypedParamListAddString(paramlist, attr,
225                                    "%s", VIR_CLIENT_INFO_SASL_USER_NAME) < 0)
226         return -1;
227 
228     if (!virNetServerClientIsLocal(client)) {
229         if (virTypedParamListAddString(paramlist, sock_addr,
230                                        "%s", VIR_CLIENT_INFO_SOCKET_ADDR) < 0)
231             return -1;
232 
233         if ((rc = virIdentityGetX509DName(identity, &attr)) < 0)
234             return -1;
235         if (rc == 1 &&
236             virTypedParamListAddString(paramlist, attr,
237                                        "%s", VIR_CLIENT_INFO_X509_DISTINGUISHED_NAME) < 0)
238             return -1;
239     } else {
240         pid_t pid;
241         uid_t uid;
242         gid_t gid;
243         if ((rc = virIdentityGetUNIXUserID(identity, &uid)) < 0)
244             return -1;
245         if (rc == 1 &&
246             virTypedParamListAddInt(paramlist, uid,
247                                     "%s", VIR_CLIENT_INFO_UNIX_USER_ID) < 0)
248             return -1;
249 
250         if ((rc = virIdentityGetUserName(identity, &attr)) < 0)
251             return -1;
252         if (rc == 1 &&
253             virTypedParamListAddString(paramlist, attr,
254                                        "%s", VIR_CLIENT_INFO_UNIX_USER_NAME) < 0)
255             return -1;
256 
257         if ((rc = virIdentityGetUNIXGroupID(identity, &gid)) < 0)
258             return -1;
259         if (rc == 1 &&
260             virTypedParamListAddInt(paramlist, gid,
261                                     "%s", VIR_CLIENT_INFO_UNIX_GROUP_ID) < 0)
262             return -1;
263 
264         if ((rc = virIdentityGetGroupName(identity, &attr)) < 0)
265             return -1;
266         if (rc == 1 &&
267             virTypedParamListAddString(paramlist, attr,
268                                        "%s", VIR_CLIENT_INFO_UNIX_GROUP_NAME) < 0)
269             return -1;
270 
271         if ((rc = virIdentityGetProcessID(identity, &pid)) < 0)
272             return -1;
273         if (rc == 1 &&
274             virTypedParamListAddInt(paramlist, pid,
275                                     "%s", VIR_CLIENT_INFO_UNIX_PROCESS_ID) < 0)
276             return -1;
277     }
278 
279     if ((rc = virIdentityGetSELinuxContext(identity, &attr)) < 0)
280         return -1;
281     if (rc == 1 &&
282         virTypedParamListAddString(paramlist, attr,
283                                    "%s", VIR_CLIENT_INFO_SELINUX_CONTEXT) < 0)
284         return -1;
285 
286     *nparams = virTypedParamListStealParams(paramlist, params);
287     return 0;
288 }
289 
adminClientClose(virNetServerClient * client,unsigned int flags)290 int adminClientClose(virNetServerClient *client,
291                      unsigned int flags)
292 {
293     virCheckFlags(0, -1);
294 
295     virNetServerClientClose(client);
296     return 0;
297 }
298 
299 int
adminServerGetClientLimits(virNetServer * srv,virTypedParameterPtr * params,int * nparams,unsigned int flags)300 adminServerGetClientLimits(virNetServer *srv,
301                            virTypedParameterPtr *params,
302                            int *nparams,
303                            unsigned int flags)
304 {
305     g_autoptr(virTypedParamList) paramlist = g_new0(virTypedParamList, 1);
306 
307     virCheckFlags(0, -1);
308 
309     if (virTypedParamListAddUInt(paramlist,
310                                  virNetServerGetMaxClients(srv),
311                                  "%s", VIR_SERVER_CLIENTS_MAX) < 0)
312         return -1;
313 
314     if (virTypedParamListAddUInt(paramlist,
315                                  virNetServerGetCurrentClients(srv),
316                                  "%s", VIR_SERVER_CLIENTS_CURRENT) < 0)
317         return -1;
318 
319     if (virTypedParamListAddUInt(paramlist,
320                                  virNetServerGetMaxUnauthClients(srv),
321                                  "%s", VIR_SERVER_CLIENTS_UNAUTH_MAX) < 0)
322         return -1;
323 
324     if (virTypedParamListAddUInt(paramlist,
325                                  virNetServerGetCurrentUnauthClients(srv),
326                                  "%s", VIR_SERVER_CLIENTS_UNAUTH_CURRENT) < 0)
327         return -1;
328 
329     *nparams = virTypedParamListStealParams(paramlist, params);
330 
331     return 0;
332 }
333 
334 int
adminServerSetClientLimits(virNetServer * srv,virTypedParameterPtr params,int nparams,unsigned int flags)335 adminServerSetClientLimits(virNetServer *srv,
336                            virTypedParameterPtr params,
337                            int nparams,
338                            unsigned int flags)
339 {
340     long long int maxClients = -1;
341     long long int maxClientsUnauth = -1;
342     virTypedParameterPtr param = NULL;
343 
344     virCheckFlags(0, -1);
345 
346     if (virTypedParamsValidate(params, nparams,
347                                VIR_SERVER_CLIENTS_MAX,
348                                VIR_TYPED_PARAM_UINT,
349                                VIR_SERVER_CLIENTS_UNAUTH_MAX,
350                                VIR_TYPED_PARAM_UINT,
351                                NULL) < 0)
352         return -1;
353 
354     if ((param = virTypedParamsGet(params, nparams,
355                                    VIR_SERVER_CLIENTS_MAX)))
356         maxClients = param->value.ui;
357 
358     if ((param = virTypedParamsGet(params, nparams,
359                                    VIR_SERVER_CLIENTS_UNAUTH_MAX)))
360         maxClientsUnauth = param->value.ui;
361 
362     if (virNetServerSetClientLimits(srv, maxClients,
363                                     maxClientsUnauth) < 0)
364         return -1;
365 
366     return 0;
367 }
368 
369 int
adminServerUpdateTlsFiles(virNetServer * srv,unsigned int flags)370 adminServerUpdateTlsFiles(virNetServer *srv,
371                           unsigned int flags)
372 {
373     virCheckFlags(0, -1);
374 
375     return virNetServerUpdateTlsFiles(srv);
376 }
377