⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smpd_adreg.cpp

📁 fortran并行计算包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* * (C) 2001 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */#include <winsock2.h>#include <windows.h>#include <iads.h>#include "smpd_service.h"#include <ntdsapi.h>#include <dsgetdc.h>#include <lm.h>#define SECURITY_WIN32#include <security.h>#include <adshlp.h>#include <atlbase.h>#include <adserr.h>static HRESULT AllowAccessToScpProperties(LPWSTR wszAccountSAM, IADs *pSCPObject);typedef struct tagADSERRMSG{    HRESULT hr;    LPCTSTR pszError;} ADSERRMSG;#define ADDADSERROR(x) x, _T(#x)static ADSERRMSG adsErr[] ={    ADDADSERROR(E_ADS_BAD_PATHNAME),	ADDADSERROR(E_ADS_INVALID_DOMAIN_OBJECT),	ADDADSERROR(E_ADS_INVALID_USER_OBJECT),	ADDADSERROR(E_ADS_INVALID_COMPUTER_OBJECT),	ADDADSERROR(E_ADS_UNKNOWN_OBJECT),	ADDADSERROR(E_ADS_PROPERTY_NOT_SET),	ADDADSERROR(E_ADS_PROPERTY_NOT_SUPPORTED),	ADDADSERROR(E_ADS_PROPERTY_INVALID),	ADDADSERROR(E_ADS_BAD_PARAMETER),	ADDADSERROR(E_ADS_OBJECT_UNBOUND),	ADDADSERROR(E_ADS_PROPERTY_NOT_MODIFIED),	ADDADSERROR(E_ADS_PROPERTY_MODIFIED),	ADDADSERROR(E_ADS_CANT_CONVERT_DATATYPE),	ADDADSERROR(E_ADS_PROPERTY_NOT_FOUND),	ADDADSERROR(E_ADS_OBJECT_EXISTS),	ADDADSERROR(E_ADS_SCHEMA_VIOLATION),	ADDADSERROR(E_ADS_COLUMN_NOT_SET),	ADDADSERROR(E_ADS_INVALID_FILTER),	ADDADSERROR(0),};static LPCTSTR GetADSIError( HRESULT hr ){    if ( hr & 0x00005000 )    {	int idx=0;	while (adsErr[idx].hr != 0 )	{	    if ( adsErr[idx].hr == hr )	    {		return adsErr[idx].pszError;	    }	    idx++;	}    }    return _T("");}static LPCTSTR GetErrorMessage( HRESULT hr ){    BOOL bRet;    static TCHAR s[1024];    LPTSTR lpBuffer=NULL;    if ( SUCCEEDED(hr) )    {	return _T("Success");    }    if ( hr & 0x00005000) /* standard ADSI Errors */    {	_tcscpy(s, GetADSIError(hr));    }    else if ( HRESULT_FACILITY(hr)==FACILITY_WIN32 )    {	bRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |	    FORMAT_MESSAGE_FROM_SYSTEM,	    NULL, hr,	    MAKELANGID(LANG_NEUTRAL,	    SUBLANG_SYS_DEFAULT),	    (LPTSTR) &lpBuffer, 0, NULL);	if ( !bRet )	{	    _sntprintf(s, 1024, _T("Error %ld"), hr);	}	if ( lpBuffer )	{	    _tcscpy(s, lpBuffer);	    LocalFree( lpBuffer );	}    }    else /* Non Win32 Error */    {	_sntprintf(s, 1024, _T("%X"), hr );	return s;    }    WCHAR szBuffer[MAX_PATH];    WCHAR szName[MAX_PATH];    DWORD dwError;    hr = ADsGetLastError( &dwError, szBuffer, (sizeof(szBuffer)/sizeof(WCHAR))-1,	szName, (sizeof(szName)/sizeof(WCHAR))-1 );    if ( SUCCEEDED(hr) && dwError != ERROR_INVALID_DATA && wcslen(szBuffer))    {	USES_CONVERSION;	_tcscat(s, _T(" -- Extended Error --- \n"));	_tcscat(s, OLE2T(szName));	_tcscat(s, _T(":\n"));	_tcscat(s, OLE2T( szBuffer ));    }    return s;}static void ReportError(TCHAR *msg, HRESULT hr){    _tprintf(TEXT("HRESULT=%d\nError message: %s\nError Text: %s\n"), hr, msg, GetErrorMessage(hr));}static void ReportServiceError(char *msg, DWORD error){    printf("error=%d\nError message: %s\nError Text: %s\n", error, msg, GetErrorMessage(error));}/* ScpCreateCreate a new service connection point as a child object of thelocal server computer object.*/static DWORD ScpCreate(		       USHORT usPort,    /* Service's default port to store in SCP. */		       LPTSTR szClass,   /* Service class string to store in SCP. */		       LPTSTR szAccount, /* Logon account that must access SCP. */		       UINT ccDN,        /* Length of the pszDN buffer in characters */		       TCHAR *pszDN)     /* Returns distinguished name of SCP. */{    DWORD dwStat, dwAttr, dwLen;    HRESULT hr;    IDispatch *pDisp; /* Returned dispinterface of new object. */    IDirectoryObject *pComp; /* Computer object; parent of SCP. */    IADs *pIADsSCP; /* IADs interface on new object. */    TCHAR szServer[MAX_PATH];    TCHAR szDn[MAX_PATH];    TCHAR szAdsPath[MAX_PATH];    TCHAR szPort[6];    HKEY hReg;    DWORD dwDisp;    TCHAR szRelativeDistinguishedName[MAX_PATH];    ADSVALUE cn, objclass, keywords[4], binding, classname, dnsname, nametype;    BSTR bstrGuid = NULL;    TCHAR pwszBindByGuidStr[1024];    VARIANT var;    /* Values for SCPs keywords attribute. */    TCHAR* KwVal[] =    {	TEXT(SMPD_SERVICE_VENDOR_GUID), /* Vendor GUID. */	    TEXT(SMPD_SERVICE_GUID),    /* Product GUID. */	    TEXT(SMPD_PRODUCT_VENDOR),  /* Vendor Name. */	    TEXT(SMPD_PRODUCT),         /* Product Name. */    };    /* SCP attributes to set during creation of SCP. */    ADS_ATTR_INFO ScpAttribs[] =    {	{TEXT("cn"), ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &cn, 1},	{TEXT("objectClass"), ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &objclass, 1},	{TEXT("keywords"), ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, keywords, 4},	{TEXT("serviceDnsName"), ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &dnsname, 1},	{TEXT("serviceDnsNameType"), ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &nametype, 1},	{TEXT("serviceClassName"), ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &classname, 1},	{TEXT("serviceBindingInformation"), ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &binding, 1},    };    if (!szClass /*|| !szAccount*/ || !pszDN || !(ccDN > 0))    {	hr = ERROR_INVALID_PARAMETER;	ReportError(TEXT("Invalid parameter."), hr);	return hr;    }    /* Get the DNS name of the local computer. */    dwLen = sizeof(szServer);    if (!GetComputerNameEx(ComputerNameDnsFullyQualified, szServer, &dwLen))    {	_tprintf(TEXT("GetComputerNameEx failed: Error %d\n"), GetLastError());	return GetLastError();    }    /*_tprintf(TEXT("GetComputerNameEx: %s\n"), szServer);*/    /* Enter the attribute values to be stored in the SCP. */    keywords[0].dwType = ADSTYPE_CASE_IGNORE_STRING;    keywords[1].dwType = ADSTYPE_CASE_IGNORE_STRING;    keywords[2].dwType = ADSTYPE_CASE_IGNORE_STRING;    keywords[3].dwType = ADSTYPE_CASE_IGNORE_STRING;    keywords[0].CaseIgnoreString = KwVal[0];    keywords[1].CaseIgnoreString = KwVal[1];    keywords[2].CaseIgnoreString = KwVal[2];    keywords[3].CaseIgnoreString = KwVal[3];    cn.dwType = ADSTYPE_CASE_IGNORE_STRING;    cn.CaseIgnoreString = TEXT(SMPD_SERVICE_NAME);    objclass.dwType = ADSTYPE_CASE_IGNORE_STRING;    objclass.CaseIgnoreString = TEXT("serviceConnectionPoint");    dnsname.dwType = ADSTYPE_CASE_IGNORE_STRING;    dnsname.CaseIgnoreString = szServer;    classname.dwType = ADSTYPE_CASE_IGNORE_STRING;    classname.CaseIgnoreString = szClass;    _sntprintf(szPort, 6, TEXT("%d"), usPort);    binding.dwType = ADSTYPE_CASE_IGNORE_STRING;    binding.CaseIgnoreString = szPort;    nametype.dwType = ADSTYPE_CASE_IGNORE_STRING;    nametype.CaseIgnoreString = TEXT("A");    /* Get the distinguished name of the computer object for the local computer. */    dwLen = sizeof(szDn);    if (!GetComputerObjectName(NameFullyQualifiedDN, szDn, &dwLen))    {	_tprintf(TEXT("GetComputerObjectName failed: Error %d\n"), GetLastError());	return GetLastError();    }    /*_tprintf(TEXT("GetComputerObjectName: %s\n"), szDn);*/    /* Compose the ADSpath and bind to the computer object for the local computer. */    _tcsncpy(szAdsPath,TEXT("LDAP://"),MAX_PATH);    _tcsncat(szAdsPath, szDn, MAX_PATH - _tcslen(szAdsPath));    hr = ADsGetObject(szAdsPath, IID_IDirectoryObject, (void **)&pComp);    if (FAILED(hr))    {	_tprintf(TEXT("ADsGetObject('%s') failed\n"), szAdsPath);	ReportError(TEXT("Failed to bind Computer Object."),hr);	return hr;    }    _tprintf(TEXT("Bound to Active directory object:\n%s\n"), szDn);    /********************************************************************    * Publish the SCP as a child of the computer object    *********************************************************************/    /* Calculate attribute count. */    dwAttr = sizeof(ScpAttribs)/sizeof(ADS_ATTR_INFO);    /* Complete the action. */    _sntprintf(szRelativeDistinguishedName, MAX_PATH, TEXT("cn=%s"), TEXT(SMPD_SERVICE_NAME));    /* Delete the previous object if it exists */    hr = pComp->DeleteDSObject(szRelativeDistinguishedName);    /* Create a new object */    hr = pComp->CreateDSObject(szRelativeDistinguishedName, ScpAttribs, dwAttr, &pDisp);    if (FAILED(hr))    {	ReportError(TEXT("Failed to create SCP:"), hr);	pComp->Release();	return hr;    }    pComp->Release();    /* Query for an IADs pointer on the SCP object. */    hr = pDisp->QueryInterface(IID_IADs,(void **)&pIADsSCP);    if (FAILED(hr))    {	ReportError(TEXT("Failed to QueryInterface for IADs:"), hr);	pDisp->Release();	return hr;    }    pDisp->Release();    /* Set ACEs on the SCP so a service can modify it. */    hr = AllowAccessToScpProperties(	szAccount, /* Service account to allow access. */	pIADsSCP); /* IADs pointer to the SCP object. */    if (FAILED(hr))    {	ReportError(TEXT("Failed to set ACEs on SCP DACL:"), hr);	return hr;    }    /* Get the distinguished name of the SCP. */    VariantInit(&var);    hr = pIADsSCP->Get(CComBSTR("distinguishedName"), &var);    if (FAILED(hr))    {	ReportError(TEXT("Failed to get distinguishedName:"), hr);	pIADsSCP->Release();	return hr;    }    /*_tprintf(TEXT("distinguishedName via IADs: %s\n"), var.bstrVal);*/    _tcsncpy(pszDN, var.bstrVal, ccDN);    /* Retrieve the SCP objectGUID in format suitable for binding. */    hr = pIADsSCP->get_GUID(&bstrGuid);    if (FAILED(hr))    {	ReportError(TEXT("Failed to get GUID:"), hr);	pIADsSCP->Release();	return hr;    }    /* Build a string for binding to the object by GUID. */    _tcsncpy(pwszBindByGuidStr, TEXT("LDAP://<GUID="), 1024);    _tcsncat(pwszBindByGuidStr, bstrGuid, 1024 -_tcslen(pwszBindByGuidStr));    _tcsncat(pwszBindByGuidStr, TEXT(">"), 1024 -_tcslen(pwszBindByGuidStr));    /*_tprintf(TEXT("GUID binding string: %s\n"), pwszBindByGuidStr);*/    pIADsSCP->Release();    /* Create a registry key to save the GUID binding string */    dwStat = RegCreateKeyEx(HKEY_LOCAL_MACHINE,	TEXT(SMPD_SERVICE_REGISTRY_KEY),	0,	NULL,	REG_OPTION_NON_VOLATILE,	KEY_ALL_ACCESS,	NULL,	&hReg,	&dwDisp);    if (dwStat != NO_ERROR)    {	ReportError(TEXT("RegCreateKeyEx failed:"), dwStat);	return dwStat;    }    /* Cache the GUID binding string under the registry key. */    dwStat = RegSetValueEx(hReg, TEXT("GUIDBindingString"), 0, REG_SZ,	(const BYTE *)pwszBindByGuidStr,	(DWORD)(2*(_tcslen(pwszBindByGuidStr))));    if (dwStat != NO_ERROR)    {	ReportError(TEXT("RegSetValueEx failed:"), dwStat);	return dwStat;    }    RegCloseKey(hReg);    /* Cleanup should delete the SCP and registry key if an error occurs. */    return dwStat;}static DWORD SpnCompose(			TCHAR ***pspn,          /* Output: an array of SPNs */			unsigned long *pulSpn,  /* Output: the number of SPNs returned */			TCHAR *pszDNofSCP,      /* Input: DN of the service's SCP */			TCHAR* pszServiceClass) /* Input: the name of the service class */{    DWORD dwStatus;    dwStatus = DsGetSpn(	DS_SPN_SERVICE,  /* Type of SPN to create (enumerated type) */	pszServiceClass, /* Service class - a name in this case */	pszDNofSCP,      /* Service name - DN of the service SCP */	0,               /* Default: omit port component of SPN */	0,               /* Number of entries in hostnames and ports arrays */	NULL,            /* Array of hostnames. Default is local computer */	NULL,            /* Array of ports. Default omits port component */	pulSpn,          /* Receives number of SPNs returned in array */	pspn             /* Receives array of SPN(s) */	);    return dwStatus;}/***************************************************************************SpnRegister()Register or unregister the SPNs under the service's account.If the service runs in LocalSystem account, pszServiceAcctDN is thedistinguished name of the local computer account.Parameters:pszServiceAcctDN - Contains the distinguished name of the logonaccount for this instance of the service.pspn - Contains an array of SPNs to register.ulSpn - Contains the number of SPNs in the array.Operation - Contains one of the DS_SPN_WRITE_OP values that determinesthe type of operation to perform on the SPNs.***************************************************************************/static DWORD SpnRegister(TCHAR *pszServiceAcctDN,			 TCHAR **pspn,			 unsigned long ulSpn,			 DS_SPN_WRITE_OP Operation){    DWORD dwStatus;    HANDLE hDs;    TCHAR szSamName[512];    DWORD dwSize = sizeof(szSamName);    PDOMAIN_CONTROLLER_INFO pDcInfo;    /* Bind to a domain controller. */    /* Get the domain for the current user. */    if (GetUserNameEx(NameSamCompatible, szSamName, &dwSize))    {	TCHAR *pWhack = _tcschr(szSamName, '\\');	if (pWhack)	{	    *pWhack = '\0';	}    }    else    {	return GetLastError();    }    /*_tprintf(TEXT("szSamName: %s\n"), szSamName);*/    /* Get the name of a domain controller in that domain. */    dwStatus = DsGetDcName(NULL,	szSamName,	NULL,	NULL,	DS_IS_FLAT_NAME |	DS_RETURN_DNS_NAME |	DS_DIRECTORY_SERVICE_REQUIRED,	&pDcInfo);    if (dwStatus != 0)    {	return dwStatus;    }    /* Bind to the domain controller. */    dwStatus = DsBind(pDcInfo->DomainControllerName, NULL, &hDs);    /* Free the DOMAIN_CONTROLLER_INFO buffer. */    NetApiBufferFree(pDcInfo);    if (dwStatus != ERROR_SUCCESS)    {	return dwStatus;    }    for (unsigned long i=0; i<ulSpn; i++)    {	_tprintf(TEXT("Service Principal Name =\n%s\n"), pspn[i]);    }    fflush(stdout);    /* Write the SPNs to the service account or computer account. */    dwStatus = DsWriteAccountSpn(	hDs,                   /* Handle to the directory. */	Operation,             /* Add or remove SPN from account's existing SPNs. */	pszServiceAcctDN,      /* DN of service account or computer account. */	ulSpn,                 /* Number of SPNs to add. */	(const TCHAR **)pspn); /* Array of SPNs. */    /* Unbind the DS in any case. */    DsUnBind(&hDs);    return dwStatus;}SMPD_BOOL smpd_setup_scp(){    DWORD dwStatus;    TCHAR szDNofSCP[100] = TEXT("");    TCHAR **pspn;    unsigned long ulSpn;    LPWSTR pwszComputerName;    DWORD dwLen;    SMPD_BOOL result = SMPD_TRUE;    CoInitialize(NULL);    /* Create the service's Service Connection Point (SCP). */    dwStatus = ScpCreate(	SMPD_LISTENER_PORT,	TEXT(SMPD_SERVICE_NAME),	NULL, /* Null defaults to the Local SYSTEM account */	100,	szDNofSCP /* Buffer returns the Distinguished Name of the SCP */	);    if (dwStatus != 0)    {	_tprintf(TEXT("ScpCreate failed: %d\n"), dwStatus);	result = SMPD_FALSE;	goto fn_exit;    }    /*_tprintf(TEXT("szDNofSCP: %s\n"), szDNofSCP);*/    /* Get the size required for the DN account name. */    dwLen = 0;    GetComputerObjectNameW(NameFullyQualifiedDN, NULL, &dwLen);    pwszComputerName = new WCHAR[dwLen + 1];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -