Exemple #1
0
        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);
                }
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }