VirtualBox

Changeset 105016 in vbox


Ignore:
Timestamp:
Jun 25, 2024 10:28:21 AM (5 months ago)
Author:
vboxsync
Message:

doc/manual,include/VBox,Frontends/VBoxManage,HostServices/SharedFolders,
Main/{include,SharedFolder,Console,Machine,VirtualBox.xidl}: Add a
new attribute to ISharedFolder for specifying a symbolic link creation
policy to restrict the source pathname when creating symbolic links
within a guest. The symbolic link policies are represented by a new
enumeration of type SymlinkPolicy_T which includes values for no
restrictions ('any'), symlink sources only within the subtree of the
share ('subtree'), symlink sources as any relative path ('relative'),
and no symlinks allowed ('forbidden'). The symlink policy can only be
applied to permanent shared folders at this stage. bugref:10619

Location:
trunk
Files:
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/manual/en_US/man_VBoxManage-sharedfolder.xml

    r99513 r105016  
    4242  <refnamediv>
    4343    <refname>VBoxManage-sharedfolder</refname>
    44     <refpurpose>add and remove shared folders</refpurpose>
     44    <refpurpose>add and remove shared folders, configure security policy for shared folders</refpurpose>
    4545    <refclass>&product-name;</refclass>
    4646  </refnamediv>
     
    5454        <arg choice="plain"><replaceable>vmname</replaceable></arg>
    5555      </group>
    56       <arg choice="req">--name=<replaceable>name</replaceable></arg>
     56      <arg choice="req">--name=<replaceable>share-name</replaceable></arg>
    5757      <arg choice="req">--hostpath=<replaceable>hostpath</replaceable></arg>
    5858      <arg>--readonly</arg>
     
    6868        <arg choice="plain"><replaceable>vmname</replaceable></arg>
    6969      </group>
    70       <arg choice="req">--name=<replaceable>name</replaceable></arg>
     70      <arg choice="req">--name=<replaceable>share-name</replaceable></arg>
    7171      <arg>--transient</arg>
     72    </cmdsynopsis>
     73
     74    <cmdsynopsis id="synopsis-vboxmanage-sharedfolder-modify">
     75      <command>VBoxManage sharedfolder modify</command>
     76      <group choice="req">
     77        <arg choice="plain"><replaceable>uuid</replaceable></arg>
     78        <arg choice="plain"><replaceable>vmname</replaceable></arg>
     79      </group>
     80      <arg choice="req">--name=<replaceable>share-name</replaceable></arg>
     81      <arg choice="req">--symlink-policy=
     82        <group choice="plain">
     83          <arg choice="plain">forbidden</arg>
     84          <arg choice="plain">subtree</arg>
     85          <arg choice="plain">relative</arg>
     86          <arg choice="plain">any</arg>
     87        </group>
     88      </arg>
    7289    </cmdsynopsis>
    7390  </refsynopsisdiv>
     
    103120        </varlistentry>
    104121        <varlistentry>
    105           <term>--name=<replaceable>name</replaceable></term>
     122          <term>--name=<replaceable>share-name</replaceable></term>
    106123          <listitem><para>
    107124              Specifies the name of the share, which is a unique name
     
    178195        </varlistentry>
    179196        <varlistentry>
    180           <term>--name=<replaceable>name</replaceable></term>
     197          <term>--name=<replaceable>share-name</replaceable></term>
    181198          <listitem><para>
    182199              Specifies the name of the share to remove.
     
    193210      </variablelist>
    194211    </refsect2>
     212    <refsect2 id="vboxmanage-sharedfolder-modify">
     213      <title>Modify a Shared Folder's Configuration</title>
     214      <remark role="help-copy-synopsis"/>
     215      <para>
     216        The <command>VBoxManage sharedfolder modify</command> command
     217        modifies the configuration of a Shared Folder.
     218      </para>
     219      <variablelist>
     220        <varlistentry>
     221          <term><option><replaceable>uuid</replaceable> | <replaceable>vmname</replaceable></option></term>
     222          <listitem><para>
     223              Specifies the name or UUID of the guest VM that shares a
     224              folder with the host system.
     225            </para></listitem>
     226        </varlistentry>
     227        <varlistentry>
     228          <term>--name=<replaceable>share-name</replaceable></term>
     229          <listitem><para>
     230              Specifies the name of the share to apply the security policy to.
     231            </para></listitem>
     232        </varlistentry>
     233        <varlistentry>
     234          <term>--symlink-policy=<replaceable>policy-name</replaceable></term>
     235          <listitem><para>
     236              Specifies the symbolic link security policy of the shared folder.
     237              Valid symlink security policies are:
     238                  <literal>forbidden</literal>, <literal>subtree</literal>,
     239                  <literal>relative</literal>, and <literal>any</literal>.
     240            </para></listitem>
     241        </varlistentry>
     242      </variablelist>
     243    </refsect2>
    195244  </refsect1>
    196245
     
    199248    <remark role="help-scope" condition="GLOBAL" />
    200249    <para>
    201       The following command creates a shared folder called
    202       <filename>o7share</filename> for the <filename>ol7</filename> VM.
    203       The share is mounted automatically when the VM is started.
     250      The following command creates a shared folder named
     251      <filename>o7share</filename> for the <filename>ol7</filename> VM
     252      and configures the share to be mounted automatically when the VM
     253      is started.
    204254    </para>
    205255<screen>$ VBoxManage sharedfolder add ol7 --name ol7share --hostpath "/home/user/ol7share" --automount</screen>
    206256    <para>
    207       The following command removes the shared folder called
    208       <filename>o7share</filename> for the <filename>ol7</filename> VM.
     257      The following command removes the shared folder named
     258      <filename>o7share</filename> from the <filename>ol7</filename> VM.
    209259    </para>
    210260<screen>$ VBoxManage sharedfolder remove ol7 --name ol7share</screen>
  • trunk/include/VBox/settings.h

    r103090 r105016  
    10091009    bool            fAutoMount;
    10101010    com::Utf8Str    strAutoMountPoint;
     1011    SymlinkPolicy_T enmSymlinkPolicy;
    10111012};
    10121013
  • trunk/include/VBox/shflsvc.h

    r99802 r105016  
    21232123#define SHFL_ADD_MAPPING_F_MISSING          (RT_BIT_32(3))
    21242124
    2125 #define SHFL_CPARMS_ADD_MAPPING  (4)
     2125#define SHFL_CPARMS_ADD_MAPPING  (5)
    21262126/** @} */
    21272127
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp

    r103594 r105016  
    799799}
    800800
     801static const char *symlinkPolicyToName(SymlinkPolicy_T enmSymlinkPolicy)
     802{
     803    switch (enmSymlinkPolicy)
     804    {
     805        case SymlinkPolicy_AllowedToAnyTarget:
     806            return ("any");
     807        case SymlinkPolicy_AllowedInShareSubtree:
     808            return ("subtree");
     809        case SymlinkPolicy_AllowedToRelativeTargets:
     810            return ("relative");
     811        case SymlinkPolicy_Forbidden:
     812            return("forbidden");
     813        default:
     814            return("none");
     815    }
     816}
     817
    801818/** Shows a shared folder.   */
    802819static HRESULT showSharedFolder(ComPtr<ISharedFolder> &sf, VMINFO_DETAILS details, const char *pszDesc,
     
    805822    Bstr name, hostPath, bstrAutoMountPoint;
    806823    BOOL writable = FALSE, fAutoMount = FALSE;
     824    SymlinkPolicy_T enmSymlinkPolicy = SymlinkPolicy_None;
    807825    CHECK_ERROR2I_RET(sf, COMGETTER(Name)(name.asOutParam()), hrcCheck);
    808826    CHECK_ERROR2I_RET(sf, COMGETTER(HostPath)(hostPath.asOutParam()), hrcCheck);
     
    810828    CHECK_ERROR2I_RET(sf, COMGETTER(AutoMount)(&fAutoMount), hrcCheck);
    811829    CHECK_ERROR2I_RET(sf, COMGETTER(AutoMountPoint)(bstrAutoMountPoint.asOutParam()), hrcCheck);
     830    CHECK_ERROR2I_RET(sf, COMGETTER(SymlinkPolicy)(&enmSymlinkPolicy), hrcCheck);
    812831
    813832    if (fFirst && details != VMINFO_MACHINEREADABLE)
     
    824843                 name.raw(), hostPath.raw(), pszDesc, writable ? Info::tr("writable") : Info::tr("readonly"),
    825844                 fAutoMount ? Info::tr(", auto-mount") : "");
     845        if (enmSymlinkPolicy != SymlinkPolicy_None)
     846            RTPrintf(Info::tr(", symlink-policy: %s"), symlinkPolicyToName(enmSymlinkPolicy));
    826847        if (bstrAutoMountPoint.isNotEmpty())
    827848            RTPrintf(Info::tr(", mount-point: '%ls'\n"), bstrAutoMountPoint.raw());
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp

    r103411 r105016  
    16371637            case VINF_GETOPT_NOT_OPTION:
    16381638                if (pszMachineName)
    1639                     return errorArgument(Misc::tr("Machine name is given more than once: first '%s', then '%s'"),
     1639                    return errorArgument(Misc::tr("Machine name given more than once: first '%s', then '%s'"),
    16401640                                         pszMachineName, ValueUnion.psz);
    16411641                pszMachineName = ValueUnion.psz;
     
    17491749            case VINF_GETOPT_NOT_OPTION:
    17501750                if (pszMachineName)
    1751                     return errorArgument(Misc::tr("Machine name is given more than once: first '%s', then '%s'"),
     1751                    return errorArgument(Misc::tr("Machine name given more than once: first '%s', then '%s'"),
    17521752                                         pszMachineName, ValueUnion.psz);
    17531753                pszMachineName = ValueUnion.psz;
     
    18101810}
    18111811
     1812static SymlinkPolicy_T nameToSymlinkPolicy(const char *pszName)
     1813{
     1814    if (!RTStrICmp(pszName, "forbidden"))
     1815        return SymlinkPolicy_Forbidden;
     1816    if (!RTStrICmp(pszName, "subtree"))
     1817        return SymlinkPolicy_AllowedInShareSubtree;
     1818    if (!RTStrICmp(pszName, "relative"))
     1819        return SymlinkPolicy_AllowedToRelativeTargets;
     1820    if (!RTStrICmp(pszName, "any"))
     1821        return SymlinkPolicy_AllowedToAnyTarget;
     1822
     1823    return SymlinkPolicy_None;
     1824}
     1825
     1826/**
     1827 * modify shared folder properties
     1828 */
     1829static RTEXITCODE handleSharedFolderModify(HandlerArg *a)
     1830{
     1831    /*
     1832     * Parse arguments (argv[0] == subcommand).
     1833     */
     1834    static const RTGETOPTDEF s_aModifyOptions[] =
     1835    {
     1836        { "--name",             'n', RTGETOPT_REQ_STRING },
     1837        { "-name",              'n', RTGETOPT_REQ_STRING },     // deprecated
     1838        { "--transient",        't', RTGETOPT_REQ_NOTHING },
     1839        { "-transient",         't', RTGETOPT_REQ_NOTHING },    // deprecated
     1840        { "--symlink-policy",   's', RTGETOPT_REQ_STRING },
     1841        { "-symlink-policy",    's', RTGETOPT_REQ_STRING },     // deprecated
     1842    };
     1843    const char *pszMachineName    = NULL;
     1844    const char *pszName           = NULL;
     1845    bool        fTransient        = false;
     1846    SymlinkPolicy_T enmSymlinkPolicy = SymlinkPolicy_None;
     1847
     1848    RTGETOPTSTATE GetState;
     1849    RTGetOptInit(&GetState, a->argc, a->argv, s_aModifyOptions, RT_ELEMENTS(s_aModifyOptions), 1 /*iFirst*/, 0 /*fFlags*/);
     1850    int c;
     1851    RTGETOPTUNION ValueUnion;
     1852    while ((c = RTGetOpt(&GetState, &ValueUnion)))
     1853    {
     1854        switch (c)
     1855        {
     1856            case 'n':
     1857                pszName = ValueUnion.psz;
     1858                break;
     1859            case 't':
     1860                fTransient = true;
     1861                break;
     1862            case 's':
     1863                enmSymlinkPolicy = nameToSymlinkPolicy(ValueUnion.psz);
     1864                if (enmSymlinkPolicy == SymlinkPolicy_None)
     1865                    return errorArgument(Misc::tr("Invalid --symlink-policy argument '%s'"), ValueUnion.psz);
     1866                break;
     1867            case VINF_GETOPT_NOT_OPTION:
     1868                if (pszMachineName)
     1869                    return errorArgument(Misc::tr("Machine name given more than once: first '%s', then '%s'"),
     1870                                         pszMachineName, ValueUnion.psz);
     1871                pszMachineName = ValueUnion.psz;
     1872                break;
     1873            default:
     1874                return errorGetOpt(c, &ValueUnion);
     1875        }
     1876    }
     1877
     1878    if (!pszMachineName)
     1879        return errorSyntax(Misc::tr("No machine was specified"));
     1880    if (!pszName)
     1881        return errorSyntax(Misc::tr("No shared folder name (--name) was supplied."));
     1882
     1883    /* the only supported option at the moment so it must be set */
     1884    if (enmSymlinkPolicy == SymlinkPolicy_None)
     1885        return errorSyntax(Misc::tr("No symbolic link policy (--symlink-policy) was supplied."));
     1886
     1887    /*
     1888     * Done parsing, do some real work.
     1889     */
     1890    ComPtr<IMachine> ptrMachine;
     1891    CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
     1892    AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
     1893
     1894    HRESULT hrc;
     1895    if (fTransient)
     1896    {
     1897        /* open an existing session for the VM */
     1898        CHECK_ERROR_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
     1899
     1900        /* get the session machine */
     1901        ComPtr<IMachine> ptrSessionMachine;
     1902        CHECK_ERROR_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
     1903
     1904        /* get the session console */
     1905        ComPtr<IConsole> ptrConsole;
     1906        CHECK_ERROR_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
     1907        if (ptrConsole.isNull())
     1908            return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running.\n"), pszMachineName);
     1909
     1910        /* find the desired transient shared folder to modify */
     1911        com::SafeIfaceArray <ISharedFolder> sharedFolders;
     1912        CHECK_ERROR_RET(ptrConsole, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sharedFolders)), RTEXITCODE_FAILURE);
     1913        if (sharedFolders.size() == 0)
     1914            return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' has no transient shared folders configured.\n"),
     1915                                  pszMachineName);
     1916
     1917        bool fFound = false;
     1918        for (size_t i = 0; i < sharedFolders.size(); ++i)
     1919        {
     1920            ComPtr<ISharedFolder> sharedFolder = sharedFolders[i];
     1921            Bstr bstrSharedFolderName;
     1922            CHECK_ERROR_RET(sharedFolder, COMGETTER(Name)(bstrSharedFolderName.asOutParam()), RTEXITCODE_FAILURE);
     1923            Utf8Str strSharedFolderName(bstrSharedFolderName);
     1924            if (!RTStrCmp(strSharedFolderName.c_str(), pszName))
     1925            {
     1926                CHECK_ERROR_RET(sharedFolder, COMSETTER(SymlinkPolicy)(enmSymlinkPolicy), RTEXITCODE_FAILURE);
     1927                fFound = true;
     1928                break;
     1929            }
     1930        }
     1931        if (!fFound)
     1932            return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Could not find a transient shared folder named '%s'.\n"),
     1933                                  pszName);
     1934
     1935        CHECK_ERROR_RET(a->session, UnlockMachine(), RTEXITCODE_FAILURE);
     1936    }
     1937    else
     1938    {
     1939        /* open a session for the VM */
     1940        CHECK_ERROR_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
     1941
     1942        /* get the mutable session machine */
     1943        ComPtr<IMachine> ptrSessionMachine;
     1944        CHECK_ERROR_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
     1945
     1946        /* find the desired shared folder to modify */
     1947        com::SafeIfaceArray <ISharedFolder> sharedFolders;
     1948        CHECK_ERROR_RET(ptrSessionMachine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sharedFolders)), RTEXITCODE_FAILURE);
     1949        if (sharedFolders.size() == 0)
     1950            return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' has no shared folders configured.\n"),
     1951                                  pszMachineName);
     1952
     1953        bool fFound = false;
     1954        for (size_t i = 0; i < sharedFolders.size(); ++i)
     1955        {
     1956            ComPtr<ISharedFolder> sharedFolder = sharedFolders[i];
     1957            Bstr bstrSharedFolderName;
     1958            CHECK_ERROR_RET(sharedFolder, COMGETTER(Name)(bstrSharedFolderName.asOutParam()), RTEXITCODE_FAILURE);
     1959            Utf8Str strSharedFolderName(bstrSharedFolderName);
     1960            if (!RTStrCmp(strSharedFolderName.c_str(), pszName))
     1961            {
     1962                CHECK_ERROR_RET(sharedFolder, COMSETTER(SymlinkPolicy)(enmSymlinkPolicy), RTEXITCODE_FAILURE);
     1963                fFound = true;
     1964                break;
     1965            }
     1966        }
     1967        if (!fFound)
     1968            return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Could not find a shared folder named '%s'.\n"), pszName);
     1969
     1970        /* commit and close the session */
     1971        if (SUCCEEDED(hrc))
     1972            CHECK_ERROR(ptrSessionMachine, SaveSettings());
     1973
     1974        CHECK_ERROR_RET(a->session, UnlockMachine(), RTEXITCODE_FAILURE);
     1975    }
     1976
     1977    return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
     1978}
    18121979
    18131980RTEXITCODE handleSharedFolder(HandlerArg *a)
     
    18261993        setCurrentSubcommand(HELP_SCOPE_SHAREDFOLDER_REMOVE);
    18271994        return handleSharedFolderRemove(a);
     1995    }
     1996
     1997    if (!strcmp(a->argv[0], "modify"))
     1998    {
     1999        setCurrentSubcommand(HELP_SCOPE_SHAREDFOLDER_MODIFY);
     2000        return handleSharedFolderModify(a);
    18282001    }
    18292002
  • trunk/src/VBox/HostServices/SharedFolders/Makefile.kmk

    r98133 r105016  
    3939VBoxSharedFolders_NAME.os2  = VBoxSFld
    4040VBoxSharedFolders_DEFS      = VBOX_WITH_HGCM RTSHFL
     41ifneq ($(KBUILD_TARGET),win)
     42 VBoxSharedFolders_DEFS    += VBOX_WITH_XPCOM
     43 VBoxSharedFolders_INCS     = $(VBOX_XPCOM_INCS)
     44endif
    4145VBoxSharedFolders_INCS.win  = \
    42         $(VBOX_PATH_SDK)
     46        $(VBOX_PATH_SDK) \
     47        $(VBOX_PATH_SDK)/bindings/mscom/include
    4348
    4449VBoxSharedFolders_LDFLAGS.darwin = \
  • trunk/src/VBox/HostServices/SharedFolders/VBoxSharedFoldersSvc.cpp

    r99802 r105016  
    164164
    165165
    166 static DECLCALLBACK(int) svcUnload (void *)
     166static DECLCALLBACK(int) svcUnload(void *)
    167167{
    168168    int rc = VINF_SUCCESS;
     
    176176}
    177177
    178 static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient, uint32_t fRequestor, bool fRestoring)
     178static DECLCALLBACK(int) svcConnect(void *, uint32_t u32ClientID, void *pvClient, uint32_t fRequestor, bool fRestoring)
    179179{
    180180    RT_NOREF(u32ClientID, fRequestor, fRestoring);
     
    187187}
    188188
    189 static DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
     189static DECLCALLBACK(int) svcDisconnect(void *, uint32_t u32ClientID, void *pvClient)
    190190{
    191191    RT_NOREF1(u32ClientID);
     
    455455}
    456456
    457 static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient,
    458                                    uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival)
     457static DECLCALLBACK(void) svcCall(void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient,
     458                                  uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival)
    459459{
    460460    RT_NOREF(u32ClientID, tsArrival);
     
    618618                   )
    619619                {
    620                     AssertMsgFailed (("Invalid parameters cbPath or cbParms (%x, %x - expected >=%x, %x)\n",
     620                    AssertMsgFailed(("Invalid parameters cbPath or cbParms (%x, %x - expected >=%x, %x)\n",
    621621                                      cbPath, cbParms, sizeof(SHFLSTRING), sizeof (SHFLCREATEPARMS)));
    622622                    rc = VERR_INVALID_PARAMETER;
     
    631631
    632632                    /* Execute the function. */
    633                     rc = vbsfCreate (pClient, root, pPath, cbPath, pParms);
     633                    rc = vbsfCreate(pClient, root, pPath, cbPath, pParms);
    634634
    635635                    if (RT_SUCCESS(rc))
     
    680680                {
    681681                    /* Execute the function. */
    682                     rc = vbsfClose (pClient, root, Handle);
     682                    rc = vbsfClose(pClient, root, Handle);
    683683
    684684                    if (RT_SUCCESS(rc))
     
    845845                     *       completed, the another thread must call
    846846                     *
    847                      *           g_pHelpers->pfnCallComplete (callHandle, rc);
     847                     *           g_pHelpers->pfnCallComplete(callHandle, rc);
    848848                     *
    849849                     * The operation is async.
     
    939939
    940940                    /* Execute the function. */
    941                     rc = vbsfDirList (pClient, root, Handle, pPath, flags, &length, pBuffer, &resumePoint, &cFiles);
     941                    rc = vbsfDirList(pClient, root, Handle, pPath, flags, &length, pBuffer, &resumePoint, &cFiles);
    942942
    943943                    if (g_pStatusLed)
     
    10021002                {
    10031003                    /* Execute the function. */
    1004                     rc = vbsfReadLink (pClient, root, pPath, cbPath, pBuffer, cbBuffer);
     1004                    rc = vbsfReadLink(pClient, root, pPath, cbPath, pBuffer, cbBuffer);
    10051005
    10061006                    if (RT_SUCCESS(rc))
     
    10481048                {
    10491049                    /* Execute the function. */
    1050                     rc = vbsfMapFolder (pClient, pszMapName, delimiter, false,  &root);
     1050                    rc = vbsfMapFolder(pClient, pszMapName, delimiter, false,  &root);
    10511051
    10521052                    if (RT_SUCCESS(rc))
     
    11181118                /* Execute the function. */
    11191119                if (RT_SUCCESS(rc))
    1120                     rc = vbsfMapFolder (pClient, pszMapName, delimiter, fCaseSensitive, &root);
     1120                    rc = vbsfMapFolder(pClient, pszMapName, delimiter, fCaseSensitive, &root);
    11211121
    11221122                if (RT_SUCCESS(rc))
     
    11561156
    11571157                /* Execute the function. */
    1158                 rc = vbsfUnmapFolder (pClient, root);
     1158                rc = vbsfUnmapFolder(pClient, root);
    11591159
    11601160                if (RT_SUCCESS(rc))
     
    12081208                    if (flags & SHFL_INFO_SET)
    12091209                    {
    1210                         rc = vbsfSetFSInfo (pClient, root, Handle, flags, &length, pBuffer);
     1210                        rc = vbsfSetFSInfo(pClient, root, Handle, flags, &length, pBuffer);
    12111211
    12121212                        if (flags & SHFL_INFO_FILE)
     
    12231223                    else /* SHFL_INFO_GET */
    12241224                    {
    1225                         rc = vbsfQueryFSInfo (pClient, root, Handle, flags, &length, pBuffer);
     1225                        rc = vbsfQueryFSInfo(pClient, root, Handle, flags, &length, pBuffer);
    12261226
    12271227                        if (flags & SHFL_INFO_FILE)
     
    13391339                {
    13401340                    /* Execute the function. */
    1341                     rc = vbsfRename (pClient, root, pSrc, pDest, flags);
     1341                    rc = vbsfRename(pClient, root, pSrc, pDest, flags);
    13421342                    if (RT_SUCCESS(rc))
    13431343                    {
     
    13891389                    /* Execute the function. */
    13901390
    1391                     rc = vbsfFlush (pClient, root, Handle);
     1391                    rc = vbsfFlush(pClient, root, Handle);
    13921392
    13931393                    if (RT_SUCCESS(rc))
     
    14471447                {
    14481448                    /* Execute the function. */
    1449                     rc = vbsfSymlink (pClient, root, pNewPath, pOldPath, pInfo);
     1449                    rc = vbsfSymlink(pClient, root, pNewPath, pOldPath, pInfo);
    14501450                    if (RT_SUCCESS(rc))
    14511451                    {
     
    16461646         * it was processed synchronously.
    16471647         */
    1648         g_pHelpers->pfnCallComplete (callHandle, rc);
     1648        g_pHelpers->pfnCallComplete(callHandle, rc);
    16491649    }
    16501650
     
    16681668 * security reasons.
    16691669 */
    1670 static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1670static DECLCALLBACK(int) svcHostCall(void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    16711671{
    16721672    int rc = VINF_SUCCESS;
     
    17001700                 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT   /* fFlags */
    17011701                 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR     /* auto mount point */
     1702                 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT   /* symlink policy */
    17021703                )
    17031704        {
     
    17111712            uint32_t fFlags             = paParms[2].u.uint32;
    17121713            SHFLSTRING *pAutoMountPoint = (SHFLSTRING *)paParms[3].u.pointer.addr;
     1714            SymlinkPolicy_T enmSymlinkPolicy = (SymlinkPolicy_T)paParms[4].u.uint32;
    17131715
    17141716            /* Verify parameters values. */
     
    17411743                                         RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_CREATE_SYMLINKS),
    17421744                                         RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_MISSING),
    1743                                          /* fPlaceholder = */ false);
     1745                                         /* fPlaceholder = */ false,
     1746                                         enmSymlinkPolicy);
    17441747                    if (RT_SUCCESS(rc))
    17451748                    {
     
    17851788            {
    17861789                /* Execute the function. */
    1787                 rc = vbsfMappingsRemove (pString);
     1790                rc = vbsfMappingsRemove(pString);
    17881791
    17891792                if (RT_SUCCESS(rc))
     
    18441847}
    18451848
    1846 extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
     1849extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad(VBOXHGCMSVCFNTABLE *ptable)
    18471850{
    18481851    int rc = VINF_SUCCESS;
  • trunk/src/VBox/HostServices/SharedFolders/mappings.cpp

    r99802 r105016  
    186186    return vbsfMappingsAdd(pLoadedMapping->pszFolderName, pLoadedMapping->pMapName,
    187187                           pLoadedMapping->fWritable, pLoadedMapping->fAutoMount, pLoadedMapping->pAutoMountPoint,
    188                            pLoadedMapping->fSymlinksCreate, /* fMissing = */ true, /* fPlaceholder = */ true);
     188                           pLoadedMapping->fSymlinksCreate, /* fMissing = */ true, /* fPlaceholder = */ true,
     189                           pLoadedMapping->enmSymlinkPolicy);
    189190}
    190191
     
    340341 */
    341342int vbsfMappingsAdd(const char *pszFolderName, PSHFLSTRING pMapName, bool fWritable,
    342                     bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fSymlinksCreate, bool fMissing, bool fPlaceholder)
     343                    bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fSymlinksCreate, bool fMissing, bool fPlaceholder,
     344                    SymlinkPolicy_T enmSymlinkPolicy)
    343345{
    344346    unsigned i;
     
    369371    for (i = 0; i < SHFL_MAX_MAPPINGS; i++)
    370372    {
    371         if (g_FolderMapping[i].fValid == false)
     373        if (!g_FolderMapping[i].fValid)
    372374        {
    373375            /* Make sure the folder name is an absolute path, otherwise we're
     
    398400            g_FolderMapping[i].fPlaceholder    = fPlaceholder;
    399401            g_FolderMapping[i].fLoadedRootId   = false;
     402            g_FolderMapping[i].enmSymlinkPolicy = enmSymlinkPolicy;
    400403
    401404            /* Check if the host file system is case sensitive */
     
    446449    for (unsigned i = 0; i < SHFL_MAX_MAPPINGS; i++)
    447450    {
    448         if (g_FolderMapping[i].fValid == true)
     451        if (g_FolderMapping[i].fValid)
    449452        {
    450453            if (!RTUtf16LocaleICmp(g_FolderMapping[i].pMapName->String.utf16, pMapName->String.utf16))
     
    599602int vbsfMappingsQueryName(PSHFLCLIENTDATA pClient, SHFLROOT root, SHFLSTRING *pString)
    600603{
    601     LogFlow(("vbsfMappingsQuery: pClient = %p, root = %d, *pString = %p\n", pClient, root, pString));
     604    LogFlow(("vbsfMappingsQueryName: pClient = %p, root = %d, *pString = %p\n", pClient, root, pString));
    602605
    603606    int rc;
     
    633636        rc = VERR_INVALID_PARAMETER;
    634637
    635     LogFlow(("vbsfMappingsQuery:Name return rc = %Rrc\n", rc));
     638    LogFlow(("vbsfMappingsQueryName returns rc = %Rrc\n", rc));
    636639    return rc;
    637640}
     
    655658        rc = VERR_FILE_NOT_FOUND;
    656659
    657     LogFlow(("vbsfMappingsQuery:Writable return rc = %Rrc\n", rc));
     660    LogFlow(("vbsfMappingsQueryWritable returns rc = %Rrc\n", rc));
    658661
    659662    return rc;
     
    670673    AssertReturn(pFolderMapping, VERR_INVALID_PARAMETER);
    671674
    672     if (pFolderMapping->fValid == true)
     675    if (pFolderMapping->fValid)
    673676        *fAutoMount = pFolderMapping->fAutoMount;
    674677    else
    675678        rc = VERR_FILE_NOT_FOUND;
    676679
    677     LogFlow(("vbsfMappingsQueryAutoMount:Writable return rc = %Rrc\n", rc));
     680    LogFlow(("vbsfMappingsQueryAutoMount returns rc = %Rrc\n", rc));
    678681
    679682    return rc;
     
    685688    int rc = VINF_SUCCESS;
    686689
    687     LogFlow(("vbsfMappingsQueryAutoMount: pClient = %p, root = %d\n", pClient, root));
     690    LogFlow(("vbsfMappingsQuerySymlinksCreate: pClient = %p, root = %d\n", pClient, root));
    688691
    689692    MAPPING *pFolderMapping = vbsfMappingGetByRoot(root);
    690693    AssertReturn(pFolderMapping, VERR_INVALID_PARAMETER);
    691694
    692     if (pFolderMapping->fValid == true)
     695    if (pFolderMapping->fValid)
    693696        *fSymlinksCreate = pFolderMapping->fSymlinksCreate;
    694697    else
    695698        rc = VERR_FILE_NOT_FOUND;
    696699
    697     LogFlow(("vbsfMappingsQueryAutoMount:SymlinksCreate return rc = %Rrc\n", rc));
     700    LogFlow(("vbsfMappingsQuerySymlinksCreate returns rc = %Rrc\n", rc));
     701
     702    return rc;
     703}
     704
     705int vbsfMappingsQuerySymlinkPolicy(PSHFLCLIENTDATA pClient, SHFLROOT root, SymlinkPolicy_T *enmSymlinkPolicy)
     706{
     707    RT_NOREF1(pClient);
     708    int rc = VINF_SUCCESS;
     709
     710    LogFlow(("vbsfMappingsQuerySymlinkPolicy: pClient = %p, root = %d\n", pClient, root));
     711
     712    MAPPING *pFolderMapping = vbsfMappingGetByRoot(root);
     713    AssertReturn(pFolderMapping, VERR_INVALID_PARAMETER);
     714
     715    if (pFolderMapping->fValid)
     716        *enmSymlinkPolicy = pFolderMapping->enmSymlinkPolicy;
     717    else
     718        rc = VERR_FILE_NOT_FOUND;
     719
     720    LogFlow(("vbsfMappingsQuerySymlinkPolicy returns rc = %Rrc\n", rc));
    698721
    699722    return rc;
     
    879902        return VERR_FILE_NOT_FOUND;
    880903    }
    881     Assert(pFolderMapping->fValid == true && pFolderMapping->cMappings > 0);
     904    Assert(pFolderMapping->fValid && pFolderMapping->cMappings > 0);
    882905
    883906    AssertLogRelReturn(root < RT_ELEMENTS(pClient->acMappings), VERR_INTERNAL_ERROR);
  • trunk/src/VBox/HostServices/SharedFolders/mappings.h

    r98103 r105016  
    5252                                             still has. fMissing is always true for this mapping. */
    5353    bool        fLoadedRootId;          /**< Set if vbsfMappingLoaded has found this mapping already. */
     54    SymlinkPolicy_T enmSymlinkPolicy;   /**< Symbolic link creation policy within the guest. */
    5455} MAPPING;
    5556/** Pointer to a MAPPING structure. */
     
    6162
    6263int vbsfMappingsAdd(const char *pszFolderName, PSHFLSTRING pMapName, bool fWritable,
    63                     bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fCreateSymlinks, bool fMissing, bool fPlaceholder);
     64                    bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fCreateSymlinks, bool fMissing, bool fPlaceholder,
     65                    SymlinkPolicy_T enmSymlinkPolicy);
    6466int vbsfMappingsRemove(PSHFLSTRING pMapName);
    6567
     
    6971int vbsfMappingsQueryAutoMount(PSHFLCLIENTDATA pClient, SHFLROOT root, bool *fAutoMount);
    7072int vbsfMappingsQuerySymlinksCreate(PSHFLCLIENTDATA pClient, SHFLROOT root, bool *fSymlinksCreate);
     73int vbsfMappingsQuerySymlinkPolicy(PSHFLCLIENTDATA pClient, SHFLROOT root, SymlinkPolicy_T *enmSymlinkPolicy);
    7174int vbsfMappingsQueryInfo(PSHFLCLIENTDATA pClient, SHFLROOT root, PSHFLSTRING pNameBuf, PSHFLSTRING pMntPtBuf,
    7275                          uint64_t *pfFlags, uint32_t *puVersion);
  • trunk/src/VBox/HostServices/SharedFolders/shfl.h

    r98103 r105016  
    3636
    3737#include <VBox/log.h>
     38#include <VBox/com/VirtualBox.h> /* For SymlinkPolicy_T. */
    3839
    3940/** Shared Folders client flags.
  • trunk/src/VBox/HostServices/SharedFolders/testcase/Makefile.kmk

    r98415 r105016  
    6969 tstSharedFolderService_DEFS    = VBOX_WITH_HGCM UNITTEST
    7070 tstSharedFolderService_INCS    = ..
     71 ifneq ($(KBUILD_TARGET),win)
     72  tstSharedFolderService_DEFS  += VBOX_WITH_XPCOM
     73  tstSharedFolderService_INCS  += $(VBOX_XPCOM_INCS)
     74 endif
     75 tstSharedFolderService_INCS.win += $(VBOX_PATH_SDK)/bindings/mscom/include
    7176 tstSharedFolderService_SOURCES = \
    7277        tstSharedFolderService.cpp \
  • trunk/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.cpp

    r104560 r105016  
    587587}
    588588
     589extern int testRTSymlinkCreate(const char *pszSymlink, const char *pszTarget, RTSYMLINKTYPE enmType, uint32_t fCreate)
     590{
     591    if (g_fFailIfNotLowercase && !RTStrIsLowerCased(strpbrk(pszSymlink, "/\\")))
     592        return VERR_FILE_NOT_FOUND;
     593    RT_NOREF4(pszSymlink, pszTarget, enmType, fCreate);
     594    return 0;
     595}
     596
    589597
    590598/*********************************************************************************************************************************
     
    678686}
    679687
     688static void fillTestShflStringUtf8(union TESTSHFLSTRING *pDest,
     689                                   const char *pcszSource)
     690{
     691    const size_t cchSource = strlen(pcszSource);
     692    AssertRelease(  cchSource * 2 + 2
     693                  < sizeof(*pDest) - RT_UOFFSETOF(SHFLSTRING, String));
     694    pDest->string.u16Length = (uint16_t)cchSource;
     695    pDest->string.u16Size   = pDest->string.u16Length + 1;
     696    memcpy(pDest->string.String.utf8, pcszSource, pDest->string.u16Size);
     697}
     698
    680699static SHFLROOT initWithWritableMapping(RTTEST hTest,
    681700                                        VBOXHGCMSVCFNTABLE *psvcTable,
     
    683702                                        const char *pcszFolderName,
    684703                                        const char *pcszMapping,
    685                                         bool fCaseSensitive = true)
     704                                        bool fCaseSensitive = true,
     705                                        SymlinkPolicy_T enmSymlinkPolicy = SymlinkPolicy_AllowedToAnyTarget)
    686706{
    687707    VBOXHGCMSVCPARM aParms[RT_MAX(SHFL_CPARMS_ADD_MAPPING,
     
    706726    HGCMSvcSetPv(&aParms[1], &Mapping,   RT_UOFFSETOF(SHFLSTRING, String)
    707727                                   + Mapping.string.u16Size);
    708     HGCMSvcSetU32(&aParms[2], 1);
     728    HGCMSvcSetU32(&aParms[2], SHFL_ADD_MAPPING_F_WRITABLE | SHFL_ADD_MAPPING_F_CREATE_SYMLINKS);
    709729    HGCMSvcSetPv(&aParms[3], &AutoMountPoint, SHFLSTRING_HEADER_SIZE + AutoMountPoint.string.u16Size);
     730    HGCMSvcSetU32(&aParms[4], enmSymlinkPolicy);
    710731    rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_ADD_MAPPING,
    711732                                SHFL_CPARMS_ADD_MAPPING, aParms);
     
    774795        *pResult = CreateParms.Result;
    775796    return VINF_SUCCESS;
     797}
     798
     799static int createSymlink(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
     800                         const char *pcszSourcePath, const char *pcszSymlinkPath)
     801{
     802    VBOXHGCMSVCPARM aParms[SHFL_CPARMS_SYMLINK];
     803    union TESTSHFLSTRING sourcePath;
     804    union TESTSHFLSTRING symlinkPath;
     805    SHFLFSOBJINFO ObjInfo;
     806    VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
     807
     808    /* vbsfSymlink() only supports UTF-8 */
     809    fillTestShflStringUtf8(&sourcePath, pcszSourcePath);
     810    fillTestShflStringUtf8(&symlinkPath, pcszSymlinkPath);
     811    psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
     812                       psvcTable->pvService, SHFL_FN_SET_UTF8,
     813                       RT_ELEMENTS(aParms), aParms, 0);
     814
     815    RT_ZERO(ObjInfo);
     816    HGCMSvcSetU32(&aParms[0], Root);
     817    HGCMSvcSetPv(&aParms[1], &symlinkPath,  RT_UOFFSETOF(SHFLSTRING, String)
     818                                + symlinkPath.string.u16Size);
     819    HGCMSvcSetPv(&aParms[2], &sourcePath,   RT_UOFFSETOF(SHFLSTRING, String)
     820                                + sourcePath.string.u16Size);
     821    HGCMSvcSetPv(&aParms[3], &ObjInfo, sizeof(ObjInfo));
     822    psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
     823                       psvcTable->pvService, SHFL_FN_SYMLINK,
     824                       RT_ELEMENTS(aParms), aParms, 0);
     825    return callHandle.rc;
    776826}
    777827
     
    10061056}
    10071057
     1058static int testSymlinkCreationForSpecificPolicy(RTTEST hTest, SymlinkPolicy_T enmSymlinkPolicy)
     1059{
     1060    VBOXHGCMSVCFNTABLE  svcTable;
     1061    VBOXHGCMSVCHELPERS  svcHelpers;
     1062    SHFLROOT Root;
     1063    const RTFILE hFile = (RTFILE) 0x10000;
     1064    SHFLCREATERESULT Result;
     1065    int rc;
     1066
     1067    Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
     1068                                   "/test/mapping", "testname",
     1069                                   true, enmSymlinkPolicy);
     1070    g_testRTFileOpen_hFile = hFile;
     1071    rc = createFile(&svcTable, Root, "file", SHFL_CF_ACCESS_READ, NULL, &Result);
     1072    RTTEST_CHECK_RC_OK(hTest, rc);
     1073    RTTEST_CHECK_MSG(hTest,
     1074                     !strcmp(&g_testRTFileOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0],
     1075                             "/test/mapping/file"),
     1076                     (hTest, "pszFilename=%s\n", &g_testRTFileOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0]));
     1077    RTTEST_CHECK_MSG(hTest, g_testRTFileOpen_fOpen == 0x181,
     1078                     (hTest, "fOpen=%llu\n", LLUIFY(g_testRTFileOpen_fOpen)));
     1079    RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
     1080                     (hTest, "Result=%d\n", (int)Result));
     1081
     1082    /* regular symlink creation should succeed unless no symlinks allowed */
     1083    rc = createSymlink(&svcTable, Root, "file", "symlink");
     1084    if (enmSymlinkPolicy == SymlinkPolicy_Forbidden)
     1085        RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT,
     1086                         (hTest, "enmSymlinkPolicy=SymlinkPolicy_Forbidden 'ln -s file symlink' failed: rc=%Rrc\n", rc));
     1087    else
     1088        RTTEST_CHECK_RC_OK(hTest, rc);
     1089
     1090    /* absolute path to symlink sources only allowed for the 'any' policy */
     1091    rc = createSymlink(&svcTable, Root, "/path/to/file", "abs-symlink");
     1092    if (enmSymlinkPolicy == SymlinkPolicy_AllowedToAnyTarget)
     1093        RTTEST_CHECK_RC_OK(hTest, rc);
     1094    else
     1095        RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT,
     1096                         (hTest, "enmSymlinkPolicy=%d 'ln -s file /absolute/path/symlink' failed: rc=%Rrc\n",
     1097                         enmSymlinkPolicy, rc));
     1098
     1099    /* relative path symlink sources with '..' components allowed only with 'relative' policy */
     1100    rc = createSymlink(&svcTable, Root, "./directory/../file", "rel-symlink");
     1101    if (   enmSymlinkPolicy == SymlinkPolicy_Forbidden
     1102        || enmSymlinkPolicy == SymlinkPolicy_AllowedInShareSubtree)
     1103        RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT,
     1104                         (hTest, "enmSymlinkPolicy=%d 'ln -s ./path/../symlink' failed: rc=%Rrc\n",
     1105                         enmSymlinkPolicy, rc));
     1106    else
     1107        RTTEST_CHECK_RC_OK(hTest, rc);
     1108
     1109    /* relative path symlink source with no '..' components always OK */
     1110    rc = createSymlink(&svcTable, Root, "./directory/file", "dotslash-symlink");
     1111    if (enmSymlinkPolicy == SymlinkPolicy_Forbidden)
     1112        RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT,
     1113                         (hTest, "enmSymlinkPolicy=%d 'ln -s ./path/../symlink' failed: rc=%Rrc\n",
     1114                         enmSymlinkPolicy, rc));
     1115    else
     1116        RTTEST_CHECK_RC_OK(hTest, rc);
     1117
     1118    unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
     1119    rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
     1120    AssertReleaseRC(rc);
     1121    rc = svcTable.pfnUnload(NULL);
     1122    AssertReleaseRC(rc);
     1123    RTTestGuardedFree(hTest, svcTable.pvService);
     1124    RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile,
     1125                     (hTest, "File=%u\n", (uintptr_t)g_testRTFileClose_hFile));
     1126
     1127    return rc;
     1128}
     1129
     1130void testSymlinkCreation(RTTEST hTest)
     1131{
     1132    SymlinkPolicy_T aEnmSymlinkPolicy[4] = {
     1133        SymlinkPolicy_AllowedToAnyTarget,
     1134        SymlinkPolicy_AllowedInShareSubtree,
     1135        SymlinkPolicy_AllowedToRelativeTargets,
     1136        SymlinkPolicy_Forbidden
     1137    };
     1138
     1139    RTTestSub(hTest, "Create variety of symlinks with different symlink policies");
     1140    for (size_t i = 0; i < RT_ELEMENTS(aEnmSymlinkPolicy); i++)
     1141        testSymlinkCreationForSpecificPolicy(hTest, aEnmSymlinkPolicy[i]);
     1142}
     1143
    10081144void testReadFileSimple(RTTEST hTest)
    10091145{
  • trunk/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.h

    r98103 r105016  
    123123/* Sub-tests for testSymlink(). */
    124124void testSymlinkBadParameters(RTTEST hTest);
     125void testSymlinkCreation(RTTEST hTest);
    125126
    126127void testMappingsAdd(RTTEST hTest);
  • trunk/src/VBox/HostServices/SharedFolders/teststubs.h

    r98103 r105016  
    101101#define RTSymlinkRead        testRTSymlinkRead
    102102extern int testRTSymlinkRead(const char *pszSymlink, char *pszTarget, size_t cbTarget, uint32_t fRead);
     103#define RTSymlinkCreate      testRTSymlinkCreate
     104extern int testRTSymlinkCreate(const char *pszSymlink, const char *pszTarget, RTSYMLINKTYPE enmType, uint32_t fCreate);
    103105
    104106#endif /* !VBOX_INCLUDED_SRC_SharedFolders_teststubs_h */
  • trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp

    r100220 r105016  
    256256    uint32_t fu32PathFlags = 0;
    257257    uint32_t fu32Options =   VBSF_O_PATH_CHECK_ROOT_ESCAPE
    258                            | (fWildCard? VBSF_O_PATH_WILDCARD: 0)
    259                            | (fPreserveLastComponent? VBSF_O_PATH_PRESERVE_LAST_COMPONENT: 0);
     258                           | (fWildCard ? VBSF_O_PATH_WILDCARD : 0)
     259                           | (fPreserveLastComponent ? VBSF_O_PATH_PRESERVE_LAST_COMPONENT : 0);
    260260
    261261    int rc = vbsfPathGuestToHost(pClient, root, pPath, cbPath,
     
    25982598    testSymlinkBadParameters(hTest);
    25992599    /* Add tests as required... */
    2600 }
    2601 #endif
    2602 int vbsfSymlink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pNewPath, SHFLSTRING *pOldPath, SHFLFSOBJINFO *pInfo)
     2600    testSymlinkCreation(hTest);
     2601}
     2602#endif
     2603
     2604int vbsfSymlink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pSymlinkPath, SHFLSTRING *pSourcePath, SHFLFSOBJINFO *pInfo)
    26032605{
    26042606    int rc = VINF_SUCCESS;
    26052607
    2606     char *pszFullNewPath = NULL;
    2607     char *pszFullOldPath = NULL;
     2608    char *pszFullSymlinkPath = NULL;
     2609    char *pszFullSourcePath = NULL;
    26082610
    26092611    /* XXX: no support for UCS2 at the moment. */
     
    26172619        return VERR_WRITE_PROTECT; /* XXX or VERR_TOO_MANY_SYMLINKS? */
    26182620
    2619     rc = vbsfBuildFullPath(pClient, root, pNewPath, pNewPath->u16Size + SHFLSTRING_HEADER_SIZE, &pszFullNewPath, NULL);
    2620     AssertRCReturn(rc, rc);
    2621 
    2622     /* Verify that the link target can be a valid host path, i.e. does not contain invalid characters. */
     2621    rc = vbsfBuildFullPath(pClient, root, pSymlinkPath, pSymlinkPath->u16Size + SHFLSTRING_HEADER_SIZE, &pszFullSymlinkPath,
     2622                           NULL);
     2623    if (RT_FAILURE(rc))
     2624        return rc;
     2625
     2626    /*
     2627     * The symbolic link source path may be located outside of the shared folder so thus
     2628     * we don't call vbsfBuildFullPath() which includes VBSF_O_PATH_CHECK_ROOT_ESCAPE to
     2629     * verify that the pathname resides within the shared folder.  Instead we call the
     2630     * heart of vbsfBuildFullPath() which is vbsfPathGuestToHost() to perform a subset
     2631     * of its checks to verify that the symbolic link source is a valid path by checking
     2632     * for invalid characters, replacing path delimiters if the guest uses a different
     2633     * slash than the host, and evaluating the symbolic link policy if one has been set.
     2634     * We don't collapse path components of '..' for example or alter the path otherwise
     2635     * as this is the documented behavior of symbolic links: the source pathname can be
     2636     * any pathname and isn't required to exist.
     2637     */
    26232638    uint32_t fu32PathFlags = 0;
    2624     uint32_t fu32Options = 0;
    2625     rc = vbsfPathGuestToHost(pClient, root, pOldPath, pOldPath->u16Size + SHFLSTRING_HEADER_SIZE,
    2626                              &pszFullOldPath, NULL, fu32Options, &fu32PathFlags);
     2639    uint32_t fu32Options = VBSF_O_PATH_CHECK_SYMLINK_POLICY;
     2640    rc = vbsfPathGuestToHost(pClient, root, pSourcePath, pSourcePath->u16Size + SHFLSTRING_HEADER_SIZE,
     2641                             &pszFullSourcePath, NULL, fu32Options, &fu32PathFlags);
    26272642    if (RT_FAILURE(rc))
    26282643    {
    2629         vbsfFreeFullPath(pszFullNewPath);
     2644        vbsfFreeFullPath(pszFullSymlinkPath);
    26302645        return rc;
    26312646    }
    26322647
    2633     /** @todo r=bird: We _must_ perform slash conversion on the target (what this
    2634      *        code calls 'pOldPath' for some peculiar reason)! */
    2635 
    2636     rc = RTSymlinkCreate(pszFullNewPath, (const char *)pOldPath->String.utf8,
    2637                          RTSYMLINKTYPE_UNKNOWN, 0);
     2648    rc = RTSymlinkCreate(pszFullSymlinkPath, pszFullSourcePath, RTSYMLINKTYPE_UNKNOWN, 0);
    26382649    if (RT_SUCCESS(rc))
    26392650    {
    26402651        RTFSOBJINFO info;
    2641         rc = RTPathQueryInfoEx(pszFullNewPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
     2652        rc = RTPathQueryInfoEx(pszFullSymlinkPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
    26422653        if (RT_SUCCESS(rc))
    26432654            vbfsCopyFsObjInfoFromIprt(pInfo, &info);
    26442655    }
    26452656
    2646     vbsfFreeFullPath(pszFullOldPath);
    2647     vbsfFreeFullPath(pszFullNewPath);
     2657    vbsfFreeFullPath(pszFullSourcePath);
     2658    vbsfFreeFullPath(pszFullSymlinkPath);
    26482659
    26492660    return rc;
  • trunk/src/VBox/HostServices/SharedFolders/vbsfpath.cpp

    r99802 r105016  
    438438}
    439439
     440/**
     441 * Validate the symbolic link creation policy inside a guest operating in a shared folder.
     442 *
     443 * @returns S_OK or VERR_WRITE_PROTECT.
     444 * @param pchSymlinkPath    The pathname of the symbolic link within the guest.
     445 * @param enmSymlinkPolicy  The symbolic link creation policy being evaluated.
     446 *
     447 * The enmSymlinkPolicy symlink creation policies are:
     448 *  - @a none:       no policy set
     449 *  - @a any:        no restrictions
     450 *  - @a forbidden:  no symlinks allowed
     451 *  - @a relative:   relative paths only ('..' path components allowed)
     452 *  - @a subtree:    relative paths only within the shared folder (no '..' path components allowed)
     453 */
     454static int vbsfPathEvalSymlinkPolicy(const char *pchSymlinkPath, SymlinkPolicy_T enmSymlinkPolicy)
     455{
     456    /* If no symlink policy has been set we continue the historical behaviour of applying no
     457     * additional restrictions.  The "any" policy also has no symlink path limitations. */
     458    if (   enmSymlinkPolicy == SymlinkPolicy_None
     459        || enmSymlinkPolicy == SymlinkPolicy_AllowedToAnyTarget)
     460        return S_OK;
     461
     462    /* No absolute paths allowed except for the "any" policy.  The symlink path can't
     463     * contain '..' components if the "subtree" policy in effect. */
     464    if (   RTPathStartsWithRoot(pchSymlinkPath)
     465        || enmSymlinkPolicy == SymlinkPolicy_Forbidden
     466        || (   enmSymlinkPolicy == SymlinkPolicy_AllowedInShareSubtree
     467            && RTStrStr(pchSymlinkPath, "..")))
     468        return VERR_WRITE_PROTECT;
     469
     470    return S_OK;
     471}
     472
    440473int vbsfPathGuestToHost(SHFLCLIENTDATA *pClient, SHFLROOT hRoot,
    441474                        PCSHFLSTRING pGuestString, uint32_t cbGuestString,
     
    565598                const char *pchSrc = pchGuestPath;
    566599
    567                 /* Strip leading delimiters from the path the guest specified. */
    568                 while (   cbSrc > 0
    569                        && *pchSrc == pClient->PathDelimiter)
    570                 {
    571                     ++pchSrc;
    572                     --cbSrc;
     600                /* when validating source file pathnames for symbolic links we don't modify the path */
     601                if (!(fu32Options & VBSF_O_PATH_CHECK_SYMLINK_POLICY))
     602                {
     603                    /* Strip leading delimiters from the path the guest specified. */
     604                    while (   cbSrc > 0
     605                           && *pchSrc == pClient->PathDelimiter)
     606                    {
     607                        ++pchSrc;
     608                        --cbSrc;
     609                    }
    573610                }
    574611
     
    615652                    *pchDst++ = 0;
    616653
    617                     /* Construct the full host path removing '.' and '..'. */
    618                     rc = vbsfPathAbs(pszRoot, pchVerifiedPath, pszFullPath, cbFullPathAlloc);
     654                    /* check if a symbolic link creation policy has been set */
     655                    if (fu32Options & VBSF_O_PATH_CHECK_SYMLINK_POLICY)
     656                    {
     657                        /* copy the verified symlink source file path to be returned to the caller */
     658                        rc = RTStrCopy(pszFullPath, cbFullPathAlloc, pchVerifiedPath);
     659                        if (RT_SUCCESS(rc))
     660                        {
     661                            SymlinkPolicy_T enmSymlinkPolicy;
     662                            rc = vbsfMappingsQuerySymlinkPolicy(pClient, hRoot, &enmSymlinkPolicy);
     663                            if (RT_SUCCESS(rc))
     664                                rc = vbsfPathEvalSymlinkPolicy(pchVerifiedPath, enmSymlinkPolicy);
     665                        }
     666                    }
     667                    else
     668                    {
     669                        /* Construct the full host path removing '.' and '..'. */
     670                        rc = vbsfPathAbs(pszRoot, pchVerifiedPath, pszFullPath, cbFullPathAlloc);
     671                    }
    619672                    if (RT_SUCCESS(rc))
    620673                    {
     
    667720                    else
    668721                    {
    669                         LogFunc(("vbsfPathAbs %Rrc\n", rc));
     722                        if (fu32Options & VBSF_O_PATH_CHECK_SYMLINK_POLICY)
     723                            LogFunc(("vbsfPathEvalSymlinkPolicy() returns rc=%Rrc\n", rc));
     724                        else
     725                            LogFunc(("vbsfPathAbs %Rrc\n", rc));
    670726                    }
    671727                }
  • trunk/src/VBox/HostServices/SharedFolders/vbsfpath.h

    r98103 r105016  
    3838#define VBSF_O_PATH_PRESERVE_LAST_COMPONENT UINT32_C(0x00000002)
    3939#define VBSF_O_PATH_CHECK_ROOT_ESCAPE       UINT32_C(0x00000004)
     40#define VBSF_O_PATH_CHECK_SYMLINK_POLICY    UINT32_C(0x00000008)
    4041
    4142#define VBSF_F_PATH_HAS_WILDCARD_IN_PREFIX UINT32_C(0x00000001) /* A component before the last one contains a wildcard. */
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r104780 r105016  
    657657      <desc>Settings version "1.20", written by VirtualBox 7.1.x.</desc>
    658658      <!--
    659           Adds VM platform support: Non-platform-specific
    660           settings were moved to the new Platform element, which now contains
    661           the platform architecture for this VM. x86-specific
    662           settings were moved from Machine to a new, dedicated Platform/x86 element.
    663           BIOSSettings were renamed to FirmwareSettings. ARM-specific settings
    664           were added to a new, dedicated Platform/ARM element. This settings
    665           version only will be written if the ARM platform architecture is being
    666           selected. Only affects the machine settings (not main configuration
    667           settings).
     659        - Machine changes:
     660          + Adds VM platform support: Non-platform-specific
     661            settings were moved to the new Platform element, which now contains
     662            the platform architecture for this VM. x86-specific
     663            settings were moved from Machine to a new, dedicated Platform/x86 element.
     664            BIOSSettings were renamed to FirmwareSettings. ARM-specific settings
     665            were added to a new, dedicated Platform/ARM element. This settings
     666            version only will be written if the ARM platform architecture is being
     667            selected. Only affects the machine settings (not main configuration
     668            settings).
     669          + Adds support for Shared Folder symbolic link configuration. (Machine
     670            settings only).
    668671      -->
    669672    </const>
     
    2442924432  <interface
    2443024433    name="ISharedFolder" extends="$unknown"
    24431     uuid="9622225a-5409-414b-bd16-77df7ba3451e"
     24434    uuid="0b108b8c-62e0-4e06-9dfa-2f1a2ad70774"
    2443224435    wsmap="managed"
    2443324436    rest="managed"
     
    2454024543        failure and should normally describe a reason of the failure (for
    2454124544        example, a file read error).
     24545      </desc>
     24546    </attribute>
     24547
     24548    <attribute name="symlinkPolicy" type="SymlinkPolicy">
     24549      <desc>
     24550        The security policy for allowing guest VMs to create symbolic links
     24551        within a Shared Folder.
    2454224552      </desc>
    2454324553    </attribute>
     
    3020530215</enum>
    3020630216
     30217  <enum
     30218    name="SymlinkPolicy"
     30219    uuid="a818472e-215d-4279-8af8-eac4c0517bcc"
     30220    >
     30221    <desc>Shared Folder Symbolic Link Security Policies</desc>
     30222    <const name="None"                       value="0">
     30223      <desc>No symlink policy set (never used by the API).</desc>
     30224    </const>
     30225    <const name="Forbidden"                  value="1">
     30226      <desc>Users in the guest VM are not able to create symbolic links inside the Shared Folder.</desc>
     30227    </const>
     30228    <const name="AllowedInShareSubtree"      value="2">
     30229      <desc>Users in the guest VM are allowed to create symbolic links within the Shared Folder so long
     30230          as the target remains in the Shared Folder or within the subtree of the Shared Folder.
     30231      </desc>
     30232    </const>
     30233    <const name="AllowedToRelativeTargets"   value="3">
     30234      <desc>Users in the guest VM are allowed to create symbolic links within the Shared Folder to
     30235          targets within the Shared Folder and its subtree as well as to relative targets (../) outside of
     30236          the Shared Folder.
     30237      </desc>
     30238    </const>
     30239    <const name="AllowedToAnyTarget"         value="4">
     30240      <desc>Users in the guest VM are allowed to create symbolic links within the Shared Folder and
     30241          its subtree as well as to other targets via either relative pathnames or absolute pathnames.
     30242      </desc>
     30243    </const>
     30244</enum>
    3020730245
    3020830246  <interface name="ICloudNetworkGatewayInfo" extends="$unknown"
  • trunk/src/VBox/Main/include/ConsoleSharedFolderImpl.h

    r98341 r105016  
    8989    const Utf8Str &i_getAutoMountPoint() const;
    9090
     91    /**
     92     * Public internal method for getting the symlink policy.
     93     */
     94    const SymlinkPolicy_T i_getSymlinkPolicy() const;
     95
    9196protected:
    9297
     
    100105private:
    101106
    102     // wrapped ISharedFolder properies.
     107    // wrapped ISharedFolder properties.
    103108    HRESULT getName(com::Utf8Str &aName);
    104109    HRESULT getHostPath(com::Utf8Str &aHostPath);
     
    111116    HRESULT setAutoMountPoint(com::Utf8Str const &aAutoMountPoint);
    112117    HRESULT getLastAccessError(com::Utf8Str &aLastAccessError);
     118    HRESULT getSymlinkPolicy(SymlinkPolicy_T *aSymlinkPolicy);
     119    HRESULT setSymlinkPolicy(SymlinkPolicy_T aSymlinkPolicy);
    113120
    114121    VirtualBoxBase * const mParent;
  • trunk/src/VBox/Main/include/MachineImpl.h

    r103977 r105016  
    911911    friend class RecordingScreenSettings;
    912912    friend class SessionMachine;
     913    friend class SharedFolder;
    913914    friend class SnapshotMachine;
    914915    friend class VirtualBox;
  • trunk/src/VBox/Main/include/SharedFolderImpl.h

    r98341 r105016  
    4949    // public initializer/uninitializer for internal purposes only
    5050    HRESULT init(Machine *aMachine, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
    51                  bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
     51                 bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError,
     52                 SymlinkPolicy_T enmSymlinkPolicy);
    5253    HRESULT initCopy(Machine *aMachine, SharedFolder *aThat);
    5354//    HRESULT init(Console *aConsole, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
     
    8990    const Utf8Str &i_getAutoMountPoint() const;
    9091
     92    /**
     93     * Public internal method for getting the symlink policy.
     94     */
     95    const SymlinkPolicy_T i_getSymlinkPolicy() const;
     96
    9197protected:
    9298
     
    97103                            bool aAutoMount,
    98104                            const com::Utf8Str &aAutoMountPoint,
    99                             bool fFailOnError);
     105                            bool fFailOnError,
     106                            SymlinkPolicy_T enmSymlinkPolicy);
    100107private:
    101108
    102     // wrapped ISharedFolder properies.
     109    // wrapped ISharedFolder properties.
    103110    HRESULT getName(com::Utf8Str &aName);
    104111    HRESULT getHostPath(com::Utf8Str &aHostPath);
     
    111118    HRESULT setAutoMountPoint(com::Utf8Str const &aAutoMountPoint);
    112119    HRESULT getLastAccessError(com::Utf8Str &aLastAccessError);
     120    HRESULT getSymlinkPolicy(SymlinkPolicy_T *aSymlinkPolicy);
     121    HRESULT setSymlinkPolicy(SymlinkPolicy_T aSymlinkPolicy);
    113122
    114123    VirtualBoxBase * const mParent;
  • trunk/src/VBox/Main/src-all/ConsoleSharedFolderImpl.cpp

    r98342 r105016  
    4444    Data()
    4545    : fWritable(false),
    46       fAutoMount(false)
     46      fAutoMount(false),
     47      enmSymlinkPolicy(SymlinkPolicy_None)
    4748    { }
    4849
     
    5354    const Utf8Str   strAutoMountPoint;
    5455    Utf8Str         strLastAccessError;
     56    SymlinkPolicy_T enmSymlinkPolicy;
    5557};
    5658
     
    305307}
    306308
     309HRESULT ConsoleSharedFolder::getSymlinkPolicy(SymlinkPolicy_T *aSymlinkPolicy)
     310{
     311    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     312    *aSymlinkPolicy = m->enmSymlinkPolicy;
     313    return S_OK;
     314}
     315
     316HRESULT ConsoleSharedFolder::setSymlinkPolicy(SymlinkPolicy_T aSymlinkPolicy)
     317{
     318    RT_NOREF(aSymlinkPolicy);
     319    return E_NOTIMPL;
     320}
    307321
    308322const Utf8Str& ConsoleSharedFolder::i_getName() const
     
    331345}
    332346
     347const SymlinkPolicy_T ConsoleSharedFolder::i_getSymlinkPolicy() const
     348{
     349    return m->enmSymlinkPolicy;
     350}
     351
    333352/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/src-all/SharedFolderImpl.cpp

    r98341 r105016  
    4646    Data()
    4747    : fWritable(false),
    48       fAutoMount(false)
     48      fAutoMount(false),
     49      enmSymlinkPolicy(SymlinkPolicy_None)
    4950    { }
    5051
     
    5556    const Utf8Str   strAutoMountPoint;
    5657    Utf8Str         strLastAccessError;
     58    SymlinkPolicy_T enmSymlinkPolicy;
    5759};
    5860
     
    109111                           bool aAutoMount,
    110112                           const Utf8Str &aAutoMountPoint,
    111                            bool fFailOnError)
     113                           bool fFailOnError,
     114                           SymlinkPolicy_T enmSymlinkPolicy)
    112115{
    113116    /* Enclose the state transition NotReady->InInit->Ready */
     
    117120    unconst(mMachine) = aMachine;
    118121
    119     HRESULT hrc = i_protectedInit(aMachine, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError);
     122    HRESULT hrc = i_protectedInit(aMachine, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError,
     123                                  enmSymlinkPolicy);
    120124
    121125    /* Confirm a successful initialization when it's the case */
     
    152156                                  aThat->m->fAutoMount,
    153157                                  aThat->m->strAutoMountPoint,
    154                                   false /* fFailOnError */ );
     158                                  false /* fFailOnError */,
     159                                  aThat->m->enmSymlinkPolicy);
    155160
    156161    /* Confirm a successful initialization when it's the case */
     
    214219                                      bool aAutoMount,
    215220                                      const Utf8Str &aAutoMountPoint,
    216                                       bool fFailOnError)
    217 {
    218     LogFlowThisFunc(("aName={%s}, aHostPath={%s}, aWritable={%d}, aAutoMount={%d}\n",
    219                       aName.c_str(), aHostPath.c_str(), aWritable, aAutoMount));
     221                                      bool fFailOnError,
     222                                      SymlinkPolicy_T enmSymlinkPolicy)
     223{
     224    LogFlowThisFunc(("aName={%s}, aHostPath={%s}, aWritable={%d}, aAutoMount={%d} enmSymlinkPolicy={%d}\n",
     225                      aName.c_str(), aHostPath.c_str(), aWritable, aAutoMount, enmSymlinkPolicy));
    220226
    221227    ComAssertRet(aParent && aName.isNotEmpty() && aHostPath.isNotEmpty(), E_INVALIDARG);
     
    271277    m->fAutoMount = aAutoMount;
    272278    unconst(m->strAutoMountPoint) = aAutoMountPoint;
     279    m->enmSymlinkPolicy = enmSymlinkPolicy;
    273280
    274281    return S_OK;
     
    385392}
    386393
     394HRESULT SharedFolder::getSymlinkPolicy(SymlinkPolicy_T *aSymlinkPolicy)
     395{
     396    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     397    *aSymlinkPolicy = m->enmSymlinkPolicy;
     398    return S_OK;
     399}
     400
     401HRESULT SharedFolder::setSymlinkPolicy(SymlinkPolicy_T aSymlinkPolicy)
     402{
     403    switch (aSymlinkPolicy)
     404    {
     405        case SymlinkPolicy_AllowedToAnyTarget:
     406        case SymlinkPolicy_AllowedInShareSubtree:
     407        case SymlinkPolicy_AllowedToRelativeTargets:
     408        case SymlinkPolicy_Forbidden:
     409            break;
     410        default:
     411            return setError(E_INVALIDARG, tr("The symbolic link policy specified (%d) is invalid."), aSymlinkPolicy);
     412    }
     413
     414    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     415    m->enmSymlinkPolicy = aSymlinkPolicy;
     416    return S_OK;
     417}
    387418
    388419const Utf8Str& SharedFolder::i_getName() const
     
    411442}
    412443
     444const SymlinkPolicy_T SharedFolder::i_getSymlinkPolicy() const
     445{
     446    return m->enmSymlinkPolicy;
     447}
     448
    413449/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r105006 r105016  
    95419541                      | (fMissing           ? SHFL_ADD_MAPPING_F_MISSING : 0));
    95429542        SHFLSTRING_TO_HGMC_PARAM(&aParams[3], pAutoMountPoint);
    9543         AssertCompile(SHFL_CPARMS_ADD_MAPPING == 4);
     9543        HGCMSvcSetU32(&aParams[4], SymlinkPolicy_None);
     9544        AssertCompile(SHFL_CPARMS_ADD_MAPPING == 5);
    95449545
    95459546        vrc = m_pVMMDev->hgcmHostCall("VBoxSharedFolders", SHFL_FN_ADD_MAPPING, SHFL_CPARMS_ADD_MAPPING, aParams);
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r103085 r105016  
    50325032                        aName.c_str());
    50335033
     5034    SymlinkPolicy_T enmSymlinkPolicy = SymlinkPolicy_None;
    50345035    sharedFolder.createObject();
    50355036    hrc = sharedFolder->init(i_getMachine(),
     
    50395040                             !!aAutomount,
    50405041                             aAutoMountPoint,
    5041                              true /* fFailOnError */);
     5042                             true /* fFailOnError */,
     5043                             enmSymlinkPolicy);
    50425044    if (FAILED(hrc)) return hrc;
    50435045
     
    88188820                                     RT_BOOL(sf.fAutoMount),
    88198821                                     sf.strAutoMountPoint,
    8820                                      false /* fFailOnError */);
     8822                                     false /* fFailOnError */,
     8823                                     sf.enmSymlinkPolicy);
    88218824            if (FAILED(hrc)) return hrc;
    88228825            mHWData->mSharedFolders.push_back(sharedFolder);
     
    1019310196            sf.fAutoMount = !!pSF->i_isAutoMounted();
    1019410197            sf.strAutoMountPoint = pSF->i_getAutoMountPoint();
     10198            sf.enmSymlinkPolicy = pSF->i_getSymlinkPolicy();
    1019510199
    1019610200            data.llSharedFolders.push_back(sf);
  • trunk/src/VBox/Main/xml/Settings.cpp

    r103085 r105016  
    37933793SharedFolder::SharedFolder() :
    37943794    fWritable(false),
    3795     fAutoMount(false)
     3795    fAutoMount(false),
     3796    enmSymlinkPolicy(SymlinkPolicy_None)
    37963797{
    37973798}
     
    38093810            && fWritable         == g.fWritable
    38103811            && fAutoMount        == g.fAutoMount
    3811             && strAutoMountPoint == g.strAutoMountPoint);
     3812            && strAutoMountPoint == g.strAutoMountPoint
     3813            && enmSymlinkPolicy  == g.enmSymlinkPolicy);
    38123814}
    38133815
     
    59925994                pelmFolder->getAttributeValue("autoMount", sf.fAutoMount);
    59935995                pelmFolder->getAttributeValue("autoMountPoint", sf.strAutoMountPoint);
     5996
     5997                Utf8Str strTemp;
     5998                if (pelmFolder->getAttributeValue("symlinkPolicy", strTemp))
     5999                {
     6000                    if (strTemp == "forbidden")
     6001                        sf.enmSymlinkPolicy = SymlinkPolicy_Forbidden;
     6002                    else if (strTemp == "subtree")
     6003                        sf.enmSymlinkPolicy = SymlinkPolicy_AllowedInShareSubtree;
     6004                    else if (strTemp == "relative")
     6005                        sf.enmSymlinkPolicy = SymlinkPolicy_AllowedToRelativeTargets;
     6006                    else if (strTemp == "any")
     6007                        sf.enmSymlinkPolicy = SymlinkPolicy_AllowedToAnyTarget;
     6008                    else
     6009                        throw ConfigFileError(this,
     6010                                              pelmHwChild,
     6011                                              N_("Invalid value '%s' in SharedFolder/@symlinkPolicy attribute"),
     6012                                              strTemp.c_str());
     6013                }
    59946014                hw.llSharedFolders.push_back(sf);
    59956015            }
     
    83098329            if (sf.strAutoMountPoint.isNotEmpty())
    83108330                pelmThis->setAttribute("autoMountPoint", sf.strAutoMountPoint);
     8331            const char *pcszSymlinkPolicy;
     8332            if (sf.enmSymlinkPolicy != SymlinkPolicy_None)
     8333            {
     8334                switch (sf.enmSymlinkPolicy)
     8335                {
     8336                    default: /*case SymlinkPolicy_Forbidden:*/    pcszSymlinkPolicy = "forbidden";  break;
     8337                    case SymlinkPolicy_AllowedInShareSubtree:     pcszSymlinkPolicy = "subtree";    break;
     8338                    case SymlinkPolicy_AllowedToRelativeTargets:  pcszSymlinkPolicy = "relative";   break;
     8339                    case SymlinkPolicy_AllowedToAnyTarget:        pcszSymlinkPolicy = "any";        break;
     8340                }
     8341                pelmThis->setAttribute("symlinkPolicy", pcszSymlinkPolicy);
     8342            }
    83118343        }
    83128344    }
     
    95319563            return;
    95329564        }
     9565
     9566        // VirtualBox 7.1 (settings v1.20) adds support for customizable control over Shared Folders symlink creation.
     9567        if (hardwareMachine.llSharedFolders.size())
     9568        {
     9569            for (SharedFoldersList::const_iterator it = hardwareMachine.llSharedFolders.begin();
     9570                 it != hardwareMachine.llSharedFolders.end();
     9571                 ++it)
     9572            {
     9573                if (it->enmSymlinkPolicy != SymlinkPolicy_None)
     9574                {
     9575                    m->sv = SettingsVersion_v1_20;
     9576                    return;
     9577                }
     9578            }
     9579        }
    95339580    }
    95349581
  • trunk/src/VBox/Main/xml/VirtualBox-settings.xsd

    r104783 r105016  
    301301    <xsd:enumeration value="VBoxSVGA"/>
    302302    <xsd:enumeration value="QemuRamFB"/>
     303  </xsd:restriction>
     304</xsd:simpleType>
     305
     306<xsd:simpleType name="TSymlinkPolicy"> <!-- new since v1.20. -->
     307  <xsd:restriction base="xsd:token">
     308    <xsd:enumeration value="forbidden"/>
     309    <xsd:enumeration value="subtree"/>
     310    <xsd:enumeration value="relative"/>
     311    <xsd:enumeration value="any"/>
    303312  </xsd:restriction>
    304313</xsd:simpleType>
     
    13051314  <xsd:attribute name="autoMount" type="xsd:boolean" default="false"/>
    13061315  <xsd:attribute name="autoMountPoint" type="xsd:string"/>
     1316  <xsd:attribute name="symlinkPolicy" type="TSymlinkPolicy" default="forbidden"/> <!-- new since v1.20. -->
    13071317</xsd:complexType>
    13081318
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette