libxl: destroy domain in migration finish phase on failure
[libvirt.git] / src / security / security_dac.c
1 /*
2  * Copyright (C) 2010-2011 Red Hat, Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
17  *
18  * POSIX DAC security driver
19  */
20
21 #include <config.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25
26 #include "security_dac.h"
27 #include "virterror_internal.h"
28 #include "util.h"
29 #include "memory.h"
30 #include "logging.h"
31 #include "pci.h"
32 #include "hostusb.h"
33 #include "storage_file.h"
34
35 #define VIR_FROM_THIS VIR_FROM_SECURITY
36
37 typedef struct _virSecurityDACData virSecurityDACData;
38 typedef virSecurityDACData *virSecurityDACDataPtr;
39
40 struct _virSecurityDACData {
41     uid_t user;
42     gid_t group;
43     bool dynamicOwnership;
44 };
45
46 void virSecurityDACSetUser(virSecurityManagerPtr mgr,
47                            uid_t user)
48 {
49     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
50     priv->user = user;
51 }
52
53 void virSecurityDACSetGroup(virSecurityManagerPtr mgr,
54                             gid_t group)
55 {
56     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
57     priv->group = group;
58 }
59
60 void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
61                                        bool dynamicOwnership)
62 {
63     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
64     priv->dynamicOwnership = dynamicOwnership;
65 }
66
67 static virSecurityDriverStatus
68 virSecurityDACProbe(void)
69 {
70     return SECURITY_DRIVER_ENABLE;
71 }
72
73 static int
74 virSecurityDACOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
75 {
76     return 0;
77 }
78
79 static int
80 virSecurityDACClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
81 {
82     return 0;
83 }
84
85
86 static const char * virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
87 {
88     return "dac";
89 }
90
91 static const char * virSecurityDACGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
92 {
93     return "0";
94 }
95
96 static int
97 virSecurityDACSetOwnership(const char *path, int uid, int gid)
98 {
99     VIR_INFO("Setting DAC user and group on '%s' to '%d:%d'", path, uid, gid);
100
101     if (chown(path, uid, gid) < 0) {
102         struct stat sb;
103         int chown_errno = errno;
104
105         if (stat(path, &sb) >= 0) {
106             if (sb.st_uid == uid &&
107                 sb.st_gid == gid) {
108                 /* It's alright, there's nothing to change anyway. */
109                 return 0;
110             }
111         }
112
113         if (chown_errno == EOPNOTSUPP || chown_errno == EINVAL) {
114             VIR_INFO("Setting user and group to '%d:%d' on '%s' not supported by filesystem",
115                      uid, gid, path);
116         } else if (chown_errno == EPERM) {
117             VIR_INFO("Setting user and group to '%d:%d' on '%s' not permitted",
118                      uid, gid, path);
119         } else if (chown_errno == EROFS) {
120             VIR_INFO("Setting user and group to '%d:%d' on '%s' not possible on readonly filesystem",
121                      uid, gid, path);
122         } else {
123             virReportSystemError(chown_errno,
124                                  _("unable to set user and group to '%d:%d' on '%s'"),
125                                  uid, gid, path);
126             return -1;
127         }
128     }
129     return 0;
130 }
131
132 static int
133 virSecurityDACRestoreSecurityFileLabel(const char *path)
134 {
135     struct stat buf;
136     int rc = -1;
137     char *newpath = NULL;
138
139     VIR_INFO("Restoring DAC user and group on '%s'", path);
140
141     if (virFileResolveLink(path, &newpath) < 0) {
142         virReportSystemError(errno,
143                              _("cannot resolve symlink %s"), path);
144         goto err;
145     }
146
147     if (stat(newpath, &buf) != 0)
148         goto err;
149
150     /* XXX record previous ownership */
151     rc = virSecurityDACSetOwnership(newpath, 0, 0);
152
153 err:
154     VIR_FREE(newpath);
155     return rc;
156 }
157
158
159 static int
160 virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
161                                    const char *path,
162                                    size_t depth ATTRIBUTE_UNUSED,
163                                    void *opaque)
164 {
165     virSecurityManagerPtr mgr = opaque;
166     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
167
168     return virSecurityDACSetOwnership(path, priv->user, priv->group);
169 }
170
171
172 static int
173 virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
174                                     virDomainObjPtr vm ATTRIBUTE_UNUSED,
175                                     virDomainDiskDefPtr disk)
176
177 {
178     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
179
180     if (!priv->dynamicOwnership)
181         return 0;
182
183     return virDomainDiskDefForeachPath(disk,
184                                        virSecurityManagerGetAllowDiskFormatProbing(mgr),
185                                        false,
186                                        virSecurityDACSetSecurityFileLabel,
187                                        mgr);
188 }
189
190
191 static int
192 virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
193                                            virDomainObjPtr vm ATTRIBUTE_UNUSED,
194                                            virDomainDiskDefPtr disk,
195                                            int migrated)
196 {
197     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
198
199     if (!priv->dynamicOwnership)
200         return 0;
201
202     /* Don't restore labels on readoly/shared disks, because
203      * other VMs may still be accessing these
204      * Alternatively we could iterate over all running
205      * domains and try to figure out if it is in use, but
206      * this would not work for clustered filesystems, since
207      * we can't see running VMs using the file on other nodes
208      * Safest bet is thus to skip the restore step.
209      */
210     if (disk->readonly || disk->shared)
211         return 0;
212
213     if (!disk->src)
214         return 0;
215
216     /* If we have a shared FS & doing migrated, we must not
217      * change ownership, because that kills access on the
218      * destination host which is sub-optimal for the guest
219      * VM's I/O attempts :-)
220      */
221     if (migrated) {
222         int rc = virStorageFileIsSharedFS(disk->src);
223         if (rc < 0)
224             return -1;
225         if (rc == 1) {
226             VIR_DEBUG("Skipping image label restore on %s because FS is shared",
227                       disk->src);
228             return 0;
229         }
230     }
231
232     return virSecurityDACRestoreSecurityFileLabel(disk->src);
233 }
234
235
236 static int
237 virSecurityDACRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
238                                         virDomainObjPtr vm,
239                                         virDomainDiskDefPtr disk)
240 {
241     return virSecurityDACRestoreSecurityImageLabelInt(mgr, vm, disk, 0);
242 }
243
244
245 static int
246 virSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
247                                   const char *file,
248                                   void *opaque)
249 {
250     virSecurityManagerPtr mgr = opaque;
251     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
252
253     return virSecurityDACSetOwnership(file, priv->user, priv->group);
254 }
255
256
257 static int
258 virSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
259                                   const char *file,
260                                   void *opaque)
261 {
262     virSecurityManagerPtr mgr = opaque;
263     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
264
265     return virSecurityDACSetOwnership(file, priv->user, priv->group);
266 }
267
268
269 static int
270 virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
271                                       virDomainObjPtr vm ATTRIBUTE_UNUSED,
272                                       virDomainHostdevDefPtr dev)
273 {
274     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
275     int ret = -1;
276
277     if (!priv->dynamicOwnership)
278         return 0;
279
280     if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
281         return 0;
282
283     switch (dev->source.subsys.type) {
284     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
285         usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
286                                       dev->source.subsys.u.usb.device);
287
288         if (!usb)
289             goto done;
290
291         ret = usbDeviceFileIterate(usb, virSecurityDACSetSecurityUSBLabel, mgr);
292         usbFreeDevice(usb);
293         break;
294     }
295
296     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
297         pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
298                                       dev->source.subsys.u.pci.bus,
299                                       dev->source.subsys.u.pci.slot,
300                                       dev->source.subsys.u.pci.function);
301
302         if (!pci)
303             goto done;
304
305         ret = pciDeviceFileIterate(pci, virSecurityDACSetSecurityPCILabel, mgr);
306         pciFreeDevice(pci);
307
308         break;
309     }
310
311     default:
312         ret = 0;
313         break;
314     }
315
316 done:
317     return ret;
318 }
319
320
321 static int
322 virSecurityDACRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
323                                       const char *file,
324                                       void *opaque ATTRIBUTE_UNUSED)
325 {
326     return virSecurityDACRestoreSecurityFileLabel(file);
327 }
328
329
330 static int
331 virSecurityDACRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
332                                        const char *file,
333                                        void *opaque ATTRIBUTE_UNUSED)
334 {
335     return virSecurityDACRestoreSecurityFileLabel(file);
336 }
337
338
339 static int
340 virSecurityDACRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
341                                            virDomainObjPtr vm ATTRIBUTE_UNUSED,
342                                            virDomainHostdevDefPtr dev)
343
344 {
345     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
346     int ret = -1;
347
348     if (!priv->dynamicOwnership)
349         return 0;
350
351     if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
352         return 0;
353
354     switch (dev->source.subsys.type) {
355     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
356         usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
357                                       dev->source.subsys.u.usb.device);
358
359         if (!usb)
360             goto done;
361
362         ret = usbDeviceFileIterate(usb, virSecurityDACRestoreSecurityUSBLabel, mgr);
363         usbFreeDevice(usb);
364
365         break;
366     }
367
368     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
369         pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
370                                       dev->source.subsys.u.pci.bus,
371                                       dev->source.subsys.u.pci.slot,
372                                       dev->source.subsys.u.pci.function);
373
374         if (!pci)
375             goto done;
376
377         ret = pciDeviceFileIterate(pci, virSecurityDACRestoreSecurityPCILabel, mgr);
378         pciFreeDevice(pci);
379
380         break;
381     }
382
383     default:
384         ret = 0;
385         break;
386     }
387
388 done:
389     return ret;
390 }
391
392
393 static int
394 virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
395                               virDomainChrSourceDefPtr dev)
396
397 {
398     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
399     char *in = NULL, *out = NULL;
400     int ret = -1;
401
402     switch (dev->type) {
403     case VIR_DOMAIN_CHR_TYPE_DEV:
404     case VIR_DOMAIN_CHR_TYPE_FILE:
405         ret = virSecurityDACSetOwnership(dev->data.file.path, priv->user, priv->group);
406         break;
407
408     case VIR_DOMAIN_CHR_TYPE_PIPE:
409         if (virFileExists(dev->data.file.path)) {
410             if (virSecurityDACSetOwnership(dev->data.file.path, priv->user, priv->group) < 0)
411                 goto done;
412         } else {
413             if ((virAsprintf(&in, "%s.in", dev->data.file.path) < 0) ||
414                 (virAsprintf(&out, "%s.out", dev->data.file.path) < 0)) {
415                 virReportOOMError();
416                 goto done;
417             }
418             if ((virSecurityDACSetOwnership(in, priv->user, priv->group) < 0) ||
419                 (virSecurityDACSetOwnership(out, priv->user, priv->group) < 0))
420                 goto done;
421         }
422         ret = 0;
423         break;
424
425     default:
426         ret = 0;
427         break;
428     }
429
430 done:
431     VIR_FREE(in);
432     VIR_FREE(out);
433     return ret;
434 }
435
436 static int
437 virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
438                                   virDomainChrSourceDefPtr dev)
439 {
440     char *in = NULL, *out = NULL;
441     int ret = -1;
442
443     switch (dev->type) {
444     case VIR_DOMAIN_CHR_TYPE_DEV:
445     case VIR_DOMAIN_CHR_TYPE_FILE:
446         ret = virSecurityDACRestoreSecurityFileLabel(dev->data.file.path);
447         break;
448
449     case VIR_DOMAIN_CHR_TYPE_PIPE:
450         if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0) ||
451             (virAsprintf(&in, "%s.in", dev->data.file.path) < 0)) {
452             virReportOOMError();
453             goto done;
454         }
455         if ((virSecurityDACRestoreSecurityFileLabel(out) < 0) ||
456             (virSecurityDACRestoreSecurityFileLabel(in) < 0))
457             goto done;
458         ret = 0;
459         break;
460
461     default:
462         ret = 0;
463         break;
464     }
465
466 done:
467     VIR_FREE(in);
468     VIR_FREE(out);
469     return ret;
470 }
471
472
473 static int
474 virSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
475                                      virDomainChrDefPtr dev,
476                                      void *opaque)
477 {
478     virSecurityManagerPtr mgr = opaque;
479
480     return virSecurityDACRestoreChardevLabel(mgr, &dev->source);
481 }
482
483
484 static int
485 virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
486                                       virDomainObjPtr vm,
487                                       int migrated)
488 {
489     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
490     int i;
491     int rc = 0;
492
493     if (!priv->dynamicOwnership)
494         return 0;
495
496
497     VIR_DEBUG("Restoring security label on %s migrated=%d",
498               vm->def->name, migrated);
499
500     for (i = 0 ; i < vm->def->nhostdevs ; i++) {
501         if (virSecurityDACRestoreSecurityHostdevLabel(mgr,
502                                                       vm,
503                                                       vm->def->hostdevs[i]) < 0)
504             rc = -1;
505     }
506     for (i = 0 ; i < vm->def->ndisks ; i++) {
507         if (virSecurityDACRestoreSecurityImageLabelInt(mgr,
508                                                        vm,
509                                                        vm->def->disks[i],
510                                                        migrated) < 0)
511             rc = -1;
512     }
513
514     if (virDomainChrDefForeach(vm->def,
515                                false,
516                                virSecurityDACRestoreChardevCallback,
517                                mgr) < 0)
518         rc = -1;
519
520     if (vm->def->os.kernel &&
521         virSecurityDACRestoreSecurityFileLabel(vm->def->os.kernel) < 0)
522         rc = -1;
523
524     if (vm->def->os.initrd &&
525         virSecurityDACRestoreSecurityFileLabel(vm->def->os.initrd) < 0)
526         rc = -1;
527
528     return rc;
529 }
530
531
532 static int
533 virSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
534                                  virDomainChrDefPtr dev,
535                                  void *opaque)
536 {
537     virSecurityManagerPtr mgr = opaque;
538
539     return virSecurityDACSetChardevLabel(mgr, &dev->source);
540 }
541
542
543 static int
544 virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
545                                   virDomainObjPtr vm,
546                                   const char *stdin_path ATTRIBUTE_UNUSED)
547 {
548     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
549     int i;
550
551     if (!priv->dynamicOwnership)
552         return 0;
553
554     for (i = 0 ; i < vm->def->ndisks ; i++) {
555         /* XXX fixme - we need to recursively label the entire tree :-( */
556         if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
557             continue;
558         if (virSecurityDACSetSecurityImageLabel(mgr,
559                                                 vm,
560                                                 vm->def->disks[i]) < 0)
561             return -1;
562     }
563     for (i = 0 ; i < vm->def->nhostdevs ; i++) {
564         if (virSecurityDACSetSecurityHostdevLabel(mgr,
565                                                   vm,
566                                                   vm->def->hostdevs[i]) < 0)
567             return -1;
568     }
569
570     if (virDomainChrDefForeach(vm->def,
571                                true,
572                                virSecurityDACSetChardevCallback,
573                                mgr) < 0)
574         return -1;
575
576     if (vm->def->os.kernel &&
577         virSecurityDACSetOwnership(vm->def->os.kernel,
578                                     priv->user,
579                                     priv->group) < 0)
580         return -1;
581
582     if (vm->def->os.initrd &&
583         virSecurityDACSetOwnership(vm->def->os.initrd,
584                                     priv->user,
585                                     priv->group) < 0)
586         return -1;
587
588     return 0;
589 }
590
591
592 static int
593 virSecurityDACSetSavedStateLabel(virSecurityManagerPtr mgr,
594                                  virDomainObjPtr vm ATTRIBUTE_UNUSED,
595                                  const char *savefile)
596 {
597     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
598
599     return virSecurityDACSetOwnership(savefile, priv->user, priv->group);
600 }
601
602
603 static int
604 virSecurityDACRestoreSavedStateLabel(virSecurityManagerPtr mgr,
605                                      virDomainObjPtr vm ATTRIBUTE_UNUSED,
606                                      const char *savefile)
607 {
608     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
609
610     if (!priv->dynamicOwnership)
611         return 0;
612
613     return virSecurityDACRestoreSecurityFileLabel(savefile);
614 }
615
616
617 static int
618 virSecurityDACSetProcessLabel(virSecurityManagerPtr mgr,
619                               virDomainObjPtr vm ATTRIBUTE_UNUSED)
620 {
621     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
622
623     VIR_DEBUG("Dropping privileges of VM to %u:%u",
624               (unsigned int) priv->user, (unsigned int) priv->group);
625
626     if (virSetUIDGID(priv->user, priv->group) < 0)
627         return -1;
628
629     return 0;
630 }
631
632
633 static int
634 virSecurityDACVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
635                      virDomainDefPtr def ATTRIBUTE_UNUSED)
636 {
637     return 0;
638 }
639
640 static int
641 virSecurityDACGenLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
642                        virDomainObjPtr vm ATTRIBUTE_UNUSED)
643 {
644     return 0;
645 }
646
647 static int
648 virSecurityDACReleaseLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
649                            virDomainObjPtr vm ATTRIBUTE_UNUSED)
650 {
651     return 0;
652 }
653
654 static int
655 virSecurityDACReserveLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
656                            virDomainObjPtr vm ATTRIBUTE_UNUSED)
657 {
658     return 0;
659 }
660
661 static int
662 virSecurityDACGetProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
663                               virDomainObjPtr vm ATTRIBUTE_UNUSED,
664                               virSecurityLabelPtr seclabel ATTRIBUTE_UNUSED)
665 {
666     return 0;
667 }
668
669 static int
670 virSecurityDACSetSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
671                                virDomainObjPtr vm ATTRIBUTE_UNUSED)
672 {
673     return 0;
674 }
675
676
677 static int
678 virSecurityDACClearSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
679                                  virDomainObjPtr vm ATTRIBUTE_UNUSED)
680 {
681     return 0;
682 }
683
684 static int
685 virSecurityDACSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
686                               virDomainObjPtr vm ATTRIBUTE_UNUSED,
687                               int fd ATTRIBUTE_UNUSED)
688 {
689     return 0;
690 }
691
692 static int
693 virSecurityDACSetProcessFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
694                                 virDomainObjPtr vm ATTRIBUTE_UNUSED,
695                                 int fd ATTRIBUTE_UNUSED)
696 {
697     return 0;
698 }
699
700
701 virSecurityDriver virSecurityDriverDAC = {
702     sizeof(virSecurityDACData),
703     "virDAC",
704
705     virSecurityDACProbe,
706     virSecurityDACOpen,
707     virSecurityDACClose,
708
709     virSecurityDACGetModel,
710     virSecurityDACGetDOI,
711
712     virSecurityDACVerify,
713
714     virSecurityDACSetSecurityImageLabel,
715     virSecurityDACRestoreSecurityImageLabel,
716
717     virSecurityDACSetSocketLabel,
718     virSecurityDACClearSocketLabel,
719
720     virSecurityDACGenLabel,
721     virSecurityDACReserveLabel,
722     virSecurityDACReleaseLabel,
723
724     virSecurityDACGetProcessLabel,
725     virSecurityDACSetProcessLabel,
726
727     virSecurityDACSetSecurityAllLabel,
728     virSecurityDACRestoreSecurityAllLabel,
729
730     virSecurityDACSetSecurityHostdevLabel,
731     virSecurityDACRestoreSecurityHostdevLabel,
732
733     virSecurityDACSetSavedStateLabel,
734     virSecurityDACRestoreSavedStateLabel,
735
736     virSecurityDACSetImageFDLabel,
737     virSecurityDACSetProcessFDLabel,
738 };