private async Task <RUserProfileCreateResponse> CreateProfileAsync(RUserProfileCreateRequest request, CancellationToken ct) { using (NamedPipeClientStream client = new NamedPipeClientStream("Microsoft.R.Host.UserProfile.Creator{b101cc2d-156e-472e-8d98-b9d999a93c7a}")) { try { await client.ConnectAsync(ct); string jsonReq = JsonConvert.SerializeObject(request); byte[] data = Encoding.Unicode.GetBytes(jsonReq.ToString()); await client.WriteAsync(data, 0, data.Length, ct); await client.FlushAsync(ct); byte[] responseRaw = new byte[1024]; var bytesRead = await client.ReadAsync(responseRaw, 0, responseRaw.Length, ct); string jsonResp = Encoding.Unicode.GetString(responseRaw, 0, bytesRead); return(JsonConvert.DeserializeObject <RUserProfileCreateResponse>(jsonResp)); } catch (Exception ex) when(!ex.IsCriticalException()) { _logger.LogError(Resources.Error_ProfileCreationFailedIO, request.Username); return(RUserProfileCreateResponse.Blank); } } }
internal static RUserProfileCreateResponse Create(RUserProfileCreateRequest request, ILogger logger = null) { IntPtr token; RUserProfileCreateResponse result = RUserProfileCreateResponse.Create(13, false, string.Empty); uint error = 0; if (LogonUser(request.Username, request.Domain, request.Password, (int)LogonType.LOGON32_LOGON_NETWORK, (int)LogonProvider.LOGON32_PROVIDER_DEFAULT, out token)) { WindowsIdentity winIdentity = new WindowsIdentity(token); StringBuilder profileDir = new StringBuilder(MAX_PATH); uint size = (uint)profileDir.Capacity; bool profileExists = false; error = CreateProfile(winIdentity.User.Value, request.Username, profileDir, size); // 0x800700b7 - Profile already exists. if (error != 0 && error != 0x800700b7) { logger?.LogError(Resources.Error_UserProfileCreateFailed, request.Domain, request.Username, error); result = RUserProfileCreateResponse.Blank; } else if (error == 0x800700b7) { profileExists = true; logger?.LogInformation(Resources.Info_UserProfileAlreadyExists, request.Domain, request.Username); } else { logger?.LogInformation(Resources.Info_UserProfileCreated, request.Domain, request.Username); } profileDir = new StringBuilder(MAX_PATH * 2); size = (uint)profileDir.Capacity; if (GetUserProfileDirectory(token, profileDir, ref size)) { logger?.LogInformation(Resources.Info_UserProfileDirectoryFound, request.Domain, request.Username, profileDir.ToString()); result = RUserProfileCreateResponse.Create(0, profileExists, profileDir.ToString()); } else { logger?.LogError(Resources.Error_UserProfileDirectoryWasNotFound, request.Domain, request.Username, Marshal.GetLastWin32Error()); result = RUserProfileCreateResponse.Create((uint)Marshal.GetLastWin32Error(), profileExists, profileDir.ToString()); } } else { logger?.LogError(Resources.Error_UserLogonFailed, request.Domain, request.Username, Marshal.GetLastWin32Error()); result = RUserProfileCreateResponse.Create((uint)Marshal.GetLastWin32Error(), false, null); } if (token != IntPtr.Zero) { CloseHandle(token); } return(result); }
private async Task <ClaimsPrincipal> SignInUsingLogonAsync(BasicSignInContext context) { var user = new StringBuilder(NativeMethods.CREDUI_MAX_USERNAME_LENGTH + 1); var domain = new StringBuilder(NativeMethods.CREDUI_MAX_PASSWORD_LENGTH + 1); uint error = NativeMethods.CredUIParseUserName(context.Username, user, user.Capacity, domain, domain.Capacity); if (error != 0) { _logger.LogError(Resources.Error_UserNameParse, context.Username, error.ToString("X")); return(null); } IntPtr token; WindowsIdentity winIdentity = null; string profilePath = string.Empty; _logger.LogTrace(Resources.Trace_LogOnUserBegin, context.Username); if (NativeMethods.LogonUser(user.ToString(), domain.ToString(), context.Password, (int)LogonType.LOGON32_LOGON_NETWORK, (int)LogonProvider.LOGON32_PROVIDER_DEFAULT, out token)) { _logger.LogTrace(Resources.Trace_LogOnSuccess, context.Username); winIdentity = new WindowsIdentity(token); StringBuilder profileDir; #if DEBUG CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromMinutes(10)); #else CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); #endif _logger.LogTrace(Resources.Trace_UserProfileCreation, context.Username); var result = await CreateProfileAsync(RUserProfileCreateRequest.Create(user.ToString(), domain.ToString(), context.Password), cts.Token); if (result.IsInvalidResponse()) { _logger.LogError(Resources.Error_ProfileCreationFailedInvalidResponse, context.Username, Resources.Info_UserProfileServiceName); return(null); } error = result.Error; // 0x800700b7 - Profile already exists. if (error != 0 && error != 0x800700b7) { _logger.LogError(Resources.Error_ProfileCreationFailed, context.Username, error.ToString("X")); return(null); } else if (error == 0x800700b7 || result.ProfileExists) { _logger.LogInformation(Resources.Info_ProfileAlreadyExists, context.Username); } else { _logger.LogInformation(Resources.Info_ProfileCreated, context.Username); } profileDir = new StringBuilder(NativeMethods.MAX_PATH * 2); uint size = (uint)profileDir.Capacity; if (NativeMethods.GetUserProfileDirectory(token, profileDir, ref size)) { profilePath = profileDir.ToString(); _logger.LogTrace(Resources.Trace_UserProfileDirectory, context.Username, profilePath); } else { _logger.LogError(Resources.Error_GetUserProfileDirectory, context.Username, Marshal.GetLastWin32Error().ToString("X")); } } else { _logger.LogError(Resources.Error_LogOnFailed, context.Username, Marshal.GetLastWin32Error().ToString("X")); return(null); } var principal = new WindowsPrincipal(winIdentity); if (principal.IsInRole(_options.AllowedGroup)) { var claims = new[] { //new Claim(ClaimTypes.Name, context.Username), new Claim(Claims.RUser, ""), // TODO: figure out how to avoid keeping raw credentials around. new Claim(Claims.Password, context.Password), new Claim(Claims.RUserProfileDir, profilePath) }; var claimsIdentity = new ClaimsIdentity(claims, context.Options.AuthenticationScheme); principal.AddIdentities(new[] { claimsIdentity }); } return(principal); }