~serge-hallyn/ubuntu/raring/libvirt/libvirt-hugepages

« back to all changes in this revision

Viewing changes to src/util/util.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-05-13 15:44:12 UTC
  • mfrom: (1.2.13)
  • Revision ID: package-import@ubuntu.com-20120513154412-fgmn5sxqdzgnzlx3
Tags: 0.9.12-0ubuntu1
* New upstream version:
  * Synchronize with debian packaging:
    - debian/control: Update build depends.
    - debian/libvirt-bin.postrm: Cleanup /var/log/libvirt
      on purge.
    - Bump standards verson (no changes).
    - debian/patches/Don-t-fail-if-we-can-t-setup-avahi.patch: Added
  * Dropped patches:
    - debian/patches/Debianize-libvirt-guests.patch
    - debian/patches/rewrite-lxc-controller-eof-handling-yet-again
    - debian/patches/ubuntu/libnl13.patch
    - debian/patches/ubuntu/fix-lxc-startup-error.patch
    - debian/patches/ubuntu/fix-bridge-fd.patch
    - debian/patches/ubuntu/skip-labelling-network-disks.patch
    - debian/patches/ubuntu/xen-xend-shutdown-detection.patch
    - debian/patches/ubuntu/xen-config-no-vfb-for-hvm.patch
    - debian/patches/debian/Disable-daemon-start-test.patch
    - debian/patches/debian/Disable-gnulib-s-test-nonplocking-pipe.sh.patch
    - debian/patches/ubuntu/9006-default-config-test-case.patch
    - debian/patches/fix-block-migration.patch
    - debian/patches/ubuntu/9022-qemu-unescape-HMP-commands-before-converting-them-to.patch
    - debian/patches/ubuntu/9023-qemu-change-rbd-auth_supported-separation-character-.patch
    - debian/patches/ubuntu/9024-qemu-allow-snapshotting-of-sheepdog-and-rbd-disks.patch
    - debian/patches/9025-qemu-change-rbd-auth_supported-separation-character-.patch
    - debian/patches/ubuntu/arm-gcc-workaround.patch
  * Rediffed:
    - debian/patches/Allow-libvirt-group-to-access-the-socket.patch
    - debian/patches/Disable-failing-virnetsockettest.patch
    - debian/patches/dnsmasq-as-priv-user
    - debian/patches/9002-better_default_uri_virsh.patch
  * debian/control: Add libnl-route-3-dev ass a build depends.
  * debian/patches/libnl3-build-fix.patch: Fix build with libnl3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * utils.c: common, generic utility functions
3
3
 *
4
 
 * Copyright (C) 2006-2011 Red Hat, Inc.
 
4
 * Copyright (C) 2006-2012 Red Hat, Inc.
5
5
 * Copyright (C) 2006 Daniel P. Berrange
6
6
 * Copyright (C) 2006, 2007 Binary Karma
7
7
 * Copyright (C) 2006 Shuveb Hussain
70
70
#include "logging.h"
71
71
#include "buf.h"
72
72
#include "util.h"
 
73
#include "storage_file.h"
73
74
#include "memory.h"
74
75
#include "threads.h"
75
76
#include "verify.h"
82
83
# define NSIG 32
83
84
#endif
84
85
 
85
 
verify(sizeof(gid_t) <= sizeof (unsigned int) &&
86
 
       sizeof(uid_t) <= sizeof (unsigned int));
 
86
verify(sizeof(gid_t) <= sizeof(unsigned int) &&
 
87
       sizeof(uid_t) <= sizeof(unsigned int));
87
88
 
88
89
#define VIR_FROM_THIS VIR_FROM_NONE
89
90
 
536
537
 
537
538
 
538
539
 
539
 
/*
540
 
 * Attempt to resolve a symbolic link, returning an
541
 
 * absolute path where only the last component is guaranteed
542
 
 * not to be a symlink.
543
 
 *
544
 
 * Return 0 if path was not a symbolic, or the link was
545
 
 * resolved. Return -1 with errno set upon error
546
 
 */
547
 
int virFileResolveLink(const char *linkpath,
548
 
                       char **resultpath)
 
540
static int
 
541
virFileResolveLinkHelper(const char *linkpath,
 
542
                         bool intermediatePaths,
 
543
                         char **resultpath)
549
544
{
550
545
    struct stat st;
551
546
 
554
549
    /* We don't need the full canonicalization of intermediate
555
550
     * directories, if linkpath is absolute and the basename is
556
551
     * already a non-symlink.  */
557
 
    if (IS_ABSOLUTE_FILE_NAME(linkpath)) {
 
552
    if (IS_ABSOLUTE_FILE_NAME(linkpath) && !intermediatePaths) {
558
553
        if (lstat(linkpath, &st) < 0)
559
554
            return -1;
560
555
 
570
565
    return *resultpath == NULL ? -1 : 0;
571
566
}
572
567
 
 
568
/*
 
569
 * Attempt to resolve a symbolic link, returning an
 
570
 * absolute path where only the last component is guaranteed
 
571
 * not to be a symlink.
 
572
 *
 
573
 * Return 0 if path was not a symbolic, or the link was
 
574
 * resolved. Return -1 with errno set upon error
 
575
 */
 
576
int virFileResolveLink(const char *linkpath,
 
577
                       char **resultpath)
 
578
{
 
579
    return virFileResolveLinkHelper(linkpath, false, resultpath);
 
580
}
 
581
 
 
582
/*
 
583
 * Attempt to resolve a symbolic link, returning an
 
584
 * absolute path where every component is guaranteed
 
585
 * not to be a symlink.
 
586
 *
 
587
 * Return 0 if path was not a symbolic, or the link was
 
588
 * resolved. Return -1 with errno set upon error
 
589
 */
 
590
int virFileResolveAllLinks(const char *linkpath,
 
591
                           char **resultpath)
 
592
{
 
593
    return virFileResolveLinkHelper(linkpath, true, resultpath);
 
594
}
573
595
 
574
596
/*
575
597
 * Check whether the given file is a link.
583
605
    if (lstat(linkpath, &st) < 0)
584
606
        return -errno;
585
607
 
586
 
    return (S_ISLNK(st.st_mode) != 0);
 
608
    return S_ISLNK(st.st_mode) != 0;
587
609
}
588
610
 
589
611
 
702
724
                return -1;
703
725
        }
704
726
 
705
 
        errno = status;
706
 
        return -1;
 
727
        if (!WIFEXITED(status)) {
 
728
            errno = EINTR;
 
729
            return -1;
 
730
        }
 
731
 
 
732
        if (status) {
 
733
            errno = WEXITSTATUS(status);
 
734
            return -1;
 
735
        }
 
736
 
 
737
        return 0;
707
738
    }
708
739
 
709
740
    /* child.
732
763
    _exit(ret);
733
764
}
734
765
 
735
 
/* return -errno on failure, or 0 on success */
736
 
static int
737
 
virFileOpenAsNoFork(const char *path, int openflags, mode_t mode,
738
 
                    uid_t uid, gid_t gid, unsigned int flags)
739
 
{
 
766
/* virFileOpenForceOwnerMode() - an internal utility function called
 
767
 * only by virFileOpenAs().  Sets the owner and mode of the file
 
768
 * opened as "fd" if it's not correct AND the flags say it should be
 
769
 * forced. */
 
770
static int
 
771
virFileOpenForceOwnerMode(const char *path, int fd, mode_t mode,
 
772
                          uid_t uid, gid_t gid, unsigned int flags)
 
773
{
 
774
    int ret = 0;
 
775
    struct stat st;
 
776
 
 
777
    if (!(flags & (VIR_FILE_OPEN_FORCE_OWNER | VIR_FILE_OPEN_FORCE_MODE)))
 
778
        return 0;
 
779
 
 
780
    if (fstat(fd, &st) == -1) {
 
781
        ret = -errno;
 
782
        virReportSystemError(errno, _("stat of '%s' failed"), path);
 
783
        return ret;
 
784
    }
 
785
    /* NB: uid:gid are never "-1" (default) at this point - the caller
 
786
     * has always changed -1 to the value of get[gu]id().
 
787
    */
 
788
    if ((flags & VIR_FILE_OPEN_FORCE_OWNER) &&
 
789
        ((st.st_uid != uid) || (st.st_gid != gid)) &&
 
790
        (fchown(fd, uid, gid) < 0)) {
 
791
        ret = -errno;
 
792
        virReportSystemError(errno,
 
793
                             _("cannot chown '%s' to (%u, %u)"),
 
794
                             path, (unsigned int) uid,
 
795
                             (unsigned int) gid);
 
796
        return ret;
 
797
    }
 
798
    if ((flags & VIR_FILE_OPEN_FORCE_MODE) &&
 
799
        ((mode & (S_IRWXU|S_IRWXG|S_IRWXO)) !=
 
800
         (st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO))) &&
 
801
        (fchmod(fd, mode) < 0)) {
 
802
        ret = -errno;
 
803
        virReportSystemError(errno,
 
804
                             _("cannot set mode of '%s' to %04o"),
 
805
                             path, mode);
 
806
        return ret;
 
807
    }
 
808
    return ret;
 
809
}
 
810
 
 
811
/* virFileOpenForked() - an internal utility function called only by
 
812
 * virFileOpenAs(). It forks, then the child does setuid+setgid to
 
813
 * given uid:gid and attempts to open the file, while the parent just
 
814
 * calls recvfd to get the open fd back from the child. returns the
 
815
 * fd, or -errno if there is an error. */
 
816
static int
 
817
virFileOpenForked(const char *path, int openflags, mode_t mode,
 
818
                  uid_t uid, gid_t gid, unsigned int flags)
 
819
{
 
820
    pid_t pid;
 
821
    int waitret, status, ret = 0;
740
822
    int fd = -1;
741
 
    int ret = 0;
742
 
 
743
 
    if ((fd = open(path, openflags, mode)) < 0) {
744
 
        ret = -errno;
745
 
        virReportSystemError(errno, _("failed to create file '%s'"),
746
 
                             path);
747
 
        goto error;
748
 
    }
749
 
 
750
 
    /* VIR_FILE_OPEN_AS_UID in flags means we are running in a child process
751
 
     * owned by uid and gid */
752
 
    if (!(flags & VIR_FILE_OPEN_AS_UID)) {
753
 
        struct stat st;
754
 
 
755
 
        if (fstat(fd, &st) == -1) {
756
 
            ret = -errno;
757
 
            virReportSystemError(errno, _("stat of '%s' failed"), path);
758
 
            goto error;
759
 
        }
760
 
        if (((st.st_uid != uid) || (st.st_gid != gid))
761
 
            && (openflags & O_CREAT)
762
 
            && (fchown(fd, uid, gid) < 0)) {
763
 
            ret = -errno;
764
 
            virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"),
765
 
                                 path, (unsigned int) uid, (unsigned int) gid);
766
 
            goto error;
767
 
        }
768
 
    }
769
 
 
770
 
    if ((flags & VIR_FILE_OPEN_FORCE_PERMS)
771
 
        && (fchmod(fd, mode) < 0)) {
772
 
        ret = -errno;
773
 
        virReportSystemError(errno,
774
 
                             _("cannot set mode of '%s' to %04o"),
775
 
                             path, mode);
776
 
        goto error;
 
823
    int pair[2] = { -1, -1 };
 
824
    int forkRet;
 
825
 
 
826
    /* parent is running as root, but caller requested that the
 
827
     * file be opened as some other user and/or group). The
 
828
     * following dance avoids problems caused by root-squashing
 
829
     * NFS servers. */
 
830
 
 
831
    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) < 0) {
 
832
        ret = -errno;
 
833
        virReportSystemError(errno,
 
834
                             _("failed to create socket needed for '%s'"),
 
835
                             path);
 
836
        return ret;
 
837
    }
 
838
 
 
839
    forkRet = virFork(&pid);
 
840
    if (pid < 0)
 
841
        return -errno;
 
842
 
 
843
    if (pid == 0) {
 
844
 
 
845
        /* child */
 
846
 
 
847
        VIR_FORCE_CLOSE(pair[0]); /* preserves errno */
 
848
        if (forkRet < 0) {
 
849
            /* error encountered and logged in virFork() after the fork. */
 
850
            ret = -errno;
 
851
            goto childerror;
 
852
        }
 
853
 
 
854
        /* set desired uid/gid, then attempt to create the file */
 
855
 
 
856
        if (virSetUIDGID(uid, gid) < 0) {
 
857
            ret = -errno;
 
858
            goto childerror;
 
859
        }
 
860
 
 
861
        if ((fd = open(path, openflags, mode)) < 0) {
 
862
            ret = -errno;
 
863
            virReportSystemError(errno,
 
864
                                 _("child process failed to create file '%s'"),
 
865
                                 path);
 
866
            goto childerror;
 
867
        }
 
868
 
 
869
        /* File is successfully open. Set permissions if requested. */
 
870
        ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags);
 
871
        if (ret < 0)
 
872
            goto childerror;
 
873
 
 
874
        do {
 
875
            ret = sendfd(pair[1], fd);
 
876
        } while (ret < 0 && errno == EINTR);
 
877
 
 
878
        if (ret < 0) {
 
879
            ret = -errno;
 
880
            virReportSystemError(errno, "%s",
 
881
                                 _("child process failed to send fd to parent"));
 
882
            goto childerror;
 
883
        }
 
884
 
 
885
    childerror:
 
886
        /* ret tracks -errno on failure, but exit value must be positive.
 
887
         * If the child exits with EACCES, then the parent tries again.  */
 
888
        /* XXX This makes assumptions about errno being < 255, which is
 
889
         * not true on Hurd.  */
 
890
        VIR_FORCE_CLOSE(pair[1]);
 
891
        if (ret < 0) {
 
892
            VIR_FORCE_CLOSE(fd);
 
893
        }
 
894
        ret = -ret;
 
895
        if ((ret & 0xff) != ret) {
 
896
            VIR_WARN("unable to pass desired return value %d", ret);
 
897
            ret = 0xff;
 
898
        }
 
899
        _exit(ret);
 
900
    }
 
901
 
 
902
    /* parent */
 
903
 
 
904
    VIR_FORCE_CLOSE(pair[1]);
 
905
 
 
906
    do {
 
907
        fd = recvfd(pair[0], 0);
 
908
    } while (fd < 0 && errno == EINTR);
 
909
    VIR_FORCE_CLOSE(pair[0]); /* NB: this preserves errno */
 
910
 
 
911
    if (fd < 0 && errno != EACCES) {
 
912
        ret = -errno;
 
913
        while (waitpid(pid, NULL, 0) == -1 && errno == EINTR);
 
914
        return ret;
 
915
    }
 
916
 
 
917
    /* wait for child to complete, and retrieve its exit code */
 
918
    while ((waitret = waitpid(pid, &status, 0) == -1)
 
919
           && (errno == EINTR));
 
920
    if (waitret == -1) {
 
921
        ret = -errno;
 
922
        virReportSystemError(errno,
 
923
                             _("failed to wait for child creating '%s'"),
 
924
                             path);
 
925
        VIR_FORCE_CLOSE(fd);
 
926
        return ret;
 
927
    }
 
928
    if (!WIFEXITED(status) || (ret = -WEXITSTATUS(status)) == -EACCES ||
 
929
        fd == -1) {
 
930
        /* fall back to the simpler method, which works better in
 
931
         * some cases */
 
932
        VIR_FORCE_CLOSE(fd);
 
933
        if (flags & VIR_FILE_OPEN_NOFORK) {
 
934
            /* If we had already tried opening w/o fork+setuid and
 
935
             * failed, no sense trying again. Just set return the
 
936
             * original errno that we got at that time (by
 
937
             * definition, always either EACCES or EPERM - EACCES
 
938
             * is close enough).
 
939
             */
 
940
            return -EACCES;
 
941
        }
 
942
        if ((fd = open(path, openflags, mode)) < 0)
 
943
            return -errno;
 
944
        ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags);
 
945
        if (ret < 0) {
 
946
            VIR_FORCE_CLOSE(fd);
 
947
            return ret;
 
948
        }
777
949
    }
778
950
    return fd;
779
 
 
780
 
error:
781
 
    VIR_FORCE_CLOSE(fd);
782
 
    return ret;
783
 
}
784
 
 
785
 
/* return -errno on failure, or 0 on success */
786
 
static int virDirCreateNoFork(const char *path, mode_t mode, uid_t uid, gid_t gid,
787
 
                              unsigned int flags) {
788
 
    int ret = 0;
789
 
    struct stat st;
790
 
 
791
 
    if ((mkdir(path, mode) < 0)
792
 
        && !((errno == EEXIST) && (flags & VIR_DIR_CREATE_ALLOW_EXIST))) {
793
 
        ret = -errno;
794
 
        virReportSystemError(errno, _("failed to create directory '%s'"),
795
 
                             path);
796
 
        goto error;
797
 
    }
798
 
 
799
 
    if (stat(path, &st) == -1) {
800
 
        ret = -errno;
801
 
        virReportSystemError(errno, _("stat of '%s' failed"), path);
802
 
        goto error;
803
 
    }
804
 
    if (((st.st_uid != uid) || (st.st_gid != gid))
805
 
        && (chown(path, uid, gid) < 0)) {
806
 
        ret = -errno;
807
 
        virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"),
808
 
                             path, (unsigned int) uid, (unsigned int) gid);
809
 
        goto error;
810
 
    }
811
 
    if ((flags & VIR_DIR_CREATE_FORCE_PERMS)
812
 
        && (chmod(path, mode) < 0)) {
813
 
        ret = -errno;
814
 
        virReportSystemError(errno,
815
 
                             _("cannot set mode of '%s' to %04o"),
816
 
                             path, mode);
817
 
        goto error;
818
 
    }
819
 
error:
820
 
    return ret;
821
951
}
822
952
 
823
953
/**
829
959
 * @gid: gid that should own file
830
960
 * @flags: bit-wise or of VIR_FILE_OPEN_* flags
831
961
 *
832
 
 * Open @path, and execute an optional callback @hook on the open file
833
 
 * description.  @hook must return 0 on success, or -errno on failure.
834
 
 * If @flags includes VIR_FILE_OPEN_AS_UID, then open the file while the
835
 
 * effective user id is @uid (by using a child process); this allows
836
 
 * one to bypass root-squashing NFS issues.  If @flags includes
837
 
 * VIR_FILE_OPEN_FORCE_PERMS, then ensure that @path has those
838
 
 * permissions before the callback, even if the file already existed
839
 
 * with different permissions.  The return value (if non-negative)
840
 
 * is the file descriptor, left open.  Return -errno on failure.  */
 
962
 * Open @path, and return an fd to the open file. @openflags contains
 
963
 * the flags normally passed to open(2), while those in @flags are
 
964
 * used internally. If @flags includes VIR_FILE_OPEN_NOFORK, then try
 
965
 * opening the file while executing with the current uid:gid
 
966
 * (i.e. don't fork+setuid+setgid before the call to open()).  If
 
967
 * @flags includes VIR_FILE_OPEN_FORK, then try opening the file while
 
968
 * the effective user id is @uid (by forking a child process); this
 
969
 * allows one to bypass root-squashing NFS issues; NOFORK is always
 
970
 * tried before FORK (the absence of both flags is treated identically
 
971
 * to (VIR_FILE_OPEN_NOFORK | VIR_FILE_OPEN_FORK)). If @flags includes
 
972
 * VIR_FILE_OPEN_FORCE_OWNER, then ensure that @path is owned by
 
973
 * uid:gid before returning (even if it already existed with a
 
974
 * different owner). If @flags includes VIR_FILE_OPEN_FORCE_MODE,
 
975
 * ensure it has those permissions before returning (again, even if
 
976
 * the file already existed with different permissions).  The return
 
977
 * value (if non-negative) is the file descriptor, left open.  Returns
 
978
 * -errno on failure.  */
841
979
int
842
980
virFileOpenAs(const char *path, int openflags, mode_t mode,
843
981
              uid_t uid, gid_t gid, unsigned int flags)
844
982
{
845
 
    pid_t pid;
846
 
    int waitret, status, ret = 0;
847
 
    int fd = -1;
848
 
    int pair[2] = { -1, -1 };
849
 
    int forkRet;
850
 
 
851
 
    if ((!(flags & VIR_FILE_OPEN_AS_UID))
 
983
    int ret = 0, fd = -1;
 
984
 
 
985
    /* allow using -1 to mean "current value" */
 
986
    if (uid == (uid_t) -1)
 
987
       uid = getuid();
 
988
    if (gid == (gid_t) -1)
 
989
       gid = getgid();
 
990
 
 
991
    /* treat absence of both flags as presence of both for simpler
 
992
     * calling. */
 
993
    if (!(flags & (VIR_FILE_OPEN_NOFORK|VIR_FILE_OPEN_FORK)))
 
994
       flags |= VIR_FILE_OPEN_NOFORK|VIR_FILE_OPEN_FORK;
 
995
 
 
996
    if ((flags & VIR_FILE_OPEN_NOFORK)
852
997
        || (getuid() != 0)
853
998
        || ((uid == 0) && (gid == 0))) {
854
 
        flags &= ~VIR_FILE_OPEN_AS_UID;
855
 
        return virFileOpenAsNoFork(path, openflags, mode, uid, gid, flags);
856
 
    }
857
 
 
858
 
    /* parent is running as root, but caller requested that the
859
 
     * file be created as some other user and/or group). The
860
 
     * following dance avoids problems caused by root-squashing
861
 
     * NFS servers. */
862
 
 
863
 
    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) < 0) {
864
 
        ret = -errno;
865
 
        virReportSystemError(errno,
866
 
                             _("failed to create socket needed for '%s'"),
867
 
                             path);
868
 
        return ret;
869
 
    }
870
 
 
871
 
    forkRet = virFork(&pid);
872
 
 
873
 
    if (pid < 0) {
874
 
        ret = -errno;
875
 
        return ret;
876
 
    }
877
 
 
878
 
    if (pid) { /* parent */
879
 
        VIR_FORCE_CLOSE(pair[1]);
880
 
 
881
 
        do {
882
 
            ret = recvfd(pair[0], 0);
883
 
        } while (ret < 0 && errno == EINTR);
884
 
 
885
 
        if (ret < 0 && errno != EACCES) {
 
999
 
 
1000
        if ((fd = open(path, openflags, mode)) < 0) {
886
1001
            ret = -errno;
887
 
            VIR_FORCE_CLOSE(pair[0]);
888
 
            while (waitpid(pid, NULL, 0) == -1 && errno == EINTR);
889
 
            goto parenterror;
890
1002
        } else {
891
 
            fd = ret;
892
 
        }
893
 
        VIR_FORCE_CLOSE(pair[0]);
894
 
 
895
 
        /* wait for child to complete, and retrieve its exit code */
896
 
        while ((waitret = waitpid(pid, &status, 0) == -1)
897
 
               && (errno == EINTR));
898
 
        if (waitret == -1) {
899
 
            ret = -errno;
900
 
            virReportSystemError(errno,
901
 
                                 _("failed to wait for child creating '%s'"),
902
 
                                 path);
903
 
            VIR_FORCE_CLOSE(fd);
904
 
            goto parenterror;
905
 
        }
906
 
        if (!WIFEXITED(status) || (ret = -WEXITSTATUS(status)) == -EACCES ||
907
 
            fd == -1) {
908
 
            /* fall back to the simpler method, which works better in
909
 
             * some cases */
910
 
            VIR_FORCE_CLOSE(fd);
911
 
            flags &= ~VIR_FILE_OPEN_AS_UID;
912
 
            return virFileOpenAsNoFork(path, openflags, mode, uid, gid, flags);
913
 
        }
914
 
        if (!ret)
 
1003
            ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags);
 
1004
            if (ret < 0)
 
1005
                goto error;
 
1006
        }
 
1007
    }
 
1008
 
 
1009
    /* If we either 1) didn't try opening as current user at all, or
 
1010
     * 2) failed, and errno/virStorageFileIsSharedFS indicate we might
 
1011
     * be successful if we try as a different uid, then try doing
 
1012
     * fork+setuid+setgid before opening.
 
1013
     */
 
1014
    if ((fd < 0) && (flags & VIR_FILE_OPEN_FORK)) {
 
1015
 
 
1016
        if (ret < 0) {
 
1017
            /* An open(2) that failed due to insufficient permissions
 
1018
             * could return one or the other of these depending on OS
 
1019
             * version and circumstances. Any other errno indicates a
 
1020
             * problem that couldn't be remedied by fork+setuid
 
1021
             * anyway. */
 
1022
            if (ret != -EACCES && ret != -EPERM)
 
1023
                goto error;
 
1024
 
 
1025
            /* On Linux we can also verify the FS-type of the
 
1026
             * directory.  (this is a NOP on other platforms). */
 
1027
            switch (virStorageFileIsSharedFS(path)) {
 
1028
            case 1:
 
1029
                /* it was on a network share, so we'll re-try */
 
1030
                break;
 
1031
            case -1:
 
1032
                /* failure detecting fstype */
 
1033
                virReportSystemError(errno, _("couldn't determine fs type "
 
1034
                                              "of mount containing '%s'"), path);
 
1035
                goto error;
 
1036
            case 0:
 
1037
            default:
 
1038
                /* file isn't on a recognized network FS */
 
1039
                goto error;
 
1040
            }
 
1041
        }
 
1042
 
 
1043
        /* passed all prerequisites - retry the open w/fork+setuid */
 
1044
        if ((fd = virFileOpenForked(path, openflags, mode, uid, gid, flags)) < 0) {
915
1045
            ret = fd;
916
 
parenterror:
917
 
        return ret;
918
 
    }
919
 
 
920
 
 
921
 
    /* child */
922
 
 
923
 
    if (forkRet < 0) {
924
 
        /* error encountered and logged in virFork() after the fork. */
925
 
        ret = -errno;
926
 
        goto childerror;
927
 
    }
928
 
    VIR_FORCE_CLOSE(pair[0]);
929
 
 
930
 
    /* set desired uid/gid, then attempt to create the file */
931
 
 
932
 
    if (virSetUIDGID(uid, gid) < 0) {
933
 
        ret = -errno;
934
 
        goto childerror;
935
 
    }
936
 
 
937
 
    ret = virFileOpenAsNoFork(path, openflags, mode, uid, gid, flags);
938
 
    if (ret < 0)
939
 
        goto childerror;
940
 
    fd = ret;
941
 
 
942
 
    do {
943
 
        ret = sendfd(pair[1], fd);
944
 
    } while (ret < 0 && errno == EINTR);
945
 
 
946
 
    if (ret < 0) {
947
 
        ret = -errno;
948
 
        goto childerror;
949
 
    }
950
 
 
951
 
childerror:
952
 
    /* ret tracks -errno on failure, but exit value must be positive.
953
 
     * If the child exits with EACCES, then the parent tries again.  */
954
 
    /* XXX This makes assumptions about errno being < 255, which is
955
 
     * not true on Hurd.  */
956
 
    VIR_FORCE_CLOSE(pair[1]);
957
 
    ret = -ret;
958
 
    if ((ret & 0xff) != ret) {
959
 
        VIR_WARN("unable to pass desired return value %d", ret);
960
 
        ret = 0xff;
961
 
    }
962
 
    _exit(ret);
963
 
 
 
1046
            fd = -1;
 
1047
            goto error;
 
1048
        }
 
1049
    }
 
1050
 
 
1051
    /* File is successfully opened */
 
1052
 
 
1053
    return fd;
 
1054
 
 
1055
error:
 
1056
    if (fd < 0) {
 
1057
        /* whoever failed the open last has already set ret = -errno */
 
1058
        virReportSystemError(-ret, openflags & O_CREAT
 
1059
                             ? _("failed to create file '%s'")
 
1060
                             : _("failed to open file '%s'"),
 
1061
                             path);
 
1062
    } else {
 
1063
        /* some other failure after the open succeeded */
 
1064
        VIR_FORCE_CLOSE(fd);
 
1065
    }
 
1066
    return ret;
 
1067
}
 
1068
 
 
1069
/* return -errno on failure, or 0 on success */
 
1070
static int virDirCreateNoFork(const char *path, mode_t mode, uid_t uid, gid_t gid,
 
1071
                              unsigned int flags) {
 
1072
    int ret = 0;
 
1073
    struct stat st;
 
1074
 
 
1075
    if ((mkdir(path, mode) < 0)
 
1076
        && !((errno == EEXIST) && (flags & VIR_DIR_CREATE_ALLOW_EXIST))) {
 
1077
        ret = -errno;
 
1078
        virReportSystemError(errno, _("failed to create directory '%s'"),
 
1079
                             path);
 
1080
        goto error;
 
1081
    }
 
1082
 
 
1083
    if (stat(path, &st) == -1) {
 
1084
        ret = -errno;
 
1085
        virReportSystemError(errno, _("stat of '%s' failed"), path);
 
1086
        goto error;
 
1087
    }
 
1088
    if (((st.st_uid != uid) || (st.st_gid != gid))
 
1089
        && (chown(path, uid, gid) < 0)) {
 
1090
        ret = -errno;
 
1091
        virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"),
 
1092
                             path, (unsigned int) uid, (unsigned int) gid);
 
1093
        goto error;
 
1094
    }
 
1095
    if ((flags & VIR_DIR_CREATE_FORCE_PERMS)
 
1096
        && (chmod(path, mode) < 0)) {
 
1097
        ret = -errno;
 
1098
        virReportSystemError(errno,
 
1099
                             _("cannot set mode of '%s' to %04o"),
 
1100
                             path, mode);
 
1101
        goto error;
 
1102
    }
 
1103
error:
 
1104
    return ret;
964
1105
}
965
1106
 
966
1107
/* return -errno on failure, or 0 on success */
1356
1497
    int err;
1357
1498
 
1358
1499
    errno = 0;
1359
 
    val = strtol(s, &p, base);
 
1500
    val = strtol(s, &p, base); /* exempt from syntax-check */
1360
1501
    err = (errno || (!end_ptr && *p) || p == s || (int) val != val);
1361
1502
    if (end_ptr)
1362
1503
        *end_ptr = p;
1375
1516
    int err;
1376
1517
 
1377
1518
    errno = 0;
1378
 
    val = strtoul(s, &p, base);
 
1519
    val = strtoul(s, &p, base); /* exempt from syntax-check */
1379
1520
    err = (errno || (!end_ptr && *p) || p == s || (unsigned int) val != val);
1380
1521
    if (end_ptr)
1381
1522
        *end_ptr = p;
1394
1535
    int err;
1395
1536
 
1396
1537
    errno = 0;
1397
 
    val = strtol(s, &p, base);
 
1538
    val = strtol(s, &p, base); /* exempt from syntax-check */
1398
1539
    err = (errno || (!end_ptr && *p) || p == s);
1399
1540
    if (end_ptr)
1400
1541
        *end_ptr = p;
1413
1554
    int err;
1414
1555
 
1415
1556
    errno = 0;
1416
 
    val = strtoul(s, &p, base);
 
1557
    val = strtoul(s, &p, base); /* exempt from syntax-check */
1417
1558
    err = (errno || (!end_ptr && *p) || p == s);
1418
1559
    if (end_ptr)
1419
1560
        *end_ptr = p;
1432
1573
    int err;
1433
1574
 
1434
1575
    errno = 0;
1435
 
    val = strtoll(s, &p, base);
1436
 
    err = (errno || (!end_ptr && *p) || p == s || (long long) val != val);
 
1576
    val = strtoll(s, &p, base); /* exempt from syntax-check */
 
1577
    err = (errno || (!end_ptr && *p) || p == s);
1437
1578
    if (end_ptr)
1438
1579
        *end_ptr = p;
1439
1580
    if (err)
1451
1592
    int err;
1452
1593
 
1453
1594
    errno = 0;
1454
 
    val = strtoull(s, &p, base);
1455
 
    err = (errno || (!end_ptr && *p) || p == s || (unsigned long long) val != val);
 
1595
    val = strtoull(s, &p, base); /* exempt from syntax-check */
 
1596
    err = (errno || (!end_ptr && *p) || p == s);
1456
1597
    if (end_ptr)
1457
1598
        *end_ptr = p;
1458
1599
    if (err)
1471
1612
    int err;
1472
1613
 
1473
1614
    errno = 0;
1474
 
    val = strtod(s, &p);
 
1615
    val = strtod(s, &p); /* exempt from syntax-check */
1475
1616
    err = (errno || (!end_ptr && *p) || p == s);
1476
1617
    if (end_ptr)
1477
1618
        *end_ptr = p;
1496
1637
    }
1497
1638
}
1498
1639
 
 
1640
/* Scale an integer VALUE in-place by an optional case-insensitive
 
1641
 * SUFFIX, defaulting to SCALE if suffix is NULL or empty (scale is
 
1642
 * typically 1 or 1024).  Recognized suffixes include 'b' or 'bytes',
 
1643
 * as well as power-of-two scaling via binary abbreviations ('KiB',
 
1644
 * 'MiB', ...) or their one-letter counterpart ('k', 'M', ...), and
 
1645
 * power-of-ten scaling via SI abbreviations ('KB', 'MB', ...).
 
1646
 * Ensure that the result does not exceed LIMIT.  Return 0 on success,
 
1647
 * -1 with error message raised on failure.  */
 
1648
int
 
1649
virScaleInteger(unsigned long long *value, const char *suffix,
 
1650
                unsigned long long scale, unsigned long long limit)
 
1651
{
 
1652
    if (!suffix || !*suffix) {
 
1653
        if (!scale) {
 
1654
            virUtilError(VIR_ERR_INTERNAL_ERROR,
 
1655
                         _("invalid scale %llu"), scale);
 
1656
            return -1;
 
1657
        }
 
1658
        suffix = "";
 
1659
    } else if (STRCASEEQ(suffix, "b") || STRCASEEQ(suffix, "byte") ||
 
1660
               STRCASEEQ(suffix, "bytes")) {
 
1661
        scale = 1;
 
1662
    } else {
 
1663
        int base;
 
1664
 
 
1665
        if (!suffix[1] || STRCASEEQ(suffix + 1, "iB")) {
 
1666
            base = 1024;
 
1667
        } else if (c_tolower(suffix[1]) == 'b' && !suffix[2]) {
 
1668
            base = 1000;
 
1669
        } else {
 
1670
            virUtilError(VIR_ERR_INVALID_ARG,
 
1671
                         _("unknown suffix '%s'"), suffix);
 
1672
            return -1;
 
1673
        }
 
1674
        scale = 1;
 
1675
        switch (c_tolower(*suffix)) {
 
1676
        case 'e':
 
1677
            scale *= base;
 
1678
            /* fallthrough */
 
1679
        case 'p':
 
1680
            scale *= base;
 
1681
            /* fallthrough */
 
1682
        case 't':
 
1683
            scale *= base;
 
1684
            /* fallthrough */
 
1685
        case 'g':
 
1686
            scale *= base;
 
1687
            /* fallthrough */
 
1688
        case 'm':
 
1689
            scale *= base;
 
1690
            /* fallthrough */
 
1691
        case 'k':
 
1692
            scale *= base;
 
1693
            break;
 
1694
        default:
 
1695
            virUtilError(VIR_ERR_INVALID_ARG,
 
1696
                         _("unknown suffix '%s'"), suffix);
 
1697
            return -1;
 
1698
        }
 
1699
    }
 
1700
 
 
1701
    if (*value && *value >= (limit / scale)) {
 
1702
        virUtilError(VIR_ERR_OVERFLOW, _("value too large: %llu%s"),
 
1703
                     *value, suffix);
 
1704
        return -1;
 
1705
    }
 
1706
    *value *= scale;
 
1707
    return 0;
 
1708
}
 
1709
 
1499
1710
/**
1500
1711
 * virSkipSpaces:
1501
1712
 * @str: pointer to the char pointer used
1602
1813
    const char *cur = *str;
1603
1814
 
1604
1815
    if ((*cur < '0') || (*cur > '9'))
1605
 
        return (-1);
 
1816
        return -1;
1606
1817
 
1607
1818
    while (c_isdigit(*cur)) {
1608
1819
        unsigned int c = *cur - '0';
1609
1820
 
1610
1821
        if ((ret > INT_MAX / 10) ||
1611
1822
            ((ret == INT_MAX / 10) && (c > INT_MAX % 10)))
1612
 
            return (-1);
 
1823
            return -1;
1613
1824
        ret = ret * 10 + c;
1614
1825
        cur++;
1615
1826
    }
1616
1827
    *str = cur;
1617
 
    return (ret);
 
1828
    return ret;
1618
1829
}
1619
1830
 
1620
1831
 
1740
1951
    return virStrncpy(dest, src, strlen(src), destbytes);
1741
1952
}
1742
1953
 
1743
 
/* Compare two MAC addresses, ignoring differences in case,
1744
 
 * as well as leading zeros.
1745
 
 */
1746
 
int
1747
 
virMacAddrCompare (const char *p, const char *q)
1748
 
{
1749
 
    unsigned char c, d;
1750
 
    do {
1751
 
        while (*p == '0' && c_isxdigit (p[1]))
1752
 
            ++p;
1753
 
        while (*q == '0' && c_isxdigit (q[1]))
1754
 
            ++q;
1755
 
        c = c_tolower (*p);
1756
 
        d = c_tolower (*q);
1757
 
 
1758
 
        if (c == 0 || d == 0)
1759
 
            break;
1760
 
 
1761
 
        ++p;
1762
 
        ++q;
1763
 
    } while (c == d);
1764
 
 
1765
 
    if (UCHAR_MAX <= INT_MAX)
1766
 
        return c - d;
1767
 
 
1768
 
    /* On machines where 'char' and 'int' are types of the same size, the
1769
 
       difference of two 'unsigned char' values - including the sign bit -
1770
 
       doesn't fit in an 'int'.  */
1771
 
    return (c > d ? 1 : c < d ? -1 : 0);
1772
 
}
1773
 
 
1774
 
/**
1775
 
 * virParseMacAddr:
1776
 
 * @str: string representation of MAC address, e.g., "0:1E:FC:E:3a:CB"
1777
 
 * @addr: 6-byte MAC address
1778
 
 *
1779
 
 * Parse a MAC address
1780
 
 *
1781
 
 * Return 0 upon success, or -1 in case of error.
1782
 
 */
1783
 
int
1784
 
virParseMacAddr(const char* str, unsigned char *addr)
1785
 
{
1786
 
    int i;
1787
 
 
1788
 
    errno = 0;
1789
 
    for (i = 0; i < VIR_MAC_BUFLEN; i++) {
1790
 
        char *end_ptr;
1791
 
        unsigned long result;
1792
 
 
1793
 
        /* This is solely to avoid accepting the leading
1794
 
         * space or "+" that strtoul would otherwise accept.
1795
 
         */
1796
 
        if (!c_isxdigit(*str))
1797
 
            break;
1798
 
 
1799
 
        result = strtoul(str, &end_ptr, 16);
1800
 
 
1801
 
        if ((end_ptr - str) < 1 || 2 < (end_ptr - str) ||
1802
 
            (errno != 0) ||
1803
 
            (0xFF < result))
1804
 
            break;
1805
 
 
1806
 
        addr[i] = (unsigned char) result;
1807
 
 
1808
 
        if ((i == 5) && (*end_ptr == '\0'))
1809
 
            return 0;
1810
 
        if (*end_ptr != ':')
1811
 
            break;
1812
 
 
1813
 
        str = end_ptr + 1;
1814
 
    }
1815
 
 
1816
 
    return -1;
1817
 
}
1818
 
 
1819
 
void virFormatMacAddr(const unsigned char *addr,
1820
 
                      char *str)
1821
 
{
1822
 
    snprintf(str, VIR_MAC_STRING_BUFLEN,
1823
 
             "%02X:%02X:%02X:%02X:%02X:%02X",
1824
 
             addr[0], addr[1], addr[2],
1825
 
             addr[3], addr[4], addr[5]);
1826
 
    str[VIR_MAC_STRING_BUFLEN-1] = '\0';
1827
 
}
1828
 
 
1829
 
void virGenerateMacAddr(const unsigned char *prefix,
1830
 
                        unsigned char *addr)
1831
 
{
1832
 
    addr[0] = prefix[0];
1833
 
    addr[1] = prefix[1];
1834
 
    addr[2] = prefix[2];
1835
 
    addr[3] = virRandom(256);
1836
 
    addr[4] = virRandom(256);
1837
 
    addr[5] = virRandom(256);
1838
 
}
1839
 
 
1840
 
 
1841
1954
int virEnumFromString(const char *const*types,
1842
1955
                      unsigned int ntypes,
1843
1956
                      const char *type)
2076
2189
}
2077
2190
 
2078
2191
 
2079
 
static char randomState[128];
2080
 
static struct random_data randomData;
2081
 
static virMutex randomLock;
2082
 
 
2083
 
int virRandomInitialize(unsigned int seed)
2084
 
{
2085
 
    if (virMutexInit(&randomLock) < 0)
2086
 
        return -1;
2087
 
 
2088
 
    if (initstate_r(seed,
2089
 
                    randomState,
2090
 
                    sizeof(randomState),
2091
 
                    &randomData) < 0)
2092
 
        return -1;
2093
 
 
2094
 
    return 0;
2095
 
}
2096
 
 
2097
 
int virRandom(int max)
2098
 
{
2099
 
    int32_t ret;
2100
 
 
2101
 
    virMutexLock(&randomLock);
2102
 
    random_r(&randomData, &ret);
2103
 
    virMutexUnlock(&randomLock);
2104
 
 
2105
 
    return (int) ((double)max * ((double)ret / (double)RAND_MAX));
2106
 
}
2107
 
 
2108
 
 
2109
2192
#ifdef HAVE_GETPWUID_R
2110
2193
enum {
2111
2194
    VIR_USER_ENT_DIRECTORY,
2166
2249
    return ret;
2167
2250
}
2168
2251
 
 
2252
static char *virGetGroupEnt(gid_t gid)
 
2253
{
 
2254
    char *strbuf;
 
2255
    char *ret;
 
2256
    struct group grbuf;
 
2257
    struct group *gr = NULL;
 
2258
    long val = sysconf(_SC_GETGR_R_SIZE_MAX);
 
2259
    size_t strbuflen = val;
 
2260
    int rc;
 
2261
 
 
2262
    /* sysconf is a hint; if it fails, fall back to a reasonable size */
 
2263
    if (val < 0)
 
2264
        strbuflen = 1024;
 
2265
 
 
2266
    if (VIR_ALLOC_N(strbuf, strbuflen) < 0) {
 
2267
        virReportOOMError();
 
2268
        return NULL;
 
2269
    }
 
2270
 
 
2271
    /*
 
2272
     * From the manpage (terrifying but true):
 
2273
     *
 
2274
     * ERRORS
 
2275
     *  0 or ENOENT or ESRCH or EBADF or EPERM or ...
 
2276
     *        The given name or gid was not found.
 
2277
     */
 
2278
    while ((rc = getgrgid_r(gid, &grbuf, strbuf, strbuflen, &gr)) == ERANGE) {
 
2279
        if (VIR_RESIZE_N(strbuf, strbuflen, strbuflen, strbuflen) < 0) {
 
2280
            virReportOOMError();
 
2281
            VIR_FREE(strbuf);
 
2282
            return NULL;
 
2283
        }
 
2284
    }
 
2285
    if (rc != 0 || gr == NULL) {
 
2286
        virReportSystemError(rc,
 
2287
                             _("Failed to find group record for gid '%u'"),
 
2288
                             (unsigned int) gid);
 
2289
        VIR_FREE(strbuf);
 
2290
        return NULL;
 
2291
    }
 
2292
 
 
2293
    ret = strdup(gr->gr_name);
 
2294
 
 
2295
    VIR_FREE(strbuf);
 
2296
    if (!ret)
 
2297
        virReportOOMError();
 
2298
 
 
2299
    return ret;
 
2300
}
 
2301
 
2169
2302
char *virGetUserDirectory(uid_t uid)
2170
2303
{
2171
2304
    return virGetUserEnt(uid, VIR_USER_ENT_DIRECTORY);
2176
2309
    return virGetUserEnt(uid, VIR_USER_ENT_NAME);
2177
2310
}
2178
2311
 
 
2312
char *virGetGroupName(gid_t gid)
 
2313
{
 
2314
    return virGetGroupEnt(gid);
 
2315
}
 
2316
 
2179
2317
 
2180
2318
int virGetUserID(const char *name,
2181
2319
                 uid_t *uid)
2395
2533
                 "%s", _("virSetUIDGID is not available"));
2396
2534
    return -1;
2397
2535
}
 
2536
 
 
2537
char *
 
2538
virGetGroupName(gid_t gid ATTRIBUTE_UNUSED)
 
2539
{
 
2540
    virUtilError(VIR_ERR_INTERNAL_ERROR,
 
2541
                 "%s", _("virGetGroupName is not available"));
 
2542
 
 
2543
    return NULL;
 
2544
}
2398
2545
#endif /* HAVE_GETPWUID_R */
2399
2546
 
2400
2547
 
2515
2662
    return false;
2516
2663
}
2517
2664
#endif
2518
 
 
2519
 
int virEmitXMLWarning(int fd,
2520
 
                      const char *name,
2521
 
                      const char *cmd) {
2522
 
    size_t len;
2523
 
    const char *prologue = "<!--\n\
2524
 
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE \n\
2525
 
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:\n\
2526
 
  virsh ";
2527
 
    const char *epilogue = "\n\
2528
 
or other application using the libvirt API.\n\
2529
 
-->\n\n";
2530
 
 
2531
 
    if (fd < 0 || !name || !cmd) {
2532
 
        errno = EINVAL;
2533
 
        return -1;
2534
 
    }
2535
 
 
2536
 
    len = strlen(prologue);
2537
 
    if (safewrite(fd, prologue, len) != len)
2538
 
        return -1;
2539
 
 
2540
 
    len = strlen(cmd);
2541
 
    if (safewrite(fd, cmd, len) != len)
2542
 
        return -1;
2543
 
 
2544
 
    if (safewrite(fd, " ", 1) != 1)
2545
 
        return -1;
2546
 
 
2547
 
    len = strlen(name);
2548
 
    if (safewrite(fd, name, len) != len)
2549
 
        return -1;
2550
 
 
2551
 
    len = strlen(epilogue);
2552
 
    if (safewrite(fd, epilogue, len) != len)
2553
 
        return -1;
2554
 
 
2555
 
    return 0;
2556
 
}
2557
 
 
2558
 
void
2559
 
virTypedParameterArrayClear(virTypedParameterPtr params, int nparams)
2560
 
{
2561
 
    int i;
2562
 
 
2563
 
    if (!params)
2564
 
        return;
2565
 
 
2566
 
    for (i = 0; i < nparams; i++) {
2567
 
        if (params[i].type == VIR_TYPED_PARAM_STRING)
2568
 
            VIR_FREE(params[i].value.s);
2569
 
    }
2570
 
}