DWORD ScmSetServicePassword( IN PCWSTR pszServiceName, IN PCWSTR pszPassword) { OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle = NULL; UNICODE_STRING ServiceName = {0, 0, NULL}; UNICODE_STRING Password; NTSTATUS Status; DWORD dwError = ERROR_SUCCESS; RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES)); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_CREATE_SECRET, &PolicyHandle); if (!NT_SUCCESS(Status)) return RtlNtStatusToDosError(Status); ServiceName.Length = (wcslen(pszServiceName) + 4) * sizeof(WCHAR); ServiceName.MaximumLength = ServiceName.Length + sizeof(WCHAR); ServiceName.Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ServiceName.MaximumLength); if (ServiceName.Buffer == NULL) return ERROR_NOT_ENOUGH_MEMORY; wcscpy(ServiceName.Buffer, L"_SC_"); wcscat(ServiceName.Buffer, pszServiceName); RtlInitUnicodeString(&Password, pszPassword); Status = LsaStorePrivateData(PolicyHandle, &ServiceName, pszPassword ? &Password : NULL); if (!NT_SUCCESS(Status)) { dwError = RtlNtStatusToDosError(Status); goto done; } done: if (ServiceName.Buffer != NULL) HeapFree(GetProcessHeap(), 0, ServiceName.Buffer); if (PolicyHandle != NULL) LsaClose(PolicyHandle); return dwError; }
mDNSBool LsaSetSecret( const char * inDomain, const char * inKey, const char * inSecret ) { size_t inDomainLength; size_t inKeyLength; char domain[ 1024 ]; char key[ 1024 ]; LSA_OBJECT_ATTRIBUTES attrs; LSA_HANDLE handle = NULL; NTSTATUS res; LSA_UNICODE_STRING lucZoneName; LSA_UNICODE_STRING lucKeyName; LSA_UNICODE_STRING lucSecretName; BOOL ok = TRUE; OSStatus err; require_action( inDomain != NULL, exit, ok = FALSE ); require_action( inKey != NULL, exit, ok = FALSE ); require_action( inSecret != NULL, exit, ok = FALSE ); // If there isn't a trailing dot, add one because the mDNSResponder // presents names with the trailing dot. ZeroMemory( domain, sizeof( domain ) ); inDomainLength = strlen( inDomain ); require_action( inDomainLength > 0, exit, ok = FALSE ); err = strcpy_s( domain, sizeof( domain ) - 2, inDomain ); require_action( !err, exit, ok = FALSE ); if ( domain[ inDomainLength - 1 ] != '.' ) { domain[ inDomainLength++ ] = '.'; domain[ inDomainLength ] = '\0'; } // <rdar://problem/4192119> // // Prepend "$" to the key name, so that there will // be no conflict between the zone name and the key // name ZeroMemory( key, sizeof( key ) ); inKeyLength = strlen( inKey ); require_action( inKeyLength > 0 , exit, ok = FALSE ); key[ 0 ] = '$'; err = strcpy_s( key + 1, sizeof( key ) - 3, inKey ); require_action( !err, exit, ok = FALSE ); inKeyLength++; if ( key[ inKeyLength - 1 ] != '.' ) { key[ inKeyLength++ ] = '.'; key[ inKeyLength ] = '\0'; } // attrs are reserved, so initialize to zeroes. ZeroMemory( &attrs, sizeof( attrs ) ); // Get a handle to the Policy object on the local system res = LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr( err, exit ); // Intializing PLSA_UNICODE_STRING structures err = MakeLsaStringFromUTF8String( &lucZoneName, domain ); require_noerr( err, exit ); err = MakeLsaStringFromUTF8String( &lucKeyName, key ); require_noerr( err, exit ); err = MakeLsaStringFromUTF8String( &lucSecretName, inSecret ); require_noerr( err, exit ); // Store the private data. res = LsaStorePrivateData( handle, &lucZoneName, &lucKeyName ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr( err, exit ); res = LsaStorePrivateData( handle, &lucKeyName, &lucSecretName ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr( err, exit ); exit: if ( handle ) { LsaClose( handle ); handle = NULL; } return ok; }
void UpdateClsidKeys( CLSID_INFO * ClsidInfo ) { HKEY hProgId; HKEY hClsid; HKEY hProgIdClsid; HKEY hKey; DWORD RegStatus; DWORD Disposition; DWORD RegType; char ProgIdClsid[64]; char Response[64]; DWORD BufSize; int n; RegStatus = RegOpenKeyEx( HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ | KEY_WRITE, &hRegClsid ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Could not open HKEY_CLASSES_ROOT\\CLSID for writing\n" ); return; } hProgId = 0; hClsid = 0; if ( ClsidInfo->ProgId ) { RegStatus = RegCreateKeyEx( HKEY_CLASSES_ROOT, ClsidInfo->ProgId, 0, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hProgId, &Disposition ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Could not open or create ProgID key %s.\n", ClsidInfo->ProgId); return; } if ( Disposition == REG_CREATED_NEW_KEY ) printf( "ProgId key %s created.\n", ClsidInfo->ProgId ); if ( ClsidInfo->ProgIdDescription ) { RegStatus = RegSetValueEx( hProgId, NULL, 0, REG_SZ, (LPBYTE) ClsidInfo->ProgIdDescription, strlen(ClsidInfo->ProgIdDescription) + sizeof(char) ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Could not set description value for ProgID %s.\n", ClsidInfo->ProgId ); return; } printf( "Setting description value %s for ProgID %s.\n", ClsidInfo->ProgIdDescription, ClsidInfo->ProgId ); } RegStatus = RegCreateKeyEx( hProgId, "CLSID", 0, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hProgIdClsid, &Disposition ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Could not open or create CLSID key for ProgID %s.\n", ClsidInfo->ProgId ); return; } // // Check if a CLSID key value already exists for this ProgID. If so, // and a CLSID was specified to us then check if they differ. // BufSize = sizeof(ProgIdClsid); RegStatus = RegQueryValueEx( hProgIdClsid, NULL, 0, &RegType, (LPBYTE) ProgIdClsid, &BufSize ); if ( RegStatus == ERROR_SUCCESS ) { if ( ClsidInfo->Clsid && (_stricmp(ClsidInfo->Clsid, ProgIdClsid) != 0) ) { printf( "ProgID %s has existing CLSID key value %s\n", ClsidInfo->ProgId, ProgIdClsid ); printf( "which differs from given CLSID %s.\n", ClsidInfo->Clsid ); printf( "Would you like to replace the existing CLSID value with the new CLSID value? " ); gets( Response ); if ( (char)CharUpper((LPSTR)Response[0]) != 'Y' ) ClsidInfo->Clsid = ProgIdClsid; } else ClsidInfo->Clsid = ProgIdClsid; } if ( ! ClsidInfo->Clsid ) { printf( "CLSID for ProgID %s not specified.\n", ClsidInfo->ProgId ); return; } if ( ClsidInfo->Clsid != ProgIdClsid ) { RegStatus = RegSetValueEx( hProgIdClsid, NULL, 0, REG_SZ, (LPBYTE) ClsidInfo->Clsid, strlen(ClsidInfo->Clsid) + sizeof(char) ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Could not set CLSID value for ProgID %s.\n", ClsidInfo->ProgId ); return; } printf( "Setting CLSID value %s for ProgID %s.\n", ClsidInfo->Clsid, ClsidInfo->ProgId ); } } RegStatus = RegCreateKeyEx( hRegClsid, ClsidInfo->Clsid, 0, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hClsid, &Disposition ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Could not open or create CLSID key %s.\n", ClsidInfo->Clsid ); return; } if ( Disposition == REG_CREATED_NEW_KEY ) printf( "CLSID key %s created.\n", ClsidInfo->Clsid ); if ( ClsidInfo->ClsidDescription ) { RegStatus = RegSetValueEx( hClsid, NULL, 0, REG_SZ, (LPBYTE) ClsidInfo->ClsidDescription, strlen(ClsidInfo->ClsidDescription) + sizeof(char) ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Could not set description value for CLSID %s.\n", ClsidInfo->Clsid ); return; } printf( "Setting description value %s for CLSID %s.\n", ClsidInfo->ClsidDescription, ClsidInfo->Clsid ); } // // Now add and delete individual keys on this CLSID. // if ( (ClsidInfo->LaunchPermission == YES) || (ClsidInfo->LaunchPermission == NO) ) { SetClsidKey( hClsid, ClsidInfo->Clsid, ClsidKeyNames[LAUNCH_PERMISSION], (ClsidInfo->LaunchPermission == YES) ? "Y" : "N" ); } if ( ClsidInfo->AccessPermission == YES ) { SetClsidKey( hClsid, ClsidInfo->Clsid, ClsidKeyNames[ACCESS_PERMISSION], NULL ); } if ( (ClsidInfo->ActivateAtStorage == YES) || (ClsidInfo->ActivateAtStorage == NO) ) { SetClsidKey( hClsid, ClsidInfo->Clsid, ClsidKeyNames[ACTIVATE_AT_STORAGE], (ClsidInfo->ActivateAtStorage == YES) ? "Y" : "N" ); } for ( n = 1; n <= CLSID_PATH_KEYS; n++ ) { if ( ! ClsidInfo->ServerPaths[n] ) continue; if ( ClsidInfo->ServerPaths[n][0] == '\0' ) DeleteClsidKey( hClsid, ClsidInfo->Clsid, ClsidKeyNames[n] ); else SetClsidKey( hClsid, ClsidInfo->Clsid, ClsidKeyNames[n], ClsidInfo->ServerPaths[n] ); } if ( ClsidInfo->RemoteServerName ) { if ( ClsidInfo->RemoteServerName[0] == '\0' ) DeleteClsidKey( hClsid, ClsidInfo->Clsid, ClsidKeyNames[REMOTE_SERVER_NAME] ); else SetClsidKey( hClsid, ClsidInfo->Clsid, ClsidKeyNames[REMOTE_SERVER_NAME], ClsidInfo->RemoteServerName ); } if ( ClsidInfo->RunAsUserName ) { DWORD CharRead; char Password1[64]; char Password2[64]; LSA_HANDLE hPolicy; LSA_OBJECT_ATTRIBUTES ObjAttributes; LSA_UNICODE_STRING LsaKey; LSA_UNICODE_STRING LsaData; WCHAR wszKey[64]; WCHAR wszPassword[64]; NTSTATUS NtStatus; BOOL Status; BOOL RunAsInteractiveUser; RunAsInteractiveUser = (_stricmp(ClsidInfo->RunAsUserName,"Interactive User") == 0); if ( ! RunAsInteractiveUser ) { InitializeObjectAttributes( &ObjAttributes, NULL, 0L, NULL, NULL ); // Open the local security policy NtStatus = LsaOpenPolicy( NULL, &ObjAttributes, POLICY_CREATE_SECRET, &hPolicy ); if ( ! NT_SUCCESS( NtStatus ) ) { printf( "Could not setup RunAs (0x%x)\n", NtStatus ); return; } lstrcpyW( wszKey, L"SCM:" ); MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, ClsidInfo->Clsid, -1, &wszKey[lstrlenW(wszKey)], sizeof(wszKey)/2 - lstrlenW(wszKey) ); LsaKey.Length = (lstrlenW(wszKey) + 1) * sizeof(WCHAR); LsaKey.MaximumLength = sizeof(wszKey); LsaKey.Buffer = wszKey; } if ( ClsidInfo->RunAsUserName[0] == '\0' ) { DeleteClsidKey( hClsid, ClsidInfo->Clsid, ClsidKeyNames[RUN_AS] ); LsaStorePrivateData( hPolicy, &LsaKey, NULL ); } else { Status = SetClsidKey( hClsid, ClsidInfo->Clsid, ClsidKeyNames[RUN_AS], ClsidInfo->RunAsUserName ); if ( ! Status ) return; if ( ! RunAsInteractiveUser && (ClsidInfo->RunAsPassword[0] == '*') ) { for (;;) { printf( "Enter RunAs password for %s : ", ClsidInfo->RunAsUserName ); ReadPassword( Password1 ); printf( "Confirm password : "******"Passwords differ, try again or hit Control-C to exit.\n" ); continue; } if ( Password1[0] == '\0' ) { printf( "Do you really want a blank password? " ); gets( Response ); if ( (char)CharUpper((LPSTR)Response[0]) != 'Y' ) continue; } break; } ClsidInfo->RunAsPassword = Password1; } // if password == "*" // Got a good one! if ( ! RunAsInteractiveUser ) { MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, ClsidInfo->RunAsPassword, -1, wszPassword, sizeof(wszPassword)/2 ); LsaData.Length = (lstrlenW(wszPassword) + 1) * sizeof(WCHAR); LsaData.MaximumLength = sizeof(wszPassword); LsaData.Buffer = wszPassword; // Store private data NtStatus = LsaStorePrivateData( hPolicy, &LsaKey, &LsaData ); if ( ! NT_SUCCESS(NtStatus) ) { printf( "Could not store password securely (0x%x)\n", NtStatus ); return; } LsaClose(hPolicy); } } } printf( "CLSID keys updated successfully.\n" ); }
HRESULT TCUserAccount::SetRunAsUser(LPCTSTR szAppID, LPCTSTR szUserName, LPCTSTR szPassword) { // Not supported under Windows9x if (IsWin9x()) return S_FALSE; // Copy the specified AppID string to a non-const wide string USES_CONVERSION; UINT cchAppID = max(_tcslen(szAppID), 48) + 1; LPWSTR pszAppID = (LPWSTR)_alloca(cchAppID * sizeof(WCHAR)); wcscpy(pszAppID, T2CW(szAppID)); // Resolve the specified string to an AppID HKEY hkey = NULL; RETURN_FAILED(ResolveAppID(pszAppID, &hkey)); CRegKey key; key.Attach(hkey); // Ensure that we have a domain name LPCTSTR pszUserName = szUserName; LPCTSTR pszWhack = _tcschr(szUserName, TEXT('\\')); if (!pszWhack || pszWhack == szUserName || (pszWhack == (szUserName + 1) && TEXT('.') == *szUserName)) { // Get the domain name and user name TCCoTaskPtr<LPTSTR> spszDomainName; RETURN_FAILED(GetSID(szUserName, NULL, &spszDomainName)); LPCTSTR pszUserOnly = pszWhack ? pszWhack + 1 : szUserName; // Concatenate the user name onto the domain name UINT cch = _tcslen(spszDomainName) + _tcslen(pszUserOnly) + 2; LPTSTR pszUserNameTemp = (LPTSTR)_alloca(cch * sizeof(TCHAR)); _tcscpy(pszUserNameTemp, spszDomainName); _tcscat(pszUserNameTemp, TEXT("\\")); _tcscat(pszUserNameTemp, pszUserOnly); pszUserName = pszUserNameTemp; } // Open the local security policy TCLsaHandle hPolicy; LSA_OBJECT_ATTRIBUTES oa = {sizeof(oa)}; RETURN_FAILED(LsaOpenPolicy(NULL, &oa, POLICY_CREATE_SECRET, &hPolicy)); // Format the key string WCHAR szKey[48] = L"SCM:"; wcscat(szKey, pszAppID); // Create an LSA_UNICODE_STRING for the key name LSA_UNICODE_STRING lsaKeyString; lsaKeyString.Length = (wcslen(szKey) + 1) * sizeof(WCHAR); lsaKeyString.MaximumLength = lsaKeyString.Length; lsaKeyString.Buffer = szKey; // Copy the specified password string to a non-const wide string UINT cchPassword = _tcslen(szPassword); LPWSTR pszPassword = (LPWSTR)_alloca((cchPassword + 1) * sizeof(WCHAR)); wcscpy(pszPassword, T2CW(szPassword)); // Create an LSA_UNICODE_STRING for the password string LSA_UNICODE_STRING lsaPasswordString; lsaPasswordString.Length = (cchPassword + 1) * sizeof(WCHAR); lsaPasswordString.MaximumLength = lsaPasswordString.Length; lsaPasswordString.Buffer = pszPassword; // Store the specified password RETURN_FAILED(LsaStorePrivateData(hPolicy, &lsaKeyString, &lsaPasswordString)); // Set the specified user name as the RunAs user for the AppID // mdvalley: Another former SetStringValue LONG lr = key.SetValue(TEXT("RunAs"), pszUserName); if (lr) return HRESULT_FROM_WIN32(lr); // Indicate success return S_OK; }