//--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1995 // // File: getobj.cxx // // Contents: Windows NT 3.5 GetObject functionality // // History: //---------------------------------------------------------------------------- #include "winnt.hxx" #pragma hdrstop extern WCHAR * szWinNTPrefix; //+--------------------------------------------------------------------------- // Function: GetObject // // Synopsis: Called by ResolvePathName to return an object // // Arguments: [LPWSTR szBuffer] // [LPVOID *ppObject] // // Returns: HRESULT // // Modifies: - // // History: 11-3-95 krishnag Created. // //---------------------------------------------------------------------------- HRESULT GetObject( LPWSTR szBuffer, LPVOID *ppObject, CWinNTCredentials& Credentials ) { OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo; CLexer Lexer(szBuffer); HRESULT hr; memset(pObjectInfo, 0, sizeof(OBJECTINFO)); hr = Object(&Lexer, pObjectInfo); BAIL_IF_ERROR(hr); hr = ValidateProvider(pObjectInfo); BAIL_IF_ERROR(hr); switch (pObjectInfo->ObjectType) { case TOKEN_DOMAIN: hr = GetDomainObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_USER: hr = GetUserObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_COMPUTER: hr = GetComputerObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_PRINTER: hr = GetPrinterObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_SERVICE: hr = GetServiceObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_FILESERVICE: hr = GetFileServiceObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_GROUP: hr = GetGroupObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_LOCALGROUP: hr = E_ADS_BAD_PATHNAME; //hr = GetLocalGroupObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_GLOBALGROUP: hr = E_ADS_BAD_PATHNAME; //hr = GetGlobalGroupObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_FILESHARE: hr = GetFileShareObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_SCHEMA: hr = GetSchemaObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_CLASS: hr = GetClassObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_PROPERTY: hr = GetPropertyObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_SYNTAX: hr = GetSyntaxObject(pObjectInfo, ppObject, Credentials); break; case TOKEN_WORKGROUP: hr = GetWorkGroupObject(pObjectInfo, ppObject, Credentials); break; default: hr = HeuristicGetObject(pObjectInfo, ppObject, Credentials); break; } cleanup: FreeObjectInfo( &ObjectInfo, TRUE ); RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetDomainObject // // Synopsis: called by GetObject // // Arguments: [POBJECTINFO pObjectInfo] // [LPVOID * ppObject] // // Returns: HRESULT // // Modifies: - // // History: 11-3-95 krishnag Created. // //---------------------------------------------------------------------------- HRESULT GetNamespaceObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { HRESULT hr; hr = ValidateNamespaceObject( pObjectInfo ); BAIL_ON_FAILURE(hr); // check if the call is from UMI if(Credentials.GetFlags() & ADS_AUTH_RESERVED) { hr = CWinNTNamespace::CreateNamespace( L"ADs:", L"WinNT:", ADS_OBJECT_BOUND, IID_IUnknown, Credentials, ppObject ); } else { // came in through ADSI hr = CoCreateInstance(CLSID_WinNTNamespace, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)ppObject ); } error: RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetDomainObject // // Synopsis: called by GetObject // // Arguments: [POBJECTINFO pObjectInfo] // [LPVOID * ppObject] // // Returns: HRESULT // // Modifies: - // // History: 11-3-95 krishnag Created. // //---------------------------------------------------------------------------- HRESULT GetDomainObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { HRESULT hr; IUnknown *pUnknown = NULL; IADs *pADs = NULL; NET_API_STATUS nasStatus; WCHAR szHostServerName[MAX_PATH]; WCHAR ADsParent[MAX_ADS_PATH]; WCHAR szSAMName[MAX_ADS_PATH]; szSAMName[0] = L'\0'; *ppObject = NULL; if (pObjectInfo->NumComponents != 1) { RRETURN(E_ADS_INVALID_DOMAIN_OBJECT); } // // Verify that this object is really a domain // // We can try and ref the domain here but it will // anyway end up in WinNTGetCachedDCName call in // CWinNTCredentials::RefDomain, so there is no point in // doing that hr = WinNTGetCachedDCName( pObjectInfo->ComponentArray[0], szHostServerName, Credentials.GetFlags() ); BAIL_ON_FAILURE(hr); if (szSAMName[0] != L'\0') { if (pObjectInfo->ComponentArray[0]) { FreeADsStr(pObjectInfo->ComponentArray[0]); } pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName); if (!pObjectInfo) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); } } hr = BuildParent( pObjectInfo, ADsParent ); BAIL_ON_FAILURE(hr); hr = CWinNTDomain::CreateDomain( ADsParent, pObjectInfo->ComponentArray[0], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; error: RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetWorkgroupObject // // Synopsis: called by GetObject. // Note: We really don't have a workgroup object. But we // need to support a syntax such as @WinNT!workstation to // allow for IADsContainer interface methods. There is // no authentication that needs to done. // // Arguments: [POBJECTINFO pObjectInfo] // [LPVOID * ppObject] // // Returns: HRESULT // // Modifies: - // // History: 05-23-96 RamV Created. // //---------------------------------------------------------------------------- HRESULT GetWorkGroupObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { HRESULT hr; IUnknown *pUnknown = NULL; IADs *pADs = NULL; WCHAR ADsParent[MAX_ADS_PATH]; WCHAR szName[MAX_PATH]; *ppObject = NULL; if (pObjectInfo->NumComponents != 1) { RRETURN(E_ADS_INVALID_DOMAIN_OBJECT); } // // any single component oleds path can be validated as a workgroup // hr = BuildParent( pObjectInfo, ADsParent ); BAIL_ON_FAILURE(hr); hr = CWinNTDomain::CreateDomain( ADsParent, pObjectInfo->ComponentArray[0], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; error: RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetUserObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 11-3-95 krishnag Created. // 8-8-96 ramv Modified. // //---------------------------------------------------------------------------- HRESULT GetUserObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szUserName = NULL; DWORD dwParentId = 0; WCHAR szComputerParent[MAX_PATH]; POBJECTINFO pUserObjectInfo = NULL; hr = ValidateUserObject( pObjectInfo, &dwParentId, Credentials ); BAIL_ON_FAILURE(hr); switch (pObjectInfo->NumComponents) { case 2: // // could be user in computer or user in domain // if(dwParentId == WINNT_DOMAIN_ID){ szDomainName = pObjectInfo->ComponentArray[0]; szUserName = pObjectInfo->ComponentArray[1]; szServerName = NULL; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); } else { // // user in a computer // hr = ConstructFullObjectInfo(pObjectInfo, &pUserObjectInfo, Credentials ); if (SUCCEEDED(hr)) { hr = BuildParent(pUserObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = pUserObjectInfo->ComponentArray[0]; szServerName = pUserObjectInfo->ComponentArray[1]; szUserName = pUserObjectInfo->ComponentArray[2]; } else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) { // We alread know that the object is valid, // So we should set appropriate values and proceed to // create the object hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = NULL; szServerName = pObjectInfo->ComponentArray[0]; szUserName = pObjectInfo->ComponentArray[1]; } } break; case 3: szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szUserName = pObjectInfo->ComponentArray[2]; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); break; } hr = CWinNTUser::CreateUser(ADsParent, dwParentId, szDomainName, szServerName, szUserName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; FreeObjectInfo(pUserObjectInfo); RRETURN(hr); error: if (pUnknown) { pUnknown->Release(); } *ppObject = NULL; FreeObjectInfo(pUserObjectInfo); RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetUserObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 8-8-96 ramv Created. // //---------------------------------------------------------------------------- HRESULT GetUserObjectInDomain( LPWSTR pszHostServerName, POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szUserName = NULL; DWORD dwParentId = WINNT_DOMAIN_ID; LPUSER_INFO_20 lpUI = NULL; NET_API_STATUS nasStatus; BOOL fRefAdded = FALSE; LPUSER_INFO_0 lpUI_0 = NULL; DWORD dwLevelUsed = 20; // At this point a \\ has been prepended to the host // we need to get rid of it. hr = Credentials.RefServer(pszHostServerName+2); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } nasStatus = NetUserGetInfo(pszHostServerName, pObjectInfo->ComponentArray[1], 20, (LPBYTE *)&lpUI); if (nasStatus == ERROR_ACCESS_DENIED) { // try and drop down to level 0 as that may work dwLevelUsed = 0; nasStatus = NetUserGetInfo( pszHostServerName, pObjectInfo->ComponentArray[1], 0, (LPBYTE *)&lpUI_0 ); } // deref if necessary, note no error recovery possible if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr); // Need to use the name returned by the call as opposed // to the name given in the ADsPath if (dwLevelUsed == 20) { if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) { FreeADsStr(pObjectInfo->ComponentArray[1]); pObjectInfo->ComponentArray[1] = AllocADsStr(lpUI->usri20_name); } if (!pObjectInfo->ComponentArray[1]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); } // if it is not a level 20 call then we will just use // whatever the user gave us szDomainName = pObjectInfo->ComponentArray[0]; szUserName = pObjectInfo->ComponentArray[1]; szServerName = NULL; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); hr = CWinNTUser::CreateUser(ADsParent, dwParentId, szDomainName, szServerName, szUserName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; error: if (FAILED(hr) && pUnknown) { pUnknown->Release(); *ppObject = NULL; } if (lpUI) NetApiBufferFree((LPBYTE)lpUI); if (lpUI_0) { NetApiBufferFree((LPBYTE)lpUI_0); } RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetUserObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 11-3-95 krishnag Created. // 8-8-96 ramv Modified. // //---------------------------------------------------------------------------- HRESULT GetUserObjectInComputer( LPWSTR pszHostServerName, // pdc name POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szUserName = NULL; DWORD dwParentId = WINNT_COMPUTER_ID; WCHAR szComputerParent[MAX_PATH]; POBJECTINFO pUserObjectInfo = NULL; WCHAR lpszUncName[MAX_PATH]; NET_API_STATUS nasStatus; LPBYTE lpUI = NULL; BOOL fRefAdded = FALSE; switch (pObjectInfo->NumComponents) { case 2: // // could be user in computer // // // first validate user // hr = Credentials.RefServer(pObjectInfo->ComponentArray[0]); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName); nasStatus = NetUserGetInfo(lpszUncName, pObjectInfo->ComponentArray[1], 20, &lpUI); if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr); // Need to use the name returned by the call as opposed // to the name given in the ADsPath if (pObjectInfo->ComponentArray[1] && ((LPUSER_INFO_20)lpUI)->usri20_name) { FreeADsStr(pObjectInfo->ComponentArray[1]); pObjectInfo->ComponentArray[1] = AllocADsStr(((LPUSER_INFO_20)lpUI)->usri20_name); } if (!pObjectInfo->ComponentArray[1]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); // This call will add the domain information to the // objectInfo blob, so that the ComponentArray[2] is valid hr = ConstructFullObjectInfo(pObjectInfo, &pUserObjectInfo, Credentials ); BAIL_ON_FAILURE(hr); hr = BuildParent(pUserObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = pUserObjectInfo->ComponentArray[0]; szServerName = pUserObjectInfo->ComponentArray[1]; szUserName = pUserObjectInfo->ComponentArray[2]; break; case 3: // // ValidateComputerParent and validate user in computer // hr = ValidateComputerParent(pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], Credentials); BAIL_ON_FAILURE(hr); hr = Credentials.RefServer(pObjectInfo->ComponentArray[1]); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } MakeUncName(pObjectInfo->ComponentArray[1], lpszUncName); nasStatus = NetUserGetInfo(lpszUncName, pObjectInfo->ComponentArray[2], 20, (LPBYTE *)&lpUI); if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr); // Need to use the name returned by the call as opposed // to the name given in the ADsPath if (pObjectInfo->ComponentArray[2] && ((LPUSER_INFO_20)lpUI)->usri20_name) { FreeADsStr(pObjectInfo->ComponentArray[2]); pObjectInfo->ComponentArray[2] = AllocADsStr(((LPUSER_INFO_20)lpUI)->usri20_name); } if (!pObjectInfo->ComponentArray[2]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szUserName = pObjectInfo->ComponentArray[2]; break; } hr = CWinNTUser::CreateUser(ADsParent, dwParentId, szDomainName, szServerName, szUserName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); error: if (FAILED(hr)) { if (pUnknown) { pUnknown->Release(); } *ppObject = NULL; } else { *ppObject = pUnknown; } if (lpUI) { NetApiBufferFree(lpUI); } FreeObjectInfo(pUserObjectInfo); RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetComputerObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 11-3-95 krishnag Created. // //---------------------------------------------------------------------------- HRESULT GetComputerObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { HRESULT hr = S_OK; WCHAR ADsParent[MAX_ADS_PATH]; TCHAR szUncName[MAX_PATH]; NET_API_STATUS nasStatus; POBJECTINFO pComputerObjectInfo = NULL; BOOL fNoWksta = FALSE; WCHAR szCompName[MAX_PATH]; DWORD dwSize = MAX_PATH; // // The following function call merely checks to see if the domain is // correct. If not, we can assume that the computer does not belong to // a domain. // hr = ValidateComputerObject(pObjectInfo, Credentials); if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) fNoWksta = TRUE; else BAIL_ON_FAILURE(hr); // Normall we can expect that the workstation service will // be started. This will not be the case for minimum installs if (!fNoWksta) { if(pObjectInfo->NumComponents == 1){ // // we need to supply the workgroup name for this computer // This is needed because EnumLocalGroups requires the // workgroup name to function properly // hr = ConstructFullObjectInfo(pObjectInfo, &pComputerObjectInfo, Credentials ); BAIL_ON_FAILURE(hr); hr = BuildParent(pComputerObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); hr = CWinNTComputer::CreateComputer( ADsParent, pComputerObjectInfo->ComponentArray[0], pComputerObjectInfo->ComponentArray[1], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, ppObject ); } else if(pObjectInfo->NumComponents == 2) { hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); hr = CWinNTComputer::CreateComputer( ADsParent, pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, ppObject); } } else { // Else clause for if(!fWksta) // This means that workstation services were not // started, we need to verify that the host computer // is the one they are interested in. if ((pObjectInfo->NumComponents != 1) || (!GetComputerName(szCompName, &dwSize))) { // We cannot get the computer name so bail BAIL_ON_FAILURE(hr); } // Compare the names before we continue #ifdef WIN95 if (_wcsicmp(szCompName, pObjectInfo->ComponentArray[0])) { #else if (CompareStringW( LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, szCompName, -1, pObjectInfo->ComponentArray[0], -1 ) != CSTR_EQUAL ) { #endif // names do not match BAIL_ON_FAILURE(hr); } hr = CWinNTComputer::CreateComputer( L"WinNT:", NULL, pObjectInfo->ComponentArray[0], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, ppObject ); BAIL_ON_FAILURE(hr); } error: if(pComputerObjectInfo){ FreeObjectInfo(pComputerObjectInfo); } RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetPrinterObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 01/03/96 Ramv Created. // //---------------------------------------------------------------------------- HRESULT GetPrinterObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR szADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szDomainName = NULL; LPWSTR szServerName = NULL; LPWSTR szPrinterName = NULL; DWORD dwParentId = 0; LPWSTR szComputerParent[MAX_PATH]; POBJECTINFO pPrinterObjectInfo = NULL; if (!(pObjectInfo->NumComponents == 3 ||pObjectInfo->NumComponents == 2)){ RRETURN(E_ADS_BAD_PATHNAME); } // check to see that the printer is a valid one hr = ValidatePrinterObject(pObjectInfo, Credentials); BAIL_ON_FAILURE(hr); dwParentId = WINNT_COMPUTER_ID; if(pObjectInfo->NumComponents == 3) { hr = BuildParent(pObjectInfo, szADsParent); BAIL_ON_FAILURE(hr); szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szPrinterName= pObjectInfo->ComponentArray[2]; } else if (pObjectInfo->NumComponents == 2){ hr = ConstructFullObjectInfo(pObjectInfo, &pPrinterObjectInfo, Credentials ); BAIL_ON_FAILURE(hr); hr = BuildParent(pPrinterObjectInfo, szADsParent); BAIL_ON_FAILURE(hr); szDomainName = pPrinterObjectInfo->ComponentArray[0]; szServerName = pPrinterObjectInfo->ComponentArray[1]; szPrinterName= pPrinterObjectInfo->ComponentArray[2]; } hr = CWinNTPrintQueue::CreatePrintQueue( szADsParent, dwParentId, szDomainName, szServerName, szPrinterName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; FreeObjectInfo(pPrinterObjectInfo); RRETURN(hr); error: if (pUnknown) { pUnknown->Release(); } *ppObject = NULL; FreeObjectInfo(pPrinterObjectInfo); RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetServiceObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 01/03/96 Ramv Created. // //---------------------------------------------------------------------------- HRESULT GetServiceObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR szADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szDomainName = NULL; LPWSTR szServerName = NULL; LPWSTR szServiceName = NULL; DWORD dwParentId = 0; POBJECTINFO pServiceObjectInfo = NULL; // // check to see that the printer is in a valid server(computer) object // if(!(pObjectInfo->NumComponents == 3 || pObjectInfo->NumComponents == 2)) { RRETURN(E_ADS_BAD_PATHNAME); } hr = ValidateServiceObject(pObjectInfo, Credentials); BAIL_ON_FAILURE(hr); dwParentId = WINNT_COMPUTER_ID; if(pObjectInfo->NumComponents == 3) { hr = BuildParent(pObjectInfo, szADsParent); BAIL_ON_FAILURE(hr); szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szServiceName= pObjectInfo->ComponentArray[2]; hr = CWinNTService::Create(szADsParent, szDomainName, szServerName, szServiceName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr); } else if (pObjectInfo->NumComponents == 2) { hr = ConstructFullObjectInfo(pObjectInfo, &pServiceObjectInfo, Credentials ); BAIL_ON_FAILURE(hr); hr = BuildParent(pServiceObjectInfo, szADsParent); BAIL_ON_FAILURE(hr); szServerName = pServiceObjectInfo->ComponentArray[1]; szServiceName= pServiceObjectInfo->ComponentArray[2]; hr = CWinNTService::Create(szADsParent, pServiceObjectInfo->ComponentArray[0], szServerName, szServiceName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr); } *ppObject = pUnknown; if(pServiceObjectInfo){ FreeObjectInfo(pServiceObjectInfo); } RRETURN(hr); error: if(pServiceObjectInfo){ FreeObjectInfo(pServiceObjectInfo); } if (pUnknown) { pUnknown->Release(); } *ppObject = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetFileServiceObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 01/15/96 Ramv Created. // //---------------------------------------------------------------------------- HRESULT GetFileServiceObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR szADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szDomainName = NULL; LPWSTR szServerName = NULL; LPWSTR szFileServiceName = NULL; DWORD dwParentId = 0; POBJECTINFO pFileServiceObjectInfo = NULL; // // check to see that the service is in a valid server(computer) object // if (!(pObjectInfo->NumComponents == 3 || pObjectInfo->NumComponents == 2)) RRETURN(E_ADS_BAD_PATHNAME); hr = ValidateFileServiceObject(pObjectInfo, Credentials); BAIL_ON_FAILURE(hr); if (pObjectInfo->NumComponents == 3){ szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szFileServiceName= pObjectInfo->ComponentArray[2]; hr = BuildParent(pObjectInfo, szADsParent); BAIL_ON_FAILURE(hr); } if (pObjectInfo->NumComponents == 2){ hr = ConstructFullObjectInfo(pObjectInfo, &pFileServiceObjectInfo, Credentials ); BAIL_ON_FAILURE(hr); hr = BuildParent(pFileServiceObjectInfo, szADsParent); BAIL_ON_FAILURE(hr); szDomainName = pFileServiceObjectInfo->ComponentArray[0]; szServerName = pFileServiceObjectInfo->ComponentArray[1]; szFileServiceName= pFileServiceObjectInfo->ComponentArray[2]; } dwParentId = WINNT_COMPUTER_ID; if(_tcsicmp(szFileServiceName,TEXT("LanmanServer")) == 0) { hr = CWinNTFileService::CreateFileService(szADsParent, dwParentId, szDomainName, szServerName, szFileServiceName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr); } else if(_tcsicmp(szFileServiceName,TEXT("FPNW")) == 0) { hr = CFPNWFileService::CreateFileService(szADsParent, dwParentId, szDomainName, szServerName, szFileServiceName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr); } *ppObject = pUnknown; if(pFileServiceObjectInfo){ FreeObjectInfo(pFileServiceObjectInfo); } RRETURN(hr); error: if(pFileServiceObjectInfo){ FreeObjectInfo(pFileServiceObjectInfo); } if (pUnknown) { pUnknown->Release(); } *ppObject = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetFileShareObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 01/15/96 Ramv Created. // //---------------------------------------------------------------------------- HRESULT GetFileShareObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR szADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPTSTR szDomainName = NULL; LPTSTR szServerName = NULL; LPTSTR szFileServiceName = NULL; LPTSTR szFileShareName = NULL; DWORD dwParentId = 0; POBJECTINFO pFileShareObjectInfo = NULL; WCHAR lpszUncName[MAX_PATH]; BOOL fRefAdded = FALSE; // // check to see that the share is in a valid fileservice // if (!(pObjectInfo->NumComponents == 4 || pObjectInfo->NumComponents == 3)) { RRETURN(E_ADS_BAD_PATHNAME); } // The server is ref'ed in this routine. hr = ValidateFileShareObject(pObjectInfo, Credentials); BAIL_ON_FAILURE(hr); dwParentId = WINNT_SERVICE_ID; if(pObjectInfo->NumComponents == 4){ hr = BuildParent(pObjectInfo, szADsParent); BAIL_ON_FAILURE(hr); szServerName = pObjectInfo->ComponentArray[1]; szFileServiceName= pObjectInfo->ComponentArray[2]; szFileShareName = pObjectInfo ->ComponentArray[3]; } else if (pObjectInfo->NumComponents == 3){ hr = ConstructFullObjectInfo(pObjectInfo, &pFileShareObjectInfo, Credentials ); BAIL_ON_FAILURE(hr); hr = BuildParent(pFileShareObjectInfo, szADsParent); BAIL_ON_FAILURE(hr); szServerName = pObjectInfo->ComponentArray[0]; szFileServiceName= pObjectInfo->ComponentArray[1]; szFileShareName = pObjectInfo ->ComponentArray[2]; } if(_tcsicmp(szFileServiceName,TEXT("LanmanServer")) == 0){ hr = CWinNTFileShare::Create(szADsParent, szServerName, szFileServiceName, szFileShareName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr); } else { // // we have validated it already, it *has* to be an FPNW server // hr = CFPNWFileShare::Create(szADsParent, szServerName, szFileServiceName, szFileShareName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr); } *ppObject = pUnknown; if(pFileShareObjectInfo){ FreeObjectInfo(pFileShareObjectInfo); } RRETURN(hr); error: if (pUnknown) { pUnknown->Release(); } if(pFileShareObjectInfo){ FreeObjectInfo(pFileShareObjectInfo); } *ppObject = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetGroupObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 11-3-95 krishnag Created. // //---------------------------------------------------------------------------- HRESULT GetGroupObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szGroupName = NULL; DWORD dwParentId = 0; ULONG uGroupType = 0; POBJECTINFO pGroupObjectInfo = NULL; hr = ValidateGroupObject( pObjectInfo, &uGroupType, &dwParentId, Credentials ); BAIL_ON_FAILURE(hr); switch (pObjectInfo->NumComponents) { case 2: // // could be group in computer or group in domain // if(dwParentId == WINNT_DOMAIN_ID){ szDomainName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1]; szServerName = NULL; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); } else { // // group in a computer // hr = ConstructFullObjectInfo(pObjectInfo, &pGroupObjectInfo, Credentials ); if (SUCCEEDED(hr)) { hr = BuildParent(pGroupObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = pGroupObjectInfo->ComponentArray[0]; szServerName = pGroupObjectInfo->ComponentArray[1]; szGroupName = pGroupObjectInfo->ComponentArray[2]; } else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) { // // We will build the info without the parent // hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = NULL; szServerName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1]; } BAIL_ON_FAILURE(hr); } break; case 3: hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szGroupName = pObjectInfo->ComponentArray[2]; break; } hr = CWinNTGroup::CreateGroup( ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); } RRETURN(hr); error: if (pUnknown) { pUnknown->Release(); } if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); } *ppObject = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetGroupObjectInComputer // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 11-3-95 ramv Created. // //---------------------------------------------------------------------------- HRESULT GetGroupObjectInComputer( LPWSTR pszHostServerName, // pdc name POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szGroupName = NULL; DWORD dwParentId = WINNT_COMPUTER_ID; ULONG uGroupType = 0; POBJECTINFO pGroupObjectInfo = NULL; WCHAR lpszUncName[MAX_PATH]; switch (pObjectInfo->NumComponents) { case 2: // // group in a computer // MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName); hr = ValidateGlobalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[1]), Credentials ); if (SUCCEEDED(hr)) { uGroupType = WINNT_GROUP_GLOBAL; }else{ hr = ValidateLocalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[1]), Credentials ); BAIL_ON_FAILURE(hr); uGroupType = WINNT_GROUP_LOCAL; } hr = ConstructFullObjectInfo(pObjectInfo, &pGroupObjectInfo, Credentials ); BAIL_ON_FAILURE(hr); hr = BuildParent(pGroupObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = pGroupObjectInfo->ComponentArray[0]; szServerName = pGroupObjectInfo->ComponentArray[1]; szGroupName = pGroupObjectInfo->ComponentArray[2]; break; case 3: hr = ValidateComputerParent(pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], Credentials); BAIL_ON_FAILURE(hr); MakeUncName( pObjectInfo->ComponentArray[1], lpszUncName ); hr = ValidateGlobalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[2]), Credentials ); if (SUCCEEDED(hr)) { uGroupType = WINNT_GROUP_GLOBAL; } else { hr = ValidateLocalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[2]), Credentials ); BAIL_ON_FAILURE(hr); uGroupType = WINNT_GROUP_LOCAL; } hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szGroupName = pObjectInfo->ComponentArray[2]; break; } if (uGroupType == WINNT_GROUP_LOCAL) { hr = CWinNTGroup::CreateGroup(ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); }else { hr = CWinNTGroup::CreateGroup(ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); } BAIL_ON_FAILURE(hr); *ppObject = pUnknown; if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); } RRETURN(hr); error: if (pUnknown) { pUnknown->Release(); } if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); } *ppObject = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetGroupObjectInDomain // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 8-8-96 Ramv Created. // //---------------------------------------------------------------------------- HRESULT GetGroupObjectInDomain( LPWSTR pszHostServerName, POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szGroupName = NULL; DWORD dwParentId = WINNT_DOMAIN_ID; ULONG uGroupType = 0; BOOL fRefAdded = FALSE; // At this point the host server name has a \\ prepended // so we need to get rid of it. hr = Credentials.RefServer(pszHostServerName+2); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } hr = ValidateGlobalGroupObject( pszHostServerName, &(pObjectInfo->ComponentArray[1]), Credentials ); if (FAILED(hr)) { hr = ValidateLocalGroupObject( pszHostServerName, &(pObjectInfo->ComponentArray[1]), Credentials ); // DeRef if ref added, no recovery possible on failed deref if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } BAIL_ON_FAILURE(hr); uGroupType = WINNT_GROUP_LOCAL; }else { uGroupType = WINNT_GROUP_GLOBAL; } // DeRef if ref added, no recovery possible on failed deref if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } szDomainName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1]; szServerName = NULL; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); if (uGroupType==WINNT_GROUP_LOCAL) { hr = CWinNTGroup::CreateGroup( ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); } else { hr = CWinNTGroup::CreateGroup(ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); } BAIL_ON_FAILURE(hr); *ppObject = pUnknown; RRETURN(hr); error: if (pUnknown) { pUnknown->Release(); } *ppObject = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetSchemaObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 1-17-96 yihsins Created. // //---------------------------------------------------------------------------- HRESULT GetSchemaObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; if (pObjectInfo->NumComponents != 2) RRETURN(E_ADS_BAD_PATHNAME); if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 ) { hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); } hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); hr = CWinNTSchema::CreateSchema( ADsParent, pObjectInfo->ComponentArray[1], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; RRETURN(hr); error: if (pUnknown) pUnknown->Release(); *ppObject = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetClassObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 1-17-96 yihsins Created. // //---------------------------------------------------------------------------- HRESULT GetClassObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; DWORD i; if (pObjectInfo->NumComponents != 3) RRETURN(E_ADS_BAD_PATHNAME); if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 ) { hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); } // // Look for the given class name // for ( i = 0; i < g_cWinNTClasses; i++ ) { if ( _wcsicmp( g_aWinNTClasses[i].bstrName, pObjectInfo->ComponentArray[2] ) == 0 ) break; } if ( i == g_cWinNTClasses ) { // Class name not found, return error hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); } // // Class name found, create and return the object // hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); hr = CWinNTClass::CreateClass( ADsParent, &g_aWinNTClasses[i], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; RRETURN(hr); error: if (pUnknown) pUnknown->Release(); *ppObject = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetSyntaxObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 1-17-96 yihsins Created. // //---------------------------------------------------------------------------- HRESULT GetSyntaxObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; DWORD i; if (pObjectInfo->NumComponents != 3) RRETURN(E_ADS_BAD_PATHNAME); if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 ) { hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); } // // Look for the given syntax name // for ( i = 0; i < g_cWinNTSyntax; i++ ) { if ( _wcsicmp( g_aWinNTSyntax[i].bstrName, pObjectInfo->ComponentArray[2] ) == 0 ) break; } if ( i == g_cWinNTSyntax ) { // Syntax name not found, return error hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); } // // Syntax name found, create and return the object // hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); hr = CWinNTSyntax::CreateSyntax( ADsParent, &(g_aWinNTSyntax[i]), ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; RRETURN(hr); error: if (pUnknown) pUnknown->Release(); *ppObject = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetPropertyObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 1-17-96 yihsins Created. // //---------------------------------------------------------------------------- HRESULT GetPropertyObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; WCHAR ADsGrandParent[MAX_ADS_PATH]; HRESULT hr = S_OK; DWORD nClass, nProp; if (pObjectInfo->NumComponents != 3) RRETURN(E_ADS_BAD_PATHNAME); if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 ) { hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); } // // We found the specified functional set, now see if we can locate // the given property name // for ( nProp = 0; nProp < g_cWinNTProperties; nProp++ ) { if ( _wcsicmp(g_aWinNTProperties[nProp].szPropertyName, pObjectInfo->ComponentArray[2] ) == 0 ) break; } if ( nProp == g_cWinNTProperties ) { // Return error because the given property name is not found hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); } // // Property name is found, so create and return the object // hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); hr = CWinNTProperty::CreateProperty( ADsParent, &(g_aWinNTProperties[nProp]), ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; RRETURN(hr); error: if (pUnknown) pUnknown->Release(); *ppObject = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 11-3-95 krishnag Created. // //---------------------------------------------------------------------------- HRESULT HeuristicGetObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { HRESULT hr = S_OK; WCHAR szHostServerName[MAX_PATH]; DWORD dwElementType; WCHAR szName[MAX_PATH]; WCHAR szSAMName[MAX_ADS_PATH]; WCHAR lpszUncName[MAX_PATH]; szSAMName[0] = L'\0'; // // Case 0: Zero components - must be a namespace object // if (pObjectInfo->NumComponents == 0) { RRETURN(GetNamespaceObject(pObjectInfo, ppObject, Credentials)); } // // Case 1: Single component - must be a domain object or // computer object // if (pObjectInfo->NumComponents == 1) { // // hr = WinNTGetCachedObject(type, hit/miss, pdcname/domain name) // // if (succeeded... // switch(type) .... call the appropriate // GetDomain or GetWorkGroup or GetComputer // hr = WinNTGetCachedName( pObjectInfo->ComponentArray[0], &dwElementType, szHostServerName, szSAMName, Credentials ); BAIL_IF_ERROR(hr); // update the name to the one on SAM if (szSAMName[0] != L'\0') { FreeADsStr(pObjectInfo->ComponentArray[0]); pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName); } if (!pObjectInfo->ComponentArray[0]) { BAIL_IF_ERROR(hr = E_OUTOFMEMORY); } switch(dwElementType) { case DOMAIN_ENTRY_TYPE: hr = GetDomainObject(pObjectInfo, ppObject, Credentials); break; case COMPUTER_ENTRY_TYPE: hr = GetComputerObject(pObjectInfo, ppObject, Credentials); break; default: hr = GetWorkGroupObject(pObjectInfo, ppObject, Credentials); break; } goto cleanup; } // // Case 2: Two components - could be user, group, computer, // or any one of the computer's sub-objects. // if (pObjectInfo->NumComponents == 2) { hr = GetSchemaObject(pObjectInfo, ppObject, Credentials); if(SUCCEEDED(hr)){ goto cleanup; } if(FAILED(hr)) { // // try doing a WinNTGetCachedDCName first // and if it goes through, then we have objects such as // user,group,computer in domain, otherwise it is the // computer case or workgroup case // // WinNtGetCachedObject will directly tell us to proceed or // not hr = WinNTGetCachedName(pObjectInfo->ComponentArray[0], &dwElementType, szHostServerName, szSAMName, Credentials ); BAIL_IF_ERROR(hr); // Again we do not have to worry about the case of the // object name, it is handled by the GetObject calls switch(dwElementType) { case DOMAIN_ENTRY_TYPE: hr = GetUserObjectInDomain(szHostServerName, pObjectInfo, ppObject, Credentials); if (FAILED(hr)) { hr = GetGroupObjectInDomain(szHostServerName, pObjectInfo, ppObject, Credentials); } if (FAILED(hr)) { hr = GetComputerObject(pObjectInfo, ppObject, Credentials); } goto cleanup; case COMPUTER_ENTRY_TYPE: hr = GetPrinterObject(pObjectInfo, ppObject, Credentials); if (FAILED(hr)) { hr = GetFileServiceObject( pObjectInfo, ppObject, Credentials ); } if (FAILED(hr)) { hr = GetServiceObject(pObjectInfo, ppObject, Credentials); } if(FAILED(hr)){ hr = GetUserObjectInComputer( pObjectInfo->ComponentArray[0], pObjectInfo, ppObject, Credentials ); } if (FAILED(hr)) { hr = GetGroupObjectInComputer( pObjectInfo->ComponentArray[0], pObjectInfo, ppObject, Credentials ); } goto cleanup; case WORKGROUP_ENTRY_TYPE: hr = GetComputerObject(pObjectInfo, ppObject, Credentials); if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) { // In this case I want to mask the error // as it means it could not find the object hr = E_ADS_UNKNOWN_OBJECT; } } goto cleanup; default: hr = E_ADS_UNKNOWN_OBJECT; goto cleanup; } } } /* NumComponents == 2 */ // // Case 3: Three components - could be user, group, printer, fileservice // or service or fileshare for computer in a workgroup environment. // if (pObjectInfo->NumComponents == 3) { if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) == 0 ){ hr = GetClassObject(pObjectInfo, ppObject, Credentials); if (FAILED(hr)) { hr = GetPropertyObject(pObjectInfo, ppObject, Credentials); } if (FAILED(hr)) { hr = GetSyntaxObject(pObjectInfo, ppObject, Credentials); } } else{ hr = GetUserObjectInComputer(pObjectInfo->ComponentArray[1], pObjectInfo, ppObject, Credentials); if (FAILED(hr)) { hr = GetGroupObjectInComputer(pObjectInfo->ComponentArray[1], pObjectInfo, ppObject, Credentials); } if(FAILED(hr)){ hr = GetPrinterObject(pObjectInfo, ppObject, Credentials); } if (FAILED(hr)) { hr = GetFileServiceObject(pObjectInfo, ppObject, Credentials); } if (FAILED(hr)) { hr = GetServiceObject(pObjectInfo, ppObject, Credentials); } if (FAILED(hr)) { hr = GetFileShareObject(pObjectInfo, ppObject, Credentials); } } if(FAILED(hr) ){ RRETURN(hr); } else{ RRETURN(S_OK); } } if (pObjectInfo->NumComponents == 4) { hr = GetFileShareObject(pObjectInfo, ppObject, Credentials); if(FAILED(hr)){ RRETURN(hr); } else{ RRETURN(S_OK); } } RRETURN (E_ADS_UNKNOWN_OBJECT); cleanup: if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) { // // There is a very good chance that this is a case // where they are trying to work on the local machine // when there are no workstation services. Note that this // means that a fully qualified name was not given. // hr = HeuristicGetObjectNoWksta( pObjectInfo, ppObject, Credentials ); } // // Propagate the error code which we have rather than // mask it and return information of little value // if (FAILED(hr)) { // the error code NERR_BadTransactConfig means that the // object did not exist, we want to mask just that ecode if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) { hr = E_ADS_UNKNOWN_OBJECT; } RRETURN(hr); } else { RRETURN(S_OK); } } //+--------------------------------------------------------------------------- // Function: HeuristicGetObjectNoWksta // // Synopsis: Tries to locate the object on local machine when there are no // workstation services. This will happen in a minimum install of NT. // // Arguments: POBJECTINFO -> data about object being located. // LPVOID -> Object to be returned in this arg. // Credentials -> Credentials blob. // // Returns: Either S_OK or HR_From_Win32(NERR_WkstaNotStarted) // // Modifies: // // History: 08-03-98 AjayR Created. // //---------------------------------------------------------------------------- HRESULT HeuristicGetObjectNoWksta( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { HRESULT hr = S_OK; HRESULT hrNoWksta = HRESULT_FROM_WIN32(NERR_WkstaNotStarted); WCHAR szHostServerName[MAX_PATH]; DWORD dwElementType; WCHAR szName[MAX_PATH]; WCHAR szSAMName[MAX_ADS_PATH]; WCHAR lpszUncName[MAX_PATH]; szSAMName[0] = L'\0'; // // Case 0: Zero components - Should no be hit here. // if (pObjectInfo->NumComponents == 0) { RRETURN(hrNoWksta); } // // Case 1: Single component - Can only be a computer object // if (pObjectInfo->NumComponents == 1) { hr = GetComputerObject(pObjectInfo, ppObject, Credentials); goto cleanup; } // // Case 2: Two components - could be user or group for now. // Other possible objects - TBD. // if (pObjectInfo->NumComponents == 2) { hr = GetPrinterObject(pObjectInfo, ppObject, Credentials); if (FAILED(hr)) { hr = GetFileServiceObject( pObjectInfo, ppObject, Credentials ); } if (FAILED(hr)) { hr = GetServiceObject(pObjectInfo, ppObject, Credentials); } if(FAILED(hr)){ hr = GetUserObject( pObjectInfo, ppObject, Credentials ); } if (FAILED(hr)) { hr = GetLocalGroupObject( pObjectInfo, ppObject, Credentials ); } goto cleanup; } /* NumComponents == 2 */ // // Case 3 or more : Three or more components - not possible // if (pObjectInfo->NumComponents > 2) { RRETURN(hrNoWksta); } RRETURN (E_ADS_UNKNOWN_OBJECT); cleanup: // // Propagate the error code which we have rather than // mask it and return information of little value // if (FAILED(hr)) { // the error code NERR_BadTransactConfig means that the // object did not exist, we want to mask just that ecode if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) { hr = E_ADS_UNKNOWN_OBJECT; } RRETURN(hr); } else { RRETURN(S_OK); } } HRESULT BuildParent( POBJECTINFO pObjectInfo, LPWSTR szBuffer ) { DWORD i = 0; DWORD dwLen = 0; if (!pObjectInfo->ProviderName) { RRETURN(E_ADS_BAD_PATHNAME); } wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName); if (pObjectInfo->NumComponents - 1) { dwLen = wcslen(pObjectInfo->ProviderName) + 3 + wcslen(pObjectInfo->DisplayComponentArray[0]); if(dwLen >= MAX_ADS_PATH) { RRETURN(E_ADS_BAD_PATHNAME); } wcscat(szBuffer, L"//"); wcscat(szBuffer, pObjectInfo->DisplayComponentArray[0]); for (i = 1; i < (pObjectInfo->NumComponents - 1); i++) { dwLen += (1 + wcslen(pObjectInfo->DisplayComponentArray[i])); if(dwLen >= MAX_ADS_PATH) { RRETURN(E_ADS_BAD_PATHNAME); } wcscat(szBuffer, L"/"); wcscat(szBuffer, pObjectInfo->DisplayComponentArray[i]); } } RRETURN(S_OK); } HRESULT BuildGrandParent( POBJECTINFO pObjectInfo, LPWSTR szBuffer ) { DWORD i = 0; if (!pObjectInfo->ProviderName) { RRETURN(E_ADS_BAD_PATHNAME); } wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName); if (pObjectInfo->NumComponents - 2) { wcscat(szBuffer, L"//"); wcscat(szBuffer, pObjectInfo->ComponentArray[0]); for (i = 1; i < (pObjectInfo->NumComponents - 2); i++) { wcscat(szBuffer, L"/"); wcscat(szBuffer, pObjectInfo->ComponentArray[i]); } } RRETURN(S_OK); } HRESULT BuildADsPath( POBJECTINFO pObjectInfo, LPWSTR szBuffer ) { DWORD i = 0; if (!pObjectInfo->ProviderName) { RRETURN(E_ADS_BAD_PATHNAME); } wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName); if (pObjectInfo->NumComponents) { wcscat(szBuffer, L"//"); wcscat(szBuffer, pObjectInfo->DisplayComponentArray[0]); for (i = 1; i < (pObjectInfo->NumComponents); i++) { wcscat(szBuffer, L"/"); wcscat(szBuffer, pObjectInfo->DisplayComponentArray[i]); } } RRETURN(S_OK); } HRESULT ValidateUserObject( POBJECTINFO pObjectInfo, PDWORD pdwParentId, CWinNTCredentials& Credentials ) { WCHAR szHostServerName[MAX_PATH]; LPUSER_INFO_20 lpUI = NULL; HRESULT hr; WCHAR lpszUncName[MAX_PATH]; NET_API_STATUS nasStatus; WCHAR szSAMName[MAX_PATH]; BOOL fRefAdded = FALSE; LPUSER_INFO_0 lpUI_0 = NULL; DWORD dwLevelUsed = 20; WCHAR szCompName[MAX_PATH]; DWORD dwSize = MAX_PATH; szSAMName[0] = L'\0'; switch (pObjectInfo->NumComponents) { case 2: // // if 2 components then either it is user in computer // or user in domain. hr = WinNTGetCachedDCName( pObjectInfo->ComponentArray[0], szHostServerName, Credentials.GetFlags() ); if(SUCCEEDED(hr)){ // Need to ref the server, note that RefServer // checks if the credentials are non null // We are not concerned about any error as we may // still succeed with default credentials. // The +2 is to skip the \\ at the head. hr = Credentials.RefServer(szHostServerName+2); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } nasStatus = NetUserGetInfo(szHostServerName, pObjectInfo->ComponentArray[1], 20, (LPBYTE *)&lpUI); // // This code is here because Level 20 reads the flags // and if you accessed WinNT://ntdev/foo with Redmond\foo // credentials, it will fail. This allow a bind but the // GetInfo will fail. // if (nasStatus == ERROR_ACCESS_DENIED) { // try and drop down to level 0 as that may work dwLevelUsed = 0; nasStatus = NetUserGetInfo( szHostServerName, pObjectInfo->ComponentArray[1], 0, (LPBYTE *)&lpUI_0 ); } // DeRef if ref added, no recovery possible on failed deref if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr); // Need to use the name returned by the call as opposed // to the name given in the ADsPath if (dwLevelUsed == 20 ) { if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) { FreeADsStr(pObjectInfo->ComponentArray[1]); pObjectInfo->ComponentArray[1] = AllocADsStr(lpUI->usri20_name); } if (!pObjectInfo->ComponentArray[1]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); } *pdwParentId = WINNT_DOMAIN_ID; } // // if we are here with hr != S_OK it could be that we have // user in a computer. // if(FAILED(hr)){ hr = ValidateComputerParent( NULL, pObjectInfo->ComponentArray[0], Credentials ); if (SUCCEEDED(hr)) { // Need to ref the server on which the object lives // Note that RefServer checks if Credentials are null. // Again, we are not concerned about any errors as we // will drop down to default credentials automatically. hr = Credentials.RefServer(pObjectInfo->ComponentArray[0]); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName); nasStatus = NetUserGetInfo(lpszUncName, pObjectInfo->ComponentArray[1], 20, (LPBYTE *)&lpUI); // DeRef if ref added, no recovery possible on failed deref if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr); // Need to use the name returned by the call as opposed // to the name given in the ADsPath if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) { FreeADsStr(pObjectInfo->ComponentArray[1]); pObjectInfo->ComponentArray[1] = AllocADsStr(lpUI->usri20_name); } if (!pObjectInfo->ComponentArray[1]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); *pdwParentId = WINNT_COMPUTER_ID; } else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) { // // Need to see if the problem was not workstation // services in which case we need to still try and // locate user if the comptuer name matches. // if (!GetComputerName(szCompName, &dwSize)) { // // We could not get the computer name so bail // BAIL_ON_FAILURE(hr); } // // Test the name before continuing. // #ifdef WIN95 if (_wcsicmp(szCompName, pObjectInfo->ComponentArray[0])) { #else if (CompareStringW( LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, szCompName, -1, pObjectInfo->ComponentArray[0], -1 ) != CSTR_EQUAL ) { #endif // names do not match BAIL_ON_FAILURE(hr); } // // Valid computer name, so we can try and check for user // MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName); nasStatus = NetUserGetInfo( lpszUncName, pObjectInfo->ComponentArray[1], 20, (LPBYTE *)&lpUI ); BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(nasStatus)); *pdwParentId = WINNT_COMPUTER_ID; } } BAIL_ON_FAILURE(hr); break; case 3: // // user in domain\computer or user in workgroup\computer // hr = ValidateComputerParent( pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], Credentials ); BAIL_ON_FAILURE(hr); // Again we need to ref the server hr = Credentials.RefServer(pObjectInfo->ComponentArray[1]); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } MakeUncName(pObjectInfo->ComponentArray[1], lpszUncName); nasStatus = NetUserGetInfo(lpszUncName, pObjectInfo->ComponentArray[2], 20, (LPBYTE *)&lpUI); // DeRef if ref added, no recovery possible on failed deref if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr); // Need to use the name returned by the call as opposed // to the name given in the ADsPath if (pObjectInfo->ComponentArray[2] && lpUI->usri20_name) { FreeADsStr(pObjectInfo->ComponentArray[2]); pObjectInfo->ComponentArray[2] = AllocADsStr(lpUI->usri20_name); } if (!pObjectInfo->ComponentArray[2]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); *pdwParentId = WINNT_COMPUTER_ID; break; default: RRETURN(E_ADS_BAD_PATHNAME); } error: if (lpUI) { NetApiBufferFree((LPBYTE)lpUI); } if (lpUI_0) { NetApiBufferFree((LPBYTE)lpUI_0); } RRETURN(hr); } HRESULT ValidateComputerParent( LPWSTR pszDomainName, LPWSTR pszComputerName, CWinNTCredentials& Credentials ) { HRESULT hr; NET_API_STATUS nasStatus; WCHAR szName[MAX_PATH]; WCHAR szSAMName[MAX_PATH]; WCHAR szCompName[MAX_PATH]; DWORD dwSize = MAX_PATH; szSAMName[0] = L'\0'; hr = WinNTGetCachedComputerName( pszComputerName, szName, szSAMName, Credentials ); if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) { // // We want to see if the computer being validated is // the current host. // if (!GetComputerName(szCompName, &dwSize) #ifdef WIN95 || (_wcsicmp(szCompName, pszComputerName)) #else || (CompareStringW( LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, szCompName, -1, pszComputerName, -1 ) != CSTR_EQUAL ) #endif ) BAIL_ON_FAILURE(hr); hr = S_OK; } BAIL_ON_FAILURE(hr); if(pszDomainName == NULL){ // // we are dealing with a case where we aren't supplied the // computer's parent. Just validate the computer // hr = S_OK; goto error; } else { #ifdef WIN95 // // No NetpNameCompare for Win9x // if (!_wcsicmp(pszDomainName, szName)) { #else if ((CompareStringW( LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, pszDomainName, -1, szName, -1 ) == CSTR_EQUAL ) || (NetpNameCompare( NULL, pszDomainName, szName, NAMETYPE_DOMAIN, 0 ) == 0 ) ) { #endif hr = S_OK; }else { hr = E_ADS_BAD_PATHNAME; } } error: RRETURN(hr); } // Overloaded ValidateComputerParent function. // This is used when the case of pszComputerName on the SAM // databsae is needed. HRESULT ValidateComputerParent( LPWSTR pszDomainName, LPWSTR pszComputerName, LPWSTR pszSAMName, CWinNTCredentials& Credentials ) { HRESULT hr; NET_API_STATUS nasStatus; WCHAR szName[MAX_PATH]; WCHAR szSAMName[MAX_PATH]; szSAMName[0] = L'\0'; hr = WinNTGetCachedComputerName( pszComputerName, szName, szSAMName, Credentials ); BAIL_ON_FAILURE(hr); if (szSAMName[0] != L'\0') { wcscpy(pszSAMName, szSAMName); } if(pszDomainName == NULL){ // // we are dealing with a case where we aren't supplied the // computer's parent. Just validate the computer // hr = S_OK; goto error; } else { #ifdef WIN95 // // No NetpNameCompare for Win9x // if (!_wcsicmp(pszDomainName, szName)) { #else if ((CompareStringW( LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, pszDomainName, -1, szName, -1 ) == CSTR_EQUAL ) || (NetpNameCompare( NULL, pszDomainName, szName, NAMETYPE_DOMAIN, 0 ) == 0 ) ) { #endif hr = S_OK; }else { hr = E_FAIL; } } error: RRETURN(hr); } HRESULT ValidateGroupObject( POBJECTINFO pObjectInfo, PULONG puGroupType, PDWORD pdwParentId, CWinNTCredentials& Credentials ) { WCHAR szHostServerName[MAX_PATH]; LPGROUP_INFO_0 lpGI = NULL; HRESULT hr; WCHAR lpszUncName[MAX_PATH]; NET_API_STATUS nasStatus; ULONG uGroupType = 0L; WCHAR szSAMName[MAX_PATH]; szSAMName[0] = L'\0'; switch (pObjectInfo->NumComponents) { case 2: // // if 2 components then either it is a group in computer // or group in domain. // hr = WinNTGetCachedDCName( pObjectInfo->ComponentArray[0], szHostServerName, Credentials.GetFlags() ); if(SUCCEEDED(hr)){ // // must be a group in a domain // *pdwParentId = WINNT_DOMAIN_ID; hr = ValidateGlobalGroupObject( szHostServerName, &(pObjectInfo->ComponentArray[1]), Credentials ); if (FAILED(hr)) { hr = ValidateLocalGroupObject( szHostServerName, &(pObjectInfo->ComponentArray[1]), Credentials ); if(SUCCEEDED(hr)){ uGroupType = WINNT_GROUP_LOCAL; } }else{ uGroupType = WINNT_GROUP_GLOBAL; } } if(FAILED(hr)){ // // potentially a group in a computer // hr = ValidateComputerParent(NULL, pObjectInfo->ComponentArray[0], Credentials); BAIL_ON_FAILURE(hr); // // group in a computer // *pdwParentId = WINNT_COMPUTER_ID; MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName); hr = ValidateGlobalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[1]), Credentials ); if (FAILED(hr)) { hr = ValidateLocalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[1]), Credentials ); BAIL_ON_FAILURE(hr); uGroupType = WINNT_GROUP_LOCAL; }else{ uGroupType = WINNT_GROUP_GLOBAL; } } break; case 3: // // if there are 3 components then we must have parentid // WINNT_COMPUTER_ID // *pdwParentId = WINNT_COMPUTER_ID; hr = ValidateComputerParent(pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], Credentials); BAIL_ON_FAILURE(hr); MakeUncName( pObjectInfo->ComponentArray[1], lpszUncName ); hr = ValidateGlobalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[2]), Credentials ); if (FAILED(hr)) { hr = ValidateLocalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[2]), Credentials ); BAIL_ON_FAILURE(hr); uGroupType = WINNT_GROUP_LOCAL; }else{ uGroupType = WINNT_GROUP_GLOBAL; } break; default: RRETURN(E_ADS_BAD_PATHNAME); } error: if (lpGI) { NetApiBufferFree((LPBYTE)lpGI); } *puGroupType = uGroupType; RRETURN(hr); } HRESULT ValidatePrinterObject( POBJECTINFO pObjectInfo, CWinNTCredentials& Credentials ) { LPTSTR szDomainName = NULL; LPTSTR szServerName = NULL; LPTSTR szPrinterName = NULL; WCHAR szPrintObjectName[MAX_PATH]; HRESULT hr = E_ADS_UNKNOWN_OBJECT; BOOL fStatus = FALSE; HANDLE hPrinter = NULL; PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_USE}; if (!(pObjectInfo->NumComponents == 3 ||pObjectInfo->NumComponents == 2)){ RRETURN(E_ADS_BAD_PATHNAME); } if(pObjectInfo->NumComponents == 3){ // // printer in domain\computer or workgroup\computer // szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szPrinterName = pObjectInfo->ComponentArray[2]; hr = ValidateComputerParent(szDomainName, szServerName, Credentials); BAIL_IF_ERROR(hr); } else if ( pObjectInfo-> NumComponents == 2 ){ szServerName = pObjectInfo->ComponentArray[0]; szPrinterName = pObjectInfo->ComponentArray[1]; } MakeUncName(szServerName, szPrintObjectName); wcscat(szPrintObjectName, TEXT("\\")); wcscat(szPrintObjectName, szPrinterName); // // validate the printer in computer now // fStatus = OpenPrinter(szPrintObjectName, &hPrinter, &PrinterDefaults); if(!fStatus){ hr = HRESULT_FROM_WIN32(GetLastError()); } else { hr = S_OK; } cleanup: if(hPrinter){ ClosePrinter(hPrinter); } RRETURN(hr); } HRESULT ValidateServiceObject( POBJECTINFO pObjectInfo, CWinNTCredentials& Credentials ) { LPTSTR szDomainName = NULL; LPTSTR szServerName = NULL; LPTSTR szServiceName = NULL; SC_HANDLE schSCMHandle=NULL; SC_HANDLE schServiceHandle=NULL; HRESULT hr = S_OK; BOOLEAN fRefAdded = FALSE; if(!(pObjectInfo->NumComponents == 3 || pObjectInfo->NumComponents == 2)) { RRETURN(E_ADS_BAD_PATHNAME); } if(pObjectInfo->NumComponents == 3){ szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szServiceName = pObjectInfo->ComponentArray[2]; // // First check to see if the computer is in the right domain // hr = ValidateComputerParent( szDomainName, szServerName, Credentials ); BAIL_ON_FAILURE(hr); } else if (pObjectInfo->NumComponents == 2){ szServerName = pObjectInfo->ComponentArray[0]; szServiceName = pObjectInfo->ComponentArray[1]; } // // check to see if the service is valid by opening the active services // database on the server // hr = Credentials.RefServer(szServerName); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } // // Open the Service Control Manager. // schSCMHandle = OpenSCManager(szServerName, NULL, GENERIC_READ); if (schSCMHandle == NULL) { hr = HRESULT_FROM_WIN32(GetLastError()); goto error; } // // Need to ref the server before opening the service // // // try to open the service // schServiceHandle = OpenService(schSCMHandle, szServiceName, GENERIC_READ); if(schServiceHandle == NULL) { CloseServiceHandle(schSCMHandle); schSCMHandle = NULL; hr = HRESULT_FROM_WIN32(GetLastError()); goto error; } CloseServiceHandle(schServiceHandle); CloseServiceHandle(schSCMHandle); error: if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } RRETURN(hr); } HRESULT GetPrinterFromPath(LPTSTR *pszPrinter, LPWSTR szPathName) { // // If passed an empty string, it returns an empty string // LPTSTR szRetval; *pszPrinter = NULL; szRetval = szPathName; ADsAssert(szPathName); while(!(*szRetval==L'\0' || *szRetval==L'\\')){ szRetval++; } if(*szRetval != L'\\'){ RRETURN(E_FAIL); } szRetval++; *pszPrinter = szRetval; RRETURN(S_OK); } HRESULT ValidateComputerObject( POBJECTINFO pObjectInfo, CWinNTCredentials& Credentials) { HRESULT hr; WCHAR szSAMName[MAX_PATH]; szSAMName[0] = L'\0'; if(!(pObjectInfo->NumComponents == 2 || pObjectInfo->NumComponents == 1)){ RRETURN(E_ADS_UNKNOWN_OBJECT); } if(pObjectInfo->NumComponents == 2){ hr = ValidateComputerParent( pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], szSAMName, Credentials ); BAIL_ON_FAILURE(hr); if (szSAMName[0] != L'\0') { FreeADsStr(pObjectInfo->ComponentArray[1]); pObjectInfo->ComponentArray[1] = AllocADsStr(szSAMName); if (!pObjectInfo->ComponentArray[1]) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); } } } else { hr = ValidateComputerParent( NULL, pObjectInfo->ComponentArray[0], szSAMName, Credentials ); BAIL_ON_FAILURE(hr); if (szSAMName[0] != L'\0') { FreeADsStr(pObjectInfo->ComponentArray[0]); pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName); if (!pObjectInfo->ComponentArray[0]) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); } } } error: RRETURN(hr); } HRESULT ValidateFileServiceObject( POBJECTINFO pObjectInfo, CWinNTCredentials& Credentials ) { HRESULT hr = S_OK; // // check to see if it is a valid service // if(!(pObjectInfo->NumComponents == 3 || pObjectInfo->NumComponents == 2)) { RRETURN(E_ADS_BAD_PATHNAME); } hr = ValidateServiceObject(pObjectInfo, Credentials); if(FAILED(hr)) RRETURN(hr); // // check to see if it is the LanmanServer or FPNW service // if (pObjectInfo->NumComponents ==3){ if(!(_wcsicmp(pObjectInfo->ComponentArray[2], TEXT("LanmanServer"))== 0 || _wcsicmp(pObjectInfo->ComponentArray[2],TEXT("FPNW"))==0)){ RRETURN(E_ADS_BAD_PATHNAME); } }else if(pObjectInfo->NumComponents == 2) { if(!(_wcsicmp(pObjectInfo->ComponentArray[1], TEXT("LanmanServer"))== 0 || _wcsicmp(pObjectInfo->ComponentArray[1],TEXT("FPNW"))==0)){ RRETURN(E_ADS_BAD_PATHNAME); } } RRETURN(hr); } HRESULT ValidateFileShareObject( POBJECTINFO pObjectInfo, CWinNTCredentials& Credentials ) { NET_API_STATUS nasStatus; LPSHARE_INFO_1 lpShareInfo1 = NULL; PNWVOLUMEINFO pVolumeInfo = NULL; LPTSTR pszDomainName = NULL; LPTSTR pszServerName = NULL; LPTSTR pszShareName = NULL; LPTSTR pszServerType = NULL; HRESULT hr = S_OK; DWORD dwSharePos = 3; BOOL fRefAdded = FALSE; // // check to see if it is a valid file share // if (pObjectInfo->NumComponents == 4 ){ pszDomainName = pObjectInfo->ComponentArray[0]; pszServerName = pObjectInfo->ComponentArray[1]; pszServerType = pObjectInfo->ComponentArray[2]; pszShareName = pObjectInfo->ComponentArray[3]; dwSharePos = 3; hr = ValidateComputerParent(pszDomainName, pszServerName, Credentials); BAIL_ON_FAILURE(hr); } else if (pObjectInfo->NumComponents == 3 ){ pszServerName = pObjectInfo->ComponentArray[0]; pszServerType = pObjectInfo->ComponentArray[1]; pszShareName = pObjectInfo->ComponentArray[2]; dwSharePos = 2; } else { hr = E_ADS_UNKNOWN_OBJECT; goto error; } if(_tcsicmp(pszServerType,TEXT("LanmanServer")) == 0){ // Need to ref this server before we do the NetShareGetInfo // so that we can authenticate against the server. hr = Credentials.RefServer(pszServerName); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } nasStatus = NetShareGetInfo(pszServerName, pszShareName, 1, (LPBYTE*)&lpShareInfo1); // DeRef if ref added, no recovery possible on failed deref if (fRefAdded) { hr = Credentials.DeRefServer(); fRefAdded = FALSE; } if(nasStatus != NERR_Success){ hr = HRESULT_FROM_WIN32(nasStatus); goto error; } else { // Need to use the name returned by the call as opposed // to the name given in the ADsPath if (pObjectInfo->ComponentArray[dwSharePos] && lpShareInfo1->shi1_netname) { FreeADsStr(pObjectInfo->ComponentArray[dwSharePos]); pObjectInfo->ComponentArray[dwSharePos] = AllocADsStr(lpShareInfo1->shi1_netname); } if (!pObjectInfo->ComponentArray[dwSharePos]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); hr = S_OK; goto error; } } else if(_tcsicmp(pszServerType,TEXT("FPNW")) == 0){ hr = Credentials.RefServer(pszServerName); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } nasStatus = ADsNwVolumeGetInfo(pszServerName, pszShareName, 1, &pVolumeInfo); // need to deref, nothing we can do if deref fails if (fRefAdded) { hr = Credentials.DeRefServer(); fRefAdded = FALSE; } if(nasStatus != NERR_Success){ hr = HRESULT_FROM_WIN32(nasStatus); goto error; } else{ // Need to use the name returned by the call as opposed // to the name given in the ADsPath if (pObjectInfo->ComponentArray[dwSharePos] && pVolumeInfo->lpPath) { FreeADsStr(pObjectInfo->ComponentArray[dwSharePos]); pObjectInfo->ComponentArray[dwSharePos] = AllocADsStr(pVolumeInfo->lpPath); } if (!pObjectInfo->ComponentArray[dwSharePos]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); hr = S_OK; goto error; } } else { hr = E_ADS_UNKNOWN_OBJECT ; } error: if(pVolumeInfo){ ADsNwApiBufferFree(pVolumeInfo); } if(lpShareInfo1){ NetApiBufferFree(lpShareInfo1); } RRETURN(hr); } HRESULT ValidateNamespaceObject( POBJECTINFO pObjectInfo ) { if (!_wcsicmp(pObjectInfo->ProviderName, szProviderName)) { RRETURN(S_OK); } RRETURN(E_FAIL); } HRESULT ValidateLocalGroupObject( LPWSTR szServerName, LPWSTR *pszGroupName, CWinNTCredentials& Credentials ) { NET_API_STATUS nasStatus; LPLOCALGROUP_INFO_1 lpGI = NULL; HRESULT hr = S_OK; BOOL fRefAdded = FALSE; // At this point the host server name has a \\ prepended // so we need to get rid of it. hr = Credentials.RefServer(szServerName+2); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } nasStatus = NetLocalGroupGetInfo( szServerName, *pszGroupName, 1, (LPBYTE*)(&lpGI) ); // // if a ref has been added we need to delete if before // checking the error status. // if (fRefAdded) { hr = Credentials.DeRefServer(); // even if we fail, we have no recovery path fRefAdded = FALSE; } hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr); // Need to use the name returned by the call as opposed // to the name given in the ADsPath if ((*pszGroupName) && lpGI->lgrpi1_name) { FreeADsStr(*pszGroupName); *pszGroupName = AllocADsStr(lpGI->lgrpi1_name); } if (!(*pszGroupName)) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); error: if (lpGI) { NetApiBufferFree(lpGI); } RRETURN(hr); } HRESULT ValidateGlobalGroupObject( LPWSTR szServerName, LPWSTR *pszGroupName, CWinNTCredentials& Credentials ) { NET_API_STATUS nasStatus; LPGROUP_INFO_1 lpGI = NULL; HRESULT hr = S_OK; BOOL fRefAdded = FALSE; // At this point the host server name has a \\ prepended // so we need to get rid of it. hr = Credentials.RefServer(szServerName+2); if (SUCCEEDED(hr)) { fRefAdded = TRUE; } nasStatus = NetGroupGetInfo( szServerName, *pszGroupName, 1, (LPBYTE*)(&lpGI) ); // // if a ref has been added we need to delete if before // checking the error status. // if (fRefAdded) { hr = Credentials.DeRefServer(); // even if we fail, we have no recovery path fRefAdded = FALSE; } hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr); // Need to use the name returned by the call as opposed // to the name given in the ADsPath if ((*pszGroupName) && lpGI->grpi1_name) { FreeADsStr(*pszGroupName); *pszGroupName = AllocADsStr(lpGI->grpi1_name); } if (!(*pszGroupName)) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); error: if (lpGI) { NetApiBufferFree(lpGI); } RRETURN(hr); } HRESULT GetComputerParent( LPTSTR pszComputerName, LPTSTR *ppszComputerParentName, CWinNTCredentials& Credentials ) { // // This function returns the computer parent irrespective of whether // the computer belongs to a domain or to a workgroup // HRESULT hr = S_OK; LPTSTR pszComputerParentName = NULL; WCHAR szDomainName[MAX_PATH]; WCHAR szSAMName[MAX_PATH]; szSAMName[0] = L'\0'; hr = WinNTGetCachedComputerName(pszComputerName, szDomainName, szSAMName, Credentials ); BAIL_ON_FAILURE(hr); pszComputerParentName = AllocADsStr(szDomainName); if(!pszComputerParentName){ hr = E_OUTOFMEMORY; } *ppszComputerParentName = pszComputerParentName; error: RRETURN(hr); } HRESULT ConstructFullObjectInfo( POBJECTINFO pObjectInfo, POBJECTINFO *ppFullObjectInfo, CWinNTCredentials& Credentials ) { // // used in the case where the domain name is not specified. // Here the assumption is that an objectinfo structure with // domain name not filled in is passed down. We create a new // object info structure with the domain/workgroup name filled // in HRESULT hr = S_OK; POBJECTINFO pTempObjectInfo = NULL; DWORD i; LPWSTR pszComputerParent = NULL; pTempObjectInfo = (POBJECTINFO)AllocADsMem(sizeof(OBJECTINFO)); if (!pTempObjectInfo) { RRETURN(hr = E_OUTOFMEMORY); } memset(pTempObjectInfo, 0, sizeof(OBJECTINFO)); if(!pObjectInfo){ RRETURN(E_OUTOFMEMORY); } pTempObjectInfo->ProviderName = AllocADsStr(pObjectInfo->ProviderName); if(!pTempObjectInfo->ProviderName){ hr = E_OUTOFMEMORY; goto error; } pTempObjectInfo->ObjectType = pObjectInfo->ObjectType; pTempObjectInfo->NumComponents = pObjectInfo->NumComponents +1; for(i=0; iComponentArray[i]) { pTempObjectInfo->ComponentArray[i+1] = AllocADsStr(pObjectInfo->ComponentArray[i]); if(!pTempObjectInfo->ComponentArray[i+1]){ hr = E_OUTOFMEMORY; goto error; } } if(pObjectInfo->DisplayComponentArray[i]) { pTempObjectInfo->DisplayComponentArray[i+1] = AllocADsStr(pObjectInfo->DisplayComponentArray[i]); if(!pTempObjectInfo->DisplayComponentArray[i+1]){ hr = E_OUTOFMEMORY; goto error; } } } hr = GetComputerParent(pObjectInfo->ComponentArray[0], &(pTempObjectInfo->ComponentArray[0]), Credentials ); BAIL_ON_FAILURE(hr); hr = GetDisplayName(pTempObjectInfo->ComponentArray[0], &(pTempObjectInfo->DisplayComponentArray[0]) ); *ppFullObjectInfo = pTempObjectInfo ; RRETURN(S_OK); error: FreeObjectInfo( pTempObjectInfo ); *ppFullObjectInfo = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetGroupObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 11-3-95 krishnag Created. // //---------------------------------------------------------------------------- HRESULT GetLocalGroupObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szGroupName = NULL; DWORD dwParentId = 0; ULONG uGroupType = 0; POBJECTINFO pGroupObjectInfo = NULL; hr = ValidateGroupObject( pObjectInfo, &uGroupType, &dwParentId, Credentials ); BAIL_ON_FAILURE(hr); if (uGroupType != WINNT_GROUP_LOCAL) { hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); } switch (pObjectInfo->NumComponents) { case 2: // // could be group in computer or group in domain // if(dwParentId == WINNT_DOMAIN_ID){ szDomainName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1]; szServerName = NULL; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); } else { // // group in a computer // hr = ConstructFullObjectInfo(pObjectInfo, &pGroupObjectInfo, Credentials ); if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) { // // Case when there are no workstation services. // hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = NULL; szServerName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1]; } else { BAIL_ON_FAILURE(hr); hr = BuildParent(pGroupObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = pGroupObjectInfo->ComponentArray[0]; szServerName = pGroupObjectInfo->ComponentArray[1]; szGroupName = pGroupObjectInfo->ComponentArray[2]; } } break; case 3: hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szGroupName = pObjectInfo->ComponentArray[2]; break; } hr = CWinNTGroup::CreateGroup(ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); } RRETURN(hr); error: if (pUnknown) { pUnknown->Release(); } if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); } *ppObject = NULL; RRETURN(hr); } //+--------------------------------------------------------------------------- // Function: GetGroupObject // // Synopsis: // // Arguments: // // Returns: // // Modifies: // // History: 11-3-95 krishnag Created. // //---------------------------------------------------------------------------- HRESULT GetGlobalGroupObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szGroupName = NULL; DWORD dwParentId = 0; ULONG uGroupType = 0; POBJECTINFO pGroupObjectInfo = NULL; hr = ValidateGroupObject( pObjectInfo, &uGroupType, &dwParentId, Credentials ); BAIL_ON_FAILURE(hr); if (uGroupType != WINNT_GROUP_GLOBAL) { hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); } switch (pObjectInfo->NumComponents) { case 2: // // could be group in computer or group in domain // if(dwParentId == WINNT_DOMAIN_ID){ szDomainName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1]; szServerName = NULL; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); } else { // // group in a computer // hr = ConstructFullObjectInfo(pObjectInfo, &pGroupObjectInfo, Credentials ); BAIL_ON_FAILURE(hr); hr = BuildParent(pGroupObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = pGroupObjectInfo->ComponentArray[0]; szServerName = pGroupObjectInfo->ComponentArray[1]; szGroupName = pGroupObjectInfo->ComponentArray[2]; } break; case 3: hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szGroupName = pObjectInfo->ComponentArray[2]; break; } hr = CWinNTGroup::CreateGroup(ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr); *ppObject = pUnknown; if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); } RRETURN(hr); error: if (pUnknown) { pUnknown->Release(); } if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); } *ppObject = NULL; RRETURN(hr); }