Index: /trunk/include/VBox/usblib-solaris.h
===================================================================
--- /trunk/include/VBox/usblib-solaris.h	(revision 38015)
+++ /trunk/include/VBox/usblib-solaris.h	(revision 38016)
@@ -105,4 +105,6 @@
     /** Device identifier (VendorId:ProductId:Release:StaticPath) */
     char           szDeviceIdent[MAXPATHLEN+48];
+    /** Callback from monitor specifying client consumer (VM) credentials */
+    DECLR0CALLBACKMEMBER(int, pfnSetConsumerCredentials,(RTPROCESS Process, int Instance, void *pvReserved));
 } VBOXUSBREQ_CLIENT_INFO, *PVBOXUSBREQ_CLIENT_INFO;
 typedef VBOXUSBREQ_CLIENT_INFO VBOXUSB_CLIENT_INFO;
Index: /trunk/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c
===================================================================
--- /trunk/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c	(revision 38015)
+++ /trunk/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c	(revision 38016)
@@ -286,4 +286,5 @@
     int                     fPoll;           /* Polling status flag */
     RTPROCESS               Process;         /* The process (id) of the session */
+    bool                    fInstanceOpen;   /* If the process is still holding this instance */
     VBOXUSBREQ_CLIENT_INFO  ClientInfo;      /* Registration data */
     vboxusb_power_t        *pPower;          /* Power Management */
@@ -352,4 +353,7 @@
 int VBoxUSBMonSolarisUnregisterClient(dev_info_t *pClientDip);
 
+/** Callbacks from Monitor */
+LOCAL int vboxUSBSolarisSetConsumerCredentials(RTPROCESS Process, int Instance, void *pvReserved);
+
 
 /*******************************************************************************
@@ -464,5 +468,5 @@
             {
                 pState = ddi_get_soft_state(g_pVBoxUSBSolarisState, instance);
-                if (pState)
+                if (RT_LIKELY(pState))
                 {
                     pState->pDip = pDip;
@@ -477,4 +481,5 @@
                     pState->fPoll = VBOXUSB_POLL_OFF;
                     pState->Process = NIL_RTPROCESS;
+                    pState->fInstanceOpen = false;
                     pState->pPower = NULL;
 
@@ -568,4 +573,5 @@
                                                                 szDevicePath);
                                                     pState->ClientInfo.Instance = instance;
+                                                    pState->ClientInfo.pfnSetConsumerCredentials = &vboxUSBSolarisSetConsumerCredentials;
                                                     rc = VBoxUSBMonSolarisRegisterClient(pState->pDip, &pState->ClientInfo);
                                                     if (RT_SUCCESS(rc))
@@ -817,4 +823,43 @@
 
 
+/**
+ * Callback invoked from the Monitor driver when a VM process tries to access
+ * this client instance. This determines which VM process will be allowed to
+ * open and access the USB device.
+ *
+ * @returns  VBox status code.
+ *
+ * @param    Process        The VM process performing the client info. query.
+ * @param    Instance       This client instance (the one set while we register
+ *                          ourselves to the Monitor driver)
+ * @param    pvReserved     Reserved for future, unused.
+ */
+LOCAL int vboxUSBSolarisSetConsumerCredentials(RTPROCESS Process, int Instance, void *pvReserved)
+{
+    LogFlowFunc((DEVICE_NAME ":vboxUSBSolarisSetConsumerCredentials Process=%u Instance=%d\n", Process, Instance));
+    vboxusb_state_t *pState = ddi_get_soft_state(g_pVBoxUSBSolarisState, Instance);
+    if (!pState)
+    {
+        LogRel((DEVICE_NAME ":vboxUSBSolarisSetConsumerCredentials failed to get device state for instance %d\n", Instance));
+        return VERR_INVALID_STATE;
+    }
+
+    int rc = VINF_SUCCESS;
+    mutex_enter(&pState->Mtx);
+
+    if (pState->fInstanceOpen == false)
+        pState->Process = Process;
+    else
+    {
+        LogRel((DEVICE_NAME ":vboxUSBSolarisSetConsumerCredentials failed! Process %u already has client open.\n", pState->Process));
+        rc = VERR_RESOURCE_BUSY;
+    }
+
+    mutex_exit(&pState->Mtx);
+
+    return rc;
+}
+
+
 int VBoxUSBSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
 {
@@ -838,8 +883,10 @@
     }
 
+    mutex_enter(&pState->Mtx);
+
     /*
      * Only one user process can open a device instance at a time.
      */
-    if (pState->Process != NIL_RTPROCESS)
+    if (pState->fInstanceOpen == true)
     {
         LogRel((DEVICE_NAME ":VBoxUSBSolarisOpen a process is already using this device instance.\n"));
@@ -847,6 +894,14 @@
     }
 
-    pState->Process = RTProcSelf();
+    if (pState->Process != RTProcSelf())
+    {
+        LogRel((DEVICE_NAME ":VBoxUSBSolarisOpen invalid process.\n"));
+        return EPERM;
+    }
+
     pState->fPoll = VBOXUSB_POLL_ON;
+    pState->fInstanceOpen = true;
+
+    mutex_exit(&pState->Mtx);
 
     NOREF(fFlag);
@@ -872,4 +927,5 @@
     pState->fPoll = VBOXUSB_POLL_OFF;
     pState->Process = NIL_RTPROCESS;
+    pState->fInstanceOpen = false;
     mutex_exit(&pState->Mtx);
 
@@ -1570,6 +1626,6 @@
     AssertPtrReturn(pEp, VERR_INVALID_POINTER);
 
-//    LogFlowFunc((DEVICE_NAME ":vboxUSBSolarisSendUrb pState=%p pUrbReq=%p bEndpoint=%#x[%d] enmDir=%#x enmType=%#x cbData=%d pvData=%p\n",
-//            pState, pUrbReq, pUrbReq->bEndpoint, EndPtIndex, pUrbReq->enmDir, pUrbReq->enmType, pUrbReq->cbData, pUrbReq->pvData));
+    /* LogFlowFunc((DEVICE_NAME ":vboxUSBSolarisSendUrb pState=%p pUrbReq=%p bEndpoint=%#x[%d] enmDir=%#x enmType=%#x cbData=%d pvData=%p\n",
+            pState, pUrbReq, pUrbReq->bEndpoint, EndPtIndex, pUrbReq->enmDir, pUrbReq->enmType, pUrbReq->cbData, pUrbReq->pvData)); */
 
     if (RT_UNLIKELY(!pUrbReq->pvData))
Index: /trunk/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSBMon-solaris.c
===================================================================
--- /trunk/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSBMon-solaris.c	(revision 38015)
+++ /trunk/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSBMon-solaris.c	(revision 38016)
@@ -165,5 +165,5 @@
 *******************************************************************************/
 /** Global Device handle we only support one instance. */
-static dev_info_t *g_pDip;
+static dev_info_t *g_pDip = NULL;
 /** Global Mutex. */
 static kmutex_t g_VBoxUSBMonSolarisMtx;
@@ -171,5 +171,5 @@
 static uint64_t g_cVBoxUSBMonSolarisClient = 0;
 /** Global list of client drivers registered with us. */
-vboxusbmon_client_t *g_pVBoxUSBMonSolarisClients = 0;
+vboxusbmon_client_t *g_pVBoxUSBMonSolarisClients = NULL;
 /** Opaque pointer to list of soft states. */
 static void *g_pVBoxUSBMonSolarisState;
@@ -293,26 +293,21 @@
         case DDI_ATTACH:
         {
-            vboxusbmon_state_t *pState = NULL;
+            if (RT_UNLIKELY(g_pDip))
+            {
+                LogRel((DEVICE_NAME ":VBoxUSBMonSolarisAttach global instance already initialized.\n"));
+                return DDI_FAILURE;
+            }
+
+            g_pDip = pDip;
             int instance = ddi_get_instance(pDip);
-            int rc;
-
-            pState = RTMemAllocZ(sizeof(*pState));
-            if (pState)
+            int rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0,
+                                                        "none", "none", 0660);
+            if (rc == DDI_SUCCESS)
             {
-                g_pDip = pDip;
-                rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0,
-                                                            "none", "none", 0666);
-                if (rc == DDI_SUCCESS)
-                {
-                    ddi_set_driver_private(pDip, pState);
-                    ddi_report_dev(pDip);
-                    return rc;
-                }
-                else
-                    LogRel((DEVICE_NAME ":ddi_create_minor_node failed! rc=%d\n", rc));
-                RTMemFree(pState);
+                ddi_report_dev(pDip);
+                return rc;
             }
             else
-                LogRel((DEVICE_NAME ":RTMemAllocZ failed to allocated %d bytes for pState\n", sizeof(*pState)));
+                LogRel((DEVICE_NAME ":VBoxUSBMonSolarisAttach ddi_create_minor_node failed! rc=%d\n", rc));
             return DDI_FAILURE;
         }
@@ -359,14 +354,7 @@
             mutex_exit(&g_VBoxUSBMonSolarisMtx);
 
-            vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
-            if (pState)
-            {
-                ddi_remove_minor_node(pDip, NULL);
-                RTMemFree(pState);
-                return DDI_SUCCESS;
-            }
-            else
-                LogRel((DEVICE_NAME ":failed to get soft state on detach.\n"));
-            break;
+            ddi_remove_minor_node(pDip, NULL);
+            g_pDip = NULL;
+            return DDI_SUCCESS;
         }
 
@@ -853,4 +841,13 @@
 }
 
+
+/**
+ * Query client driver information. This also has a side-effect that it informs
+ * the client driver which upcoming VM process should be allowed to open it.
+ *
+ * @returns  VBox status code.
+ * @param    pState         Pointer to the device state.
+ * @param    pClientInfo    Pointer to the client info. object.
+ */
 static int vboxUSBMonSolarisClientInfo(vboxusbmon_state_t *pState, PVBOXUSB_CLIENT_INFO pClientInfo)
 {
@@ -870,8 +867,21 @@
             RTStrPrintf(pClientInfo->szClientPath, sizeof(pClientInfo->szClientPath), "%s", pCur->Info.szClientPath);
 
+            /*
+             * Inform the client driver that this is the client process that is going to open it. We can predict the future!
+             */
+            int rc;
+            if (pCur->Info.pfnSetConsumerCredentials)
+            {
+                rc = pCur->Info.pfnSetConsumerCredentials(pState->Process, pCur->Info.Instance, NULL /* pvReserved */);
+                if (RT_FAILURE(rc))
+                    LogRel((DEVICE_NAME ":vboxUSBMonSolarisClientInfo pfnSetConsumerCredentials failed. rc=%d\n", rc));
+            }
+            else
+                rc = VERR_INVALID_FUNCTION;
+
             mutex_exit(&g_VBoxUSBMonSolarisMtx);
 
-            LogFlow((DEVICE_NAME ":vboxUSBMonSolarisClientInfo found. %s\n", pClientInfo->szDeviceIdent));
-            return VINF_SUCCESS;
+            LogFlow((DEVICE_NAME ":vboxUSBMonSolarisClientInfo found. %s rc=%d\n", pClientInfo->szDeviceIdent, rc));
+            return rc;
         }
         pPrev = pCur;
@@ -900,32 +910,28 @@
     if (RT_LIKELY(g_pDip))
     {
-        vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
-
-        if (RT_LIKELY(pState))
-        {
-            vboxusbmon_client_t *pClient = RTMemAlloc(sizeof(vboxusbmon_client_t));
-            if (RT_LIKELY(pClient))
-            {
-                bcopy(pClientInfo, &pClient->Info, sizeof(pClient->Info));
-                pClient->pDip = pClientDip;
-
-                mutex_enter(&g_VBoxUSBMonSolarisMtx);
-                pClient->pNext = g_pVBoxUSBMonSolarisClients;
-                g_pVBoxUSBMonSolarisClients = pClient;
-                mutex_exit(&g_VBoxUSBMonSolarisMtx);
-
-                LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisRegisterClient registered. %d %s %s\n",
-                            pClient->Info.Instance, pClient->Info.szClientPath, pClient->Info.szDeviceIdent));
-
-                return VINF_SUCCESS;
-            }
-            else
-                return VERR_NO_MEMORY;
+        vboxusbmon_client_t *pClient = RTMemAllocZ(sizeof(vboxusbmon_client_t));
+        if (RT_LIKELY(pClient))
+        {
+            pClient->Info.Instance = pClientInfo->Instance;
+            strncpy(pClient->Info.szClientPath, pClientInfo->szClientPath, sizeof(pClient->Info.szClientPath));
+            strncpy(pClient->Info.szDeviceIdent, pClientInfo->szDeviceIdent, sizeof(pClient->Info.szDeviceIdent));
+            pClient->Info.pfnSetConsumerCredentials = pClientInfo->pfnSetConsumerCredentials;
+            pClient->pDip = pClientDip;
+
+            mutex_enter(&g_VBoxUSBMonSolarisMtx);
+            pClient->pNext = g_pVBoxUSBMonSolarisClients;
+            g_pVBoxUSBMonSolarisClients = pClient;
+            mutex_exit(&g_VBoxUSBMonSolarisMtx);
+
+            LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisRegisterClient registered. %d %s %s\n",
+                        pClient->Info.Instance, pClient->Info.szClientPath, pClient->Info.szDeviceIdent));
+
+            return VINF_SUCCESS;
         }
         else
-            return VERR_INTERNAL_ERROR;
+            return VERR_NO_MEMORY;
     }
     else
-        return VERR_INTERNAL_ERROR_2;
+        return VERR_INVALID_STATE;
 }
 
@@ -941,46 +947,40 @@
 {
     LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient pClientDip=%p\n", pClientDip));
+    AssertReturn(pClientDip, VERR_INVALID_PARAMETER);
 
     if (RT_LIKELY(g_pDip))
     {
-        vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
-
-        if (RT_LIKELY(pState))
-        {
-            mutex_enter(&g_VBoxUSBMonSolarisMtx);
-
-            vboxusbmon_client_t *pCur = g_pVBoxUSBMonSolarisClients;
-            vboxusbmon_client_t *pPrev = NULL;
-            while (pCur)
+        mutex_enter(&g_VBoxUSBMonSolarisMtx);
+
+        vboxusbmon_client_t *pCur = g_pVBoxUSBMonSolarisClients;
+        vboxusbmon_client_t *pPrev = NULL;
+        while (pCur)
+        {
+            if (pCur->pDip == pClientDip)
             {
-                if (pCur->pDip == pClientDip)
-                {
-                    if (pPrev)
-                        pPrev->pNext = pCur->pNext;
-                    else
-                        g_pVBoxUSBMonSolarisClients = pCur->pNext;
-
-                    mutex_exit(&g_VBoxUSBMonSolarisMtx);
-
-                    LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient unregistered. %d %s %s\n",
-                                pCur->Info.Instance, pCur->Info.szClientPath, pCur->Info.szDeviceIdent));
-                    RTMemFree(pCur);
-                    pCur = NULL;
-                    return VINF_SUCCESS;
-                }
-                pPrev = pCur;
-                pCur = pCur->pNext;
+                if (pPrev)
+                    pPrev->pNext = pCur->pNext;
+                else
+                    g_pVBoxUSBMonSolarisClients = pCur->pNext;
+
+                mutex_exit(&g_VBoxUSBMonSolarisMtx);
+
+                LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient unregistered. %d %s %s\n",
+                            pCur->Info.Instance, pCur->Info.szClientPath, pCur->Info.szDeviceIdent));
+                RTMemFree(pCur);
+                pCur = NULL;
+                return VINF_SUCCESS;
             }
-
-            mutex_exit(&g_VBoxUSBMonSolarisMtx);
-
-            LogRel((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient Failed to find registered client %p\n", pClientDip));
-            return VERR_SEARCH_ERROR;
-        }
-        else
-            return VERR_INTERNAL_ERROR;
+            pPrev = pCur;
+            pCur = pCur->pNext;
+        }
+
+        mutex_exit(&g_VBoxUSBMonSolarisMtx);
+
+        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient Failed to find registered client %p\n", pClientDip));
+        return VERR_NOT_FOUND;
     }
     else
-        return VERR_INTERNAL_ERROR_2;
+        return VERR_INVALID_STATE;
 }
 
Index: /trunk/src/VBox/Installer/solaris/vboxconfig.sh
===================================================================
--- /trunk/src/VBox/Installer/solaris/vboxconfig.sh	(revision 38015)
+++ /trunk/src/VBox/Installer/solaris/vboxconfig.sh	(revision 38016)
@@ -562,6 +562,12 @@
         # For VirtualBox 3.1 the new USB code requires Nevada > 123
         if test "$HOST_OS_MINORVERSION" -gt 123; then
+            # Add a group "vboxuser" (8-character limit) for USB access.
+            # All users which need host USB-passthrough support will have to be added to this group.
+            groupadd vboxuser >/dev/null 2>&1
+
             add_driver "$MOD_VBOXUSBMON" "$DESC_VBOXUSBMON" "$FATALOP" "not-$NULLOP" "'* 0666 root sys'"
             load_module "drv/$MOD_VBOXUSBMON" "$DESC_VBOXUSBMON" "$FATALOP"
+
+            chown root:vboxuser "/devices/pseudo/vboxusbmon@0:vboxusbmon"
 
             # Add vboxusbmon to devlink.tab
Index: /trunk/src/VBox/Main/src-server/solaris/USBProxyServiceSolaris.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/solaris/USBProxyServiceSolaris.cpp	(revision 38015)
+++ /trunk/src/VBox/Main/src-server/solaris/USBProxyServiceSolaris.cpp	(revision 38016)
@@ -161,59 +161,4 @@
 }
 
-#if 0
-static int solarisWalkMinor(di_node_t Node, di_minor_t Minor, void *pvArg)
-{
-    char *pszDevFsPath = di_devfs_path(Node);
-    char *pszMinorName = di_minor_name(Minor);
-    PUSBDEVICE pDev = (PUSBDEVICE)pvArg;
-
-    AssertRelease(pDev);
-
-    if (!pszDevFsPath || !pszMinorName)
-        return DI_WALK_CONTINUE;
-
-    RTStrAPrintf(&pDev->pszApId, "/devices%s:%s", pszDevFsPath, pszMinorName);
-    di_devfs_path_free(pszDevFsPath);
-
-    syslog(LOG_ERR, "VBoxUsbApId:%s\n", pDev->pszApId);
-    return DI_WALK_TERMINATE;
-}
-
-static bool solarisGetApId(PUSBDEVICE pDev, char *pszDevicePath, di_node_t RootNode)
-{
-    pDev->pszApId = NULL;
-
-    /* Skip "/devices" prefix if any */
-    char achDevicesDir[] = "/devices/";
-    if (strncmp(pszDevicePath, achDevicesDir, sizeof(achDevicesDir)) == 0)
-        pszDevicePath += sizeof(achDevicesDir);
-
-    char *pszPhysical = RTStrDup(pszDevicePath);
-    char *pszTmp = NULL;
-
-    /* Remove dynamic component "::" if any */
-    if ((pszTmp = strstr(pszPhysical, "::")) != NULL)
-        *pszTmp = '\0';
-
-    /* Remove minor name if any */
-    if ((pszTmp = strrchr(pszPhysical, ':')) != NULL)
-        *pszTmp = '\0';
-
-    /* Walk device tree */
-//    di_node_t RootNode = di_init("/", DINFOCPYALL);
-//    if (RootNode != DI_NODE_NIL)
-//    {
-//        di_node_t MinorNode = di_lookup_node(RootNode, pszPhysical);
-//        if (MinorNode != DI_NODE_NIL)
-        {
-            di_walk_minor(RootNode, NULL, DI_CHECK_ALIAS | DI_CHECK_INTERNAL_PATH, pDev, solarisWalkMinor);
-            return true;
-        }
-//        di_fini(RootNode);
-//    }
-
-    return false;
-}
-#endif
 
 static int solarisWalkDeviceNode(di_node_t Node, void *pvArg)
@@ -316,23 +261,4 @@
                 pCur->bPort = 0;
 
-#if 0
-            /*
-             * Obtain the dev_t of the device.
-             */
-            di_minor_t Minor = di_minor_next(Node, DI_MINOR_NIL);
-            AssertBreak(Minor != DI_MINOR_NIL);
-            dev_t DeviceNum = di_minor_devt(Minor);
-
-            int DevInstance = 0;
-            rc = solarisUSBGetInstance(pszDevicePath, &DevInstance);
-
-            char szAddress[PATH_MAX + 128];
-            RTStrPrintf(szAddress, sizeof(szAddress), "/dev/usb/%x.%x|%s", pCur->idVendor, pCur->idProduct, pszDevicePath);
-            /* @todo after binding ugen we need to append the instance number to the address. Not yet sure how we can update PUSBDEVICE at that time. */
-
-            pCur->pszAddress = RTStrDup(szAddress);
-            AssertBreak(pCur->pszAddress);
-#endif
-
             char pathBuf[PATH_MAX];
             RTStrPrintf(pathBuf, sizeof(pathBuf), "%s", pszDevicePath);
@@ -368,18 +294,14 @@
             pCur->enmState = solarisDetermineUSBDeviceState(pCur, Node);
 
-//            fValidDevice = solarisGetApId(pCur, pszDevicePath, Node);
-            fValidDevice = true;
-
             /*
              * Valid device, add it to the list.
              */
-            if (fValidDevice)
-            {
-                pCur->pPrev = pList->pTail;
-                if (pList->pTail)
-                    pList->pTail = pList->pTail->pNext = pCur;
-                else
-                    pList->pTail = pList->pHead = pCur;
-            }
+            fValidDevice = true;
+            pCur->pPrev = pList->pTail;
+            if (pList->pTail)
+                pList->pTail = pList->pTail->pNext = pCur;
+            else
+                pList->pTail = pList->pHead = pCur;
+
             rc = DI_WALK_CONTINUE;
         } while(0);
